From e02c2b8e4a5d796e5a5bc1fac86cd49a44c92e78 Mon Sep 17 00:00:00 2001 From: eternasuno <22316214+eternasuno@users.noreply.github.com> Date: Tue, 3 Dec 2024 09:04:19 +0000 Subject: [PATCH 1/2] [feat] Add webi feature --- src/webi-packages/README.md | 18 +++++ src/webi-packages/devcontainer-feature.json | 17 +++++ src/webi-packages/install.sh | 17 +++++ src/webi-packages/utils.sh | 79 +++++++++++++++++++++ test/webi-packages/scenarios.json | 18 +++++ test/webi-packages/test.sh | 11 +++ test/webi-packages/test_alpine.sh | 11 +++ 7 files changed, 171 insertions(+) create mode 100644 src/webi-packages/README.md create mode 100644 src/webi-packages/devcontainer-feature.json create mode 100755 src/webi-packages/install.sh create mode 100644 src/webi-packages/utils.sh create mode 100644 test/webi-packages/scenarios.json create mode 100755 test/webi-packages/test.sh create mode 100755 test/webi-packages/test_alpine.sh diff --git a/src/webi-packages/README.md b/src/webi-packages/README.md new file mode 100644 index 000000000..085d41a23 --- /dev/null +++ b/src/webi-packages/README.md @@ -0,0 +1,18 @@ + +# webi packages (webi-packages) + +Install webi and use it to install specified packages + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainers-extra/features/webi-packages:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| packages | List of packages to install, comma-separated (e.g., 'node@lts', 'deno'). | string | - | diff --git a/src/webi-packages/devcontainer-feature.json b/src/webi-packages/devcontainer-feature.json new file mode 100644 index 000000000..135b3d954 --- /dev/null +++ b/src/webi-packages/devcontainer-feature.json @@ -0,0 +1,17 @@ +{ + "id": "webi-packages", + "version": "1.0.0", + "name": "webi packages", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/webi-packages", + "description": "Install webi and use it to install specified packages", + "options": { + "packages": { + "type": "string", + "description": "List of packages to install, comma-separated (e.g., 'node@lts', 'deno')", + "default": "" + } + }, + "installsAfter": [ + "ghcr.io/devcontainers/features/common-utils" + ] +} \ No newline at end of file diff --git a/src/webi-packages/install.sh b/src/webi-packages/install.sh new file mode 100755 index 000000000..a82fa2479 --- /dev/null +++ b/src/webi-packages/install.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +PACKAGES="${PACKAGES:-""}" + +if [ "$(id -u)" -ne 0 ]; then + echo "Script must be run as root. Use sudo, su, or add \"USER root\" to your Dockerfile before running this script." + exit 1 +fi + +. ./utils.sh + +install_webi "$(determine_user "$USERNAME")" "$PACKAGES" + +clean diff --git a/src/webi-packages/utils.sh b/src/webi-packages/utils.sh new file mode 100644 index 000000000..ba07f4efb --- /dev/null +++ b/src/webi-packages/utils.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +install_webi() { + local USERNAME="$1" + local PACKAGES="$2" + + check_command curl + + su - "${USERNAME}" </dev/null; then + echo "Installing webinstall.dev for user ${USERNAME}..." + curl -sS https://webi.sh/webi | sh + source ~/.config/envman/PATH.env + echo "Webinstall.dev installation completed for user ${USERNAME}" + fi + + if [ -n "$PACKAGES" ]; then + echo "Installing specified packages: ${PACKAGES}" + webi $(echo "$PACKAGES" | tr ',' ' ') + fi +EOF +} + +determine_user() { + local USERNAME="${1:-"auto"}" + if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then + USERNAME="" + check_command awk >/dev/null 2>&1 + POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") + for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do + if id -u "${CURRENT_USER}" >/dev/null 2>&1; then + USERNAME=${CURRENT_USER} + break + fi + done + if [ "${USERNAME}" = "" ]; then + USERNAME=root + fi + elif [ "${USERNAME}" = "none" ] || ! id -u "${USERNAME}" >/dev/null 2>&1; then + USERNAME=root + fi + + echo "${USERNAME}" +} + +check_command() { + local cmd=$1 + + if command -v "$cmd" &>/dev/null; then + echo "$cmd is already installed" + return 0 + fi + + echo "$cmd not found, attempting to install..." + + if command -v apt &>/dev/null; then + echo "Installing using apt..." + apt update + apt -y install --no-install-recommends "$cmd" + return $? + fi + + if command -v apk &>/dev/null; then + echo "Installing using apk..." + apk update + apk add --no-cache "$cmd" + return $? + fi + + echo "Error: No supported package manager found (apt/apk)" + return 1 +} + +clean() { + if command -v apt &>/dev/null; then + apt clean + rm -rf /var/lib/apt/lists/* + fi +} diff --git a/test/webi-packages/scenarios.json b/test/webi-packages/scenarios.json new file mode 100644 index 000000000..0db483f8f --- /dev/null +++ b/test/webi-packages/scenarios.json @@ -0,0 +1,18 @@ +{ + "test": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "webi-packages": { + "packages": "node@18,deno" + } + } + }, + "test_alpine": { + "image": "mcr.microsoft.com/devcontainers/base:alpine", + "features": { + "webi-packages": { + "packages": "node@18" + } + } + } +} \ No newline at end of file diff --git a/test/webi-packages/test.sh b/test/webi-packages/test.sh new file mode 100755 index 000000000..e3f1dd062 --- /dev/null +++ b/test/webi-packages/test.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +check "node version is equal to 18.*.*" sh -c "node --version | grep '18.*.*'" + +check "deno --version" deno --version + +reportResults diff --git a/test/webi-packages/test_alpine.sh b/test/webi-packages/test_alpine.sh new file mode 100755 index 000000000..28665a051 --- /dev/null +++ b/test/webi-packages/test_alpine.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +source ~/.config/envman/PATH.env + +check "node version is equal to 18.*.*" sh -c "node --version | grep '18.*.*'" + +reportResults From 8df05d8a03a634d7a0ba366e482f8b2b6f8810f5 Mon Sep 17 00:00:00 2001 From: eternasuno <22316214+eternasuno@users.noreply.github.com> Date: Mon, 9 Dec 2024 00:59:10 +0000 Subject: [PATCH 2/2] [fix] review problem --- src/webi-packages/install.sh | 2 +- src/webi-packages/utils.sh | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/webi-packages/install.sh b/src/webi-packages/install.sh index a82fa2479..f7f8873c5 100755 --- a/src/webi-packages/install.sh +++ b/src/webi-packages/install.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/src/webi-packages/utils.sh b/src/webi-packages/utils.sh index ba07f4efb..e5ac74c41 100644 --- a/src/webi-packages/utils.sh +++ b/src/webi-packages/utils.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash install_webi() { local USERNAME="$1" @@ -26,7 +26,8 @@ determine_user() { if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then USERNAME="" check_command awk >/dev/null 2>&1 - POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") + USERNAME_UID_1000="$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)" + POSSIBLE_USERS=("vscode" "node" "codespace" "${USERNAME_UID_1000}") for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do if id -u "${CURRENT_USER}" >/dev/null 2>&1; then USERNAME=${CURRENT_USER}