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..0af2e9c66 --- /dev/null +++ b/src/podman-outside-of-podman/install.sh @@ -0,0 +1,388 @@ +#!/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) + cleanup() { + rm -rf "$tmp_dir" + } + trap cleanup EXIT + + 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" + + 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-remote-static-${os}_${arch}" -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 \ + 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 ===" 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/src/zig/README.md b/src/zig/README.md index 1f6a4f28d..d7eca6a70 100644 --- a/src/zig/README.md +++ b/src/zig/README.md @@ -15,7 +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 | +| 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 aa1215be1..a16cae75b 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,10 +9,15 @@ "type": "string", "proposals": [ "latest", - "0.10.0" + "stable", + "0.16.0", + "0.15.2", + "0.14.1", + "0.13.0", + "0.12.1" ], - "default": "latest", - "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 old mode 100755 new mode 100644 index 6582cc62c..a8eaf2a0e --- a/src/zig/install.sh +++ b/src/zig/install.sh @@ -36,9 +36,12 @@ 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') +elif [[ "$ZIG_VERSION" == "stable" ]]; then + # 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') 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