From 845e3fe30e67540c7f6a7160e2ce9002f78da78d Mon Sep 17 00:00:00 2001 From: MasterofJOKers Date: Sat, 25 Feb 2023 17:15:23 +0100 Subject: [PATCH] Add remap-uid-and-gid-for-lv I've used this script to remap files' uids/gids of containers created without a custom userns into their new range. It's inferior to `fuidshift` from the `lxc` project in that it doesn't handle ACLs and is quite slow - probably because it calls a binary for every file. By default, it runs in debug mode only printing the chown command instead of executing it. You need to edit the file to use it. It also only works with LVs (logical volumes from LVM), mounting them automatically. --- lxc/remap-uid-and-gid-for-lv | 71 ++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100755 lxc/remap-uid-and-gid-for-lv diff --git a/lxc/remap-uid-and-gid-for-lv b/lxc/remap-uid-and-gid-for-lv new file mode 100755 index 0000000..ca21fd1 --- /dev/null +++ b/lxc/remap-uid-and-gid-for-lv @@ -0,0 +1,71 @@ +#!/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 []" + printf "\nIf 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. +find . -xdev -not -type l -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 %s:%s %s\n" ${NEW_U} ${NEW_G} "${P}" + # chown ${NEW_U}:${NEW_G} "${P}" + done + +cd / +umount /mnt