From 606ae7d18503eb8d92b3af0cb21059b6ba0594ee Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sun, 13 Mar 2011 19:02:58 +0000 Subject: add full systemd support for new as well as migrated packages --- Makefile | 5 +-- add-service | 98 ++++++++++++++++++++++++++++++++-------------------- del-service | 58 ++++++++++++++++++++----------- migrate-service | 53 ++++++++++++++++++++++++++++ postun-unit | 40 +++++++++++++++++++++ rpm-helper.macros.in | 22 ++++++++---- 6 files changed, 211 insertions(+), 65 deletions(-) create mode 100644 migrate-service create mode 100755 postun-unit diff --git a/Makefile b/Makefile index d773394..c81de7a 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,12 @@ PACKAGE = rpm-helper -VERSION = 0.23.9 +VERSION = 0.24.0 SVNPATH = svn+ssh://svn.mandriva.com/svn/soft/rpm/$(PACKAGE) SCRIPT_FILES = add-user del-user add-service del-service create-file \ add-group del-group add-shell del-shell verify-shell \ add-syslog del-syslog add-webapp del-webapp \ - get-password create-ssl-certificate + get-password create-ssl-certificate \ + migrate-service postun-unit MACROS_FILES = rpm-helper.macros CONF_FILES = ssl TEST_FILES = t/*.t diff --git a/add-service b/add-service index 46a98ac..783ffdf 100755 --- a/add-service +++ b/add-service @@ -4,46 +4,51 @@ # Module : rpm-helper # File : add-service # Version : $Id$ -# Author : Frederic Lepied +# Authors : Frederic Lepied, Andrey Borzenkov # Created On : Mon Jul 8 08:14:34 2002 # Purpose : helper script for rpm scriptlets to add a # service. #--------------------------------------------------------------- -if [ $# != 3 ]; then - echo "usage: $0 " 1>&2 +if [ x$1 = x--no-sysv ]; then + do_sysv=no + shift +else + do_sysv=yes +fi + +if [ $# -lt 3 ]; then + echo "usage: $0 [--no-sysv] [] ..." 1>&2 exit 1 fi pkg=$1 # name of the package num=$2 # number of packages installed -srv=$3 # name of the service - -systemd=no -sysv=no -options=--quiet - -[ -x /bin/systemctl -a -r /lib/systemd/system/${srv}.service ] && systemd=yes -[ -r /etc/rc.d/init.d/${srv} ] && sysv=yes -[ $sysv = yes ] && options="$options --no-reload" -unit=${srv}.service +if [ $do_sysv = yes ]; then + srv=$3 # name of the SysV script + shift 3 +else + srv= + shift 2 +fi +units="$*" # systemd units +units_to_enable= # units enabled by msec add_chkconfig_service() { - srv=$1 - - - # support for systemd. chkconfig will do daemon-reload for us - if [ $systemd = yes ]; then - /bin/systemctl $options enable ${unit} + if [ -n "$units_to_enable" ]; then + /bin/systemctl --quiet enable $units_to_enable fi - if [ $sysv = yes ]; then + if [ -n "$srv" ]; then /sbin/chkconfig --add $srv + else + exit 0 fi if [ -r /etc/sysconfig/system ]; then . /etc/sysconfig/system fi + # TODO what to do with system units here? if [ -z "$ADD_SERVICES_TO_CURRENT_PROFILE_ONLY" ]; then # add the service to all the profiles at once if [ -d /etc/netprofile/profiles/default/services ]; then @@ -69,39 +74,58 @@ add_service() { LIST=/etc/security/msec/server.$SECURE_LEVEL fi + # This is half-hearted support for msec: we check "srv" for a unit + # with name "srv.service". This should account for most(?) common + # case when SysV script srv is replaced by single unit srv.service + # If SysV name was supplied, we assume units are equivalent and do + # not need to be checked. + # TODO should msec support full unit name? if [ -f $LIST ]; then - if grep -q "^${srv}$" $LIST ; then - add_chkconfig_service $srv + if [ -n "$srv" ]; then + if fgrep -qx "${srv}" $LIST; then + units_to_enable="$units" + else + srv= + fi + else + for i in $units; do + [ $i != ${i%.service} ] && ! fgrep -qx ${i%.service} $LIST && continue + units_to_enable="$units_to_enable $i" + done fi else - # Low security: install all the services - add_chkconfig_service $srv + units_to_enable="$units" fi + + add_chkconfig_service } if [ $num = 1 ]; then # First install mode add_service else - # Upgrade mode. + # Upgrade mode. systemd units are restarted in postun + [ -n "$srv" ] || exit 0 # if the service is activated, add it again to be able to handle - # changes in start/stop levels or systemd WantedBy lines + # changes in start/stop levels. This does not change enabled/disabled + # state, so we do not do it for systemd where dependencies are handled + # automatically. - if [ $systemd = yes ] && /bin/systemctl is-enabled ${unit}; then - /bin/systemctl --quiet enable ${unit} - fi + # Restart only SysV services here only if no additional systemd + # units are defined or systemd is not active. Otherwise user is expected + # to add postun script that handles systemd units. - if [ $sysv = yes ]; then - set -- /etc/rc3.d/S??$srv - if [ $# -gt 1 ]; then - echo 1>&2 "add-service: Error: $srv appears multiple times: $*" - fi + 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 - /sbin/chkconfig --add $srv - fi + if [ -f "$1" ]; then + /sbin/chkconfig --add $srv + fi + if [ -z "$units" ] || ! /bin/mountpoint -q /sys/fs/cgroup/systemd; then # restart the service if already running if [ -f /var/lock/subsys/$srv ]; then /sbin/service $srv restart > /dev/null || : diff --git a/del-service b/del-service index c95f992..47b66a7 100755 --- a/del-service +++ b/del-service @@ -4,42 +4,60 @@ # Module : rpm-helper # File : del-service # Version : $Id$ -# Author : Frederic Lepied +# Authors : Frederic Lepied, Andrey Borzenkov # Created On : Tue Jul 9 08:11:26 2002 # Purpose : helper script for rpm scriptlets to remove a # service. #--------------------------------------------------------------- -if [ $# != 3 ]; then - echo "usage: $0 " 1>&2 +if [ x$1 = x--no-sysv ]; then + do_sysv=no + shift +else + do_sysv=yes +fi + +if [ $# -lt 3 ]; then + echo "usage: $0 [--no-sysv] [] ..." 1>&2 exit 1 fi pkg=$1 # name of the package num=$2 # number of packages installed -srv=$3 # name of the service - -systemd=no -sysv=no -options=--quiet +if [ $do_sysv = yes ]; then + srv=$3 # name of the SysV script + shift 3 +else + srv= + shift 2 +fi +units="$*" # systemd units +units_to_remove= -[ -x /bin/systemctl -a -r /lib/systemd/system/${srv}.service ] && systemd=yes -[ -r /etc/rc.d/init.d/${srv} ] && sysv=yes -[ $sysv = yes ] && options="$options --no-reload" -unit=${srv}.service if [ $num = 0 ]; then - # Will be redirected to systemd if needed + if [ -z "$DURING_INSTALL" ]; then - /sbin/service $srv stop > /dev/null || : + if [ -n "$units" ]; then + if /bin/mountpoint -q /sys/fs/cgroup/systemd; then + /bin/systemctl stop $units + fi + elif [ -n "srv" ]; then + /sbin/service $srv stop > /dev/null || : + fi fi - # support for systemd. chkconfig will do daemon-reload for us - if [ $systemd = yes ]; then - /bin/systemctl $options disable ${unit} - fi - if [ $sysv = yes ]; then - /sbin/chkconfig --del $srv + [ -n "$units" ] && /bin/systemctl --no-reload --quiet disable $units + [ -n "$srv" ] && /sbin/chkconfig --del $srv + + # Yes - this is very ugly workaround. chkconfig --del does daemon-reload, + # but initscript is still there, so it remains loaded. Remove file and + # reload again. Systemd units are supposed to provide postun script + + if [ -n "$srv" -a -z "$units" ] && \ + /bin/mountpoint -q /sys/fs/cgroup/systemd; then + /bin/rm -f /etc/rc.d/init.d/$srv + /bin/systemctl daemon-reload fi fi diff --git a/migrate-service b/migrate-service new file mode 100644 index 0000000..de08435 --- /dev/null +++ b/migrate-service @@ -0,0 +1,53 @@ +#!/bin/sh +#--------------------------------------------------------------- +# Project : Mandriva Linux +# Module : rpm-helper +# File : migrate-service +# Version : $Id$ +# Authors : Andrey Borzenkov +# Created On : Sat Mar 12 18:37:00 2011 +# Purpose : helper script for rpm scriptlets to migrate +# from SysV script to systemd unit. +#--------------------------------------------------------------- + +if [ $# -lt 3 ]; then + echo "usage: $0 {pre|post} ..." 1>&2 + exit 1 +fi + +phase=$1 # pre/post +srv=$2 # name of the SysV script +shift 2 # systemd units + +if [ $phase = pre ]; then + # create flag that service was active and stop it + # As we are booted under systemd, we can just as well ask it ... + /bin/rm -f /tmp/systemd-migrate-active-$srv + if /bin/mountpoint -q /sys/fs/cgroup/systemd; then + active=$(/bin/systemctl show --no-pager -p ActiveState $srv.service 2> /dev/null) + if [ "${active#ActiveState=}" = active ]; then + /bin/touch /tmp/systemd-migrate-active-$srv + /bin/systemctl stop $srv.service + fi + fi + + # enable units if service was active in run-levels 3 or 5. + # This loosely corresponds to systemctl is-enabled. We assume, that + # units do include correct [Install] entries. + if /sbin/chkconfig --no-redirect --level=3 $srv || \ + /sbin/chkconfig --no-redirect --level=5 $srv; then + /bin/systemctl --no-reload --quiet enable "$@" || : + fi +else + # Reload daemon after old package was removed + # Restart new units if old SysV script was started. + if /bin/mountpoint -q /sys/fs/cgroup/systemd; then + /bin/systemctl daemon-reload + if [ -f /tmp/systemd-migrate-active-$srv ]; then + /bin/systemctl start "$@" + fi + fi + /bin/rm -f /tmp/systemd-migrate-active-$srv +fi + +# migrate-service ends here diff --git a/postun-unit b/postun-unit new file mode 100755 index 0000000..dfc4b82 --- /dev/null +++ b/postun-unit @@ -0,0 +1,40 @@ +#!/bin/sh +#--------------------------------------------------------------- +# Project : Mandriva Linux +# Module : rpm-helper +# File : postun-unit +# Version : $Id$ +# Authors : Andrey Borzenkov +# Created On : Sat Mar 12 18:05:00 2011 +# Purpose : helper script for rpm scriptlets to remove a +# systemd unit. +#--------------------------------------------------------------- + +# Reload systemd configuration and try to restart units +# It has to be done in postun because package removal may delete +# some links and we need to inform systemd about it + +/bin/mountpoint -q /sys/fs/cgroup/systemd || exit 0 + +if [ $# -lt 3 ]; then + echo "usage: $0 ..." 1>&2 + exit 1 +fi + +pkg=$1 # name of the package +num=$2 # number of packages installed +shift 2 # systemd units + +/bin/systemctl daemon-reload + +if [ $num -ge 1 ]; then + if [ -z "$DURING_INSTALL" ]; then + # New package may have removed some units so restart will + # fail for them; catch it. + # TODO find a way to pass parameters from current packages + # into script installed by previous version + /bin/systemctl try-restart "$@" || : + fi +fi + +# postun-unit ends here diff --git a/rpm-helper.macros.in b/rpm-helper.macros.in index 8d0859a..813b65b 100644 --- a/rpm-helper.macros.in +++ b/rpm-helper.macros.in @@ -15,11 +15,11 @@ # initscripts macros %_add_service_helper %_rpm_helper_dir/add-service -%_post_service() %_add_service_helper %{name} $1 %{1} \ +%_post_service() %_add_service_helper %{name} $1 %{*} \ %{nil} %_del_service_helper %_rpm_helper_dir/del-service -%_preun_service() %_del_service_helper %{name} $1 %{1} \ +%_preun_service() %_del_service_helper %{name} $1 %{*} \ %{nil} %_add_user_helper %_rpm_helper_dir/add-user @@ -66,8 +66,18 @@ %{nil} # systemd support -%_systemd_migrate_service() \ -if [ -x /bin/systemctl ] && /sbin/chkconfig --no-redirect --level=3 %{1}; then \ - /bin/systemctl --quiet enable %{1}.service \ -fi \ +%_migrate_service_helper %_rpm_helper_dir/migrate-service +%_systemd_migrate_service_pre() %_migrate_service_helper pre %{*} \ +%{nil} +%_systemd_migrate_service_post() %_migrate_service_helper post %{*} \ +%{nil} + +%_post_unit() %_add_service_helper --no-sysv %{name} $1 %{*} \ +%{nil} + +%_preun_unit() %_del_service_helper --no-sysv %{name} $1 %{*} \ +%{nil} + +%_postun_unit_helper %_rpm_helper_dir/postun-unit +%_postun_unit() %_postun_unit_helper %{name} $1 %{*} \ %{nil} -- cgit v1.2.1