From 452a603cdf4c709e0556bed3a9e58b63e803f6f4 Mon Sep 17 00:00:00 2001 From: Karamelmar Date: Mon, 9 Mar 2026 12:05:08 +0100 Subject: [PATCH] Add auto-install for missing prerequisites - New lib/prereqs.sh: detects distro (Arch, Debian/Ubuntu, RHEL/Fedora, openSUSE) and installs git + podman/docker if missing - Podman preferred over docker; user chooses if neither present - Docker install also enables systemd service and adds user to docker group - README updated: prereqs table now shows auto-install support Co-Authored-By: Claude Sonnet 4.6 --- README.md | 14 +++-- lib/prereqs.sh | 144 +++++++++++++++++++++++++++++++++++++++++++++++++ wizard.sh | 16 +----- 3 files changed, 154 insertions(+), 20 deletions(-) create mode 100644 lib/prereqs.sh diff --git a/README.md b/README.md index 1357fcf..c89f5ff 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,16 @@ Open in devcontainer โ†’ start Context Studio โ†’ talk to your agent team. ## ๐Ÿ“‹ Prerequisites -| | Tool | Purpose | +| | Tool | Notes | |---|------|---------| -| ๐Ÿ”€ | `git` | Clone repos | -| ๐Ÿณ | `docker` or `podman` | Run devcontainer | -| ๐Ÿ”‘ | SSH key โ†’ `github.com` | Access context-studio-core | -| ๐Ÿ—๏ธ | `ANTHROPIC_API_KEY` | Claude agents | +| ๐Ÿ”€ | `git` | Auto-installed if missing | +| ๐Ÿณ | `podman` _(preferred)_ or `docker` | Auto-installed if missing | +| ๐Ÿ”‘ | SSH key โ†’ `github.com` | Must be set up manually | +| ๐Ÿ—๏ธ | `ANTHROPIC_API_KEY` | Must be set in your environment | + +**Auto-install supported on:** Arch ยท Debian/Ubuntu ยท RHEL/Fedora ยท openSUSE + +> The wizard detects your distro and installs `git` and `podman`/`docker` automatically if they are missing. SSH key and API key must be set up by you. --- diff --git a/lib/prereqs.sh b/lib/prereqs.sh new file mode 100644 index 0000000..3e5840b --- /dev/null +++ b/lib/prereqs.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env bash +# prereqs.sh โ€” detect distro, install missing prerequisites + +# Detect package manager / distro family +detect_distro() { + if command -v pacman &>/dev/null; then echo "arch"; + elif command -v apt-get &>/dev/null; then echo "debian"; + elif command -v dnf &>/dev/null; then echo "rhel"; + elif command -v yum &>/dev/null; then echo "rhel-yum"; + elif command -v zypper &>/dev/null; then echo "suse"; + else echo "unknown"; + fi +} + +install_pkg() { + local pkg="$1" + local distro + distro="$(detect_distro)" + + info "Installing $pkg (distro: $distro)..." + case "$distro" in + arch) + sudo pacman -Sy --noconfirm "$pkg" ;; + debian) + sudo apt-get update -qq && sudo apt-get install -y "$pkg" ;; + rhel) + sudo dnf install -y "$pkg" ;; + rhel-yum) + sudo yum install -y "$pkg" ;; + suse) + sudo zypper install -y "$pkg" ;; + *) + die "Unsupported distro โ€” please install $pkg manually." ;; + esac +} + +ensure_git() { + if command -v git &>/dev/null; then + success "git: $(git --version)" + return + fi + warn "git not found." + ask_yn _install "Install git now?" "y" + [[ "$_install" != "y" ]] && die "git is required." + install_pkg git + command -v git &>/dev/null || die "git installation failed." + success "git installed: $(git --version)" +} + +ensure_container_runtime() { + # Already available? + if command -v podman &>/dev/null; then + CONTAINER_CMD="podman" + success "podman: $(podman --version)" + return + fi + if command -v docker &>/dev/null; then + CONTAINER_CMD="docker" + success "docker: $(docker --version | head -1)" + return + fi + + warn "No container runtime found (podman or docker)." + echo "" + echo -e " ${CYAN}podman${RESET} is preferred (rootless, no daemon)" + echo -e " ${CYAN}docker${RESET} is the alternative" + echo "" + ask_choice _runtime "Which would you like to install?" \ + "podman (recommended)" \ + "docker" + + case "$_runtime" in + podman*) + _install_podman + CONTAINER_CMD="podman" + ;; + docker*) + _install_docker + CONTAINER_CMD="docker" + ;; + esac + + command -v "$CONTAINER_CMD" &>/dev/null \ + || die "$CONTAINER_CMD installation failed. Please install manually." + success "$CONTAINER_CMD installed: $($CONTAINER_CMD --version | head -1)" +} + +_install_podman() { + local distro + distro="$(detect_distro)" + case "$distro" in + arch) install_pkg podman ;; + debian) install_pkg podman ;; + rhel) install_pkg podman ;; + rhel-yum) install_pkg podman ;; + suse) install_pkg podman ;; + *) die "Unsupported distro โ€” install podman manually: https://podman.io/getting-started/installation" ;; + esac +} + +_install_docker() { + local distro + distro="$(detect_distro)" + case "$distro" in + arch) + install_pkg docker + sudo systemctl enable --now docker + sudo usermod -aG docker "$USER" + warn "Added $USER to docker group โ€” log out and back in for it to take effect." + ;; + debian) + install_pkg docker.io + sudo systemctl enable --now docker + sudo usermod -aG docker "$USER" + warn "Added $USER to docker group โ€” log out and back in for it to take effect." + ;; + rhel) + install_pkg docker + sudo systemctl enable --now docker + sudo usermod -aG docker "$USER" + warn "Added $USER to docker group โ€” log out and back in for it to take effect." + ;; + rhel-yum) + install_pkg docker + sudo systemctl enable --now docker + sudo usermod -aG docker "$USER" + warn "Added $USER to docker group โ€” log out and back in for it to take effect." + ;; + suse) + install_pkg docker + sudo systemctl enable --now docker + sudo usermod -aG docker "$USER" + warn "Added $USER to docker group โ€” log out and back in for it to take effect." + ;; + *) + die "Unsupported distro โ€” install docker manually: https://docs.docker.com/engine/install/" ;; + esac +} + +check_prerequisites() { + header "Checking Prerequisites" + ensure_git + ensure_container_runtime +} diff --git a/wizard.sh b/wizard.sh index bd9b221..458efac 100755 --- a/wizard.sh +++ b/wizard.sh @@ -7,25 +7,11 @@ set -euo pipefail WIZARD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$WIZARD_DIR/lib/utils.sh" +source "$WIZARD_DIR/lib/prereqs.sh" source "$WIZARD_DIR/lib/core.sh" source "$WIZARD_DIR/lib/project.sh" source "$WIZARD_DIR/lib/workflow.sh" -# โ”€โ”€ Prerequisites โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ -check_prerequisites() { - header "Checking Prerequisites" - require_cmd git - if command -v docker &>/dev/null; then - CONTAINER_CMD="docker" - elif command -v podman &>/dev/null; then - CONTAINER_CMD="podman" - else - die "Neither docker nor podman found. Install one to use devcontainers." - fi - success "git: $(git --version)" - success "$CONTAINER_CMD: $($CONTAINER_CMD --version | head -1)" -} - # โ”€โ”€ Project info โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ collect_project_info() { header "Project Details"