diff options
author | Michael Stapelberg <stapelberg@debian.org> | 2013-06-11 23:32:11 +0200 |
---|---|---|
committer | Michael Stapelberg <michael@stapelberg.de> | 2013-06-11 23:32:11 +0200 |
commit | d50611823c584b891ad076ef922cfddd67c51752 (patch) | |
tree | 05af91f2d36860de4428a45d72ef8b0d6c62455a | |
parent | 244fbdca67461cf62f263fa79afde9395f5a4500 (diff) | |
download | init-system-helpers-d50611823c584b891ad076ef922cfddd67c51752.tar.gz |
add dh-systemd package, update changelogdebian/1.1
-rw-r--r-- | Makefile.PL | 11 | ||||
-rw-r--r-- | autoscripts/postinst-systemd-enable | 1 | ||||
-rw-r--r-- | autoscripts/postinst-systemd-enable-restart | 6 | ||||
-rw-r--r-- | autoscripts/postinst-systemd-enable-start | 6 | ||||
-rw-r--r-- | autoscripts/postinst-systemd-restart | 3 | ||||
-rw-r--r-- | autoscripts/postinst-systemd-start | 3 | ||||
-rw-r--r-- | autoscripts/postrm-systemd | 5 | ||||
-rw-r--r-- | autoscripts/postrm-systemd-reload | 9 | ||||
-rw-r--r-- | autoscripts/postrm-systemd-reload-only | 3 | ||||
-rw-r--r-- | autoscripts/prerm-systemd | 3 | ||||
-rw-r--r-- | autoscripts/prerm-systemd-restart | 3 | ||||
-rw-r--r-- | debian/changelog | 7 | ||||
-rw-r--r-- | debian/control | 11 | ||||
-rw-r--r-- | debian/dh-systemd.install | 4 | ||||
-rw-r--r-- | debian/init-system-helpers.install | 2 | ||||
-rw-r--r-- | lib/Debian/Debhelper/Sequence/systemd.pm | 8 | ||||
-rwxr-xr-x | script/dh_systemd | 301 |
17 files changed, 386 insertions, 0 deletions
diff --git a/Makefile.PL b/Makefile.PL index 81e1723..def37bc 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -4,5 +4,16 @@ name 'init-system-helpers'; version '1.0'; install_script 'deb-systemd-helper'; +install_script 'dh_systemd'; + +postamble <<'END_OF_MAKEFILE'; +install:: extra_install +pure_install:: extra_install +install_vendor:: extra_install + +extra_install: + install -d $(DESTDIR)/usr/share/debhelper/autoscripts + install -m 640 autoscripts/* $(DESTDIR)/usr/share/debhelper/autoscripts +END_OF_MAKEFILE WriteAll; diff --git a/autoscripts/postinst-systemd-enable b/autoscripts/postinst-systemd-enable new file mode 100644 index 0000000..052dc0e --- /dev/null +++ b/autoscripts/postinst-systemd-enable @@ -0,0 +1 @@ +deb-systemd-helper enable #UNITFILES# >/dev/null || true diff --git a/autoscripts/postinst-systemd-enable-restart b/autoscripts/postinst-systemd-enable-restart new file mode 100644 index 0000000..a63aa6b --- /dev/null +++ b/autoscripts/postinst-systemd-enable-restart @@ -0,0 +1,6 @@ +deb-systemd-helper enable #UNITFILES# >/dev/null || true + +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + systemctl try-restart #UNITFILES# >/dev/null || true +fi diff --git a/autoscripts/postinst-systemd-enable-start b/autoscripts/postinst-systemd-enable-start new file mode 100644 index 0000000..6cccdcf --- /dev/null +++ b/autoscripts/postinst-systemd-enable-start @@ -0,0 +1,6 @@ +deb-systemd-helper enable #UNITFILES# >/dev/null || true + +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true + systemctl start #UNITFILES# >/dev/null || true +fi diff --git a/autoscripts/postinst-systemd-restart b/autoscripts/postinst-systemd-restart new file mode 100644 index 0000000..e96bc93 --- /dev/null +++ b/autoscripts/postinst-systemd-restart @@ -0,0 +1,3 @@ +if [ -d /run/systemd/system ]; then + systemctl try-restart #UNITFILES# >/dev/null || true +fi diff --git a/autoscripts/postinst-systemd-start b/autoscripts/postinst-systemd-start new file mode 100644 index 0000000..bf6458b --- /dev/null +++ b/autoscripts/postinst-systemd-start @@ -0,0 +1,3 @@ +if [ -d /run/systemd/system ]; then + systemctl start #UNITFILES# >/dev/null || true +fi diff --git a/autoscripts/postrm-systemd b/autoscripts/postrm-systemd new file mode 100644 index 0000000..ddc2269 --- /dev/null +++ b/autoscripts/postrm-systemd @@ -0,0 +1,5 @@ +if [ "$1" = "remove" ] || [ "$1" = "purge" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper disable #UNITFILES# >/dev/null + fi +fi diff --git a/autoscripts/postrm-systemd-reload b/autoscripts/postrm-systemd-reload new file mode 100644 index 0000000..d86be20 --- /dev/null +++ b/autoscripts/postrm-systemd-reload @@ -0,0 +1,9 @@ +if [ "$1" = "remove" ] || [ "$1" = "purge" ]; then + if [ -x "/usr/bin/deb-systemd-helper" ]; then + deb-systemd-helper disable #UNITFILES# >/dev/null + fi +fi + +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true +fi diff --git a/autoscripts/postrm-systemd-reload-only b/autoscripts/postrm-systemd-reload-only new file mode 100644 index 0000000..91cd9e8 --- /dev/null +++ b/autoscripts/postrm-systemd-reload-only @@ -0,0 +1,3 @@ +if [ -d /run/systemd/system ]; then + systemctl --system daemon-reload >/dev/null || true +fi diff --git a/autoscripts/prerm-systemd b/autoscripts/prerm-systemd new file mode 100644 index 0000000..aa36110 --- /dev/null +++ b/autoscripts/prerm-systemd @@ -0,0 +1,3 @@ +if [ -d /run/systemd/system ]; then + systemctl stop #UNITFILES# >/dev/null +fi diff --git a/autoscripts/prerm-systemd-restart b/autoscripts/prerm-systemd-restart new file mode 100644 index 0000000..6f4e584 --- /dev/null +++ b/autoscripts/prerm-systemd-restart @@ -0,0 +1,3 @@ +if [ -d /run/systemd/system ] && [ "$1" = remove ]; then + systemctl stop #UNITFILES# >/dev/null +fi diff --git a/debian/changelog b/debian/changelog index e517e92..c6546ad 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +init-system-helpers (1.1) unstable; urgency=low + + * deb-systemd-helper: also store enable state for already enabled units + * add dh-systemd package which contains the dh_systemd debhelper add-on + + -- Michael Stapelberg <stapelberg@debian.org> Tue, 11 Jun 2013 23:32:02 +0200 + init-system-helpers (1.0) unstable; urgency=low * Initial release diff --git a/debian/control b/debian/control index 23b0e20..369bd92 100644 --- a/debian/control +++ b/debian/control @@ -22,3 +22,14 @@ Description: helper tools for all init systems While this package is maintained by pkg-systemd-maintainers, it is NOT specific to systemd at all. Maintainers of other init systems are welcome to include their helpers in this package. + +Package: dh-systemd +Architecture: all +Depends: ${perl:Depends}, ${misc:Depends}, debhelper +Description: debhelper add-on to handle systemd unit files + dh-systemd provides a debhelper sequence addon named 'systemd' and the + dh_systemd command. + . + The dh_systemd command adds the appropriate code to the postinst, prerm and + postrm maint scripts to properly enable/disable systemd service files and deal + with start/stop/restart on upgrades for systemd-only service files. diff --git a/debian/dh-systemd.install b/debian/dh-systemd.install new file mode 100644 index 0000000..5e5dc1c --- /dev/null +++ b/debian/dh-systemd.install @@ -0,0 +1,4 @@ +usr/bin/dh_systemd +usr/share/perl5/Debian/Debhelper/Sequence/systemd.pm +usr/share/debhelper/autoscripts +usr/share/man/man1/dh_systemd.1p diff --git a/debian/init-system-helpers.install b/debian/init-system-helpers.install new file mode 100644 index 0000000..3813300 --- /dev/null +++ b/debian/init-system-helpers.install @@ -0,0 +1,2 @@ +usr/bin/deb-systemd-helper +usr/share/man/man1/deb-systemd-helper.1p diff --git a/lib/Debian/Debhelper/Sequence/systemd.pm b/lib/Debian/Debhelper/Sequence/systemd.pm new file mode 100644 index 0000000..6ad0274 --- /dev/null +++ b/lib/Debian/Debhelper/Sequence/systemd.pm @@ -0,0 +1,8 @@ +#!/usr/bin/perl +use warnings; +use strict; +use Debian::Debhelper::Dh_Lib; + +insert_after("dh_installinit", "dh_systemd"); + +1 diff --git a/script/dh_systemd b/script/dh_systemd new file mode 100755 index 0000000..e513e14 --- /dev/null +++ b/script/dh_systemd @@ -0,0 +1,301 @@ +#!/usr/bin/perl -w + +=head1 NAME + +dh_systemd - enable/start/stop/restart systemd unit files + +=cut + +use strict; +use Debian::Debhelper::Dh_Lib; +use File::Find; +use Text::ParseWords qw(shellwords); # in core since Perl 5 + +=head1 SYNOPSIS + +B<dh_systemd> [S<I<debhelper options>>] [B<--no-enable>] [B<--restart-after-upgrade>] [B<--no-restart-on-upgrade>] [B<--assume-sysv-present>] [S<I<unit file> ...>] + +=head1 DESCRIPTION + +B<dh_systemd> is a debhelper program that is responsible for enabling, +starting/stopping or restarting systemd unit files. + +In the simple case, it finds all unit files installed by a package (e.g. +bacula-fd.service) and enables them. It is not necessary that the machine +actually runs systemd during package installation time, enabling happens on all +machines in order to be able to switch from sysvinit to systemd and back. + +Furthermore, as with B<dh_installinit>, the unit file is stopped before +upgrades and started afterwards (unless B<--restart-after-upgrade> is +specified, in which case it will only be restarted after the upgrade). +This logic is not used when there is a corresponding SysV init script +because invoke-rc.d performs the stop/start/restart in that case. + +In the complex case, you can call B<dh_systemd> manually and specify +flags per unit file. An example is colord, which ships colord.service, a +dbus-activated service without an [Install] section. This service file cannot +be enabled or disabled (a state called "static" by systemd) because it has no +[Install] section. Therefore, run + + dh_systemd --no-enable colord.service + +=head1 OPTIONS + +=over 4 + +=item B<--no-enable> + +Do not enable the unit file. This option is most useful when calling +B<dh_systemd> for a specific unit file. + +Example (see DESCRIPTION): + dh_systemd --no-enable colord.service + +=item B<--restart-after-upgrade> + +Do not stop the unit file until after the package upgrade has been completed. +This is different than the default behavior, which stops the unit file in the +F<prerm> and starts it again in the F<postinst> maintscript. + +This can be useful for daemons that should not have a possibly long +downtime during upgrade. But you should make sure that the daemon will not +get confused by the package being upgraded while it's running before using +this option. + +=item B<-r>, B<--no-restart-on-upgrade> + +Do not stop service on upgrade. + +=item B<--assume-sysv-present> + +When running B<dh_systemd> before B<dh_installinit>, init scripts might +not be installed yet and thus cannot be found by B<dh_systemd>. By +specifying B<--assume-sysv-present>, start/stop/restart will be done through +invoke-rc.d, i.e. no systemd-specific code will be generated. + +This option is only useful in cases where the init script is installed with a +different name and you need to run B<dh_systemd> before B<dh_installinit> in +order to get aliases (symlinks) created in the scripts before invoke-rc.d is +called. + +=back + +=head1 NOTES + +Note that this command is not idempotent. L<dh_prep(1)> should be called +between invocations of this command (with the same arguments). Otherwise, it +may cause multiple instances of the same text to be added to maintainer +scripts. + +Note that B<dh_systemd> should be run after B<dh_installinit> so that it +can detect corresponding SysV init scripts. The default sequence in B<dh> does +the right thing, this note is only relevant when you are calling +B<dh_systemd> manually. + +=cut + +init(options => { + "r" => \$dh{R_FLAG}, + "no-restart-on-upgrade" => \$dh{R_FLAG}, + "no-start" => \$dh{NO_START}, + "no-enable" => \$dh{NO_ENABLE}, + "R|restart-after-upgrade" => \$dh{RESTART_AFTER_UPGRADE}, + "assume-sysv-present" => \$dh{ASSUME_SYSV_PRESENT}, + "no-also" => \$dh{NO_ALSO}, +}); + +# Extracts the Also= or Alias= line(s) from a unit file. +# In case this produces horribly wrong results, you can pass --no-also, but +# that should really not be necessary. Please report bugs to +# pkg-systemd-maintainers. +sub extract_key { + my ($unit_path, $key) = @_; + my @values; + my $fh; + + if ($dh{NO_ALSO}) { + return @values; + } + + if (!open($fh, '<', $unit_path)) { + warning("Cannot open($unit_path) for extracting the Also= line(s)"); + return; + } + while (my $line = <$fh>) { + chomp($line); + + if ($line =~ /^\s*$key=(.+)$/i) { + @values = (@values, shellwords($1)); + } + } + close($fh); + return @values; +} + +foreach my $package (@{$dh{DOPACKAGES}}) { + my $tmpdir = tmpdir($package); + my @installed_units; + my %unitfiles; + my %aliases; + + find({ + wanted => sub { + my $name = $File::Find::name; + return unless -f $name; + return unless $name =~ m,^$tmpdir/lib/systemd/system/[^/]+$,; + push @installed_units, $name; + }, + no_chdir => 1, + }, $tmpdir); + + # Handle either only the unit files which were passed as arguments or + # all unit files that are installed in this package. + my @args = @ARGV > 0 ? @ARGV : @installed_units; + + # This hash prevents us from looping forever in the following while loop. + # An actual real-world example of such a loop is systemd’s + # systemd-readahead-drop.service, which contains + # Also=systemd-readahead-collect.service, and that file in turn + # contains Also=systemd-readahead-drop.service, thus forming an endless + # loop. + my %seen; + + # We use while/shift because we push to the list in the body. + while (@args) { + my $name = shift @args; + my $base = basename($name); + + # Try to make the path absolute, so that the user can call + # dh_installsystemd bacula-fd.service + if ($base eq $name) { + # NB: This works because @installed_units contains + # files from precisely one directory. + my ($full) = grep { basename($_) eq $base } @installed_units; + if (defined($full)) { + $name = $full; + } else { + warning(qq|Could not find "$name" in the /lib/systemd/system of $package.| . + qq|This could be a typo, or using Also= with a service file from another package.| . + qq|Please check carefully that this message is harmless.|); + } + } + + # Skip template service files like e.g. getty@.service. + # Enabling, disabling, starting or stopping those services + # without specifying the instance (e.g. getty@ttyS0.service) is + # not useful. + if ($name =~ /\@/) { + return; + } + + # Handle all unit files specified via Also= explicitly. + # This is not necessary for enabling, but for disabling, as we + # cannot read the unit file when disabling (it was already + # deleted). + my @also = grep { !exists($seen{$_}) } extract_key($name, 'Also'); + $seen{$_} = 1 for @also; + @args = (@args, @also); + + $aliases{$name} = [ extract_key($name, 'Alias') ]; + my @sysv = grep { + my $base = $_; + $base =~ s/\.service$//g; + -f "$tmpdir/etc/init.d/$base" + } ($base, @{$aliases{$name}}); + if (@sysv > 0 || $dh{ASSUME_SYSV_PRESENT}) { + $unitfiles{$name} = 'sysv'; + } else { + $unitfiles{$name} = 'systemd-only'; + } + } + + # Calls autoscript() as appropriate. + # Called once for all systemd files that have a corresponding SysV init + # script (invoke-rc.d handles start/stop/restart) and once for all + # systemd files without a corresponding SysV init script (systemctl + # handles start/stop/restart). + my $add_scripts = sub { + my ($units, $sysv_present) = @_; + + return 0 if @$units == 0; + + # The $package and $sed parameters are always the same. + # This wrapper function makes the following logic easier to read. + my $sd_autoscript = sub { + my ($script, $filename) = @_; + my $unitargs = join(" ", map { basename($_) } @$units); + autoscript($package, $script, $filename, "s/#UNITFILES#/$unitargs/"); + }; + + if (! $dh{NO_ENABLE}) { + if ($sysv_present) { + $sd_autoscript->("postinst", "postinst-systemd-enable"); + } elsif ($dh{RESTART_AFTER_UPGRADE}) { + $sd_autoscript->("postinst", "postinst-systemd-enable-restart"); + } elsif ($dh{NO_START}) { + # RESTART_AFTER_UPGRADE takes precedence + $sd_autoscript->("postinst", "postinst-systemd-enable"); + } else { + $sd_autoscript->("postinst", "postinst-systemd-enable-start"); + } + } else { + if (!$sysv_present && $dh{RESTART_AFTER_UPGRADE}) { + $sd_autoscript->("postinst", "postinst-systemd-restart"); + } elsif (!$sysv_present) { + # We need to stop/start before/after the upgrade. + $sd_autoscript->("postinst", "postinst-systemd-start"); + } + } + + if (! $dh{NO_ENABLE}) { + # These autoscripts contain a call to deb-systemd-helper disable, + # which needs to have all Aliases passed explicitly + # in order to properly cleanup the state file (the + # information is stored only in the symlinks which the + # admin might have removed). + my $filename = 'postrm-systemd'; + $filename .= '-reload' if !$sysv_present; + + my @both = @$units; + for my $unit (@$units) { + @both = (@both, @{$aliases{$unit}}); + } + + my $unitargs = join(" ", map { basename($_) } @both); + autoscript($package, "postrm", $filename, "s/#UNITFILES#/$unitargs/"); + } else { + if (!$sysv_present) { + $sd_autoscript->("postrm", "postrm-systemd-reload-only"); + } + } + + if (!$sysv_present) { + if ($dh{R_FLAG} || $dh{RESTART_AFTER_UPGRADE}) { + # stop service only on remove + $sd_autoscript->("prerm", "prerm-systemd-restart"); + } elsif (!$dh{NO_START}) { + # always stop service + $sd_autoscript->("prerm", "prerm-systemd"); + } + } + + return 1; + }; + + if (($add_scripts->([ grep { $unitfiles{$_} eq 'systemd-only' } keys %unitfiles ], 0) + + $add_scripts->([ grep { $unitfiles{$_} eq 'sysv' } keys %unitfiles ], 1)) > 0) { + # init-system-helpers ships deb-systemd-helper which we use in + # our autoscripts + addsubstvar($package, "misc:Depends", "init-system-helpers"); + } +} + +=head1 SEE ALSO + +L<debhelper(7)> + +=head1 AUTHORS + +pkg-systemd-maintainers@lists.alioth.debian.org + +=cut |