main
  1#!/usr/bin/env nix-shell
  2#! nix-shell -i bash -p jq
  3# shellcheck shell=bash
  4
  5# DetectRuntime.sh - Detect Docker or Podman runtime and return information
  6# Usage: DetectRuntime.sh [--runtime docker|podman] [--json]
  7
  8set -euo pipefail
  9
 10show_usage() {
 11    cat <<EOF
 12Usage: DetectRuntime.sh [OPTIONS]
 13
 14Detect container runtime (Docker or Podman) and return information.
 15
 16OPTIONS:
 17    --runtime RUNTIME    Force specific runtime (docker|podman)
 18    --json              Output in JSON format
 19    -h, --help          Show this help message
 20
 21EXAMPLES:
 22    DetectRuntime.sh                    # Auto-detect available runtime
 23    DetectRuntime.sh --runtime docker   # Force Docker runtime
 24    DetectRuntime.sh --json             # Output as JSON
 25EOF
 26}
 27
 28detect_runtime() {
 29    local force_runtime=""
 30    local output_json=false
 31
 32    # Parse arguments
 33    while [[ $# -gt 0 ]]; do
 34        case $1 in
 35            --runtime)
 36                force_runtime="$2"
 37                shift 2
 38                ;;
 39            --json)
 40                output_json=true
 41                shift
 42                ;;
 43            -h|--help)
 44                show_usage
 45                exit 0
 46                ;;
 47            *)
 48                echo "ERROR: Unknown option: $1" >&2
 49                show_usage >&2
 50                exit 1
 51                ;;
 52        esac
 53    done
 54
 55    local runtime=""
 56    local compose=""
 57    local version=""
 58    local rootless="false"
 59    local socket=""
 60
 61    # If specific runtime requested, check only that one
 62    if [[ -n "$force_runtime" ]]; then
 63        case "$force_runtime" in
 64            podman)
 65                if ! command -v podman &>/dev/null; then
 66                    echo "ERROR: Podman requested but not found in PATH" >&2
 67                    exit 1
 68                fi
 69                runtime="podman"
 70                ;;
 71            docker)
 72                if ! command -v docker &>/dev/null; then
 73                    echo "ERROR: Docker requested but not found in PATH" >&2
 74                    exit 1
 75                fi
 76                runtime="docker"
 77                ;;
 78            *)
 79                echo "ERROR: Invalid runtime '$force_runtime'. Must be 'docker' or 'podman'" >&2
 80                exit 1
 81                ;;
 82        esac
 83    fi
 84
 85    # Auto-detect if no runtime forced
 86    if [[ -z "$runtime" ]]; then
 87        # Check for Podman first (preference for rootless)
 88        if command -v podman &>/dev/null; then
 89            runtime="podman"
 90        # Fall back to Docker
 91        elif command -v docker &>/dev/null; then
 92            runtime="docker"
 93        else
 94            echo "ERROR: Neither Docker nor Podman found in PATH" >&2
 95            exit 1
 96        fi
 97    fi
 98
 99    # Get runtime-specific information
100    case "$runtime" in
101        podman)
102            version=$(podman --version | awk '{print $3}')
103
104            # Check if running rootless
105            if podman info --format '{{.Host.Security.Rootless}}' 2>/dev/null | grep -q "true"; then
106                rootless="true"
107                socket="unix://$XDG_RUNTIME_DIR/podman/podman.sock"
108            else
109                rootless="false"
110                socket="unix:///run/podman/podman.sock"
111            fi
112
113            # Check for podman-compose
114            if command -v podman-compose &>/dev/null; then
115                compose="podman-compose"
116            elif command -v docker-compose &>/dev/null; then
117                compose="docker-compose"
118            else
119                compose="none"
120            fi
121            ;;
122        docker)
123            version=$(docker --version | awk '{print $3}' | tr -d ',')
124            rootless="false"
125            socket="unix:///var/run/docker.sock"
126
127            # Check for docker-compose
128            if docker compose version &>/dev/null 2>&1; then
129                compose="docker-compose-plugin"
130            elif command -v docker-compose &>/dev/null; then
131                compose="docker-compose"
132            else
133                compose="none"
134            fi
135            ;;
136    esac
137
138    # Output format
139    if [[ "$output_json" == true ]]; then
140        jq -n \
141            --arg runtime "$runtime" \
142            --arg version "$version" \
143            --arg compose "$compose" \
144            --arg rootless "$rootless" \
145            --arg socket "$socket" \
146            '{
147                runtime: $runtime,
148                version: $version,
149                compose: $compose,
150                rootless: ($rootless == "true"),
151                socket: $socket
152            }'
153    else
154        echo "Runtime: $runtime"
155        echo "Version: $version"
156        echo "Compose: $compose"
157        echo "Rootless: $rootless"
158        echo "Socket: $socket"
159    fi
160}
161
162detect_runtime "$@"