1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
|
#!/bin/sh
# Copyright: 2022-2025 Lorenzo Puliti <plorenzo@disroot.org>
# License: BSD-3-clause
set -e
# purge bits disabled for now
runitsvdir=$CPSV_DEST
if [ "$(id -u)" != 0 ] ; then #user instances
[ "$(id -u)" -lt '1000' ] && echo "invalid uid, exit" && exit 0
username="$(id -u -n)"
test -n "$runitsvdir" || runitsvdir=/home/$username/.runit/sv
defaultdir=/home/$username/.service
debdefault=/home/$username/.runit/runsvdir/default
else
test -n "$runitsvdir" || runitsvdir=/usr/share/runit/sv.current
defaultdir=/etc/service
debdefault=/etc/runit/runsvdir/default
fi
# policy-rc.d layer
if [ -x /usr/sbin/policy-rc.d ]; then
set +e ; /usr/sbin/policy-rc.d ; rc=$? ; set -e
if [ "$rc" = "101" ]; then
echo "trigger action denied by policy-rc.d" && exit 0
fi
fi
case ${1} in
setup)
[ -e /etc/runit/verbose ] && echo "Runit triggered upgrade: ${1}"
if [ "$(id -u)" != 0 ]; then #user instances
mkdir -p /home/$username/.runit/sv
CPSV_DEST=/home/$username/.runit/sv cpsv s || true
list="$runitsvdir/*"
else
mkdir -p /usr/share/runit/sv.now
if [ -x /etc/runit/atomic.upgrade ]; then
/etc/runit/atomic.upgrade
else
#force sv.current to point to sv.now?
CPSV_DEST=/usr/share/runit/sv.now CPSV_SOURCE=/usr/share/runit/sv.src cpsv -f s || true
list="/etc/sv/* separator $runitsvdir/*"
fi
fi
if [ ! -d "$debdefault" ] ; then
echo "$debdefault : directory not found, exit" && exit 1
fi
separator=
for svpath in $list ; do
if [ "$svpath" = 'separator' ]; then
separator=1
continue
fi
[ -r "$svpath/.meta/bin" ] || continue # rule out no binfile case
currentsvd=${svpath%/*}
service=${svpath##*/}
usersv=${service%@user};
if [ "$(id -u)" != 0 ]; then #user service
[ "$service" = "$usersv" ] && continue #skip services that are not user-services templates
else # system wide service
[ "$service" != "$usersv" ] && continue #no-op for user services when run by root
if [ -n "$separator" ]; then
#skip pkg sv in favor of local service in /etc/sv/
[ -d "/etc/sv/$service" ] && continue
fi
fi
binpath="$(cat $svpath/.meta/bin)"
test -n $binpath || continue # rule out empty bin file
if [ -x /usr/sbin/policy-rc.d ]; then
set +e ; /usr/sbin/policy-rc.d "$service" start ; rc=$? ; set -e
if [ "$rc" = "101" ]; then
echo "$service: action denied by policy-rc.d" && continue
fi
fi
if [ ! -e "$binpath" ] ; then #disable unless noreplace
[ -e "$debdefault/$service" ] || continue # skip already disabled
if [ ! -e "$svpath/.meta/noreplace" ]; then
if [ -r "$svpath/.meta/enable" ]; then
enable=$(cat "$svpath/.meta/enable")
if [ "$enable" = yes ]; then
rm -f "$debdefault/$service"
[ -e /etc/runit/verbose ] && echo "$service disabled"
fi
else
rm -f "$debdefault/$service"
[ -e /etc/runit/verbose ] && echo "$service disabled"
fi
# if [ -r "$runitsvdir/$service/.meta/pkg" ]; then
# pkgname=$(cat "$runitsvdir/$service/.meta/pkg")
# if ! dpkg -l "$pkgname" > /dev/null ; then
#NAME="$service" /lib/runit-helper/runit-helper postrm purge
# [ -e /etc/runit/verbose ] && echo "$service purged"
# fi
# fi
else #noreplace
[ -h "$debdefault/$service" ] && \
echo "please disable $service manually from a getty"
fi
else # enable unless 'enble=no'
if [ -e "$svpath/.meta/enable" ]; then
enable=$(cat "$svpath/.meta/enable")
if [ "$enable" = yes ] && \
[ ! -h "$debdefault/.$service" ] ; then
# avoid infinte loop of symlinks
if [ ! -h "$debdefault/$service" ]; then
ln -sf "$svpath" "$debdefault/$service"
[ -e /etc/runit/verbose ] && echo "$service enabled"
echo $(stat -c %W "$binpath") > "$svpath/.meta/wtime"
fi
fi
else
if [ ! -h "$debdefault/.$service" ] && \
[ ! -h "$debdefault/$service" ]; then
ln -sf "$svpath" "$debdefault/$service"
[ -e /etc/runit/verbose ] && echo "$service enabled"
echo $(stat -c %W "$binpath") > "$svpath/.meta/wtime"
fi
fi
fi
unset binpath
done
unset separator
# purge fallback for case: [ ! -e runitsvdir/service ] && [ -d /var/log/runit/service ]
# pkg removed + not purged + system rebooted; then pkg purge happens
# when purge of pkg happens in a later time we have to cleanup the log directory
# for logdir in /var/log/runit/* ; do
# service=$(basename "$logdir")
# [ -d "$runitsvdir/$service" ] || continue # already covered by former loop
# [ -r "$logdir/.pkg" ] || continue
# pkgname=$(cat "$logdir/.pkg")
# if ! dpkg -l "$pkgname" > /dev/null ; then
# rm -f "$debdefault/$service"
# rm -f "$debdefault/.$service"
# [ -d "${logdir}" ] && rm -r "${logdir}"
# [ -e /etc/runit/verbose ] && echo "$service purged (logdir fallback)"
# fi
# done
if [ -f /etc/runit/stopit ] && pidof runsvdir > /dev/null ; then
[ "$(id -u)" = 0 ] && kill -s ALRM 1 # force rescan to pick changes in enabled/disabled service status
fi
;;
upgrade)
if [ ! -d "$defaultdir" ]; then
echo "$defaultdir : directory not found, exit" && exit 1
fi
if [ ! -f /etc/runit/stopit ] && ! pidof -q runsvdir ; then
[ -e /etc/runit/verbose ] && echo "no runsvdir found, exit"
exit 0 # noop if runit is not init and there's no runsvdir running
fi
if [ "$(id -u)" != 0 ]; then
[ -d /etc/service/runsvdir@"$username" ] || exit 0
fi
[ -e /etc/runit/verbose ] && echo "Runit triggered upgrade: ${1}"
#runitsvdir=$CPSV_DEST
#test -n "$runitsvdir" || runitsvdir=/usr/share/runit/sv.current //=/home/$username/.runit/sv
#defaultdir=/etc/service //=/home/$username/service
for path in "$defaultdir"/* ; do
[ -r "$path/.meta/bin" ] || continue #rule out no binfile
binpath="$(cat $path/.meta/bin)"
test -n $binpath || continue # rule out empty bin file
[ -e "$binpath" ] || continue #still enabled due to noreplace, but binary removed
if [ -r "$path/.meta/wtime" ]; then
bintime="$(stat -c %W $binpath)"
svtime="$(cat $path/.meta/wtime)"
if [ -n "$svtime" ]; then
# skip services non upgraded
[ "$bintime" -le "$svtime" ] && continue
fi
fi
service=${path##*/}
if [ -x /usr/sbin/policy-rc.d ]; then
set +e ; /usr/sbin/policy-rc.d "$service" restart ; rc=$? ; set -e
if [ "$rc" = "101" ]; then
echo "$service: restart action denied by policy-rc.d" && continue
fi
fi
# sv restart $service # after checking that is up + ok-pipe
[ -p "$path/supervise/ok" ] || continue
if [ -r "$path/.meta/onupgrade" ]; then
onupgrade=$(cat "$path/.meta/onupgrade")
test -n "$onupgrade" || continue
if [ "${onupgrade}" = restart ] || [ "${onupgrade}" = reload ] ; then
[ -e /etc/runit/debug ] && echo "sv ${onupgrade} $service"
sv "${onupgrade}" "$service" || true
fi
else
[ -e /etc/runit/debug ] && echo "sv restart $service"
sv restart "$service" || true #fallback to restart (debhelper default)
fi
echo $(stat -c %W "$binpath") > "$path/.meta/wtime"
unset binpath
unset bintime
unset svtime
done
;;
*)
;;
esac
|