Files
webgui/emhttp/plugins/dynamix.docker.manager/scripts/docker_rm

84 lines
3.1 KiB
Bash
Executable File

#!/bin/bash
# Useful to delete a docker runtime diretory. In case of btrfs storage driver, handles deletion of btrfs
# subvolumes used to store image layers. Similarly, in caes of zfs storage driver, handles deletion of
# zfs datasets used to store image layers. Assumes dockerd is not running.
# Note: If the $target diretory is spit across multiple volumes, this operation is a no-op.
# Caution: in case of 'native' zfs storage driver which uses datasets to store layers, $target is irrelevant
# because datasets are not listed under directories. This script will destroy *all* legacy datasets in the
# volume. For example, consider two directories on same volume:
# /mnt/cache/docker
# /mnt/cache/docker-backup
# Each directory holds a valid docker tree structure, maybe 'docker' is current and 'docker-backup' is
# a backup. User decides he no loner needs 'docker-backup' so he invokes this script. The result will be
# that not only will /mnt/cache/docker-backup be deleted, but all datasets belonging to /mnt/cache/docker
# will also be deleted. This is because we cannot tell which datasets belong with which docker instance.
# If /mnt/cache/docker and /mnt/cache/docker-backup were themselves datasets, then we would be able to, but
# this is not implemented here.
dereference() {
local DIR=$1
# if directory is on user share, attempt to dereference
if [[ "$DIR" == /mnt/user/* ]]; then
# getfattr would return blank if /mnt/user/<share> is a bind-mount
local DISK=$(getfattr -n system.LOCATIONS --absolute-names --only-values "$DIR" 2>/dev/null)
if [[ -n "$DISK" ]]; then
# whitespace in $DISK would exist if $target is split across multiple volumes
[[ ! "$DISK" =~ [[:space:]] ]] && DIR="${DIR/user/$DISK}" || DIR=""
fi
fi
echo "$DIR"
}
rm_docker() {
local target="${1%/}"
# sanity check that this is a docker folder
if [[ ! -d "$target/containerd" ]]; then
echo "docker_rm: $target is not a docker folder"
exit 1
fi
# dereference folder on user share
target=$(dereference "$target")
if [[ -z "$target" ]]; then
echo "docker_rm: $target is split across multiple volumes"
exit 1
fi
if [[ -d "$target/btrfs/subvolumes" ]]; then
# delete btrfs subvolumes
for subvol in "$target/btrfs/subvolumes/"*; do
btrfs subvolume delete -cR "$subvol"
done
elif [[ -d "$target/zfs" ]]; then
# destroy zfs 'legacy' datasets
zfs list -rHo name,mountpoint "$target" 2>/dev/null | awk '$2 == "legacy" {print $1}' | while read -r dataset; do
echo "docker_rm: zfs destroy -R $dataset"
zfs destroy -R "$dataset"
done
fi
# delete files and directories
echo "docker_rm: rm -rf $target"
rm -rf "$target"
}
# delete the docker image file or folder
if [[ -f /boot/config/docker.cfg ]]; then
rm -f /var/local/emhttp/plugins/dynamix.docker.manager/docker.json
. /boot/config/docker.cfg
if [[ -f $DOCKER_IMAGE_FILE ]]; then
echo "Deleting $DOCKER_IMAGE_FILE ..."
rm -f "$DOCKER_IMAGE_FILE"
elif [[ -d $DOCKER_IMAGE_FILE ]]; then
echo "Deleting $DOCKER_IMAGE_FILE ..."
rm_docker "$DOCKER_IMAGE_FILE"
fi
fi