Systemd

systemd is a common service manager used by many Linux distributions. resticprofile can create systemd timer and service files.

User systemd units are created under the user’s systemd profile (~/.config/systemd/user).

System units are created in /etc/systemd/system.

systemd calendars

resticprofile uses the systemd OnCalendar format to schedule events.

Test systemd calendars with systemd-analyze. It will display the next trigger time:

systemd-analyze calendar 'daily'

  Original form: daily
Normalized form: *-*-* 00:00:00
    Next elapse: Sat 2020-04-18 00:00:00 CDT
       (in UTC): Sat 2020-04-18 05:00:00 UTC
       From now: 10h left

First time schedule

When you schedule a profile with the schedule command, resticprofile will:

  • Create the unit file (type notify)
  • Create the timer file
  • Run systemctl daemon-reload (if schedule-permission is set to system)
  • Run systemctl enable
  • Run systemctl start

Priority and CPU scheduling

resticprofile allows you to set the nice value, CPU scheduling policy, and IO nice values for the systemd service. This works properly for resticprofile >= 0.29.0.

systemd unit optionresticprofile option
CPUSchedulingPolicySet to idle if priority is background, otherwise defaults to standard policy
Nicenice from global section
IOSchedulingClassionice-class from global section
IOSchedulingPriorityionice-level from global section
Note

When setting CPUSchedulingPolicy to idle (by setting priority to background), the backup might never execute if all your CPU cores are always busy.

Permission

Until version v0.30.0, the user permission was actually user_logged_on unless you activated lingering for the user.

This is now fixed:

PermissionType of unitWithout lingeringWith lingering
systemsystem servicecan run any timecan run any time
usersystem service with User= field definedcan run any timecan run any time
user_logged_onuser serviceruns only when user is logged oncan run any time

Run after the network is up

Setting the profile option schedule-after-network-online: true ensures scheduled services wait for a network connection before running. This is achieved with an After=network-online.target entry in the service.

systemd drop-in files

You can automatically populate *.conf.d drop-in files for profiles, allowing easy overrides of generated services without modifying service templates. For example:

version = "1"

[root]
  systemd-drop-in-files = ["99-drop-in-example.conf"]

  [root.backup]
    schedule = "hourly"
    schedule-permission = "system"
    schedule-lock-wait = "45m"
    schedule-after-network-online = true
---
version: 1

root:
  systemd-drop-in-files:
    - "99-drop-in-example.conf"

  backup:
    schedule: hourly
    schedule-permission: system
    schedule-lock-wait: 45m
    schedule-after-network-online: true
"version" = "1"

"root" = {
  "systemd-drop-in-files" = ["99-drop-in-example.conf"]
  "backup" = {
    "schedule" = "hourly"
    "schedule-permission" = "system"
    "schedule-lock-wait" = "45m"
    "schedule-after-network-online" = true
  }
}
{
  "version": "1",
  "root": {
    "systemd-drop-in-files": ["99-drop-in-example.conf"],
    "backup": {
      "schedule": "hourly",
      "schedule-permission": "system",
      "schedule-lock-wait": "45m",
      "schedule-after-network-online": true
    }
  }
}

Where 99-drop-in-example.conf is in the same directory as profiles.toml and with the contents

[Service]
Environment=RCLONE_CONFIG=%d/rclone.conf
SetCredentialEncrypted=restic-repo-password: \
        Whxqht+dQJax1aZeCGLxmiAAAAABAAAADAAAABAAAABl6ctIWEqgRC4yHbgAAAAA8umMn \
        +6KYd8tAL58jUmtf/5wckDcxQSeuo+xd9OzN5XG7QW0iBIRRGCuWvvuAAiHEAKSk9MR8p \
        EDSaSm
SetCredentialEncrypted=rclone.conf: \
        Whxqht+dQJax1aZeCGLxmiAAAAABAAAADAAAABAAAAC+vNhJYedv5QmyDHYAAAAAimeli \
        +Oo+URGN47SUBf7Jm1n3gdu22+Sd/eL7CjzpYQvHAMOCY8xz9hp9kW9/DstWHTfdsHJo7 \
        thOpk4IbSSazCPwEr39VVQONLxzpRlY22LkQKLoGAVD4Yifk+U5aJJ4FlRW/VGpPoef2S \
        rGvQzqQI7kNX+v7EPXj4B0tSUeBBJJCEu4mgajZNAhwHtbw==

Generated with the following. See systemd credentials docs for more details. This allows using a TPM-backed encrypted password outside the resticprofile config.

systemd-ask-password -n | sudo systemd-creds encrypt --name=restic-repo-password -p - -
sudo systemd-creds encrypt --name=rclone.conf -p - - <<EOF
[restic-example]
type = smb
host = example
user = restic
pass = $(systemd-ask-password -n "smb restic user password" | rclone obscure -)
EOF

How to change the default systemd unit and timer file using a template

By default, resticprofile automatically generates a systemd unit and timer.

You can create custom templates to add features (e.g., sending an email on failure).

The format is a Go template. Specify your custom unit and/or timer file in the global section of the configuration to apply it to all profiles:

[global]
  systemd-unit-template = "service.tmpl"
  systemd-timer-template = "timer.tmpl"
---
global:
  systemd-unit-template: service.tmpl
  systemd-timer-template: timer.tmpl
"global" = {
  "systemd-unit-template" = "service.tmpl"
  "systemd-timer-template" = "timer.tmpl"
}
{
  "global": {
    "systemd-unit-template": "service.tmpl",
    "systemd-timer-template": "timer.tmpl"
  }
}

Here are the defaults if you don’t specify your own. I recommend using them as a starting point for your templates.

Default unit file

[Unit]
Description={{ .JobDescription }}
{{ if .AfterNetworkOnline }}After=network-online.target
{{ end }}
[Service]
Type=notify
WorkingDirectory={{ .WorkingDirectory }}
ExecStart={{ .CommandLine }}
{{ if .Nice }}Nice={{ .Nice }}
{{ end -}}
{{ if .CPUSchedulingPolicy }}CPUSchedulingPolicy={{ .CPUSchedulingPolicy }}
{{ end -}}
{{ if .IOSchedulingClass }}IOSchedulingClass={{ .IOSchedulingClass }}
{{ end -}}
{{ if .IOSchedulingPriority }}IOSchedulingPriority={{ .IOSchedulingPriority }}
{{ end -}}
{{ range .Environment -}}
Environment="{{ . }}"
{{ end -}}

Default timer file

[Unit]
Description={{ .TimerDescription }}

[Timer]
{{ range .OnCalendar -}}
OnCalendar={{ . }}
{{ end -}}
Unit={{ .SystemdProfile }}
Persistent=true

[Install]
WantedBy=timers.target

Template variables

These are available for both the unit and timer templates:

  • JobDescription string
  • TimerDescription string
  • WorkingDirectory string
  • CommandLine string
  • OnCalendar array of strings
  • SystemdProfile string
  • Nice integer
  • Environment array of strings