github.com/rigado/snapd@v2.42.5-go-mod+incompatible/cmd/snap-mgmt/snap-mgmt.sh.in (about) 1 #!/bin/bash 2 3 # Overlord management of snapd for package manager actions. 4 # Implements actions that would be invoked in %pre(un) actions for snapd. 5 # Derived from the snapd.postrm scriptlet used in the Ubuntu packaging for 6 # snapd. 7 8 set -e 9 set +x 10 11 SNAP_MOUNT_DIR="@SNAP_MOUNT_DIR@" 12 13 show_help() { 14 exec cat <<'EOF' 15 Usage: snap-mgmt.sh [OPTIONS] 16 17 A simple script to cleanup snap installations. 18 19 optional arguments: 20 --help Show this help message and exit 21 --snap-mount-dir=<path> Provide a path to be used as $SNAP_MOUNT_DIR 22 --purge Purge all data from $SNAP_MOUNT_DIR 23 EOF 24 } 25 26 SNAP_UNIT_PREFIX="$(systemd-escape -p ${SNAP_MOUNT_DIR})" 27 28 systemctl_stop() { 29 unit="$1" 30 if systemctl is-active -q "$unit"; then 31 echo "Stopping $unit" 32 systemctl stop -q "$unit" || true 33 fi 34 } 35 36 purge() { 37 # shellcheck disable=SC1091 38 distribution=$(. /etc/os-release; echo "${ID}-${VERSION_ID}") 39 40 if [ "$distribution" = "ubuntu-14.04" ]; then 41 # snap.mount.service is a trusty thing 42 systemctl_stop snap.mount.service 43 else 44 # undo any bind mount to ${SNAP_MOUNT_DIR} that resulted from LP:#1668659 45 # (that bug can't happen in trusty -- and doing this would mess up snap.mount.service there) 46 if grep -q "${SNAP_MOUNT_DIR} ${SNAP_MOUNT_DIR}" /proc/self/mountinfo; then 47 umount -l "${SNAP_MOUNT_DIR}" || true 48 fi 49 fi 50 51 units=$(systemctl list-unit-files --no-legend --full | grep -vF snap.mount.service || true) 52 # *.snap mount points 53 mounts=$(echo "$units" | grep "^${SNAP_UNIT_PREFIX}[-.].*\\.mount" | cut -f1 -d ' ') 54 # services from snaps 55 services=$(echo "$units" | grep '^snap\..*\.service' | cut -f1 -d ' ') 56 for unit in $services $mounts; do 57 # ensure its really a snap mount unit or systemd unit 58 if ! grep -q 'What=/var/lib/snapd/snaps/' "/etc/systemd/system/$unit" && ! grep -q 'X-Snappy=yes' "/etc/systemd/system/$unit"; then 59 echo "Skipping non-snapd systemd unit $unit" 60 continue 61 fi 62 63 echo "Stopping $unit" 64 systemctl_stop "$unit" 65 66 if echo "$unit" | grep -q '.*\.mount' ; then 67 # Transform ${SNAP_MOUNT_DIR}/core/3440 -> core/3440 removing any 68 # extra / preceding snap name, eg: 69 # /var/lib/snapd/snap/core/3440 -> core/3440 70 # /snap/core/3440 -> core/3440 71 # /snap/core//3440 -> core/3440 72 # NOTE: we could have used `systemctl show $unit -p Where --value` 73 # but systemd 204 shipped with Ubuntu 14.04 does not support this 74 snap_rev=$(systemctl show "$unit" -p Where | sed -e 's#Where=##' -e "s#$SNAP_MOUNT_DIR##" -e 's#^/*##') 75 snap=$(echo "$snap_rev" |cut -f1 -d/) 76 rev=$(echo "$snap_rev" |cut -f2 -d/) 77 if [ -n "$snap" ]; then 78 echo "Removing snap $snap" 79 # aliases 80 if [ -d "${SNAP_MOUNT_DIR}/bin" ]; then 81 find "${SNAP_MOUNT_DIR}/bin" -maxdepth 1 -lname "$snap" -delete 82 find "${SNAP_MOUNT_DIR}/bin" -maxdepth 1 -lname "$snap.*" -delete 83 fi 84 # generated binaries 85 rm -f "${SNAP_MOUNT_DIR}/bin/$snap" 86 rm -f "${SNAP_MOUNT_DIR}/bin/$snap".* 87 # snap mount dir 88 umount -l "${SNAP_MOUNT_DIR}/$snap/$rev" 2> /dev/null || true 89 rm -rf "${SNAP_MOUNT_DIR:?}/$snap/$rev" 90 rm -f "${SNAP_MOUNT_DIR}/$snap/current" 91 # snap data dir 92 rm -rf "/var/snap/$snap/$rev" 93 rm -rf "/var/snap/$snap/common" 94 rm -f "/var/snap/$snap/current" 95 # opportunistic remove (may fail if there are still revisions left) 96 for d in "${SNAP_MOUNT_DIR}/$snap" "/var/snap/$snap"; do 97 if [ -d "$d" ]; then 98 rmdir --ignore-fail-on-non-empty "$d" 99 fi 100 done 101 # udev rules 102 find /etc/udev/rules.d -name "*-snap.${snap}.rules" -execdir rm -f "{}" \; 103 # dbus policy files 104 if [ -d /etc/dbus-1/system.d ]; then 105 find /etc/dbus-1/system.d -name "snap.${snap}.*.conf" -execdir rm -f "{}" \; 106 fi 107 # timer files 108 find /etc/systemd/system -name "snap.${snap}.*.timer" | while read -r f; do 109 systemctl_stop "$(basename "$f")" 110 rm -f "$f" 111 done 112 fi 113 fi 114 115 echo "Removing $unit" 116 rm -f "/etc/systemd/system/$unit" 117 rm -f "/etc/systemd/system/multi-user.target.wants/$unit" 118 done 119 120 echo "Discarding preserved snap namespaces" 121 # opportunistic as those might not be actually mounted 122 if [ -d /run/snapd/ns ]; then 123 if [ "$(find /run/snapd/ns/ -name "*.mnt" | wc -l)" -gt 0 ]; then 124 for mnt in /run/snapd/ns/*.mnt; do 125 umount -l "$mnt" || true 126 rm -f "$mnt" 127 done 128 fi 129 find /run/snapd/ns/ \( -name '*.fstab' -o -name '*.user-fstab' -o -name '*.info' \) -delete 130 umount -l /run/snapd/ns/ || true 131 fi 132 133 echo "Removing downloaded snaps" 134 rm -rf /var/lib/snapd/snaps/* 135 136 echo "Removing features exported from snapd to helper tools" 137 rm -rf /var/lib/snapd/features 138 139 echo "Final directory cleanup" 140 rm -rf "${SNAP_MOUNT_DIR}" 141 rm -rf /var/snap 142 143 echo "Removing leftover snap shared state data" 144 rm -rf /var/lib/snapd/desktop/applications/* 145 rm -rf /var/lib/snapd/seccomp/bpf/* 146 rm -rf /var/lib/snapd/device/* 147 rm -rf /var/lib/snapd/assertions/* 148 rm -rf /var/lib/snapd/cookie/* 149 rm -rf /var/lib/snapd/cache/* 150 rm -rf /var/lib/snapd/mount/* 151 rm -rf /var/lib/snapd/sequence/* 152 rm -rf /var/lib/snapd/apparmor/* 153 rm -f /var/lib/snapd/state.json 154 rm -f /var/lib/snapd/system-key 155 156 echo "Removing snapd catalog cache" 157 rm -rf /var/cache/snapd/* 158 159 if test -d /etc/apparmor.d; then 160 # Remove auto-generated rules for snap-confine from the 'core' snap 161 echo "Removing extra snap-confine apparmor rules" 162 # shellcheck disable=SC2046 163 rm -f /etc/apparmor.d/$(echo "$SNAP_UNIT_PREFIX" | tr '-' '.').core.*.usr.lib.snapd.snap-confine 164 fi 165 } 166 167 while [ -n "$1" ]; do 168 case "$1" in 169 --help) 170 show_help 171 exit 172 ;; 173 --snap-mount-dir=*) 174 SNAP_MOUNT_DIR=${1#*=} 175 SNAP_UNIT_PREFIX=$(systemd-escape -p "$SNAP_MOUNT_DIR") 176 shift 177 ;; 178 --purge) 179 purge 180 shift 181 ;; 182 *) 183 echo "Unknown command: $1" 184 exit 1 185 ;; 186 esac 187 done