#!/usr/bin/env bash # ============================================================================= # kamos-build.sh # # Build the KAMOS Gaming OS image directly on this Mac, push to Forgejo, # and sign it. Replaces the broken Forgejo CI workflow. # # Usage: # chmod +x kamos-build.sh # ./kamos-build.sh # # What it does: # 1. Checks Podman + cosign are installed (offers to install if not) # 2. Starts the Podman virtual machine (Linux env on macOS) # 3. Builds linux/amd64 image (uses QEMU emulation on Apple Silicon - slow # first time, ~30-60 min; faster afterwards because layers cache) # 4. Logs into your Forgejo registry # 5. Pushes the image # 6. Signs it with cosign # ============================================================================= set -euo pipefail # ---- config ---------------------------------------------------------------- REGISTRY="cgi.medsys.cloud" NAMESPACE="mkm1971" IMAGE_NAME="kamos" IMAGE_REF="${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}" TAGS=("stable" "latest" "$(date +%Y%m%d)") GREEN="\033[0;32m" YELLOW="\033[1;33m" RED="\033[0;31m" NC="\033[0m" log() { echo -e "${GREEN}==>${NC} $*"; } warn() { echo -e "${YELLOW}!! ${NC} $*"; } err() { echo -e "${RED}!! ${NC} $*" >&2; } # ---- preflight ------------------------------------------------------------- log "Pre-flight checks" if ! command -v brew >/dev/null 2>&1; then err "Homebrew is not installed. Install it first from https://brew.sh" exit 1 fi for tool in podman cosign; do if ! command -v "$tool" >/dev/null 2>&1; then warn "$tool not found. Installing via brew..." brew install "$tool" fi done # ---- podman machine -------------------------------------------------------- log "Ensure podman machine is running" if ! podman machine list --format '{{.Name}} {{.Running}}' | grep -q "true"; then if ! podman machine list --format '{{.Name}}' | grep -q .; then log "No podman machine yet - creating one (8 GB RAM, 80 GB disk)" podman machine init --cpus 6 --memory 8192 --disk-size 80 fi log "Starting podman machine" podman machine start fi # ---- build ---------------------------------------------------------------- log "Build linux/amd64 image (this is the slow step on Apple Silicon)" build_args=() for t in "${TAGS[@]}"; do build_args+=(--tag "${IMAGE_REF}:${t}") done podman build \ --platform=linux/amd64 \ --pull=newer \ "${build_args[@]}" \ . log "Build complete" podman images | grep "${IMAGE_NAME}" || true # ---- login ---------------------------------------------------------------- log "Login to Forgejo registry at ${REGISTRY}" warn "When prompted: username = ${NAMESPACE}, password = your REGISTRY_TOKEN" podman login "${REGISTRY}" --username "${NAMESPACE}" # ---- push ----------------------------------------------------------------- log "Push image with all tags" for t in "${TAGS[@]}"; do log " pushing ${IMAGE_REF}:${t}" podman push "${IMAGE_REF}:${t}" done # ---- sign (optional, best-effort) ----------------------------------------- # Cosign on macOS sometimes can't find podman's auth credentials (they're at # ~/.config/containers/auth.json instead of ~/.docker/config.json). We point # it at podman's auth file and don't fail the script if signing breaks - the # image is already pushed, signing is just a verification add-on. if [ -f cosign.key ] && [ "${SKIP_SIGN:-0}" != "1" ]; then log "Sign image with cosign (best-effort)" # Tell cosign where podman stored credentials. PODMAN_AUTH="${HOME}/.config/containers/auth.json" if [ -f "${PODMAN_AUTH}" ]; then export DOCKER_CONFIG="${HOME}/.config/containers" fi for t in "${TAGS[@]}"; do digest=$(skopeo inspect \ --authfile "${PODMAN_AUTH}" \ --format '{{.Digest}}' \ "docker://${IMAGE_REF}:${t}" 2>/dev/null || true) if [ -n "$digest" ]; then log " signing ${IMAGE_REF}@${digest}" COSIGN_PASSWORD="" cosign sign --yes \ --key cosign.key \ "${IMAGE_REF}@${digest}" \ || warn "Sign failed for tag ${t} (image still pushed and usable)" else warn "Could not get digest for tag ${t} - skipping sign" fi done else warn "Skipping image signing (set SKIP_SIGN=0 with cosign.key present to enable)" fi # ---- done ----------------------------------------------------------------- echo log "All done." echo echo " Image: ${IMAGE_REF}" echo " Tags: ${TAGS[*]}" echo echo " Switch your NVIDIA PC to it with:" echo echo " sudo bootc switch ${IMAGE_REF}:stable" echo " sudo systemctl reboot" echo