Ich weiß jetzt, wie das geht. Wenn Sie dieser Erklärung nicht folgen können, fragen Sie bitte zurück, aber stellen Sie auch sicher, dass Sie sich in den Lesungen, die ich unten gebe, über die Benutzer informiert haben
Vorläufige Annahmen
Ich werde mich an die folgenden Annahmen halten, die sich aus Ihrer Frage ergeben:
- Host hat ein
user1
und ein user2
, wenn eine Information nicht spezifisch für eine ist, werden wir verwendenuserX
- Der Container wird durch eine Variable benannt, als die wir rendern
$container
- Home-Ordner für
user1
und user2
werden in der von Bash als ~user1
und bekannten Notation angegeben ~user2
.
- Wir gehen davon aus, dass die untergeordneten UID- und GID-Bereiche der Kürze
user1
halber 100000..165536 für und 200000..265536 sinduser2
- Der Root-FS-Ordner für
$container
wird als gerendert $rootfs
, unabhängig davon, wo er landen wird ( ~userX/.local/share/lxc/$container/rootfs
)
- Die Containerkonfiguration ist standardmäßig in
~userX/.local/share/lxc/$container/config
Container bewegen
Es gibt zwei relevante Daten, die die userns
Container regeln :
- Eigentümer und Gruppe für die Dateien / Ordner der Ordner, aus denen die
$container
- die untergeordneten UIDs und GIDs, die an zwei Stellen zugewiesen wurden:
/etc/sub{uid,gid}
für das Benutzerkonto (manipuliert über usermod --{add,del}-sub-{uid,gid}s
) bzw. lxc.id_map
in der $container
Konfiguration ( ~userX/.local/share/lxc/$container/config
)
- Ich weiß nicht genau, ob es möglich ist, für jeden Container unterschiedliche Bereiche in der Containerkonfiguration zu definieren. Wenn der
userX
Hostbenutzer beispielsweise 65536 untergeordnete GIDs und UIDs hat, ist es möglicherweise möglich, 5000 bis 65 verschiedenen Containern zuzuweisen, aber ich habe diese Hypothese nicht getestet.
- Es ist jedoch sicher, dass diese Einstellung mit LXC kommuniziert. Dies sind die gültigen Bereiche für GID und UID im untergeordneten Namespace.
So ist der Kern ist wirklich , dass Sie darauf achten müssen, dass die Datei / Ordner - Besitzer und die Gruppe für den Container die Konfiguration entsprechen, die wiederum eine gültige Teilmenge des Host untergeordneter GIDs / UIDs zugeordnet sein muss user1
und user2
jeweils.
Wenn Sie beispielsweise Bash verwenden, können Sie $((expression))
arithmetische Ausdrücke verwenden und let
Variablen arithmetische Ausdrücke zuweisen. Dies ist sehr nützlich, wenn Sie einen Basiswert (100000 bzw. 200000) und die GID / UID für die "internen" Benutzer kennen.
Die Hauptpunkte sind:
- es ist möglich
- Es sind entweder die Fähigkeits-
CAP_CHOWN
oder die Superuser-Rechte erforderlich
Hier ist ein Skript, das wahrscheinlich noch etwas verfeinert werden muss (Beispiel: Migration von einem vom Root erstellten Container zu einem nicht privilegierten), aber es funktioniert für mich zu diesem Zweck:
#!/usr/bin/env bash
function syntax
{
echo "SYNTAX: ${0##*/} <from-user> <to-user> <container-name>"
[[ -n "$1" ]] && echo -e "\nERROR: ${1}."
exit 1
}
# Checks
[[ -n "$1" ]] || syntax "<from-user> is not set"
[[ -n "$2" ]] || syntax "<to-user> is not set"
[[ -n "$3" ]] || syntax "<container-name> is not set"
[[ "$UID" -eq "0" ]] || syntax "${0##*/}" "You must be superuser to make use of this script"
# Constants with stuff we need
readonly USERFROM=$1
readonly USERTO=$2
shift; shift
readonly CONTAINER=${1:-*}
LXCLOCAL=".local/share/lxc"
readonly HOMEFROM=$(eval echo ~$USERFROM)
readonly HOMETO=$(eval echo ~$USERTO)
readonly LXCFROM="$HOMEFROM/$LXCLOCAL"
readonly LXCTO="$HOMETO/$LXCLOCAL"
readonly GIDBASEFROM=$(awk -F : "\$1 ~/$USERFROM/ {print \$2}" /etc/subgid)
readonly UIDBASEFROM=$(awk -F : "\$1 ~/$USERFROM/ {print \$2}" /etc/subuid)
readonly GIDSIZEFROM=$(awk -F : "\$1 ~/$USERFROM/ {print \$3}" /etc/subgid)
readonly UIDSIZEFROM=$(awk -F : "\$1 ~/$USERFROM/ {print \$3}" /etc/subuid)
readonly GIDBASETO=$(awk -F : "\$1 ~/$USERTO/ {print \$2}" /etc/subgid)
readonly UIDBASETO=$(awk -F : "\$1 ~/$USERTO/ {print \$2}" /etc/subuid)
readonly GIDSIZETO=$(awk -F : "\$1 ~/$USERTO/ {print \$3}" /etc/subgid)
readonly UIDSIZETO=$(awk -F : "\$1 ~/$USERTO/ {print \$3}" /etc/subuid)
unset LXCLOCAL
# More checks
[[ -d "$LXCFROM" ]] || syntax "Could not locate '$LXCFROM'. It is not a directory as expected"
[[ -e "$LXCTO" ]] && syntax "Destination '$LXCTO' already exists. However, it must not"
for i in GIDBASEFROM UIDBASEFROM GIDBASETO UIDBASETO; do
(($i > 0)) || syntax "Could not determine base/offset of subordinate UID/GID range"
done
for i in GIDSIZEFROM UIDSIZEFROM GIDSIZETO UIDSIZETO; do
(($i > 0)) || syntax "Could not determine length of subordinate UID/GID range"
done
echo "Going to migrate container: $CONTAINER"
echo -e "\tfrom user $USERFROM ($HOMEFROM): subUID=${UIDBASEFROM}..$((UIDBASEFROM+UIDSIZEFROM)); subGID=${GIDBASEFROM}..$((GIDBASEFROM+GIDSIZEFROM))"
echo -e "\tto user $USERTO ($HOMETO): subUID=${UIDBASETO}..$((UIDBASETO+UIDSIZETO)); subGID=${GIDBASETO}..$((GIDBASETO+GIDSIZETO))"
while read -p "Do you want to continue? (y/N) "; do
case ${REPLY:0:1} in
y|Y)
break;
;;
*)
echo "User asked to abort."
exit 1
;;
esac
done
# Find the UIDs and GIDs in use in the container
readonly SUBGIDSFROM=$(find -H "$LXCFROM" -printf '%G\n'|sort -u)
readonly SUBUIDSFROM=$(find -H "$LXCFROM" -printf '%U\n'|sort -u)
# Change group
for gid in $SUBGIDSFROM; do
let GIDTO=$(id -g "$USERTO")
if ((gid == $(id -g "$USERFROM"))); then
echo "Changing group from $USERFROM ($gid) to $USERTO ($GIDTO)"
find -H "$LXCFROM/$CONTAINER" -gid $gid -exec chgrp $GIDTO {} +
elif ((gid >= GIDBASEFROM )) && ((gid <= GIDBASEFROM+GIDSIZEFROM)); then
let GIDTO=$((gid-GIDBASEFROM+GIDBASETO))
echo "Changing group $gid -> $GIDTO"
find -H "$LXCFROM/$CONTAINER" -gid $gid -exec chgrp $GIDTO {} +
else
echo "ERROR: Some file/folder inside '$LXCFROM/$CONTAINER' has a group not assigned to $USERFROM (assigned subordinate GIDs)."
echo -e "Use:\n\tfind -H '$LXCFROM/$CONTAINER' -gid $gid\nto list those files/folders."
exit 1
fi
done
# Change owner
for uid in $SUBUIDSFROM; do
let UIDTO=$(id -u "$USERTO")
if ((uid == $(id -u "$USERFROM"))); then
echo "Changing owner from $USERFROM ($uid) to $USERTO ($UIDTO)"
find -H "$LXCFROM/$CONTAINER" -uid $uid -exec chown $UIDTO {} +
elif ((uid >= UIDBASEFROM )) && ((uid <= UIDBASEFROM+UIDSIZEFROM)); then
let UIDTO=$((uid-UIDBASEFROM+UIDBASETO))
echo "Changing owner $uid -> $UIDTO"
find -H "$LXCFROM/$CONTAINER" -uid $uid -exec chown $UIDTO {} +
else
echo "ERROR: Some file/folder inside '$LXCFROM/$CONTAINER' has an owner not assigned to $USERFROM (assigned subordinate UIDs)."
echo -e "Use:\n\tfind -H '$LXCFROM/$CONTAINER' -uid $uid\nto list those files/folders."
exit 1
fi
done
mv "$LXCFROM/$CONTAINER" "$LXCTO/" || { echo "ERROR: failed to move to destination: ${LXCTO}/${CONTAINER}."; exit 1; }
Zusätzlich zu den Lizenzbedingungen des StackExchange-Netzwerks stelle ich diese öffentlich zur Verfügung. Also wiederverwenden und modifizieren für jeden Zweck, aber es kommt ohne Garantie und ich kann nicht für seine Verwendung oder Missbrauch haftbar gemacht werden.
Verwendungszweck
SYNTAX: lxc-reassign-userns.sh <from-user> <to-user> <container-name>
Er geht davon aus find
, sort
, uniq
, awk
( mawk
und gawk
sollte funktionieren) id
, bash
, chown
, chmod
und so weiter zur Verfügung zu stehen und alle Befehlszeile zu verstehen , schaltet es verwendet. Für Bash readonly
und let
und arithmetische Ausdrücke wird angenommen, dass sie verstanden werden. Es find
wird davon ausgegangen, dass +
es sich um einen gültigen Terminator für die -exec
Aktion handelt.
Diese Liste ist wahrscheinlich nicht vollständig.
Backups
Ja, Sie können Sicherungen erstellen und an anderer Stelle wiederherstellen, sofern Sie auch den Dateieigentümer und die Gruppe entsprechend anpassen.
Angenommen, Sie verwenden so etwas wie tar
, gibt es eine Einschränkung: tar
Ignoriert Sockets und $rootfs/dev/log
wirft ein Problem auf - andere können ebenfalls ein ähnliches Problem verursachen.
Ressourcen:
cp
stattmv
mit den entsprechenden Flags, um alle Eigenschaften beizubehalten, die Sie in meinem Skript beibehalten müssen.