From 2963ae91192b29a8ec049d7376dc69ff21b725f4 Mon Sep 17 00:00:00 2001 From: Chuck Lantz Date: Fri, 28 Oct 2022 12:32:58 -0500 Subject: Fix privs in Node, regressions from #199 (#241) Co-authored-by: Samruddhi Khandale --- src/node/devcontainer-feature.json | 7 ++- src/node/install.sh | 108 +++++++++++++++++++---------------- test/node/install_additional_node.sh | 2 +- test/node/non_root_user.sh | 13 +++++ test/node/scenarios.json | 11 +++- 5 files changed, 89 insertions(+), 52 deletions(-) create mode 100755 test/node/non_root_user.sh diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index 43ba0fa..cdc2fec 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node", - "version": "1.0.8", + "version": "1.1.0", "name": "Node.js (via nvm) and yarn", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/node", "description": "Installs Node.js, nvm, yarn, and needed dependencies.", @@ -27,6 +27,11 @@ "type": "string", "default": "/usr/local/share/nvm", "description": "The path where NVM will be installed." + }, + "nvmVersion": { + "type": "string", + "default": "0.39.2", + "description": "Version of NVM to install." } }, "customizations": { diff --git a/src/node/install.sh b/src/node/install.sh index 2bdd21a..cc5e1dc 100755 --- a/src/node/install.sh +++ b/src/node/install.sh @@ -1,13 +1,14 @@ #!/bin/bash -#------------------------------------------------------------------------------------------------------------- +#------------------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. -#------------------------------------------------------------------------------------------------------------- +# Licensed under the MIT License. See https://github.com/devcontainers/features/blob/main/LICENSE for license information. +#------------------------------------------------------------------------------------------------------------------------- # -# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/node.md -# Maintainer: The VS Code and Codespaces Teams +# Docs: https://github.com/devcontainers/features/tree/main/src/node +# Maintainer: The Dev Container spec maintainers export NODE_VERSION=${VERSION:-"lts"} +export NVM_VERSION="${NVMVERSION:-"0.39.2"}" export NVM_DIR=${NVMINSTALLPATH:-"/usr/local/share/nvm"} INSTALL_TOOLS_FOR_NODE_GYP="${NODEGYPDEPENDENCIES:-true}" @@ -18,8 +19,6 @@ ADDITIONAL_VERSIONS=${ADDITIONALVERSIONS:-""} USERNAME=${USERNAME:-"automatic"} UPDATE_RC=${UPDATE_RC:-"true"} -export NVM_VERSION="0.38.0" - set -e # Clean up @@ -105,67 +104,73 @@ elif [ "${NODE_VERSION}" = "latest" ]; then export NODE_VERSION="node" fi +# Install snipppet that we will run as the user +nvm_install_snippet="$(cat << EOF +set -e +umask 0002 +# Do not update profile - we'll do this manually +export PROFILE=/dev/null +curl -so- https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh | bash +source ${NVM_DIR}/nvm.sh +if [ "${NODE_VERSION}" != "" ]; then + nvm alias default ${NODE_VERSION} +fi +EOF +)" + +# Snippet that should be added into rc / profiles +nvm_rc_snippet="$(cat << EOF +export NVM_DIR="${NVM_DIR}" +[ -s "\$NVM_DIR/nvm.sh" ] && . "\$NVM_DIR/nvm.sh" +[ -s "\$NVM_DIR/bash_completion" ] && . "\$NVM_DIR/bash_completion" +EOF +)" + # Create a symlink to the installed version for use in Dockerfile PATH statements export NVM_SYMLINK_CURRENT=true -# Install the specified node version if NVM directory already exists, then exit -if [ -d "${NVM_DIR}" ]; then - echo "NVM already installed." - if [ "${NODE_VERSION}" != "" ]; then - su ${USERNAME} -c ". $NVM_DIR/nvm.sh && nvm install ${NODE_VERSION} && nvm clear-cache" - fi - # Clean up - rm -rf /var/lib/apt/lists/* - exit 0 -fi - -# Create nvm group, nvm dir, and set sticky bit +# Create nvm group to the user's UID or GID to change while still allowing access to nvm if ! cat /etc/group | grep -e "^nvm:" > /dev/null 2>&1; then groupadd -r nvm fi -umask 0002 usermod -a -G nvm ${USERNAME} -mkdir -p ${NVM_DIR} -chown "${USERNAME}:nvm" ${NVM_DIR} -chmod -R g+r+w ${NVM_DIR} -su ${USERNAME} -c "$(cat << EOF - set -e - umask 0002 - # Do not update profile - we'll do this manually - export PROFILE=/dev/null - curl -so- https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh | bash - source ${NVM_DIR}/nvm.sh + +# Install nvm (which also installs NODE_VERSION), otherwise +# use nvm to install the specified node version. Always use +# umask 0002 so both the owner so that everything is u+rw,g+rw +umask 0002 +if [ ! -d "${NVM_DIR}" ]; then + # Create nvm dir, and set sticky bit + mkdir -p ${NVM_DIR} + chown "${USERNAME}:nvm" ${NVM_DIR} + chmod g+rws ${NVM_DIR} + su ${USERNAME} -c "${nvm_install_snippet}" 2>&1 + # Update rc files + if [ "${UPDATE_RC}" = "true" ]; then + updaterc "${nvm_rc_snippet}" + fi +else + echo "NVM already installed." if [ "${NODE_VERSION}" != "" ]; then - nvm alias default ${NODE_VERSION} + su ${USERNAME} -c "umask 0002 && . $NVM_DIR/nvm.sh && nvm install ${NODE_VERSION}" fi - nvm clear-cache -EOF -)" 2>&1 -# Update rc files -if [ "${UPDATE_RC}" = "true" ]; then -updaterc "$(cat <