From dc2d39056024e3762d94c7747116bd84121deb9f Mon Sep 17 00:00:00 2001 From: Omer Tuchfeld Date: Thu, 1 Aug 2024 12:51:36 +0200 Subject: [PATCH] ilab-wrapper: Run podman with sudo # Background The ilab command is wrapped by an `ilab` script which launches ilab inside a podman container. # Issue Since the ilab container image is pulled during the bootc image build process using the root user, the image is not accessible to non-root users. # Solution We run the container as sudo in order to be able to access the root container storage. But for security reasons we map root UID 0 inside the container to the current user's UID (and all the other subuids to the user's /etc/subuid range) so that we're effectively running the container as the current user. # Additional changes Changed `"--env" "HOME"` to `"--env" "HOME=$HOME"` to pass the HOME environment variable from the current shell and not from the sudo environment. # Future work In the future, we will run podman as the current user, once we figure a reasonable way for the current user to access the root's user container storage Signed-off-by: Omer Tuchfeld --- training/ilab-wrapper/ilab | 55 +++++++++++++++---- .../nvidia-bootc/duplicated/ilab-wrapper/ilab | 55 +++++++++++++++---- 2 files changed, 88 insertions(+), 22 deletions(-) diff --git a/training/ilab-wrapper/ilab b/training/ilab-wrapper/ilab index 94aa812e..e0f4c430 100755 --- a/training/ilab-wrapper/ilab +++ b/training/ilab-wrapper/ilab @@ -8,21 +8,54 @@ export ENTRYPOINT="/opt/python3.11/venv/bin/ilab" export PARAMS=("$@") for dir in "$HOME/.cache" "$HOME/.config" "$HOME/.local"; do - mkdir -p "$dir" + mkdir -p "$dir" done if [[ "$1" = "shell" ]]; then - export ENTRYPOINT=bash - export PARAMS=() + export ENTRYPOINT=bash + export PARAMS=() fi -PODMAN_COMMAND=("podman" "run" "--rm" "-it" - "--device" "${CONTAINER_DEVICE}" - "--security-opt" "label=disable" "--net" "host" - "-v" "$HOME:$HOME" - "--env" "HOME" - "--entrypoint" "$ENTRYPOINT" - "--env" "HF_TOKEN" - "${IMAGE_NAME}") +# We run the container as sudo in order to be able to access the root container +# storage, which has the ilab image pre-pulled. But for security reasons we map +# root UID 0 inside the container to the current user's UID (and all the other +# subuids to the user's /etc/subuid range) so that we're effectively running +# the container as the current user. +# +# In the future, we will run podman as the current user, once we figure a +# reasonable way for the current user to access the root's user container +# storage. +CURRENT_USER_NAME=$(id --user --name) +CURRENT_USER_SUBUID_RANGE=$(awk \ + --field-separator ':' \ + --assign current_user="$CURRENT_USER_NAME" \ + --assign current_uid="$UID" \ + '$1 == current_user || $1 == current_uid {print $2 ":" $3}' \ + /etc/subuid) + +# TODO: Handle multiple subuid ranges, for now, hard fail +if [[ $(echo "$CURRENT_USER_SUBUID_RANGE" | wc -l) != 1 ]]; then + if [[ -z "$CURRENT_USER_SUBUID_RANGE" ]]; then + echo "No subuid range found for user $CURRENT_USER_NAME ($UID)" + else + echo "Multiple subuid ranges found for user $CURRENT_USER_NAME ($UID):" + echo "$CURRENT_USER_SUBUID_RANGE" + fi + exit 1 +fi + +IMPERSONATE_CURRENT_USER_PODMAN_FLAGS=("--uidmap" "0:$UID" "--uidmap" "1:$CURRENT_USER_SUBUID_RANGE") + +PODMAN_COMMAND=("sudo" "podman" "run" "--rm" "-it" + "${IMPERSONATE_CURRENT_USER_PODMAN_FLAGS[@]}" + "--device" "${CONTAINER_DEVICE}" + "--security-opt" "label=disable" "--net" "host" + "-v" "$HOME:$HOME" + # This is intentionally NOT using "--env" "HOME" because we want the HOME + # of the current shell and not the HOME set by sudo + "--env" "HOME=$HOME" + "--entrypoint" "$ENTRYPOINT" + "--env" "HF_TOKEN" + "${IMAGE_NAME}") exec "${PODMAN_COMMAND[@]}" "${PARAMS[@]}" diff --git a/training/nvidia-bootc/duplicated/ilab-wrapper/ilab b/training/nvidia-bootc/duplicated/ilab-wrapper/ilab index 94aa812e..e0f4c430 100755 --- a/training/nvidia-bootc/duplicated/ilab-wrapper/ilab +++ b/training/nvidia-bootc/duplicated/ilab-wrapper/ilab @@ -8,21 +8,54 @@ export ENTRYPOINT="/opt/python3.11/venv/bin/ilab" export PARAMS=("$@") for dir in "$HOME/.cache" "$HOME/.config" "$HOME/.local"; do - mkdir -p "$dir" + mkdir -p "$dir" done if [[ "$1" = "shell" ]]; then - export ENTRYPOINT=bash - export PARAMS=() + export ENTRYPOINT=bash + export PARAMS=() fi -PODMAN_COMMAND=("podman" "run" "--rm" "-it" - "--device" "${CONTAINER_DEVICE}" - "--security-opt" "label=disable" "--net" "host" - "-v" "$HOME:$HOME" - "--env" "HOME" - "--entrypoint" "$ENTRYPOINT" - "--env" "HF_TOKEN" - "${IMAGE_NAME}") +# We run the container as sudo in order to be able to access the root container +# storage, which has the ilab image pre-pulled. But for security reasons we map +# root UID 0 inside the container to the current user's UID (and all the other +# subuids to the user's /etc/subuid range) so that we're effectively running +# the container as the current user. +# +# In the future, we will run podman as the current user, once we figure a +# reasonable way for the current user to access the root's user container +# storage. +CURRENT_USER_NAME=$(id --user --name) +CURRENT_USER_SUBUID_RANGE=$(awk \ + --field-separator ':' \ + --assign current_user="$CURRENT_USER_NAME" \ + --assign current_uid="$UID" \ + '$1 == current_user || $1 == current_uid {print $2 ":" $3}' \ + /etc/subuid) + +# TODO: Handle multiple subuid ranges, for now, hard fail +if [[ $(echo "$CURRENT_USER_SUBUID_RANGE" | wc -l) != 1 ]]; then + if [[ -z "$CURRENT_USER_SUBUID_RANGE" ]]; then + echo "No subuid range found for user $CURRENT_USER_NAME ($UID)" + else + echo "Multiple subuid ranges found for user $CURRENT_USER_NAME ($UID):" + echo "$CURRENT_USER_SUBUID_RANGE" + fi + exit 1 +fi + +IMPERSONATE_CURRENT_USER_PODMAN_FLAGS=("--uidmap" "0:$UID" "--uidmap" "1:$CURRENT_USER_SUBUID_RANGE") + +PODMAN_COMMAND=("sudo" "podman" "run" "--rm" "-it" + "${IMPERSONATE_CURRENT_USER_PODMAN_FLAGS[@]}" + "--device" "${CONTAINER_DEVICE}" + "--security-opt" "label=disable" "--net" "host" + "-v" "$HOME:$HOME" + # This is intentionally NOT using "--env" "HOME" because we want the HOME + # of the current shell and not the HOME set by sudo + "--env" "HOME=$HOME" + "--entrypoint" "$ENTRYPOINT" + "--env" "HF_TOKEN" + "${IMAGE_NAME}") exec "${PODMAN_COMMAND[@]}" "${PARAMS[@]}"