aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Guthrie <colin@mageia.org>2012-02-16 14:14:41 +0000
committerColin Guthrie <colin@mageia.org>2012-02-16 14:14:41 +0000
commit7a025f125cbe7c0b0acebca8be8a99e8758a6ef9 (patch)
tree5b2d4484ef8a102a81daba5d63d7aedcc9a7bdfd
parentfce915361aecd3be1fe7b9d21c7ad5115637a544 (diff)
downloadrpm-helper-7a025f125cbe7c0b0acebca8be8a99e8758a6ef9.tar
rpm-helper-7a025f125cbe7c0b0acebca8be8a99e8758a6ef9.tar.gz
rpm-helper-7a025f125cbe7c0b0acebca8be8a99e8758a6ef9.tar.bz2
rpm-helper-7a025f125cbe7c0b0acebca8be8a99e8758a6ef9.tar.xz
rpm-helper-7a025f125cbe7c0b0acebca8be8a99e8758a6ef9.zip
Migrate service enabled/disabled status from sysvinit to systemd on upgrade
-rw-r--r--Makefile6
-rw-r--r--NEWS6
-rw-r--r--README.systemd8
-rwxr-xr-xadd-service155
4 files changed, 148 insertions, 27 deletions
diff --git a/Makefile b/Makefile
index d1cce64..5838e45 100644
--- a/Makefile
+++ b/Makefile
@@ -12,12 +12,14 @@ MACROS_FILES = rpm-helper.macros
CONF_FILES = ssl
TEST_FILES = t/*.t
FILES = AUTHORS README COPYING NEWS Makefile \
- $(SCRIPT_FILES) $(MACROS_FILES:=.in) $(CONF_FILES) \
+ $(SCRIPT_FILES) $(MACROS_FILES:=.in) $(CONF_FILES) \
$(TEST_FILES)
+SYSTEMDMIGRATION_FILES = README.systemd
pkgdatadir = /usr/share/$(PACKAGE)
rpmmacrosdir = /etc/rpm/macros.d
sysconfigdir = /etc/sysconfig
+systemdmigrationdir = /var/lib/rpm-helper/systemd-migration
all:
@echo "use make install or make dist"
@@ -29,6 +31,8 @@ install: $(MACROS_FILES)
install -m 644 $(MACROS_FILES) $(DESTDIR)/$(rpmmacrosdir)
install -d -m 755 $(DESTDIR)$(sysconfigdir)
install -m 644 $(CONF_FILES) $(DESTDIR)/$(sysconfigdir)
+ install -d -m 755 $(DESTDIR)$(systemdmigrationdir)
+ install -m 644 $(SYSTEMDMIGRATION_FILES) $(DESTDIR)/$(systemdmigrationdir)
rpm-helper.macros: rpm-helper.macros.in
sed -e 's:@pkgdatadir@:$(pkgdatadir):' < $< > $@
diff --git a/NEWS b/NEWS
index e74ba07..8d96916 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,9 @@
- * Silent enable/disable services
+ * Silent enable/disable services
+ * Migrate service enabled/disabled status from sysvinit to systemd
+ on upgrade
2011-11-03 D Morgan <dmorgan@mageia.org> 0.24.5
- * Add support for systemd .path files
+ * Add support for systemd .path files
2011-11-03 Colin Guthrie <colin@mageia.org> 0.24.4
* fix up missing file in the Makefile
diff --git a/README.systemd b/README.systemd
new file mode 100644
index 0000000..db76ef8
--- /dev/null
+++ b/README.systemd
@@ -0,0 +1,8 @@
+This folder is used to track systemd migration.
+
+When you install an updated package that contains a native systemd unit which
+supersedes the legacy sysvinit script, the fact that the service is enabled or
+not must be migrated to the systemd way of doing things.
+
+This folder is simply a place to store a note of which services have been
+migrated, such that the process is not repeated on subsequent package updates.
diff --git a/add-service b/add-service
index fb17a43..bd51d86 100755
--- a/add-service
+++ b/add-service
@@ -40,31 +40,55 @@ else
fi
units="$*" # systemd units
units_to_enable= # units enabled by msec
+systemd_migration_dir=/var/lib/rpm-helper/systemd-migration
+mkdir -p "${systemd_migration_dir}"
+
+SYSTEMUNITDIR=/lib/systemd/system
+USERUNITDIR=/etc/systemd/system
+RUNTIMEUNITDIR=/run/systemd/system
+
+find_unit() {
+ unit=$(basename $1)
+
+ # We need to normalise the systemd unit name as the native unit may not have
+ # the same filename (sans it's .service suffix) as sysvinit script.
+ # In this case, symlinks are used to mask the sysvinit file, but for enabling
+ # and disabling units we must use the official name.
+
+ searchunit=
+ if [ -f "$SYSTEMUNITDIR/$unit" ]; then
+ if [ -L "$SYSTEMUNITDIR/$unit" ]; then
+ searchunit=$(/usr/bin/readlink "$SYSTEMUNITDIR/$unit")
+ else
+ searchunit="$SYSTEMUNITDIR/$unit"
+ fi
+ elif [ -f "$USERUNITDIR/$unit" ]; then
+ if [ -L "$USERUNITDIR/$unit" ]; then
+ searchunit=$(/usr/bin/readlink "$USERUNITDIR/$unit")
+ else
+ searchunit="$USERUNITDIR/$unit"
+ fi
+ elif [ -f "$RUNTIMEUNITDIR/$unit" ]; then
+ if [ -L "$RUNTIMEUNITDIR/$unit" ]; then
+ searchunit=$(/usr/bin/readlink "$RUNTIMEUNITDIR/$unit")
+ else
+ searchunit="$RUNTIMEUNITDIR/$unit"
+ fi
+ fi
+ if [ -n "$searchunit" ]; then
+ echo -n $searchunit
+ fi
+}
+
# If only a sysvinit service is given, then deal with a systemd unit of the same
# name. Specific specs can enable specific unit names as needed but this should
# catch the most common usage.
if [ -z "$units" ]; then
units="$srv.service"
-
- # We need to normalise the systemd unit name as the native unit may not have
- # the same filename (sans it's .service suffix) as sysvinit script.
- # In this case, symlinks are used to mask the sysvinit file, but for enabling
- # and disabling units we must use the official name.
- SYSTEMUNITDIR=/lib/systemd/system
- USERUNITDIR=/etc/systemd/system
- RUNTIMEUNITDIR=/run/systemd/system
-
- searchunit=
- if [ -f "$SYSTEMUNITDIR/$units" ]; then
- searchunit=$(/usr/bin/readlink "$SYSTEMUNITDIR/$units")
- elif [ -f "$USERUNITDIR/$units" ]; then
- searchunit=$(/usr/bin/readlink "$USERUNITDIR/$units")
- elif [ -f "$RUNTIMEUNITDIR/$units" ]; then
- searchunit=$(/usr/bin/readlink "$RUNTIMEUNITDIR/$units")
- fi
+ searchunit=$(find_unit $units)
if [ -n "$searchunit" ]; then
- units=$searchunit
+ units=$(basename $searchunit)
fi
fi
@@ -112,6 +136,12 @@ add_service() {
if [ -n "$units_to_enable" ]; then
/bin/systemctl --quiet enable $units_to_enable >/dev/null
fi
+
+ # When no native systemd unit exists, the above command will actually
+ # just end up running chkconfig anyway, but if a native systemd unit exists
+ # the legacy init script will not be enabled.
+ # In order to enable switching back ot sysvinit, we should enable the
+ # sysvinit scripts too.
if [ -n "$srv" -a -f /etc/rc.d/init.d/$srv ]; then
/sbin/chkconfig --add $srv
@@ -131,20 +161,97 @@ add_service() {
fi
}
+check_sysvinit_service() {
+ rl=$1
+ srv=$2
+
+ set -- /etc/rc${rl}.d/S??$srv
+ if [ $# -gt 1 ]; then
+ echo 1>&2 "add-service: Error: $srv appears multiple times at runlevel $rl: $*"
+ fi
+
+ echo -n $1
+}
if [ $num = 1 ]; then
# First install mode
add_service
else
# Upgrade mode.
+
+ # Handle migration to systemd.
+ # If a previously installed package only had a sysvinit script, but an
+ # updated package has a native systemd unit, we need to make sure we migrate
+ # any service enablement for various targets (née runlevels)
+ if [ -n "$srv" -a -n "$units" ]; then
+ if [ ! -f "${systemd_migration_dir}/$srv" ]; then
+ full_path_units=
+ for unit in $units; do
+ # We need a full path for the symlink. Also it's possible
+ # that $unit contains "foo.service" where foo is actually
+ # a sysvinit script and thus we'll not have anything native.
+ # We only consider a "migration" to have taken place when
+ # we genuinely have a native systemd unit.
+ unit=$(find_unit $unit)
+ if [ -n "$unit" ]; then
+ full_path_units="$full_path_units $unit"
+ fi
+ done
+
+ if [ -n "$full_path_units" ]; then
+ enable_targets=
+ # We have not yet migrated this service
+ # First we check in which runlevels the legacy service is enabled
+ # Only bother checking runlevels 1 3 and 5
+ script=$(check_sysvinit_service 1 $srv)
+
+ # NB We only check that the link exists as the old sysvinit
+ # script may have been removed during migration to systemd
+ # native unit.
+ if [ -L "$script" ]; then
+ enable_targets="$enable_targets rescue.target"
+ fi
+
+ script=$(check_sysvinit_service 3 $srv)
+ if [ -L "$script" ]; then
+ enable_targets="$enable_targets multi-user.target"
+ else
+ # As graphical.target includes everything in multi-user.target,
+ # we only need to check 5 when 3 does NOT give us a result.
+ script=$(check_sysvinit_service 5 $srv)
+ if [ -L "$script" ]; then
+ enable_targets="$enable_targets graphical.target"
+ fi
+ fi
+
+ if [ -n "$enable_targets" ]; then
+ for enable_target in $enable_targets; do
+ wantsdir=$USERUNITDIR/${enable_target}.wants
+ mkdir -p $wantsdir
+ for unit in $full_path_units; do
+ if [ ! -f $wantsdir/$(basename $unit) ]; then
+ echo 1>&2 "Migrating sysvinit service '$srv' to systemd native unit '$(basename $unit)' for target '${enable_target}'"
+ ln -s $unit $wantsdir/$(basename $unit)
+ fi
+ done
+ done
+ if [ x$init = xsystemd ]; then
+ /bin/systemctl --system daemon-reload
+ fi
+ fi
+
+ # It could be that a package is installed but not enabled.
+ # If that is the case, we should still consider it "migrated"
+ # even when we do not enable anything.
+ touch "${systemd_migration_dir}/$srv"
+ fi
+ fi
+ fi
+
if [ x$init = xsystemd ]; then
/bin/systemctl --quiet try-restart $units
elif [ -f /etc/rc.d/init.d/$srv ]; then
- set -- /etc/rc3.d/S??$srv
- if [ $# -gt 1 ]; then
- echo 1>&2 "add-service: Error: $srv appears multiple times: $*"
- fi
-
- if [ -f "$1" ]; then
+ script=$(check_sysvinit_service 3 $srv);
+ if [ -f "$script" ]; then
/sbin/chkconfig --add $srv
fi