TT Lab
Get started
Learn Learning paths Courses

LFCS — Linux Foundation System Administrator

Writing Unit Files and Scheduling Configuration

Continue in TT Lab

Goal

You write systemd unit files and timers, cron files, log rotation settings, and drop-in overrides yourself, following the syntax and section rules.

Why it matters

In this lab environment systemctl is blocked, so you cannot start services. So all grading is done on file contents. At first glance it seems like a loss, but in practice it lets you concentrate exactly on the spot where people get the most wrong on the exam — the reason you miss a unit problem on the LFCS is not that the service failed to start, but that you put a directive in the wrong section or got the format wrong. If you write WantedBy in [Service], it will not be enabled; a timer's WantedBy is timers.target, not multi-user.target; and a file in /etc/cron.d has one more user field. When you change ExecStart in a drop-in, if you do not clear it once with an empty line, there become two commands and startup fails. All of these are errors you can catch from the file alone.

Steps

  1. Create /root/lfcs-svc/lfcs-api.service and put the three sections [Unit], [Service], and [Install] in this order. Put a non-empty Description= in [Unit].
  2. In the same file, fill in After=network-online.target, Wants=network-online.target, Type=simple, ExecStart=/usr/local/bin/lfcs-api --port 8080, Restart=on-failure, RestartSec=5, User=lfcsapi, and WantedBy=multi-user.target, each in the appropriate section.
  3. In /root/lfcs-svc/lfcs-backup.timer, put a [Timer] section with OnCalendar=*-*-* 03:30:00, Persistent=true, and Unit=lfcs-backup.service, and enable it with WantedBy=timers.target. In the paired /root/lfcs-svc/lfcs-backup.service, put Type=oneshot and ExecStart=/usr/local/bin/lfcs-backup.sh.
  4. Create /etc/cron.d/lfcs-report and put in a line beginning with */15 * * * * root /usr/local/bin/lfcs-report.sh, but send the output to /var/log/lfcs-report.log.
  5. In /root/lfcs-svc/lfcsops.crontab, put 30 2 * * 1-5 /usr/local/bin/lfcs-rotate.sh in user crontab format. This format has no user field.
  6. In /etc/cron.d/lfcs-report, put the two lines SHELL=/bin/bash and PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin before the schedule line.
  7. In /root/lfcs-svc/lfcs-report.logrotate, create a block for /var/log/lfcs-report.log and put in daily, rotate 14, compress, delaycompress, missingok, notifempty, and create 0640 root adm.
  8. Create /root/lfcs-svc/lfcs-api.service.d/override.conf, put an empty-valued ExecStart= first under [Service], and then add ExecStart=/usr/local/bin/lfcs-api --port 9090 and MemoryMax=512M.

Notes

Build the unit file skeleton

Create /root/lfcs-svc/lfcs-api.service and put the three sections [Unit], [Service], and [Install] in this order. Put a non-empty Description= in [Unit].

A unit file is in INI format and section names are wrapped in square brackets. Get the order and capitalization of the three sections exactly right.

Execution, restart, and enable directives

In the same file, fill in After=network-online.target, Wants=network-online.target, Type=simple, ExecStart=/usr/local/bin/lfcs-api --port 8080, Restart=on-failure, RestartSec=5, User=lfcsapi, and WantedBy=multi-user.target, each in the appropriate section.

Which section each directive belongs to is fixed. The enable target goes in [Install], the way it runs goes in [Service], and ordering dependencies go in [Unit].

Timer unit and its paired service

In /root/lfcs-svc/lfcs-backup.timer, put a [Timer] section with OnCalendar=*-*-* 03:30:00, Persistent=true, and Unit=lfcs-backup.service, and enable it with WantedBy=timers.target. In the paired /root/lfcs-svc/lfcs-backup.service, put Type=oneshot and ExecStart=/usr/local/bin/lfcs-backup.sh.

A timer does not do work itself; it wakes the unit with the same name. There is a separate directive that makes it catch up on runs that passed while it was off.

Writing a /etc/cron.d file

Create /etc/cron.d/lfcs-report and put in a line beginning with */15 * * * * root /usr/local/bin/lfcs-report.sh, but send the output to /var/log/lfcs-report.log.

A system cron file has one more field, the user to run as, after the 5 time fields. If you do not keep the output, cron tries to send it by mail.

User crontab format

In /root/lfcs-svc/lfcsops.crontab, put 30 2 * * 1-5 /usr/local/bin/lfcs-rotate.sh in user crontab format. This format has no user field.

A user crontab has no user field. In the day-of-week field, a range is written with a hyphen.

cron's PATH problem

In /etc/cron.d/lfcs-report, put the two lines SHELL=/bin/bash and PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin before the schedule line.

Environment variable lines take effect only if they come before the schedule line. The reason for this step is that the PATH cron gives by default is much shorter than that of a login shell.

Log rotation settings

In /root/lfcs-svc/lfcs-report.logrotate, create a block for /var/log/lfcs-report.log and put in daily, rotate 14, compress, delaycompress, missingok, notifempty, and create 0640 root adm.

After the target path, open a brace block and put in one directive per line. There is a directive that specifies the permissions and ownership of the new file to be created right after rotation.

Drop-in override

Create /root/lfcs-svc/lfcs-api.service.d/override.conf, put an empty-valued ExecStart= first under [Service], and then add ExecStart=/usr/local/bin/lfcs-api --port 9090 and MemoryMax=512M.

The drop-in directory name is the unit file name with a suffix attached. A list-type directive appends to the existing value unless you first put a line that clears its value.