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
|
#!/bin/sh
set -e
systemctl_stop() {
unit="$1"
echo "Stopping unit $unit"
systemctl stop -q "$unit" || true
for i in $(seq 20); do
echo "Waiting until unit $unit is stopped [attempt $i]"
if ! systemctl is-active -q "$unit"; then
echo "$unit is stopped."
return
fi
sleep .1
done
}
is_component_mount_unit() {
systemctl show "$1" -p Where | sed 's#Where=##' | grep -q "${SNAP_MOUNT_DIR}/"'[^/]*/components/mnt/[^/]*/[^/]*'
}
if [ "$1" = "purge" ]; then
# Undo any bind mounts to ${SNAP_MOUNT_DIR} or /var/snap done by parallel
# installs or LP:#1668659
for mp in /snap /var/snap; do
if grep -q " $mp $mp" /proc/self/mountinfo; then
umount -l "$mp" || true
fi
done
units=$(systemctl list-unit-files --full | grep '^snap[-.]' | cut -f1 -d ' ' | grep -vF snap.mount.service || true)
mounts=$(echo "$units" | grep '^snap[-.].*\.mount$' || true)
services=$(echo "$units" | grep '^snap[-.].*\.service$' || true)
slices=$(echo "$units" | grep '^snap[-.].*\.slice$' || true)
# *.snap and *.comp mount points
snap_mounts=""
components_mounts=""
for mount in $mounts; do
if is_component_mount_unit "$mount"; then
components_mounts="$components_mounts $mount"
else
snap_mounts="$snap_mounts $mount"
fi
done
# component mounts must come first so that they are unmounted before we
# unmount the snap mounts
for unit in $services $components_mounts $snap_mounts $slices; do
# ensure its really a snap mount unit or systemd unit
if ! grep -q 'What=/var/lib/snapd/snaps/' "/etc/systemd/system/$unit" && ! grep -q 'X-Snappy=yes' "/etc/systemd/system/$unit"; then
echo "Skipping non-snapd systemd unit $unit"
continue
fi
echo "Stopping $unit"
systemctl_stop "$unit"
# if it is a mount unit, we can find the snap name in the mount
# unit (we just ignore unit files)
snap=$(grep 'Where=/snap/' "/etc/systemd/system/$unit"|cut -f3 -d/)
rev=$(grep 'Where=/snap/' "/etc/systemd/system/$unit"|cut -f4 -d/)
if [ -n "$snap" ] && ! is_component_mount_unit "$unit"; then
echo "Removing snap $snap and revision $rev"
# aliases
if [ -d /snap/bin ]; then
find /snap/bin -maxdepth 1 -lname "$snap" -delete
find /snap/bin -maxdepth 1 -lname "$snap.*" -delete
fi
# generated binaries
rm -f "/snap/bin/$snap"
rm -f "/snap/bin/$snap".*
# snap mount dir
# we pass -d (clean up loopback devices) for trusty compatibility
umount -d -l "/snap/$snap/$rev" 2> /dev/null || true
rm -rf "/snap/$snap/$rev"
rm -f "/snap/$snap/current"
# snap data dir
rm -rf "/var/snap/$snap/$rev"
rm -rf "/var/snap/$snap/common"
rm -f "/var/snap/$snap/current"
# opportunistic remove (may fail if there are still revisions left
for d in "/snap/$snap" "/var/snap/$snap"; do
if [ -d "$d" ]; then
rmdir --ignore-fail-on-non-empty "$d" || true
fi
done
# udev rules
find /etc/udev/rules.d -name "*-snap.${snap}.rules" -execdir rm -f "{}" \;
# dbus policy files
if [ -d /etc/dbus-1/system.d ]; then
find /etc/dbus-1/system.d -name "snap.${snap}.*.conf" -execdir rm -f "{}" \;
fi
# modules
rm -f "/etc/modules-load.d/snap.${snap}.conf"
rm -f "/etc/modprobe.d/snap.${snap}.conf"
# timer and socket units
find /etc/systemd/system -name "snap.${snap}.*.timer" -o -name "snap.${snap}.*.socket" | while read -r f; do
systemctl_stop "$(basename "$f")"
rm -f "$f"
done
# user services, sockets, and timers - we make no attempt to stop any of them.
# TODO: ask snapd to ask each snapd.session-agent.service to stop snaps
# user-session services and stop itself.
find /etc/systemd/user -name "snap.${snap}.*.timer" -o -name "snap.${snap}.*.socket" -o -name "snap.${snap}.*.service" | while read -r f; do
rm -f "$f"
done
fi
echo "Removing $unit"
rm -f "/etc/systemd/system/$unit"
rm -f "/etc/systemd/system/multi-user.target.wants/$unit"
done
# Units may have been removed do a reload
systemctl -q daemon-reload || true
# snapd session-agent
rm -f /etc/systemd/user/snapd.session-agent.socket
rm -f /etc/systemd/user/snapd.session-agent.service
rm -f /etc/systemd/user/sockets.target.wants/snapd.session-agent.socket
# generated readme files
rm -f "/snap/README"
echo "Discarding preserved snap namespaces"
# opportunistic as those might not be actually mounted
if [ -d /run/snapd/ns ]; then
if [ "$(find /run/snapd/ns/ -name "*.mnt" | wc -l)" -gt 0 ]; then
for mnt in /run/snapd/ns/*.mnt; do
umount -l "$mnt" || true
rm -f "$mnt"
done
fi
find /run/snapd/ns/ \( -name '*.fstab' -o -name '*.user-fstab' -o -name '*.info' \) -delete
umount -l /run/snapd/ns/ || true
fi
# inside containers we have a generator that creates a bind mount to /snap
if [ -e /run/systemd/container ]; then
echo "Unmount /snap inside a container"
umount /snap || true
fi
echo "Final directory cleanup"
for d in "/snap/bin" "/snap" "/var/snap"; do
# Force remove due to directories for old revisions could still exist
rm -rf "$d"
if [ -d "$d" ]; then
echo "Cannot remove directory $d"
fi
done
echo "Removing extra snap-confine apparmor rules"
rm -f /etc/apparmor.d/snap.core.*.usr.lib.snapd.snap-confine
echo "Removing snapd cache"
rm -rf /var/cache/snapd/*
echo "Removing snapd state"
rm -rf /var/lib/snapd
fi
#DEBHELPER#
|