From 6704cd752703159530775718d6d61fdeed027bdb Mon Sep 17 00:00:00 2001 From: David Boreham Date: Fri, 24 Feb 2023 22:14:28 -0700 Subject: [PATCH] Implement new approach: build a uid-specific container --- app/build_containers.py | 6 ++++-- .../cerc-builder-js/Dockerfile | 18 +++++++++++++++- .../cerc-builder-js/check-uid.sh | 21 +++++++++++++++++++ .../cerc-builder-js/entrypoint.sh | 2 +- .../cerc-builder-js/fixup-for-uid.sh | 18 ---------------- 5 files changed, 43 insertions(+), 22 deletions(-) create mode 100755 app/data/container-build/cerc-builder-js/check-uid.sh delete mode 100755 app/data/container-build/cerc-builder-js/fixup-for-uid.sh diff --git a/app/build_containers.py b/app/build_containers.py index 7ecf4a82..04cecd62 100644 --- a/app/build_containers.py +++ b/app/build_containers.py @@ -83,7 +83,9 @@ def command(ctx, include, exclude): container_build_env = { "CERC_NPM_URL": "http://gitea.local:3000/api/packages/cerc-io/npm/", "CERC_NPM_AUTH_TOKEN": config("CERC_NPM_AUTH_TOKEN", default=""), - "CERC_REPO_BASE_DIR": dev_root_path + "CERC_REPO_BASE_DIR": dev_root_path, + "CERC_HOST_UID": f"{os.getuid()}", + "CERC_HOST_GID": f"{os.getgid()}" } def process_container(container): @@ -106,7 +108,7 @@ def command(ctx, include, exclude): build_command = os.path.join(container_build_dir, "default-build.sh") + f" {container}:local {repo_dir_or_build_dir}" if not dry_run: if verbose: - print(f"Executing: {build_command}") + print(f"Executing: {build_command} with environment: {container_build_env}") build_result = subprocess.run(build_command, shell=True, env=container_build_env) if verbose: print(f"Return code is: {build_result.returncode}") diff --git a/app/data/container-build/cerc-builder-js/Dockerfile b/app/data/container-build/cerc-builder-js/Dockerfile index 9a1cf680..fb7043c9 100644 --- a/app/data/container-build/cerc-builder-js/Dockerfile +++ b/app/data/container-build/cerc-builder-js/Dockerfile @@ -1,14 +1,30 @@ # Originally from: https://github.com/devcontainers/images/blob/main/src/javascript-node/.devcontainer/Dockerfile +# Which depends on: https://github.com/nodejs/docker-node/blob/main/Dockerfile-debian.template # [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster ARG VARIANT=16-bullseye FROM node:${VARIANT} +# Set these args to change the uid/gid for the base container's "node" user to match that of the host user (so bind mounts work as expected). +ARG CERC_HOST_UID=1000 +ARG CERC_HOST_GID=1000 +# Make these values available at runtime to allow a consistency check. +ENV HOST_UID=${CERC_HOST_UID} +ENV HOST_GID=${CERC_HOST_GID} + ARG USERNAME=node ARG NPM_GLOBAL=/usr/local/share/npm-global # Add NPM global to PATH. ENV PATH=${NPM_GLOBAL}/bin:${PATH} +RUN \ + if [ ${CERC_HOST_GID} -ne 1000 ] ; then \ + groupmod -g ${CERC_HOST_GID} ${USERNAME} ; \ + fi \ + && if [ ${CERC_HOST_UID} -ne 1000 ] ; then \ + usermod -u ${CERC_HOST_UID} -g ${CERC_HOST_GID} ${USERNAME} ; \ + fi + RUN \ # Configure global npm install location, use group to adapt to UID/GID changes if ! cat /etc/group | grep -e "^npm:" > /dev/null 2>&1; then groupadd -r npm; fi \ @@ -39,7 +55,7 @@ RUN mkdir /scripts COPY build-npm-package.sh /scripts COPY yarn-local-registry-fixup.sh /scripts COPY build-npm-package-local-dependencies.sh /scripts -COPY fixup-for-uid.sh /scripts +COPY check-uid.sh /scripts ENV PATH="${PATH}:/scripts" COPY entrypoint.sh . diff --git a/app/data/container-build/cerc-builder-js/check-uid.sh b/app/data/container-build/cerc-builder-js/check-uid.sh new file mode 100755 index 00000000..a8cbc324 --- /dev/null +++ b/app/data/container-build/cerc-builder-js/check-uid.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Make the container usable for uid/gid != 1000 +if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then + set -x +fi +current_uid=$(id -u) +current_gid=$(id -g) +# Don't check if running as root +if [[ ${current_uid} == 0 ]]; then + exit 0 +fi +# Check the current uid/gid vs the uid/gid used to build the container. +# We do this because both bind mounts and npm tooling require the uid/gid to match. +if [[ ${current_gid} != ${HOST_GID} ]]; then + echo "Warning: running with gid: ${current_gid} which is not the gid for which this container was built (${HOST_GID})" + exit 0 +fi +if [[ ${current_uid} != ${HOST_UID} ]]; then + echo "Warning: running with gid: ${current_uid} which is not the uid for which this container was built (${HOST_UID})" + exit 0 +fi diff --git a/app/data/container-build/cerc-builder-js/entrypoint.sh b/app/data/container-build/cerc-builder-js/entrypoint.sh index cfbce454..ab80737a 100755 --- a/app/data/container-build/cerc-builder-js/entrypoint.sh +++ b/app/data/container-build/cerc-builder-js/entrypoint.sh @@ -1,3 +1,3 @@ #!/bin/sh -/scripts/fixup-for-uid.sh +/scripts/check-uid.sh exec "$@" diff --git a/app/data/container-build/cerc-builder-js/fixup-for-uid.sh b/app/data/container-build/cerc-builder-js/fixup-for-uid.sh deleted file mode 100755 index 04089d08..00000000 --- a/app/data/container-build/cerc-builder-js/fixup-for-uid.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# Make the container usable for uid/gid != 1000 -if [[ -n "$CERC_SCRIPT_DEBUG" ]]; then - set -x -fi -current_uid=$(id -u) -current_gid=$(id -g) -user_name="hostuser" -# First check the current uid. If == 1000 then exit, nothing needed because that uid already exists -if [[ ${current_uid} == 1000 ]]; then - exit 0 -fi -# Also exit for root -if [[ ${current_uid} == 0 ]]; then - exit 0 -fi -# Create the user with home dir -useradd -m -d /home/${user_name} -s /bin/bash -g ${current_gid} -u ${current_uid} ${user_name}