When this table is present in Cargo.toml
AND maintainer-scripts
is also specified, correct installation of systemd units will be handled automatically for you.
This works as follows:
- Assets will be added for any matching systemd unit files found in the
unit-scripts
(see below) directory. - Shell script fragments will be generated for enabling, disabling, starting, stopping, and restarting the corresponding systemd services, when the package is installed, updated, or removed.
maintainer-scripts
(prerm
,postrm
,preinst
and/orpostinst
) will be augmented (by replacing the special token#DEBHELPER#
), or created if missing, using the generated shell script fragments.
Note: <maintainer-scripts>
MUST be set, even if it is an empty directory. If non-empty, any maintainer scripts present MUST contain the #DEBHELPER#
token denoting the point at which generated shell script fragments should be inserted.
The exact behaviour can be tuned using the following options:
- unit-scripts: Directory containing zero or more systemd unit files (see below for matching rules) (defaults to the value of the
maintainer-scripts
option). - unit-name: Only include systemd unit files for this unit (see below for matching rules).
- enable: Enable the systemd unit on package installation and disable it on package removal (default
true
). - start: Start the systemd unit on package installation and stop it on package removal (default
true
). - restart-after-upgrade: If true, postpone systemd service restart until after upgrade is complete (+ = less downtime, - = can confuse some programs), otherwise stop the service before upgrade and start it again after upgrade (default
true
). - stop-on-upgrade: If true stop the systemd on package upgrade and removal, otherwise stop the sytemsd service only on package removal (default
true
).
Systemd unit file names must match one of the following patterns:
<package>.<unit>.<suffix>
- only ifunit-name
is specified<package>.<unit>@.<suffix>
- only ifunit-name
is specified<package>.<suffix>
<package>@.<suffix>
<unit>.<suffix>
- only ifunit-name
is specified<unit>@.<suffix>
- only ifunit-name
is specified
Where <suffix>
is one of: mount
(@ not supported), path
, service
, socket
, target
, timer
, tmpfile
(@ not supported)
User supplied maintainer-scripts
file names must match one of the following patterns:
<package>.<unit>.<script>
- only ifunit-name
is specified<package>.<script>
<unit>.<script>
- only ifunit-name
is specified<script>
Where <script>
is one of: preinst
, postinst
, prerm
, postrm
.
NOTE: When using the variant feature, <package>
will actually be <package>-<variant>
unless the variant name has been overridden using name
in the variant specific metadata table. You can use this to supply variant specific unit files and maintainer scripts.
See:
- The dh_installsystemd Ubuntu 20.04 man page
- The systemd documentation for more details on unit naming.
- The Debian Policy Manual for more information about maintainer scripts.
- A list of shell fragments which may be inserted.
Cargo.toml
:
[package]
name = "example"
version = "1.2.3"
description = "An example package to demonstrate cargo-deb systemd-units support."
license = "MIT"
authors = ["cargo-deb team"]
[package.metadata.deb]
maintainer-scripts = "debian/"
systemd-units = { enable = false }
debian/service
:
[Unit]
Description=Example
[Service]
ExecStart=/usr/bin/example
[Install]
WantedBy=multi-user.target
src/main.rs
:
fn main() {
println!("Hello World!");
}
Invoke cargo-deb with verbose output enabled:
$ cargo-deb -v
Compiling example v1.2.3 (/tmp/t)
Running `rustc --crate-name example src/main.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C opt-level=3 -Cembed-bitcode=no -C metadata=25d9e83f3daf475a -C extra-filename=-25d9e83f3daf475a --out-dir /tmp/t/target/release/deps -L dependency=/tmp/t/target/release/deps`
Finished release [optimized] target(s) in 0.12s
info: Stripped '/tmp/t/target/release/example'
info: /tmp/t/target/release/example -> usr/bin/example
info: - -> usr/share/doc/example/copyright
info: /tmp/t/debian/service -> lib/systemd/system/example.service
info: Determining augmentations needed for systemd unit example.service
info: Maintainer script postinst will be augmented with autoscript postinst-systemd-dont-enable
info: Maintainer script postrm will be augmented with autoscript postrm-systemd
info: Maintainer script postinst will be augmented with autoscript postinst-systemd-restart
info: Maintainer script prerm will be augmented with autoscript prerm-systemd-restart
info: Maintainer script postrm will be augmented with autoscript postrm-systemd-reload-only
info: Generating maintainer script postinst
info: Generating maintainer script prerm
info: Generating maintainer script postrm
info: compressed/original ratio 91596/243712 (37%)
/tmp/t/target/debian/example_1.2.3_amd64.deb
Use dpkg
to inspect the created archives maintainer scripts:
$ dpkg -e target/debian/example_1.2.3_amd64.deb deb_out
$ ls -la deb_out/
total 28
drwxr-xr-x 2 ximon ximon 4096 aug 19 12:31 .
drwxrwxr-x 6 ximon ximon 4096 aug 19 12:31 ..
-rw-r--r-- 1 ximon ximon 249 aug 19 12:28 control
-rw-r--r-- 1 ximon ximon 185 aug 19 12:28 md5sums
-rwxr-xr-x 1 ximon ximon 1211 aug 19 12:28 postinst
-rwxr-xr-x 1 ximon ximon 599 aug 19 12:28 postrm
-rwxr-xr-x 1 ximon ximon 206 aug 19 12:28 prerm
Inspect one of the generated maintainer scripts:
$ cat deb_out/postinst
#!/bin/sh
set -e
# Automatically added by cargo-deb
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if deb-systemd-helper debian-installed example.service; then
# This will only remove masks created by d-s-h on package removal.
deb-systemd-helper unmask example.service >/dev/null || true
if deb-systemd-helper --quiet was-enabled example.service; then
# Create new symlinks, if any.
deb-systemd-helper enable example.service >/dev/null || true
fi
fi
# Update the statefile to add new symlinks (if any), which need to be cleaned
# up on purge. Also remove old symlinks.
deb-systemd-helper update-state example.service >/dev/null || true
fi
# End automatically added section
# Automatically added by cargo-deb
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if [ -d /run/systemd/system ]; then
systemctl --system daemon-reload >/dev/null || true
if [ -n "$2" ]; then
_dh_action=restart
else
_dh_action=start
fi
deb-systemd-invoke $_dh_action example.service >/dev/null || true
fi
fi
# End automatically added section
Note that two shell script fragments have been injected into the maintainer script and that the #RESTART_ACTION#
and #UNITFILE#
placeholder tokens have been replaced compared to the original autoscripts here and here.
For a more advanced example you might want to look at the NLnet Labs Krill project use of cargo-deb (disclaimer: this author is a contributor) which shows:
- Use of
unit-name
(here). - Use of user provided maintainer scripts (e.g. here) with included
#DEBHELPER#
token to add maintainer script fragments to existing scripts which create a shell user and create (and remove on purge) a config file. - Use of operating system specific systemd service unit files via cargo-deb variants and symbolic links (e.g. here).
- Use of
--variant
and--deb-version
command line arguments (here).
Additionally, though not strictly related to systemd-units support but still cargo-deb related, it shows: