diff options
author | Michael Stapelberg <stapelberg@debian.org> | 2013-05-05 11:25:48 +0200 |
---|---|---|
committer | Michael Stapelberg <michael@stapelberg.de> | 2013-05-10 00:21:16 +0200 |
commit | 073cc4186276016caafcdaaffe79da5a47ae0552 (patch) | |
tree | 9a54daadb66022949727393d20262ef743ce8a81 | |
download | init-system-helpers-073cc4186276016caafcdaaffe79da5a47ae0552.tar.gz |
Imported Debian version 1.0
-rw-r--r-- | Makefile.PL | 8 | ||||
-rw-r--r-- | debian/changelog | 5 | ||||
-rw-r--r-- | debian/compat | 1 | ||||
-rw-r--r-- | debian/control | 24 | ||||
-rw-r--r-- | debian/copyright | 38 | ||||
-rw-r--r-- | debian/init-system-helpers.dirs | 1 | ||||
-rwxr-xr-x | debian/rules | 13 | ||||
-rw-r--r-- | debian/source/format | 1 | ||||
-rwxr-xr-x | script/deb-systemd-helper | 251 |
9 files changed, 342 insertions, 0 deletions
diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..81e1723 --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,8 @@ +use inc::Module::Install; + +name 'init-system-helpers'; +version '1.0'; + +install_script 'deb-systemd-helper'; + +WriteAll; diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..e517e92 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +init-system-helpers (1.0) unstable; urgency=low + + * Initial release + + -- Michael Stapelberg <stapelberg@debian.org> Sun, 05 May 2013 11:25:48 +0200 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +8 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..648b17d --- /dev/null +++ b/debian/control @@ -0,0 +1,24 @@ +Source: init-system-helpers +Section: admin +Priority: extra +Maintainer: pkg-systemd-maintainers <pkg-systemd-maintainers@lists.alioth.debian.org> +Uploaders: Michael Stapelberg <stapelberg@debian.org>, + Tollef Fog Heen <tfheen@debian.org>, + Michael Biebl <biebl@debian.org> +Build-Depends: debhelper (>= 8.0.0), libmodule-install-perl +Standards-Version: 3.9.4 +Vcs-Git: git://git.debian.org/collab-maint/init-system-helpers.git +Vcs-Browser: http://git.debian.org/?p=collab-maint/init-system-helpers.git;a=summary + +Package: init-system-helpers +Architecture: all +Depends: ${perl:Depends}, ${misc:Depends} +Description: helper tools for all init systems + This package contains helper tools that are necessary for switching between + the various init systems that Debian contains (e.g. sysvinit, upstart, + systemd). An example is deb-systemd-helper, a script that enables systemd unit + files without depending on a running systemd. + . + 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. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..8c22c5b --- /dev/null +++ b/debian/copyright @@ -0,0 +1,38 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ + +Files: deb-systemd-helper +Copyright: 2013 Michael Stapelberg +License: BSD + +Files: debian/* +Copyright: 2013 Michael Stapelberg <stapelberg@debian.org> +License: BSD + +License: BSD + Copyright © 2013 Michael Stapelberg + All rights reserved. + . + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + . + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + . + * Neither the name of Michael Stapelberg nor the + names of contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY Michael Stapelberg ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL Michael Stapelberg BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/debian/init-system-helpers.dirs b/debian/init-system-helpers.dirs new file mode 100644 index 0000000..b86a93f --- /dev/null +++ b/debian/init-system-helpers.dirs @@ -0,0 +1 @@ +/var/lib/systemd diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..b760bee --- /dev/null +++ b/debian/rules @@ -0,0 +1,13 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +%: + dh $@ diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/script/deb-systemd-helper b/script/deb-systemd-helper new file mode 100755 index 0000000..d324557 --- /dev/null +++ b/script/deb-systemd-helper @@ -0,0 +1,251 @@ +#!/usr/bin/env perl +# vim:ts=4:sw=4:expandtab +# © 2013 Michael Stapelberg <stapelberg@debian.org> +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Michael Stapelberg nor the +# names of contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# . +# THIS SOFTWARE IS PROVIDED BY Michael Stapelberg ''AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL Michael Stapelberg BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=head1 NAME + +deb-systemd-helper - subset of systemctl for machines not running systemd + +=head1 SYNOPSIS + +B<deb-systemd-helper> enable|disable|is-enabled|reenable S<I<unit file> ...> + +=head1 DESCRIPTION + +B<deb-systemd-helper> is a Debian-specific helper script which re-implements +the enable, disable, is-enabled and reenable commands from systemctl. Unlike +systemctl, B<deb-systemd-helper> does not require systemd to be running. + +The "enable" action will only be performed once (when first installing the +package). On the first "enable", an state file is created which will be deleted +upon "disable", which is called when dpkg removes the package. + +B<deb-systemd-helper> is intended to be used from maintscripts to enable +systemd unit files. It is specifically NOT intended to be used interactively by +users. Instead, users should run systemd and use systemctl, or not bother about +the systemd enabled state in case they are not running systemd. + +=cut + +use strict; +use warnings; +use File::Path qw(make_path); # in core since Perl 5.001 +use File::Basename; # in core since Perl 5 +use File::Find; # in core since Perl 5 +use Text::ParseWords qw(shellwords); # in core since Perl 5 +use Data::Dumper; + +my $state_dir = '/var/lib/systemd/deb-systemd-helper-enabled'; + +# Globals are bad, but in this specific case, it really makes things much +# easier to write and understand. +my $changed_sth; + +sub error { + print STDERR "$0: error: @_\n"; + exit (1); +} + +sub find_unit { + my ($scriptname) = @_; + + my $service_path = $scriptname; + if (-f "/etc/systemd/system/$scriptname") { + $service_path = "/etc/systemd/system/$scriptname"; + } elsif (-f "/lib/systemd/system/$scriptname") { + $service_path = "/lib/systemd/system/$scriptname"; + } + return $service_path; +} + +sub make_link { + my ($service_path, $service_link, $action) = @_; + my $already_enabled = 1; + + if ($action eq 'is-enabled') { + $already_enabled = 0 if ! -l $service_link; + } elsif (! -l $service_link) { + my $statefile = "$state_dir/" . basename($service_link); + if (-e $statefile) { +# TODO: remove this message + print STDERR "DEBUG: not enabling $service_link due to existing $statefile.\n"; + return $already_enabled; + } + make_path(dirname($service_link)); + print STDERR "ln -s '$service_path' '$service_link'\n"; + symlink($service_path, $service_link) or + error("unable to link $service_link to $service_path: $!"); + + # Store the fact that we ran enable for this service_path, + # so that we can skip enable the next time. + # This allows us to call deb-systemd-helper unconditionally + # and still only enable unit files on the initial installation + # of a package. + if (! -d $state_dir) { + # /var/lib/systemd is shipped by this package + mkdir $state_dir; + } + open(my $fh, '>', $statefile); + close($fh); + $changed_sth = 1; + } + + return $already_enabled; +} + +sub make_systemd_links { + my ($scriptname, $service_path, $action) = @_; + + my $already_enabled = 1; + open my $fh, '<', $service_path or error("unable to read $service_path"); + while (my $line = <$fh>) { + chomp($line); + my $service_link; + + if ($line =~ /^\s*(WantedBy|RequiredBy)=(.+)$/i) { + for my $value (shellwords($2)) { + my $wants_dir = "/etc/systemd/system/$value"; + $wants_dir .= '.wants' if $1 eq 'WantedBy'; + $wants_dir .= '.requires' if $1 eq 'RequiredBy'; + $already_enabled = 0 if + !make_link($service_path, "$wants_dir/$scriptname", $action); + } + } + + if ($line =~ /^\s*Also=(.+)$/i) { + for my $value (shellwords($1)) { + $already_enabled = 0 if + !make_systemd_links($value, find_unit($value), $action); + } + } + + if ($line =~ /^\s*Alias=(.+)$/i) { + for my $value (shellwords($1)) { + $already_enabled = 0 if + !make_link($service_path, "/etc/systemd/system/$1", $action); + } + } + + } + close($fh); + + return $already_enabled; +} + +sub remove_links { + my ($service_path) = @_; + # scan /etc/systemd/system/* and delete symlinks to $service_path + find({ + wanted => sub { + my $link = $File::Find::name; + return unless -l $link; + return unless readlink($link) eq $service_path || + basename(readlink($link)) eq $service_path; + print STDERR "rm '$link'\n"; + unlink($link) or error("unable to delete $link: $!"); + $changed_sth = 1; + }, + follow => 0, + no_chdir => 1, + }, '/etc/systemd/system/'); + + my $statefile = "$state_dir/" . basename($service_path); + unlink($statefile) if -e $statefile; + + # Read $service_path, recurse for all Also= units. + # This might not work when $service_path was already deleted, + # i.e. after apt-get remove. In this case we just return + # silently in order to not confuse the user about whether + # disabling actually worked or not — the case is handled by + # dh_installsystemd generating an appropriate disable + # command by parsing the service file at debhelper-time. + open my $fh, '<', $service_path or return; + while (my $line = <$fh>) { + chomp($line); + my $service_link; + + if ($line =~ /^\s*Also=(.+)$/i) { + remove_links(find_unit($1)); + } + } + close($fh); +} + +my $action = shift; +if (!defined($action)) { + # Called without arguments. Explain that this script should not be run interactively. + print "$0 is a program which should be called by dpkg maintscripts only.\n"; + print "Please do not run it interactively, ever. Also see the manpage deb-systemd-helper(1).\n"; + exit 0; +} + +if (!$ENV{DPKG_MAINTSCRIPT_PACKAGE}) { + print STDERR "$0 was not called from dpkg. Exiting.\n"; + exit 1; +} + +my $rc = $action eq 'is-enabled' ? 1 : 0; +for my $scriptname (@ARGV) { + my $service_path = find_unit($scriptname); + + if ($action eq 'is-enabled') { + my $enabled = make_systemd_links($scriptname, $service_path, $action); + print STDERR ($enabled ? "enabled\n" : "disabled\n"); + $rc = 0 if $enabled; + } + + if ($action eq 'reenable') { + remove_links($service_path); + make_systemd_links($scriptname, $service_path, $action); + } + + if ($action eq 'disable') { + remove_links($service_path); + } + + if ($action eq 'enable') { + make_systemd_links($scriptname, $service_path, $action); + } +} + +# If we changed anything and this machine is running systemd, tell +# systemd to reload so that it will immediately pick up our +# changes. +if ($changed_sth && -d "/run/systemd/system") { + system("systemctl", "daemon-reload"); +} + +exit $rc; + +=head1 AUTHOR + +Michael Stapelberg <stapelberg@debian.org> + +=cut |