From 5c9c4b2f192299cf880924c91080ad74a2ceb720 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:46:42 +0000 Subject: [PATCH 1/3] Initial plan From 3a8443b690635edc1185f458bd494fc6d85e4ff7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:54:14 +0000 Subject: [PATCH 2/3] Add sshd feature Co-authored-by: sebst <592313+sebst@users.noreply.github.com> --- .github/workflows/test.yaml | 2 + src/sshd/README.md | 30 ++++++++++++++ src/sshd/devcontainer-feature.json | 19 +++++++++ src/sshd/install.sh | 63 ++++++++++++++++++++++++++++++ test/sshd/test.sh | 22 +++++++++++ 5 files changed, 136 insertions(+) create mode 100644 src/sshd/README.md create mode 100644 src/sshd/devcontainer-feature.json create mode 100644 src/sshd/install.sh create mode 100644 test/sshd/test.sh diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9c73ad0..9070303 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -52,6 +52,7 @@ jobs: - smallstep.com - starship.rs - swc.rs + - sshd - tailscale.com - webinstall.dev - yq @@ -114,6 +115,7 @@ jobs: - smallstep.com - starship.rs - swc.rs + - sshd - tailscale.com - webinstall.dev - yq diff --git a/src/sshd/README.md b/src/sshd/README.md new file mode 100644 index 0000000..d42866e --- /dev/null +++ b/src/sshd/README.md @@ -0,0 +1,30 @@ +# sshd (sshd) + +Install OpenSSH server (sshd) and ensure it starts when the container starts + +## Example Usage + +```json +"features": { + "ghcr.io/devcontainer-community/devcontainer-features/sshd:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| port | Port for sshd to listen on. | string | 2222 | + +## Notes + +The `openssh-server` package is installed via `apt` and sshd is configured to +listen on the specified port (default `2222`). An entrypoint script is added +that starts the sshd daemon automatically each time the container starts. + +To connect from the host you may need to forward the port in your +`devcontainer.json`: + +```json +"forwardPorts": [2222] +``` diff --git a/src/sshd/devcontainer-feature.json b/src/sshd/devcontainer-feature.json new file mode 100644 index 0000000..105b2fe --- /dev/null +++ b/src/sshd/devcontainer-feature.json @@ -0,0 +1,19 @@ +{ + "name": "sshd", + "id": "sshd", + "version": "1.0.0", + "description": "Install OpenSSH server (sshd) and ensure it starts when the container starts", + "documentationURL": "https://github.com/devcontainer-community/devcontainer-features/tree/main/src/sshd", + "options": { + "port": { + "type": "string", + "default": "2222", + "proposals": [ + "2222", + "22" + ], + "description": "Port for sshd to listen on." + } + }, + "entrypoint": "/usr/local/share/sshd/entrypoint.sh" +} diff --git a/src/sshd/install.sh b/src/sshd/install.sh new file mode 100644 index 0000000..9c0a7ed --- /dev/null +++ b/src/sshd/install.sh @@ -0,0 +1,63 @@ +#!/bin/bash +set -o errexit +set -o pipefail +set -o noclobber +set -o nounset +set -o allexport + +readonly name="sshd" + +apt_get_update() { + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update -y + fi +} + +apt_get_checkinstall() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + apt_get_update + DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends --no-install-suggests --option 'Debug::pkgProblemResolver=true' --option 'Debug::pkgAcquire::Worker=1' "$@" + fi +} + +apt_get_cleanup() { + apt-get clean + rm -rf /var/lib/apt/lists/* +} + +echo_banner() { + local text="$1" + echo -e "\e[1m\e[97m\e[41m$text\e[0m" +} + +install() { + apt_get_checkinstall openssh-server + + # Create SSH drop-in config directory if missing and add devcontainer config + mkdir -p /etc/ssh/sshd_config.d + echo "Port ${PORT}" > /etc/ssh/sshd_config.d/devcontainer.conf + + # Generate SSH host keys at install time so they are baked into the image + ssh-keygen -A + + # Create entrypoint directory and script + mkdir -p /usr/local/share/sshd + cat > /usr/local/share/sshd/entrypoint.sh << 'EOF' +#!/bin/bash +# Regenerate host keys if any are missing (e.g. first start of a new container) +ssh-keygen -A 2>/dev/null || true +# Start sshd in daemon mode if it is not already running +if ! pgrep sshd > /dev/null 2>&1; then + /usr/sbin/sshd +fi +EOF + chmod 755 /usr/local/share/sshd/entrypoint.sh + + apt_get_cleanup +} + +echo_banner "devcontainer.community" +echo "Installing $name..." +install "$@" +echo "(*) Done!" diff --git a/test/sshd/test.sh b/test/sshd/test.sh new file mode 100644 index 0000000..460b76a --- /dev/null +++ b/test/sshd/test.sh @@ -0,0 +1,22 @@ +#!/bin/bash + + +set -e + +# Optional: Import test library bundled with the devcontainer CLI +# See https://github.com/devcontainers/cli/blob/HEAD/docs/features/test.md#dev-container-features-test-lib +# Provides the 'check' and 'reportResults' commands. +source dev-container-features-test-lib + +# Feature-specific tests +# The 'check' command comes from the dev-container-features-test-lib. Syntax is... +# check