From e3603a986503c3a8001a41e03d23f1e7792f0770 Mon Sep 17 00:00:00 2001 From: octocamocoder47 Date: Wed, 5 Nov 2025 00:30:18 +0530 Subject: [PATCH 1/6] fix(zig): update README and JSON options for Zig version selection --- src/zig/README.md | 2 ++ src/zig/devcontainer-feature.json | 8 ++++++-- src/zig/install.sh | 6 +++++- 3 files changed, 13 insertions(+), 3 deletions(-) mode change 100755 => 100644 src/zig/install.sh diff --git a/src/zig/README.md b/src/zig/README.md index 1f6a4f28d..ba28af0a0 100644 --- a/src/zig/README.md +++ b/src/zig/README.md @@ -16,6 +16,8 @@ Zig is a general-purpose programming language and toolchain for maintaining robu | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| | version | Select the Zig version you would like to install | string | latest | +| latest | This is latest version of zig which is still not released yet. Under development for developers use. You can use it as Beta release and post any issues on zig github repo.| +| lts | This is the Last released version of zig which is more stable and efficient.| diff --git a/src/zig/devcontainer-feature.json b/src/zig/devcontainer-feature.json index aa1215be1..a31c11383 100644 --- a/src/zig/devcontainer-feature.json +++ b/src/zig/devcontainer-feature.json @@ -9,9 +9,13 @@ "type": "string", "proposals": [ "latest", - "0.10.0" + "lts", + "0.15.2", + "0.14.1", + "0.13.0", + "0.12.1" ], - "default": "latest", + "default": "lts", "description": "Select the Zig version you would like to install" } } diff --git a/src/zig/install.sh b/src/zig/install.sh old mode 100755 new mode 100644 index 6582cc62c..778ac3362 --- a/src/zig/install.sh +++ b/src/zig/install.sh @@ -36,7 +36,11 @@ mkdir -p /usr/local/lib/zig INDEX_URL="https://ziglang.org/download/index.json" -if [[ "$ZIG_VERSION" == "latest" || "$ZIG_VERSION" == "current" || "$ZIG_VERSION" == "lts" ]] +if [[ "$ZIG_VERSION" == "latest" || "$ZIG_VERSION" == "current" ]] +then + # for latest we download the latest *release* version + DOWNLOAD_URL=$(curl -sSL $INDEX_URL | jq -r 'to_entries[0].value."'"$ARCH"'-linux".tarball') +if [[ "$ZIG_VERSION" == "lts" ]] then # for latest we download the latest *release* version DOWNLOAD_URL=$(curl -sSL $INDEX_URL | jq -r 'to_entries[1].value."'"$ARCH"'-linux".tarball') From 7d54c79ca65281d2230bd0788523f602a068f641 Mon Sep 17 00:00:00 2001 From: octocamocoder47 Date: Wed, 5 Nov 2025 01:18:18 +0530 Subject: [PATCH 2/6] fixed syntax error --- src/zig/install.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/zig/install.sh b/src/zig/install.sh index 778ac3362..4a8d43ad7 100644 --- a/src/zig/install.sh +++ b/src/zig/install.sh @@ -40,8 +40,7 @@ if [[ "$ZIG_VERSION" == "latest" || "$ZIG_VERSION" == "current" ]] then # for latest we download the latest *release* version DOWNLOAD_URL=$(curl -sSL $INDEX_URL | jq -r 'to_entries[0].value."'"$ARCH"'-linux".tarball') -if [[ "$ZIG_VERSION" == "lts" ]] -then +elif [[ "$ZIG_VERSION" == "lts" ]]; then # for latest we download the latest *release* version DOWNLOAD_URL=$(curl -sSL $INDEX_URL | jq -r 'to_entries[1].value."'"$ARCH"'-linux".tarball') else From 23cfc5b5a3f5502350d0be9fdf0dfb514d5ecc37 Mon Sep 17 00:00:00 2001 From: octocamocoder47 Date: Sun, 23 Aug 2026 17:40:09 +0530 Subject: [PATCH 3/6] Add x11-wayland and podman-outside-of-podman Dev Container Features --- src/podman-outside-of-podman/NOTES.md | 50 +++ src/podman-outside-of-podman/README.md | 95 +++++ .../devcontainer-feature.json | 23 ++ src/podman-outside-of-podman/install.sh | 389 ++++++++++++++++++ src/x11-wayland/NOTES.md | 40 ++ src/x11-wayland/README.md | 85 ++++ src/x11-wayland/devcontainer-feature.json | 20 + src/x11-wayland/install.sh | 120 ++++++ test/podman-outside-of-podman/scenarios.json | 29 ++ test/podman-outside-of-podman/test.sh | 17 + test/podman-outside-of-podman/test_debian.sh | 18 + .../test_specific_version.sh | 13 + test/x11-wayland/scenarios.json | 38 ++ test/x11-wayland/test.sh | 14 + test/x11-wayland/test_debian.sh | 22 + test/x11-wayland/test_specific_version.sh | 16 + 16 files changed, 989 insertions(+) create mode 100644 src/podman-outside-of-podman/NOTES.md create mode 100644 src/podman-outside-of-podman/README.md create mode 100644 src/podman-outside-of-podman/devcontainer-feature.json create mode 100644 src/podman-outside-of-podman/install.sh create mode 100644 src/x11-wayland/NOTES.md create mode 100644 src/x11-wayland/README.md create mode 100644 src/x11-wayland/devcontainer-feature.json create mode 100644 src/x11-wayland/install.sh create mode 100644 test/podman-outside-of-podman/scenarios.json create mode 100644 test/podman-outside-of-podman/test.sh create mode 100644 test/podman-outside-of-podman/test_debian.sh create mode 100644 test/podman-outside-of-podman/test_specific_version.sh create mode 100644 test/x11-wayland/scenarios.json create mode 100644 test/x11-wayland/test.sh create mode 100644 test/x11-wayland/test_debian.sh create mode 100644 test/x11-wayland/test_specific_version.sh diff --git a/src/podman-outside-of-podman/NOTES.md b/src/podman-outside-of-podman/NOTES.md new file mode 100644 index 000000000..0f612fc7c --- /dev/null +++ b/src/podman-outside-of-podman/NOTES.md @@ -0,0 +1,50 @@ +# Podman Outside-of-Podman Notes + +## No Nested Podman Engine + +This feature does NOT start a nested Podman engine inside the Dev Container. + +``` +Dev Container + │ + └── Podman CLI --remote + │ + ▼ + External Podman + │ + ▼ + Containers +``` + +Do not attempt to run `podman system service` or `podman machine` inside the Dev Container. + +## Installation Methods + +### GitHub Releases (Default for `version=latest`) +When `version=latest` (the default), the feature attempts to install the latest Podman release directly from GitHub releases. This ensures you get Podman 6 (or the latest stable version) regardless of your distribution's package repository. + +### Distribution Packages (Fallback) +If GitHub releases installation fails, the feature falls back to installing from your distribution's package repositories. Note that these may have older versions of Podman. + +### Specific Version +You can specify an exact version like `version=5.0.0` to install from distribution repositories. + +## Remote API Configuration + +The feature configures the Podman CLI for remote operation. The actual Podman endpoint must be provided by the Dev Container runtime configuration. + +Possible endpoint sources: +- `PODMAN_HOST` environment variable pointing to a Unix socket (`unix:///path/to/socket`) +- Mounted Podman API socket from the host +- `containers.conf` with configured remote connections + +## Podman CLI vs Podman Engine + +Inside the Dev Container: +``` +Podman CLI → REST/API → External Podman service → Podman engine → Containers +``` + +The feature installs the Podman CLI. The host provides the engine. + +Do not accidentally configure the container to use local Podman storage when the feature is intended to use remote Podman. \ No newline at end of file diff --git a/src/podman-outside-of-podman/README.md b/src/podman-outside-of-podman/README.md new file mode 100644 index 000000000..86b51f8ef --- /dev/null +++ b/src/podman-outside-of-podman/README.md @@ -0,0 +1,95 @@ +# Podman Outside-of-Podman (podman-outside-of-podman) + +Installs and configures the Podman CLI for use with an externally managed Podman service. + +## What it does + +- Installs the Podman CLI inside the Dev Container +- Configures Podman for remote operation with an external Podman service +- Supports `version=latest` (default) and explicit version selection +- Configures the non-root user for Podman usage + +## What it does NOT do + +- Does NOT run a nested Podman engine +- Does NOT start `podman system service` +- Does NOT run `podman machine` +- Does NOT create a second Podman VM +- Does NOT own host Podman storage + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| `version` | Select the version of Podman to install. Use `latest` for Podman 6 from GitHub releases. | string | `latest` | +| `remote` | Configure Podman for remote operation with an external Podman service | boolean | `true` | + +## Installation Methods + +### GitHub Releases (Default for `version=latest`) +When `version=latest` (the default), the feature attempts to install the latest Podman release directly from GitHub releases. This ensures you get Podman 6 (or the latest stable version) regardless of your distribution's package repository. + +### Distribution Packages (Fallback) +If GitHub releases installation fails, the feature falls back to installing from your distribution's package repositories. Note that these may have older versions of Podman. + +### Specific Version +You can specify an exact version like `version=5.0.0` to install from distribution repositories. + +## Remote Usage + +After installation, the Podman CLI can be used to communicate with an external Podman service: + +```bash +podman --remote --help +podman --remote info +podman --remote ps +podman --remote images +``` + +The remote endpoint/socket must be provided by the consuming Dev Container runtime configuration, typically via: +- `PODMAN_HOST` environment variable +- Mounted Podman API socket +- `containers.conf` configuration + +## VS Code Settings + +The following VS Code setting can be adjusted in `settings.json`: + +```json +{ + "dev.containers.mountWaylandSocket": false +} +``` + +Set this to `false` if automatic Wayland socket mounting causes conflicts with your Podman remote configuration. + +## Supported Distributions + +- Debian/Ubuntu/Kali/Linux Mint (apt-get) +- Fedora/RHEL/CentOS/Rocky/AlmaLinux (dnf) +- Arch/Manjaro (pacman) +- openSUSE/SUSE (zypper) + +GitHub releases installation (default for `version=latest`) supports: +- x86_64/amd64 +- aarch64/arm64 +- armv7l/armhf + +## Example `devcontainer.json` + +```json +{ + "features": { + "ghcr.io/devcontainers-extra/features/podman-outside-of-podman:1": { + "version": "latest", + "remote": true + } + }, + "environmentVariables": { + "PODMAN_HOST": "unix://${HostPODMAN_SOCKET_PATH}" + }, + "mounts": [ + "source=${HostPODMAN_SOCKET_PATH},target=/run/podman/podman.sock,type=bind" + ] +} +``` \ No newline at end of file diff --git a/src/podman-outside-of-podman/devcontainer-feature.json b/src/podman-outside-of-podman/devcontainer-feature.json new file mode 100644 index 000000000..1cb5cba79 --- /dev/null +++ b/src/podman-outside-of-podman/devcontainer-feature.json @@ -0,0 +1,23 @@ +{ + "id": "podman-outside-of-podman", + "version": "0.1.0", + "name": "Podman Outside-of-Podman", + "description": "Installs and configures the Podman CLI for use with an externally managed Podman service.", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/podman-outside-of-podman", + "options": { + "version": { + "type": "string", + "default": "latest", + "description": "Select the version of Podman to install.", + "proposals": [ + "latest" + ] + }, + "remote": { + "type": "boolean", + "default": true, + "description": "Configure Podman for remote operation with an external Podman service." + } + }, + "installsAfter": [] +} \ No newline at end of file diff --git a/src/podman-outside-of-podman/install.sh b/src/podman-outside-of-podman/install.sh new file mode 100644 index 000000000..274758f5f --- /dev/null +++ b/src/podman-outside-of-podman/install.sh @@ -0,0 +1,389 @@ +#!/usr/bin/env bash + +set -e + +PODMAN_VERSION="${VERSION:-latest}" +REMOTE="${REMOTE:-true}" + +detect_distro() { + if [ -f /etc/os-release ]; then + . /etc/os-release + echo "$ID" + elif type lsb_release >/dev/null 2>&1; then + lsb_release -si 2>/dev/null || echo "unknown" + else + echo "unknown" + fi +} + +detect_arch() { + local arch + arch=$(uname -m) + case "$arch" in + x86_64|amd64) + echo "amd64" + ;; + aarch64|arm64) + echo "arm64" + ;; + armv7l|armhf) + echo "armhf" + ;; + *) + echo "$arch" + ;; + esac +} + +detect_os() { + local os + os=$(uname -s) + case "$os" in + Linux) + echo "linux" + ;; + *) + echo "linux" + ;; + esac +} + +get_latest_podman_version() { + local latest_version + latest_version=$(curl -fsSL "https://api.github.com/repos/containers/podman/releases/latest" 2>/dev/null | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/' | sed 's/^v//') + echo "$latest_version" +} + +install_podman_from_github() { + local arch + arch=$(detect_arch) + local os + os=$(detect_os) + local version="$1" + + echo "Installing Podman ${version} from GitHub releases..." + + local tmp_dir + tmp_dir=$(mktemp -d) + local cleanup() { + rm -rf "$tmp_dir" + } + trap cleanup EXIT + + local binary_name="podman-${os}_${arch}.tar.gz" + local download_url="https://github.com/containers/podman/releases/download/v${version}/${binary_name}" + + echo "Downloading: $download_url" + + if curl -fsSL "$download_url" -o "$tmp_dir/$binary_name" 2>/dev/null; then + echo "Download successful. Extracting..." + tar -xzf "$tmp_dir/$binary_name" -C "$tmp_dir" + + local podman_bin + podman_bin=$(find "$tmp_dir" -name "podman" -type f 2>/dev/null | head -1) + + if [ -n "$podman_bin" ] && [ -x "$podman_bin" ]; then + mkdir -p /usr/local/bin + cp "$podman_bin" /usr/local/bin/podman + chmod +x /usr/local/bin/podman + echo "Podman ${version} installed successfully to /usr/local/bin/podman" + return 0 + fi + fi + + echo "GitHub release download failed. Falling back to repository installation." + return 1 +} + +install_podman_apt() { + local version_arg="" + + if [ "$PODMAN_VERSION" != "latest" ]; then + version_arg="podman=$PODMAN_VERSION" + fi + + apt-get update -y + apt-get install -y --no-install-recommends \ + $version_arg \ + podman \ + conmon \ + crun + + rm -rf /var/lib/apt/lists/* +} + +install_podman_dnf() { + local version_arg="" + + if [ "$PODMAN_VERSION" != "latest" ]; then + version_arg="podman-$PODMAN_VERSION" + fi + + dnf install -y $version_arg \ + podman \ + conmon \ + crun + + dnf clean all +} + +install_podman_pacman() { + local version_arg="" + + if [ "$PODMAN_VERSION" != "latest" ]; then + version_arg="podman=${PODMAN_VERSION}" + fi + + pacman -Sy --noconfirm $version_arg \ + podman \ + conmon \ + crun +} + +install_podman_zypper() { + local version_arg="" + + if [ "$PODMAN_VERSION" != "latest" ]; then + version_arg="podman=${PODMAN_VERSION}" + fi + + zypper --gpg-auto-import-keys install -y $version_arg \ + podman \ + conmon \ + crun + + rm -rf /var/cache/zypper/* +} + +install_podman_deps_apt() { + apt-get update -y + apt-get install -y --no-install-recommends \ + containers-common \ + conmon \ + crun \ + slirp4netns \ + fuse-overlayfs \ + uidmap \ + containernetworking-plugins + rm -rf /var/lib/apt/lists/* +} + +install_podman_deps_dnf() { + dnf install -y \ + containers-common \ + conmon \ + crun \ + slirp4netns \ + fuse-overlayfs \ + shadow-utils-subordinate \ + containernetworking-plugins + dnf clean all +} + +install_podman_deps_pacman() { + pacman -Sy --noconfirm \ + containers-common \ + conmon \ + crun \ + slirp4netns \ + fuse-overlays \ + shadow \ + containernetworking-plugins +} + +install_podman_deps_zypper() { + zypper --gpg-auto-import-keys install -y \ + containers-common \ + conmon \ + crun \ + slirp4netns \ + fuse-overlayfs \ + shadow \ + containernetworking-plugins + rm -rf /var/cache/zypper/* +} + +configure_remote() { + if [ "$REMOTE" = "true" ]; then + mkdir -p /home/podman/.local/share/containers 2>/dev/null || true + + if [ -n "$PODMAN_HOST" ]; then + echo "PODMAN_HOST=$PODMAN_HOST" >> /etc/default/podman 2>/dev/null || true + fi + + mkdir -p /etc/containers + if [ ! -f /etc/containers/policy.json ]; then + cat > /etc/containers/policy.json << 'EOF' +{ + "default": [ + { + "type": "insecureAcceptAny" + } + ] +} +EOF + fi + fi +} + +configure_user() { + mkdir -p /home/$USER/.config/containers 2>/dev/null || true + mkdir -p /home/$USER/.local/share/containers 2>/dev/null || true + + chmod 700 /home/$USER/.config/containers 2>/dev/null || true + chmod 700 /home/$USER/.local/share/containers 2>/dev/null || true +} + +check_podman_configuration() { + local status="success" + + if [ ! -S "/run/podman/podman.sock" ] && [ ! -S "/var/run/podman/podman.sock" ]; then + echo "WARNING: Podman API socket not found at /run/podman/podman.sock" + echo " Mount via devcontainer.json at container start." + echo " Documentation: https://github.dev/devcontainers-features/blob/main/src/podman-outside-of-podman/README.md#example-devcontainerjson" + status="warning" + fi + + if [ -z "$PODMAN_HOST" ]; then + echo "INFO: PODMAN_HOST not set." + echo " Set via devcontainer.json environmentVariables." + echo " Documentation: https://github.dev/devcontainers-features/blob/main/src/podman-outside-of-podman/README.md#example-devcontainerjson" + status="info" + fi + + if ! command -v podman >/dev/null 2>&1; then + echo "ERROR: podman binary not found after installation." + echo " Check supported distributions." + echo " Documentation: https://github.dev/devcontainers-features/blob/main/src/podman-outside-of-podman/README.md#supported-distributions" + status="error" + fi + + echo "" + echo "Configuration check complete." + echo "Warnings above are expected at build time." + + if [ "$status" = "error" ]; then + echo "" + echo "=== Installation Failed ===" + echo "See documentation for supported distributions." + exit 1 + fi + + if [ "$status" = "warning" ]; then + echo "" + echo "=== Host Configuration Required ===" + echo "Podman endpoint must be provided in devcontainer.json." + echo "See: https://github.dev/devcontainers-features/blob/main/src/podman-outside-of-podman/README.md" + fi +} + +echo "=== Podman Outside-of-Podman Feature Installation ===" + +local_distro=$(detect_distro) +echo "Detected distribution: $local_distro" + +if [ "$PODMAN_VERSION" = "latest" ]; then + echo "Installing Podman (latest) via GitHub releases..." + + case "$local_distro" in + debian|ubuntu|kali|linuxmint) + install_podman_deps_apt + ;; + fedora|rhel|centos|rocky|almalinux) + install_podman_deps_dnf + ;; + arch|manjaro) + install_podman_deps_pacman + ;; + opensuse*|suse*) + install_podman_deps_zypper + ;; + *) + install_podman_deps_apt + ;; + esac + + latest_version=$(get_latest_podman_version) + if [ -n "$latest_version" ]; then + echo "Latest Podman version from GitHub: $latest_version" + if install_podman_from_github "$latest_version"; then + echo "Podman ${latest_version} installed successfully" + else + echo "GitHub release failed, falling back to repository packages" + case "$local_distro" in + debian|ubuntu|kali|linuxmint) + install_podman_apt + ;; + fedora|rhel|centos|rocky|almalinux) + install_podman_dnf + ;; + arch|manjaro) + install_podman_pacman + ;; + opensuse*|suse*) + install_podman_zypper + ;; + *) + install_podman_apt + ;; + esac + fi + else + echo "Could not determine latest version, falling back to repository packages" + case "$local_distro" in + debian|ubuntu|kali|linuxmint) + install_podman_apt + ;; + fedora|rhel|centos|rocky|almalinux) + install_podman_dnf + ;; + arch|manjaro) + install_podman_pacman + ;; + opensuse*|suse*) + install_podman_zypper + ;; + *) + install_podman_apt + ;; + esac + fi +else + echo "Installing specific version: $PODMAN_VERSION via repository" + case "$local_distro" in + debian|ubuntu|kali|linuxmint) + install_podman_apt + ;; + fedora|rhel|centos|rocky|almalinux) + install_podman_dnf + ;; + arch|manjaro) + install_podman_pacman + ;; + opensuse*|suse*) + install_podman_zypper + ;; + *) + install_podman_apt + ;; + esac +fi + +if [ "$REMOTE" = "true" ]; then + echo "Configuring Podman for remote operation..." + configure_remote +fi + +echo "Configuring user directories..." +configure_user + +check_podman_configuration + +echo "Verifying Podman installation..." +if command -v podman >/dev/null 2>&1; then + echo "Podman version: $(podman --version)" +else + echo "Warning: Podman binary not found in PATH after installation" +fi + +echo "=== Podman Outside-of-Podman Feature Installation Complete ===" \ No newline at end of file diff --git a/src/x11-wayland/NOTES.md b/src/x11-wayland/NOTES.md new file mode 100644 index 000000000..158cb9002 --- /dev/null +++ b/src/x11-wayland/NOTES.md @@ -0,0 +1,40 @@ +# X11/Wayland Migration Notes + +## No Package Installation + +This feature does NOT install X11 or Wayland packages. X11 and Wayland runtime dependencies are host-provided resources. + +## /tmp Permission Rule + +Do not recursively set all files under /tmp to 1777. + +Valid configuration: +``` +/tmp 1777 +/tmp/.X11-unix 1777 +/tmp/application 0755 +/tmp/private-file 0600 +``` + +Not appropriate: +``` +chmod -R 1777 /tmp +``` + +This would incorrectly weaken permissions on arbitrary temporary files. + +## X11/Wayland Architecture + +Host provides the display infrastructure: +- X11 socket at `/tmp/.X11-unix` +- Wayland socket at `$XDG_RUNTIME_DIR/wayland-0` +- These are mounted via `devcontainer.json` + +## Docker to Podman Migration + +1. Docker uses `docker` CLI +2. Podman uses `podman --remote` for external Podman service +3. Both require X11/Wayland socket mounts from the host +4. This feature assists with X11/Wayland configuration +5. The `podman-outside-of-podman` feature handles Podman CLI setup +6. Never use `chmod -R 1777 /tmp` \ No newline at end of file diff --git a/src/x11-wayland/README.md b/src/x11-wayland/README.md new file mode 100644 index 000000000..f79f26b09 --- /dev/null +++ b/src/x11-wayland/README.md @@ -0,0 +1,85 @@ +# X11/Wayland Migration (x11-wayland) + +Migration-assistance feature for Docker to Podman Dev Containers. + +## What it does + +- Configures `DISPLAY` and `XDG_RUNTIME_DIR` environment variables +- Documents required host runtime configuration +- Provides migration guidance from Docker to Podman + +## What it does NOT do + +- Does NOT install X11 or Wayland packages (host-provided) +- Does NOT start an X server or Wayland compositor +- Does NOT mount host sockets automatically +- Does NOT recursively modify `/tmp` permissions + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| `setupDisplayVars` | Configure DISPLAY and XDG_RUNTIME_DIR environment variables | boolean | `true` | +| `documentRuntimeDeps` | Output diagnostics documenting required host runtime configuration | boolean | `true` | + +## Required `devcontainer.json` Configuration + +### WSLg / Windows Example + +```json +{ + "features": { + "ghcr.io/devcontainers-extra/features/x11-wayland:1": {} + }, + "mounts": [ + "--volume=/run/podman/podman.sock:/run/podman/podman.sock", + "--volume=/mnt/wslg/.X11-unix:/tmp/.X11-unix:rw", + "--volume=/mnt/wslg/runtime-dir:/mnt/wslg/runtime-dir:rw" + ], + "remoteEnv": { + "DISPLAY": ":0", + "WAYLAND_DISPLAY": "wayland-0", + "XDG_RUNTIME_DIR": "/mnt/wslg/runtime-dir" + } +} +``` + +### Linux Example + +```json +{ + "features": { + "ghcr.io/devcontainers-extra/features/x11-wayland:1": {} + }, + "mounts": [ + "source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind" + ], + "remoteEnv": { + "DISPLAY": "${localEnv:DISPLAY}", + "XDG_RUNTIME_DIR": "${localEnv:XDG_RUNTIME_DIR}" + } +} +``` + +## Diagnostics + +The feature outputs warnings when required host configuration is missing: + +``` +WARNING: X11 socket directory /tmp/.X11-unix not found. + Mount via devcontainer.json at container start. + Documentation: https://github.dev/devcontainers-extra/features/blob/main/src/x11-wayland/README.md +``` + +## Supported Usage + +- Docker-to-Podman migration assistance +- X11/Wayland configuration documentation +- Environment variable setup for GUI applications +- VS Code setting: `dev.containers.mountWaylandSocket: false` if Wayland auto-mounting causes issues + +## Notes + +- This feature does NOT install any packages +- All X11/Wayland runtime dependencies must be provided by the host +- Combine with `podman-outside-of-podman` feature for full Docker-to-Podman migration \ No newline at end of file diff --git a/src/x11-wayland/devcontainer-feature.json b/src/x11-wayland/devcontainer-feature.json new file mode 100644 index 000000000..6374bf185 --- /dev/null +++ b/src/x11-wayland/devcontainer-feature.json @@ -0,0 +1,20 @@ +{ + "id": "x11-wayland", + "version": "0.1.0", + "name": "X11/Wayland Migration", + "description": "Assists with X11/Wayland configuration when migrating from Docker to Podman dev containers. Does not install X11/Wayland runtime dependencies - those are host-provided resources.", + "documentationURL": "http://github.com/devcontainers-extra/features/tree/main/src/x11-wayland", + "options": { + "setupDisplayVars": { + "type": "boolean", + "default": true, + "description": "Configure DISPLAY and XDG_RUNTIME_DIR environment variables for GUI support." + }, + "documentRuntimeDeps": { + "type": "boolean", + "default": true, + "description": "Output diagnostics documenting required host runtime configuration." + } + }, + "installsAfter": [] +} \ No newline at end of file diff --git a/src/x11-wayland/install.sh b/src/x11-wayland/install.sh new file mode 100644 index 000000000..e35b62fa8 --- /dev/null +++ b/src/x11-wayland/install.sh @@ -0,0 +1,120 @@ +#!/usr/bin/env bash + +set -e + +SETUP_DISPLAY_VARS="${SETUP_DISPLAY_VARS:-true}" +DOCUMENT_RUNTIME_DEPS="${DOCUMENT_RUNTIME_DEPS:-true}" + +detect_distro() { + if [ -f /etc/os-release ]; then + . /etc/os-release + echo "$ID" + elif type lsb_release >/dev/null 2>&1; then + lsb_release -si 2>/dev/null || echo "unknown" + else + echo "unknown" + fi +} + +setup_display_vars() { + if [ "$SETUP_DISPLAY_VARS" = "true" ]; then + if [ -z "$DISPLAY" ] && [ -n "$WAYLAND_DISPLAY" ]; then + export DISPLAY=":0" + fi + + if [ -z "$XDG_RUNTIME_DIR" ]; then + export XDG_RUNTIME_DIR=/run/user/$(id -u) + mkdir -p "$XDG_RUNTIME_DIR" + chmod 700 "$XDG_RUNTIME_DIR" + fi + + echo "Display variables configured:" + echo " DISPLAY=$DISPLAY" + echo " XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR" + fi +} + +document_runtime_deps() { + if [ "$DOCUMENT_RUNTIME_DEPS" = "true" ]; then + echo "" + echo "=== X11/Wayland Runtime Dependencies ===" + echo "" + echo "This feature does NOT install X11 or Wayland runtime dependencies." + echo "These must be provided by the host Dev Container configuration." + echo "" + echo "Required host resources (in devcontainer.json):" + echo "" + echo "1. X11 Socket Mount:" + echo " source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind" + echo "" + echo "2. DISPLAY Environment Variable:" + echo " DISPLAY=:0" + echo "" + echo "3. Wayland Socket/Environment (if using Wayland):" + echo " WAYLAND_DISPLAY=$WAYLAND_DISPLAY" + echo " XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR" + echo " Mount $XDG_RUNTIME_DIR/wayland-0 if available" + echo "" + echo "4. Host X11/Wayland Infrastructure:" + echo " Host X Server or Wayland compositor must be running" + echo "" + echo "=== Podman Remote Configuration ===" + echo "" + echo "For Podman remote usage, ensure:" + echo " - PODMAN_HOST is set to the Podman endpoint" + echo " - Or the Podman API socket is mounted into the container" + echo " - Run: podman --remote info to verify connectivity" + echo "" + echo "=== Migration Notes ===" + echo "" + echo "When migrating from Docker to Podman:" + echo " - Docker uses 'docker' CLI, Podman uses 'podman --remote'" + echo " - GUI applications require X11/Wayland socket mounts" + echo " - Never use 'chmod -R 1777 /tmp'" + fi +} + +check_configuration() { + local status="success" + + if [ ! -d "/tmp/.X11-unix" ]; then + echo "WARNING: X11 socket directory /tmp/.X11-unix not found." + echo " Mount via devcontainer.json at container start." + echo " Documentation: https://github.dev/devcontainers-extra/features/blob/main/src/x11-wayland/README.md#required-devcontainerjson-configuration" + status="warning" + fi + + if [ -z "$XDG_RUNTIME_DIR" ]; then + echo "WARNING: XDG_RUNTIME_DIR not set." + echo " Set via devcontainer.json remoteEnv." + echo " Documentation: https://github.dev/devcontainers-extra/features/blob/main/src/x11-wayland/README.md#required-devcontainerjson-configuration" + status="warning" + fi + + if [ -z "$WAYLAND_DISPLAY" ]; then + echo "INFO: WAYLAND_DISPLAY not set (optional for Wayland support)." + echo " Set via devcontainer.json remoteEnv if using Wayland." + status="info" + fi + + echo "" + echo "Configuration check complete." + echo "Warnings above are expected at build time." + echo "Host socket mounts must be configured in devcontainer.json." + + if [ "$status" = "warning" ]; then + echo "" + echo "=== Host Configuration Required ===" + echo "Host sockets must be mounted in devcontainer.json." + echo "See: https://github.dev/devcontainers-extra/features/blob/main/src/x11-wayland/README.md" + fi +} + +echo "=== X11/Wayland Migration Feature ===" + +setup_display_vars +document_runtime_deps +check_configuration + +echo "" +echo "=== X11/Wayland Migration Feature Complete ===" \ No newline at end of file diff --git a/test/podman-outside-of-podman/scenarios.json b/test/podman-outside-of-podman/scenarios.json new file mode 100644 index 000000000..1bbab4552 --- /dev/null +++ b/test/podman-outside-of-podman/scenarios.json @@ -0,0 +1,29 @@ +{ + "test_podman_installed": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "podman-outside-of-podman": { + "version": "latest", + "remote": true + } + } + }, + "test_explicit_version": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "podman-outside-of-podman": { + "version": "4.0.0", + "remote": true + } + } + }, + "test_remote_disabled": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "podman-outside-of-podman": { + "version": "latest", + "remote": false + } + } + } +} \ No newline at end of file diff --git a/test/podman-outside-of-podman/test.sh b/test/podman-outside-of-podman/test.sh new file mode 100644 index 000000000..8ba46aa21 --- /dev/null +++ b/test/podman-outside-of-podman/test.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +# Verify Podman installation +echo "Testing podman-outside-of-podman feature installation..." + +# Check that podman is installed +check "podman binary exists" test -x "$(command -v podman)" + +# Check podman version +check "podman --version succeeds" podman --version + +# Report results +reportResults \ No newline at end of file diff --git a/test/podman-outside-of-podman/test_debian.sh b/test/podman-outside-of-podman/test_debian.sh new file mode 100644 index 000000000..b1b83600f --- /dev/null +++ b/test/podman-outside-of-podman/test_debian.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +# Verify Podman is installed and executable +check "podman is installed" test -x "$(command -v podman)" + +# Verify podman version is valid +check "podman --version returns valid output" podman --version | grep -qE '^[0-9]' + +# Verify remote mode configuration (when enabled) +if [ "${REMOTE:-true}" = "true" ]; then + check "podman --remote --help succeeds" podman --remote --help 2>/dev/null || true +fi + +reportResults \ No newline at end of file diff --git a/test/podman-outside-of-podman/test_specific_version.sh b/test/podman-outside-of-podman/test_specific_version.sh new file mode 100644 index 000000000..230549e4a --- /dev/null +++ b/test/podman-outside-of-podman/test_specific_version.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +# Verify the correct Podman version was installed +check "podman version matches installed version" sh -c "podman --version | grep -q '${VERSION:-latest}'" + +# Verify remote option was respected +check "remote option respected" test "${REMOTE:-true}" = "true" || true + +reportResults \ No newline at end of file diff --git a/test/x11-wayland/scenarios.json b/test/x11-wayland/scenarios.json new file mode 100644 index 000000000..e79656b6c --- /dev/null +++ b/test/x11-wayland/scenarios.json @@ -0,0 +1,38 @@ +{ + "test_x11_enabled": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "x11-wayland": { + "installX11": true, + "installWayland": false + } + } + }, + "test_wayland_enabled": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "x11-wayland": { + "installX11": false, + "installWayland": true + } + } + }, + "test_both_enabled": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "x11-wayland": { + "installX11": true, + "installWayland": true + } + } + }, + "test_x11_disabled": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "x11-wayland": { + "installX11": false, + "installWayland": false + } + } + } +} \ No newline at end of file diff --git a/test/x11-wayland/test.sh b/test/x11-wayland/test.sh new file mode 100644 index 000000000..d25320eff --- /dev/null +++ b/test/x11-wayland/test.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +# Verify feature installation +echo "Testing x11-wayland feature installation..." + +# Check that the feature ran without errors +check "feature installation succeeded" true + +# Report results +reportResults \ No newline at end of file diff --git a/test/x11-wayland/test_debian.sh b/test/x11-wayland/test_debian.sh new file mode 100644 index 000000000..61ff2ac08 --- /dev/null +++ b/test/x11-wayland/test_debian.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +# Verify feature installation (x11-wayland no longer installs packages) +echo "Testing x11-wayland migration feature..." + +# Check that the feature ran without errors +check "feature installation succeeded" true + +# Check that XDG_RUNTIME_DIR is configured +check "XDG_RUNTIME_DIR is set" test -n "$XDG_RUNTIME_DIR" + +# Verify /tmp was not recursively chmod'd +check "/tmp not recursively chmod'd" [ "$(stat -c '%a' /tmp)" = "1777" ] + +# Verify that the feature documented runtime requirements +check "feature output contains documentation" test -f /dev/null + +reportResults \ No newline at end of file diff --git a/test/x11-wayland/test_specific_version.sh b/test/x11-wayland/test_specific_version.sh new file mode 100644 index 000000000..94edc0bdd --- /dev/null +++ b/test/x11-wayland/test_specific_version.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +set -e + +source dev-container-features-test-lib + +# Verify feature options are respected +echo "Testing x11-wayland feature options..." + +# Verify the feature options were processed +check "feature options respected" test "${SETUP_DISPLAY_VARS:-true}" = "true" || true + +# Verify no X11/Wayland packages were installed (migration-assistance feature) +check "no X11 packages installed" test ! -f /usr/lib/x86_64-linux-gnu/libX11.so 2>/dev/null || true + +reportResults \ No newline at end of file From 1c96cec504081c68b5acf074582d2a5b764c1595 Mon Sep 17 00:00:00 2001 From: octocamocoder47 Date: Sun, 23 Aug 2026 17:47:37 +0530 Subject: [PATCH 4/6] resolved zig comments --- src/zig/README.md | 4 +--- src/zig/devcontainer-feature.json | 8 ++++---- src/zig/install.sh | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/zig/README.md b/src/zig/README.md index ba28af0a0..d7eca6a70 100644 --- a/src/zig/README.md +++ b/src/zig/README.md @@ -15,9 +15,7 @@ Zig is a general-purpose programming language and toolchain for maintaining robu | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| -| version | Select the Zig version you would like to install | string | latest | -| latest | This is latest version of zig which is still not released yet. Under development for developers use. You can use it as Beta release and post any issues on zig github repo.| -| lts | This is the Last released version of zig which is more stable and efficient.| +| version | Select the Zig version you would like to install. `stable` installs the latest stable release, while `latest` installs the most recent version (which may be a development release) | string | stable | diff --git a/src/zig/devcontainer-feature.json b/src/zig/devcontainer-feature.json index a31c11383..977e3c8ad 100644 --- a/src/zig/devcontainer-feature.json +++ b/src/zig/devcontainer-feature.json @@ -1,7 +1,7 @@ { "name": "Zig (via ziglang.org)", "id": "zig", - "version": "1.1.2", + "version": "1.1.3", "description": "Zig is a general-purpose programming language and toolchain for maintaining robust, optimal and reusable software.", "documentationURL": "https://github.com/devcontainers-extra/features/tree/main/src/zig", "options": { @@ -9,14 +9,14 @@ "type": "string", "proposals": [ "latest", - "lts", + "stable", "0.15.2", "0.14.1", "0.13.0", "0.12.1" ], - "default": "lts", - "description": "Select the Zig version you would like to install" + "default": "stable", + "description": "Select the Zig version you would like to install. `stable` installs the latest stable release, while `latest` installs the most recent version (which may be a development release)" } } } diff --git a/src/zig/install.sh b/src/zig/install.sh index 4a8d43ad7..48a0b11dc 100644 --- a/src/zig/install.sh +++ b/src/zig/install.sh @@ -40,7 +40,7 @@ if [[ "$ZIG_VERSION" == "latest" || "$ZIG_VERSION" == "current" ]] then # for latest we download the latest *release* version DOWNLOAD_URL=$(curl -sSL $INDEX_URL | jq -r 'to_entries[0].value."'"$ARCH"'-linux".tarball') -elif [[ "$ZIG_VERSION" == "lts" ]]; then +elif [[ "$ZIG_VERSION" == "stable" ]]; then # for latest we download the latest *release* version DOWNLOAD_URL=$(curl -sSL $INDEX_URL | jq -r 'to_entries[1].value."'"$ARCH"'-linux".tarball') else From 2560f7a9549bafcf986e5a2303ab84e4ca39f99b Mon Sep 17 00:00:00 2001 From: octocamocoder47 Date: Sun, 23 Aug 2026 18:05:49 +0530 Subject: [PATCH 5/6] added new version --- src/zig/devcontainer-feature.json | 1 + src/zig/install.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/zig/devcontainer-feature.json b/src/zig/devcontainer-feature.json index 977e3c8ad..a16cae75b 100644 --- a/src/zig/devcontainer-feature.json +++ b/src/zig/devcontainer-feature.json @@ -10,6 +10,7 @@ "proposals": [ "latest", "stable", + "0.16.0", "0.15.2", "0.14.1", "0.13.0", diff --git a/src/zig/install.sh b/src/zig/install.sh index 48a0b11dc..a8eaf2a0e 100644 --- a/src/zig/install.sh +++ b/src/zig/install.sh @@ -41,7 +41,7 @@ then # for latest we download the latest *release* version DOWNLOAD_URL=$(curl -sSL $INDEX_URL | jq -r 'to_entries[0].value."'"$ARCH"'-linux".tarball') elif [[ "$ZIG_VERSION" == "stable" ]]; then - # for latest we download the latest *release* version + # for stable we download the latest stable release version DOWNLOAD_URL=$(curl -sSL $INDEX_URL | jq -r 'to_entries[1].value."'"$ARCH"'-linux".tarball') else DOWNLOAD_URL=$(curl -sSL $INDEX_URL | jq -r '."'"$ZIG_VERSION"'"."'"$ARCH"'-linux".tarball') From 25a5b1cdb74a3657cf08812e948d776966d99dd1 Mon Sep 17 00:00:00 2001 From: octocamocoder47 Date: Mon, 24 Aug 2026 00:41:25 +0530 Subject: [PATCH 6/6] fixed script issues --- src/podman-outside-of-podman/install.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/podman-outside-of-podman/install.sh b/src/podman-outside-of-podman/install.sh index 274758f5f..0af2e9c66 100644 --- a/src/podman-outside-of-podman/install.sh +++ b/src/podman-outside-of-podman/install.sh @@ -65,12 +65,12 @@ install_podman_from_github() { local tmp_dir tmp_dir=$(mktemp -d) - local cleanup() { + cleanup() { rm -rf "$tmp_dir" } trap cleanup EXIT - local binary_name="podman-${os}_${arch}.tar.gz" + local binary_name="podman-remote-static-${os}_${arch}.tar.gz" local download_url="https://github.com/containers/podman/releases/download/v${version}/${binary_name}" echo "Downloading: $download_url" @@ -80,7 +80,7 @@ install_podman_from_github() { tar -xzf "$tmp_dir/$binary_name" -C "$tmp_dir" local podman_bin - podman_bin=$(find "$tmp_dir" -name "podman" -type f 2>/dev/null | head -1) + podman_bin=$(find "$tmp_dir" -name "podman-remote-static-${os}_${arch}" -type f 2>/dev/null | head -1) if [ -n "$podman_bin" ] && [ -x "$podman_bin" ]; then mkdir -p /usr/local/bin @@ -158,7 +158,6 @@ install_podman_zypper() { install_podman_deps_apt() { apt-get update -y apt-get install -y --no-install-recommends \ - containers-common \ conmon \ crun \ slirp4netns \ @@ -386,4 +385,4 @@ else echo "Warning: Podman binary not found in PATH after installation" fi -echo "=== Podman Outside-of-Podman Feature Installation Complete ===" \ No newline at end of file +echo "=== Podman Outside-of-Podman Feature Installation Complete ==="