#!/bin/sh # Copyright (C) 2017 Dmitry Bogatov # Author: Dmitry Bogatov # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 3 # of the License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . set -e # rescan and invoke-rc.d actions are done only if runit is init is_runit () { [ -f /run/runit.stopit ] } is_installed () { [ -f /sbin/runit ] } # No-Op if the service is not enabled # sv can't send signals to a disabled service is_enabled () { [ -h /etc/service/"$NAME" ] } sv_warn () { echo "warning: sv: failed to signal $NAME" true } # workaround for races as in #919296 ok_pipe () { [ -p "/etc/sv/$NAME/supervise/ok" ] } postinst () { local action="${1}" previous="${2:-}" if [ -x /usr/sbin/policy-rc.d ]; then set +e ; /usr/sbin/policy-rc.d "${NAME}" start ; rc=$? ; set -e if [ "$rc" = "101" ]; then echo "runit: ${NAME}: start action denied by policy-rc.d" && return 0 fi fi # create supervise links at runtime, only if runit is installed mkdir -p /run/runit/supervise if [ -e /lib/runit/make_svlinks ]; then /lib/runit/make_svlinks "$NAME" fi # It is important to not override local admin # decision (see #899242 and 942323 ). if [ "${ENABLE}" = yes ]; then if [ ! -h "/etc/runit/runsvdir/default/.$NAME" ] && \ [ ! -h "/etc/runit/runsvdir/default/$NAME" ]; then # $NAME link tested to avoid infinte loop of symlinks ln -sf "/etc/sv/$NAME" "/etc/runit/runsvdir/default/$NAME" if is_runit && pidof runsvdir > /dev/null ; then # always force a rescan after enable kill -s ALRM 1 fi fi # ENABLE=no is always a no-op fi #invoke-rc.d if is_runit && is_enabled ; then if [ "${action}" = 'configure' ] || [ "${action}" = 'abort-upgrade' ] || \ [ "${action}" = 'abort-deconfigure' ] || [ "${action}" = 'abort-remove' ] ; then if [ "${ONUPGRADE}" = restart ] && [ -n "${previous}" ] && ok_pipe ; then sv restart ${NAME} || sv_warn elif [ "${ONUPGRADE}" = reload ] && [ -n "${previous}" ] && ok_pipe ; then sv reload ${NAME} || sv_warn elif ok_pipe ; then # ONUPGRADE=stop || ONUPGRADE=nostop # ONUPGRADE= restart || reload and [ ! -n "${previous}" ] sv start ${NAME} || sv_warn else return 0 fi fi fi } prerm () { local action="${1}" # invoke-rc.d if is_runit && is_enabled ; then if [ -x /usr/sbin/policy-rc.d ]; then set +e ; /usr/sbin/policy-rc.d "${NAME}" stop ; rc=$? ; set -e if [ "$rc" = "101" ]; then echo "runit: ${NAME}: stop action denied by policy-rc.d" && return 0 fi fi if [ "${ONUPGRADE}" = stop ] && ok_pipe ; then sv stop ${NAME} || sv_warn elif [ "${action}" = 'remove' ] && ok_pipe ; then # ONUPGRADE=restart || ONUPGRADE=nostop sv stop ${NAME} || sv_warn else return 0 fi fi } postrm () { local action="${1}" if [ "${action}" != 'purge' ] && [ "${action}" != 'remove' ] ; then return fi # When "ENABLE=no" the $NAME link is an admin decision # so we don't remove it. # Links in other runsvdirs is responsibility of administrator. if [ "${action}" = 'remove' ] && [ "${ENABLE}" = yes ] ; then rm -f "/etc/runit/runsvdir/default/$NAME" fi if [ "${action}" = 'purge' ] ; then rm -f "/etc/runit/runsvdir/default/$NAME" rm -f "/etc/runit/runsvdir/default/.$NAME" #TODO: make sure runsv exit before we remove supervise files, printf x on supervise fi # If runscript was never invoked, there will be no files # in this directory, and `dpkg' will remove it. In this case, # we have nothing to do. for supervise in "/etc/sv/$NAME/supervise" \ "/etc/sv/$NAME/log/supervise"; do if [ -d "$supervise" ] ; then #TODO test/loop that runsv is gone before remove supervise files # Actually only `down' may be absent, but it does not # matter. for file in control lock ok pid stat status down ; do rm -f "$supervise/$file" done # It should be empty now. If it is not, it means that # system administrator put something there. It is very # stupid, but will of user is sacred, and directory is # left as-is in such case. # # NOTE: Non-POSIX option is used. The day coreutils will # no longer be essential, it will require a fix. if [ -h "$supervise" ]; then rm "$supervise" else rmdir --ignore-fail-on-non-empty "$supervise" fi fi done if [ "${action}" = 'purge' ] ; then #rm -f "/etc/runit/runsvdir/default/$NAME" #rm -f "/etc/runit/runsvdir/default/.$NAME" readonly logdir="/var/log/runit/${NAME}" if [ -d "${logdir}" ] ; then rm -r "${logdir}" fi fi } #called as NAME='servicename' PKG='pkgname' /usr/lib/runit-helper/runit-helper sv_purge sv_purge () { [ -z "$PKG" ] && echo "$PKG empty" && return 0 [ -z "$NAME" ] && echo "$NAME empty" && return 0 if echo "$NAME" | grep -E '.*/$' >/dev/null ; then echo "warning: $NAME : not allowed, ends with /" return 0 #ends with / , dangerous with rm -rf fi servicesdir=/usr/share/runit/sv.now #if it's enabled, make sure runsv exits before the dir is removed if [ -h /etc/runit/runsvdir/default/$NAME ]; then if [ -r /etc/runit/runsvdir/default/$NAME/supervise/stat ]; then svstatus="$(cat /etc/runit/runsvdir/default/$NAME/supervise/stat)" fi case "$svstatus" in run|down|'run, want down' ) #maybe also 'down, want up' and 'finish' touch "/etc/runit/runsvdir/default/$NAME/down" || true printf x > "/etc/runit/runsvdir/default/$NAME/supervise/control" && \ unlink "/etc/runit/runsvdir/default/$NAME" ;; *) unlink "/etc/runit/runsvdir/default/$NAME" ;; esac fi if [ -r "$servicesdir/$NAME/.meta/pkg" ]; then thispkg="$(cat $servicesdir/$NAME/.meta/pkg)" if [ "$thispkg" = "$PKG" ]; then #TODO: also clean supervise in /run ? rm -r "$servicesdir/$NAME" logdir="/var/log/runit/${NAME}" if [ -d "${logdir}" ] ; then rm -r "${logdir}" fi fi else #give up if not from this package #should not happen in /usr/share/runit/sv.now/ but still.. return 0 fi } "$@" # vim: sw=4:et