From 885432d1b1719dab1be99a20af3a1964f0ba5db0 Mon Sep 17 00:00:00 2001 From: AnExiledDev Date: Thu, 26 Feb 2026 16:40:21 +0000 Subject: [PATCH] Add container runtime pre-flight check Validates Docker or Podman is installed and running before attempting to build the devcontainer. Aborts with OS-specific remediation guidance (Windows/WSL, macOS, Linux) instead of a cryptic Docker client error. --- .devcontainer/CHANGELOG.md | 3 + .devcontainer/devcontainer.json | 2 + .devcontainer/scripts/preflight.sh | 113 +++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100755 .devcontainer/scripts/preflight.sh diff --git a/.devcontainer/CHANGELOG.md b/.devcontainer/CHANGELOG.md index 7702d01..f70cf68 100644 --- a/.devcontainer/CHANGELOG.md +++ b/.devcontainer/CHANGELOG.md @@ -14,6 +14,9 @@ ### Added +#### Startup +- **Container runtime pre-flight check** — validates Docker or Podman is installed and running before attempting to build the devcontainer; aborts with OS-specific remediation guidance (Windows/WSL, macOS, Linux) instead of a cryptic Docker client error + #### README - **"Why CodeForge?" section** — motivation and value proposition explaining the project's origins as a power user's personal setup - **Architecture overview** — three-layer diagram (DevContainer → CodeForge Layer → Claude Code) with brief descriptions and link to full architecture docs diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b658bb4..b4705b0 100755 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,6 +5,8 @@ "workspaceFolder": "/workspaces", "workspaceMount": "source=${localWorkspaceFolder},target=/workspaces,type=bind", + "initializeCommand": "bash .devcontainer/scripts/preflight.sh", + "mounts": [ { "source": "codeforge-claude-config-${devcontainerId}", diff --git a/.devcontainer/scripts/preflight.sh b/.devcontainer/scripts/preflight.sh new file mode 100755 index 0000000..d75224e --- /dev/null +++ b/.devcontainer/scripts/preflight.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-3.0-only +# Copyright (c) 2026 Marcus Krueger +# Pre-flight check: validates a container runtime is available on the host. +# Runs via initializeCommand BEFORE any container build/pull/start. + +set -euo pipefail + +# --- OS detection --- + +detect_os() { + if [[ -f /proc/version ]] && grep -qi 'microsoft\|wsl' /proc/version 2>/dev/null; then + echo "wsl" + elif [[ "$(uname -s)" == "Darwin" ]]; then + echo "macos" + else + echo "linux" + fi +} + +# --- Timeout wrapper (macOS lacks coreutils timeout) --- + +run_with_timeout() { + local seconds="$1" + shift + if command -v timeout &>/dev/null; then + timeout "$seconds" "$@" &>/dev/null 2>&1 + else + # Fallback for macOS: background + kill + "$@" &>/dev/null 2>&1 & + local pid=$! + (sleep "$seconds" && kill "$pid" 2>/dev/null) & + local watchdog=$! + if wait "$pid" 2>/dev/null; then + kill "$watchdog" 2>/dev/null + wait "$watchdog" 2>/dev/null + return 0 + else + kill "$watchdog" 2>/dev/null + wait "$watchdog" 2>/dev/null + return 1 + fi + fi +} + +# --- Runtime detection --- + +check_runtime() { + local runtime="$1" + if ! command -v "$runtime" &>/dev/null; then + return 1 + fi + if run_with_timeout 5 "$runtime" info; then + return 0 + fi + return 1 +} + +# --- Main --- + +for runtime in docker podman; do + if check_runtime "$runtime"; then + exit 0 + fi +done + +# No working runtime found — determine why and advise + +found_binary="" +for runtime in docker podman; do + if command -v "$runtime" &>/dev/null; then + found_binary="$runtime" + break + fi +done + +HOST_OS="$(detect_os)" + +echo "" +echo "╔══════════════════════════════════════════════════════════════╗" +echo "║ CodeForge: Container runtime not available ║" +echo "╚══════════════════════════════════════════════════════════════╝" +echo "" + +if [[ -n "$found_binary" ]]; then + echo " Found '$found_binary' but the daemon is not responding." + echo "" + case "$HOST_OS" in + wsl) + echo " Fix: Start Docker Desktop and enable WSL 2 integration:" + echo " Settings → Resources → WSL Integration" + ;; + macos) + echo " Fix: Start Docker Desktop:" + echo " open -a Docker" + ;; + linux) + echo " Fix: Start the Docker daemon:" + echo " sudo systemctl start docker" + ;; + esac +else + echo " No container runtime (docker or podman) found in PATH." + echo "" + echo " Install Docker Desktop:" + echo " https://www.docker.com/products/docker-desktop/" + echo "" + echo " Or install Podman:" + echo " https://podman.io/getting-started/installation" +fi + +echo "" +exit 1