Implement install stages S0–S2: bootstrap, env, model and vision smoke.
Operator can run make bootstrap/install through S2 using nemohermes/openshell wrappers; docs and implement queue updated. No S3+ and no push.
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bash
|
||||
# scripts/lib/common.sh — shared helpers for all host scripts
|
||||
# Sourced by bootstrap.sh, install.sh, and stage scripts.
|
||||
# Do not execute directly.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ── Colours (auto-disable when not a tty) ──────────────────────────────────
|
||||
if [[ -t 2 ]]; then
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
||||
BOLD='\033[1m'; NC='\033[0m'
|
||||
else
|
||||
RED=''; GREEN=''; YELLOW=''; BOLD=''; NC=''
|
||||
fi
|
||||
|
||||
# ── Logging ────────────────────────────────────────────────────────────────
|
||||
# Use printf to avoid echo -e interpreting escape sequences in arguments.
|
||||
log_info() { printf "${GREEN}[INFO]${NC} %s\n" "$*"; }
|
||||
log_warn() { printf "${YELLOW}[WARN]${NC} %s\n" "$*" >&2; }
|
||||
log_error() { printf "${RED}[ERROR]${NC} %s\n" "$*" >&2; }
|
||||
log_section() { printf "\n${BOLD}═══ %s ═══${NC}\n" "$*"; }
|
||||
|
||||
# ── Repo root (works from any subdirectory) ────────────────────────────────
|
||||
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || echo "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)")"
|
||||
|
||||
# ── Env loading ────────────────────────────────────────────────────────────
|
||||
# NOTE: Sources .env directly as shell code. This is a known pattern with a
|
||||
# theoretical injection surface if .env contains shell commands. In practice,
|
||||
# .env is created from .env.example (controlled by this repo) and edited by
|
||||
# the operator. Defense-in-depth: parse line-by-line instead of sourcing,
|
||||
# but the current approach matches the broader ecosystem convention.
|
||||
load_env() {
|
||||
local env_file="${1:-${REPO_ROOT}/.env}"
|
||||
if [[ -f "$env_file" ]]; then
|
||||
# shellcheck disable=SC1091
|
||||
set -a; source "$env_file"; set +a
|
||||
log_info "Loaded env from $env_file"
|
||||
else
|
||||
log_warn ".env not found at $env_file — variables must be set externally"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── CLI detection ──────────────────────────────────────────────────────────
|
||||
cmd_exists() { command -v "$1" &>/dev/null; }
|
||||
|
||||
require_cmd() {
|
||||
if ! cmd_exists "$1"; then
|
||||
log_error "Required command not found: $1"
|
||||
if [[ "${2:-}" ]]; then
|
||||
log_error "$2"
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Sandbox name ───────────────────────────────────────────────────────────
|
||||
get_sandbox_name() {
|
||||
echo "${LUMINA_SANDBOX:-hermes}"
|
||||
}
|
||||
|
||||
# ── Docker check ───────────────────────────────────────────────────────────
|
||||
docker_available() {
|
||||
cmd_exists docker && docker info &>/dev/null
|
||||
}
|
||||
|
||||
# ── nemohermes check ───────────────────────────────────────────────────────
|
||||
nemohermes_available() {
|
||||
cmd_exists nemohermes
|
||||
}
|
||||
|
||||
# ── openshell check ────────────────────────────────────────────────────────
|
||||
openshell_available() {
|
||||
cmd_exists openshell
|
||||
}
|
||||
|
||||
# ── Guard: script must be run as operator (not root-only, but warn) ────────
|
||||
warn_if_root() {
|
||||
if [[ "$(id -u)" -eq 0 ]]; then
|
||||
log_warn "Running as root. Some host scripts work better as a regular user with sudo access."
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user