You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
script-dump/lxc/remap-uid-and-gid-for-lv

84 lines
2.6 KiB

#!/bin/sh
# Remap all files uid/gid to a new range
#
# This is an inferior version of `fuidshift` from the `lxd-tools` Debian package, as it only handles uid/gid and
# doesn't handle ACLs and thus journalctl's files and by that hinders updating systemd inside the container. It's also
# quite slow.
usage () {
echo "remap-uid-and-gid <container-name> [<target-lv>]"
printf "\nIf <target-lv> is not given it is computed from a default value with the given container name\n"
exit 1
}
CONTAINER_NAME="${1}"
if [ "${CONTAINER_NAME}" = "" ]; then
usage
fi
TARGET_LV="${2}"
if [ "${TARGET_LV}" = "" ]; then
GUESSED_LV="/dev/mapper/daffy--vg-lxc--${CONTAINER_NAME}"
if [ -e "${GUESSED_LV}" ]; then
TARGET_LV="${GUESSED_LV}"
fi
fi
if [ "${TARGET_LV}" = "" ]; then
usage
fi
if mount | grep -qF " on /mnt"; then
echo "Mountpoint /mnt is already in use."
exit 1
fi
mount "${TARGET_LV}" /mnt
cd /mnt
ROOT_USER_ID=$(get-lxc-idmap-config u $CONTAINER_NAME | cut -d ' ' -f 5)
ROOT_GROUP_ID=$(get-lxc-idmap-config g $CONTAINER_NAME | cut -d ' ' -f 5)
printf "uid: %s gid: %s\n" $ROOT_USER_ID $ROOT_GROUP_ID
# We ignore links here, because they might not point to a valid location and would make our program fail. They are also
# owned by whoever mounted the filesystem it seems, so don't need a chown.
# Funny enough, the above statement is not true. I see symlinks in the container that are not owned by a valid user
# inside the container ...
# chown
# -h, --no-dereference
# affect symbolic links instead of any referenced file (useful only on systems
# that can change the ownership of a symlink)
#
# --from=CURRENT_OWNER:CURRENT_GROUP
# change the owner and/or group of each file only if its current owner and/or
# group match those specified here. Either may be omitted, in which case a
# match is not required for the omitted attribute
#
find . -xdev -printf "%U %G %p\n" | \
while read F; do
U=$(echo $F | cut -d ' ' -f 1)
if [ ${U} -lt ${ROOT_USER_ID} ] || [ ${U} -gt $(( ${ROOT_USER_ID} + 65535 )) ]; then
NEW_U=$(( ${U} + ${ROOT_USER_ID} ))
else
NEW_U=${U}
fi
G=$(echo $F | cut -d ' ' -f 2)
if [ ${G} -lt ${ROOT_GROUP_ID} ] || [ ${G} -gt $(( ${ROOT_GROUP_ID} + 65535 )) ]; then
NEW_G=$(( ${G} + ${ROOT_GROUP_ID} ))
else
NEW_G=${G}
fi
if [ "${U}" = "${NEW_U}" ] && [ "${G}" = "${NEW_G}" ]; then
continue
fi
P=$(echo $F | cut -d ' ' -f 3-)
printf "chown --no-dereference %s:%s %s\n" ${NEW_U} ${NEW_G} "${P}"
# chown --no-dereference ${NEW_U}:${NEW_G} "${P}"
done
cd /
umount /mnt