-
Notifications
You must be signed in to change notification settings - Fork 3
systemd service files
Currently, some help is needed converting the old Upstart/SysV xboxdrv service files we have, into systemd service files. Work has begun on this, but verification and testing are very welcome. For information on writing service files, please see resources below.
systemd consists of two main concepts: a unit and a target. A unit is a configuration file that describes the properties of the process that you'd like to run. This is normally a docker run command or something similar. A target is a grouping mechanism that allows systemd to start up groups of processes at the same time. This happens at every boot as processes are started at different run levels.
systemd is the first process started on a systemd-compatible system, and it reads different targets and starts the processes specified which allows the operating system to start. The target that you'll interact with is the multi-user.target
which holds all of the general use unit files for our containers.
Each target is actually a collection of symlinks to our unit files. This is specified in the unit file by WantedBy=multi-user.target. Running systemctl enable foo.service
creates symlinks to the unit inside multi-user.target.wants
.
####Unit File
Unit files are located within the R/W filesystem at /etc/systemd/system. Let's create a simple unit named hello.service:
[Unit]
Description=MyApp
After=docker.service
Requires=docker.service
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill busybox1
ExecStartPre=-/usr/bin/docker rm busybox1
ExecStartPre=/usr/bin/docker pull busybox
ExecStart=/usr/bin/docker run --name busybox1 busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"
[Install]
WantedBy=multi-user.target
####Explanations
The Description
shows up in the systemd log and a few other places. Write something that will help you understand exactly what this does later on.
After=docker.service
and Requires=docker.service
means this unit will only start after docker.service
is active. You can define as many of these as you want.
ExecStart=
allows you to specify any command that you'd like to run when this unit is started. The pid assigned to this process is what systemd will monitor to determine whether the process has crashed or not. Do not run docker containers with -d as this will prevent the container from starting as a child of this pid. systemd will think the process has exited and the unit will be stopped.
WantedBy=
is the target that this unit is a part of.
To start a new unit, we need to tell systemd to create the symlink and then start the file:
$ sudo systemctl enable /etc/systemd/system/hello.service
$ sudo systemctl start hello.service
To verify the unit started, you can see the list of containers running with docker ps and read the unit's output with journalctl:
$ journalctl -f -u hello.service
-- Logs begin at Fri 2014-02-07 00:05:55 UTC. --
Feb 11 17:46:26 localhost docker[23470]: Hello World
Feb 11 17:46:27 localhost docker[23470]: Hello World
Feb 11 17:46:28 localhost docker[23470]: Hello World
Source: CoreOS.com
Additional Reading:
You don't have to create a true systemd service file, but it is suggested. If "conversion" is not in the cards, you can make use of calling a script through the Exec
line of the systemd service file.
Therefore you need two files: the script and the "service" file. Let's say your script is called vgaoff. Place your script in /usr/lib/systemd/scripts, make it executable. Then create a new service file in /usr/lib/systemd/system (a plain text file, let's call it vgaoff.service). So this is the location of your files:
- The script:
/usr/lib/systemd/scripts/vgaoff
- The service:
/usr/lib/systemd/system/vgaoff.service
Now you have to edit the service file. Its content depends on how your script works:
If vgaoff just powers off the gpu, e.g.: exec blah-blah pwrOFF etc
...then the content of vgaoff.service should be:
[Unit]
Description=Power-off gpu
[Service]
Type=oneshot
ExecStart=/usr/lib/systemd/scripts/vgaoff
[Install]
WantedBy=multi-user.target
If vgaoff is used to power off the GPU and also to power it back on, e.g.:
start() {
exec blah-blah pwrOFF etc
}
stop() {
exec blah-blah pwrON etc
}
case $1 in
start|stop) "$1" ;;
esac
...then the content of vgaoff.service should be:
[Unit]
Description=Power-off gpu
[Service]
Type=oneshot
ExecStart=/usr/lib/systemd/scripts/vgaoff start
ExecStop=/usr/lib/systemd/scripts/vgaoff stop
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Once you have the files in place and configured you can enable the service: systemctl enable vgaoff.service
It should then start automatically after rebooting the machine.
- For the most trivial cases, you can do without the script and execute a certain command directly through the .service file:
To power off:
[Unit]
Description=Power-off gpu
[Service]
Type=oneshot
ExecStart=/bin/sh -c "echo OFF > /whatever/vga_pwr_gadget/switch"
[Install]
WantedBy=multi-user.target
To power off & on:
[Unit]
Description=Power-off gpu
[Service]
Type=oneshot
ExecStart=/bin/sh -c "echo OFF > /whatever/vga_pwr_gadget/switch"
ExecStop=/bin/sh -c "echo ON > /whatever/vga_pwr_gadget/switch"
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Source: StackExchange