my-homelab-configs/jeannie

512 lines
18 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUILDX_CONFIG="/tmp/buildx-config.toml"
HOMELAB_STATE_DIR="${HOMELAB_STATE_DIR:-${XDG_DATA_HOME:-${HOME}/.local/share}/homelab}"
COSIGN_KEY_PREFIX="${COSIGN_KEY_PREFIX:-${HOMELAB_STATE_DIR}/cosign/cosign}"
COSIGN_KEY_PATH="${COSIGN_KEY_PATH:-${COSIGN_KEY_PREFIX}.key}"
COSIGN_PUBLIC_KEY_PATH="${COSIGN_PUBLIC_KEY_PATH:-${COSIGN_KEY_PREFIX}.pub}"
COSIGN_PASSWORD_FILE="${COSIGN_PASSWORD_FILE:-${HOMELAB_STATE_DIR}/cosign/cosign.password}"
COSIGN_VERSION="${COSIGN_VERSION:-2.6.3}"
COSIGN_BIN="${COSIGN_BIN:-}"
HOMELAB_COSIGN_PUBLIC_KEY_CONFIGMAP="${HOMELAB_COSIGN_PUBLIC_KEY_CONFIGMAP:-homelab-cosign-public-key}"
HOMELAB_SBOM_PREDICATE_TYPE="${HOMELAB_SBOM_PREDICATE_TYPE:-https://spdx.dev/Document}"
JEANNIE_LOG_DIR="${JEANNIE_LOG_DIR:-${HOMELAB_STATE_DIR}/logs}"
JEANNIE_LOG_FILE="${JEANNIE_LOG_FILE:-}"
JEANNIE_ERROR_LOG_FILE="${JEANNIE_ERROR_LOG_FILE:-}"
JEANNIE_STEP_INDEX=0
JEANNIE_STEP_TOTAL=0
# shellcheck disable=SC1091
source "${REPO_ROOT}/scripts/report-ui"
source "${REPO_ROOT}/lib/jeannie/core.sh"
source "${REPO_ROOT}/lib/jeannie/env.sh"
source "${REPO_ROOT}/lib/jeannie/toolchain.sh"
source "${REPO_ROOT}/lib/jeannie/pimox.sh"
source "${REPO_ROOT}/lib/jeannie/preflight.sh"
source "${REPO_ROOT}/lib/jeannie/pipeline.sh"
source "${REPO_ROOT}/lib/jeannie/security.sh"
# shellcheck disable=SC1091
source "${REPO_ROOT}/lib/jeannie/commands.sh"
trap 'rm -f "${BUILDX_CONFIG}"' EXIT
load_homelab_inventory_defaults
export_homelab_inventory_tf_vars
KUBECONFIG_PATH="${KUBECONFIG_PATH:-${TF_VAR_kubeconfig_path:-${LAB_KUBECONFIG_PATH:-/home/jv/.kube/config}}}"
print_usage() {
cat <<'EOF'
Usage: ./jeannie <command> [args]
Base, Inventory, And Planning
help | -h | --help Show this grouped help.
validate Run repo validation checks.
inventory-check Validate the canonical homelab inventory.
preflight Run non-mutating infrastructure preflight checks.
doctor-preapply Run deeper pre-apply safety checks.
plan [all|provisioning|cluster|platform|apps|edge]
Run OpenTofu plans without applying changes.
Build And Bootstrap
up Deploy the full homelab pipeline.
deploy-gitea Deploy the Debian-hosted Gitea container.
deploy-heimdall Deploy the Debian-hosted Heimdall dashboard.
deploy-matrix Deploy the Matrix homeserver (Synapse + Element + Postgres).
deploy-omniroute Deploy the OmniRoute LLM routing gateway.
deploy-hermes Deploy the Hermes agent (git-install + venv + gateway service).
bootstrap-gitea-repo Ensure the Gitea repo and SSH key wiring exist.
rpi-services Deploy Pi-hole, Unbound, and Uptime Kuma on RPi4.
ollama-setup Install/configure Ollama on the Debian host.
artifact-cache {status|up|down|instructions}
Manage optional Debian artifact caches.
blockchain-devnet {status|up|down|logs|rpc}
Manage the local Ethereum Anvil devnet.
blockchain-test [forge args...] Run Foundry tests for labs/blockchain.
blockchain-wallet {instructions|new|address|sign-message}
Practice dev wallet and signing workflows.
golden-ledger {show|check} Show or validate Pimox golden image versions.
Cluster Lifecycle
rebuild-cluster Recreate the cluster through the guarded path.
stop-cluster Stop Kubernetes and worker VMs without destroy.
start-cluster Start Kubernetes and desired worker VMs.
workers <list|tailnet|start|stop|restart|drain|uncordon|recreate-plan|rebalance>
Manage Pimox/Kubernetes workers.
move-prometheus-stack-workers Move monitoring workloads to worker nodes.
doctor-versions [--all|--details|--verbose|--json]
Check Kubernetes/container tooling versions.
Operator View And Reports
status [--all|--details|--verbose|--json] Problems-first cascade from host to public URLs.
status --heal-plan Build a guarded self-heal plan from status.
status --heal Dry-run auto-eligible self-heal actions.
scorecard Compact pass/warn/fail operator scorecard.
capacity Compact capacity and placement report.
capacity-advisor Decide whether to add VMs or fix placement/resources.
capacity-limits [namespace] Recommend requests/limits YAML snippets.
recover-plan Print disaster recovery order and prerequisites.
recover-power [--dry-run] Run or preview post-outage recovery.
heal {plan|apply} Plan/apply guarded self-healing actions.
incident {list|replay|triage} Classify incident text and suggest read-only next steps.
safety-case [--since REF] [PATH...] Generate risk, blast-radius, test, and rollback case.
agent-sandbox {check|policy} Classify proposed commands against agent policy.
impact [--since REF] [PATH...] Explain affected lab areas before changes.
review-last-change [REF] Summarize changed files, impact, validation.
map [--dot] Print the homelab dependency map.
change-journal {list|path} Show risky-command journal entries.
release-snapshot Write a pre-change release snapshot.
Observability And GitOps
grafana-dashboards {list|apply} List or apply repo-managed Grafana dashboards.
gitops-status Print focused Argo CD health and sync status.
platform Deploy platform stack only.
edge Deploy/check the OCI edge stack only.
promote {plan|validate|rollback APP} Run canary promotion gates and rollback plan.
cert-check Check public DNS, TLS, and edge URL health.
backup-status Check backup and restore-drill freshness.
synthetic-checks Run end-to-end service probes.
resource-budget Report Kubernetes resource request/limit gaps.
route-inventory Report routes and Uptime Kuma coverage.
control-plane {status|taint|untaint|pods}
Keep normal pods off the Debian control plane.
explain <command>|output Explain warnings/errors and fix commands.
Recovery And State
backup-gitea Back up the Debian-hosted Gitea data.
drill-restore Run all restore drills.
drill-gitea-restore Run the Gitea restore drill.
drill-pihole-restore Run the Pi-hole restore drill.
state-backup Back up local OpenTofu state files.
Focused Doctors
doctor-edge [--all|--details|--verbose|--json]
Diagnose edge routing and public exposure.
doctor-gitea [--all|--details|--verbose|--json]
Diagnose Gitea local/public access.
doctor-rpi [--all|--details|--verbose|--json]
Diagnose RPi services and DNS.
doctor-cluster [--all|--details|--verbose|--json]
Diagnose Kubernetes cluster health.
Access, Secrets, And Policy
access-audit Audit SSH, Gitea, Kubernetes, and Tailscale access.
kubeconfig-readonly Create/check read-only kubeconfig material.
secrets-init Initialize SOPS/age secret tooling.
secrets-check Validate repo-managed secret prerequisites.
tailnet-policy-check Validate Tailscale ACL policy as code.
fix-debian-docker-root Repair Debian Docker root placement.
Apps And Services
apps Deploy application stack only.
website-translation-model Prepare website translation model support.
website-ollama-listen Configure website Ollama access.
install-gitea-runner [TOKEN] Install the Gitea Actions runner.
openwrt Deploy/check OpenWrt lab config.
Security Learning
security-scan Run the security scan bundle.
security-prepare Prepare defensive security tools.
security-zap Run OWASP ZAP checks.
security-k8s Run Kubernetes security checks.
security-host Run host security checks.
security-trivy Run Trivy scans.
security-secrets Run secret leak checks.
security-nuclei Run Nuclei web checks.
security-web Run web security checks.
security-logs Review security-relevant logs.
security-runtime Check runtime security sensors.
security-attack-path Print prioritized attack-path findings.
prompt-injection-lab {list|run|show} Run local prompt-injection defense drills.
red-blue {plan|run|ledger} Run or plan safe red-team/blue-team loop.
AI And Indexing
ai-index Build the local homelab RAG index.
ai-check Query/check the local AI index.
ask [--citations] QUESTION... Find relevant docs/runbooks/commands.
ai-evals {list|run|show} Run deterministic Jeannie/RAG eval cases.
ai-scheduler {simulate|recommend NAME} Simulate AI workload placement policy.
ai-memory {check} Check local RAG index provenance freshness.
model-observe {prompts|run|report} Track model behavior over stable prompts.
Destructive
nuke Guarded cluster state destruction path.
EOF
}
if [[ "${JEANNIE_LIBRARY_MODE:-false}" == "true" ]]; then
# shellcheck disable=SC2317
return 0 2>/dev/null || exit 0
fi
case "${1:-}" in
__up-task)
up_task "${2:-}"
;;
"" | help | -h | --help)
print_usage
;;
up)
record_change_journal "up" "$@"
up
;;
plan)
plan_homelab "${2:-all}"
;;
rebuild-cluster)
record_change_journal "rebuild-cluster" "$@"
rebuild_cluster
;;
stop-cluster)
record_change_journal "stop-cluster" "$@"
stop_cluster
;;
start-cluster)
record_change_journal "start-cluster" "$@"
start_cluster
;;
status)
status_report "${@:2}"
;;
capacity)
capacity_report "$@"
;;
capacity-advisor)
capacity_advisor "$@"
;;
capacity-limits)
capacity_limits "$@"
;;
recover-plan)
recover_plan
;;
gitops-status)
gitops_status
;;
platform)
record_change_journal "platform" "$@"
require_debian_server "platform"
jeannie_log_start "platform"
jeannie_step_plan 1
run_step "Platform OpenTofu apply" platform_apply
echo "Log: ${JEANNIE_LOG_FILE}"
;;
edge)
record_change_journal "edge" "$@"
require_debian_server "edge"
jeannie_log_start "edge"
jeannie_step_plan 1
run_step "Edge OpenTofu apply" edge_apply
echo "Log: ${JEANNIE_LOG_FILE}"
;;
promote)
promote "$@"
;;
cert-check)
cert_check
;;
release-snapshot)
record_change_journal "release-snapshot" "$@"
release_snapshot
;;
backup-status)
backup_status
;;
synthetic-checks)
synthetic_checks
;;
resource-budget)
resource_budget "$@"
;;
control-plane)
control_plane "$@"
;;
artifact-cache)
artifact_cache "$@"
;;
blockchain-devnet)
blockchain_devnet "$@"
;;
blockchain-test)
blockchain_test "$@"
;;
blockchain-wallet)
blockchain_wallet "$@"
;;
golden-ledger)
golden_ledger "$@"
;;
route-inventory)
route_inventory
;;
explain)
explain "$@"
;;
recover-power)
recover_power "$@"
;;
heal)
heal "$@"
;;
incident)
incident_commander "$@"
;;
safety-case)
safety_case "$@"
;;
agent-sandbox)
agent_sandbox "$@"
;;
scorecard)
scorecard
;;
grafana-dashboards)
grafana_dashboards "$@"
;;
workers)
workers_manage "$@"
;;
change-journal)
change_journal "$@"
;;
map)
homelab_map "$@"
;;
validate)
validate_homelab
;;
access-audit)
access_audit
;;
kubeconfig-readonly)
kubeconfig_readonly
;;
apps)
record_change_journal "apps" "$@"
require_debian_server "apps"
jeannie_log_start "apps"
jeannie_step_plan 1
run_step "Applications" apps
echo "Log: ${JEANNIE_LOG_FILE}"
;;
website-translation-model)
website_translation_model
;;
website-ollama-listen)
website_ollama_listen
;;
ollama-setup)
ollama_setup
;;
deploy-gitea)
record_change_journal "deploy-gitea" "$@"
deploy_gitea
;;
deploy-heimdall)
record_change_journal "deploy-heimdall" "$@"
deploy_heimdall
;;
deploy-matrix)
record_change_journal "deploy-matrix" "$@"
deploy_matrix
;;
deploy-omniroute)
record_change_journal "deploy-omniroute" "$@"
deploy_omniroute
;;
deploy-hermes)
record_change_journal "deploy-hermes" "$@"
deploy_hermes
;;
rpi-services)
record_change_journal "rpi-services" "$@"
deploy_rpi_services
;;
bootstrap-gitea-repo)
bootstrap_gitea_repo
;;
backup-gitea)
backup_gitea
;;
drill-restore)
drill_restore
;;
drill-gitea-restore)
drill_gitea_restore
;;
drill-pihole-restore)
drill_pihole_restore
;;
install-gitea-runner)
install_gitea_runner "${2:-}"
;;
move-prometheus-stack-workers)
move_prometheus_stack_workers
;;
doctor-versions)
doctor_versions "${@:2}"
;;
doctor-edge)
doctor_edge "${@:2}"
;;
doctor-gitea)
doctor_gitea "${@:2}"
;;
doctor-rpi)
doctor_rpi "${@:2}"
;;
doctor-cluster)
doctor_cluster "${@:2}"
;;
preflight)
homelab_preflight "full"
;;
doctor-preapply)
doctor_preapply
;;
inventory-check)
inventory_check
;;
state-backup)
backup_tofu_state
;;
fix-debian-docker-root)
fix_debian_docker_root
;;
secrets-init)
secrets_init
;;
secrets-check)
secrets_check
;;
tailnet-policy-check)
tailnet_policy_check
;;
ai-index)
ai_index
;;
ai-check)
ai_check
;;
ask)
ask_homelab "$@"
;;
ai-evals)
ai_evals "$@"
;;
ai-scheduler)
ai_scheduler "$@"
;;
ai-memory)
ai_memory "$@"
;;
model-observe)
model_observe "$@"
;;
impact)
impact "$@"
;;
review-last-change)
review_last_change "$@"
;;
security-scan)
security_scan
;;
security-prepare)
security_prepare
;;
security-zap)
security_zap
;;
security-k8s)
security_k8s
;;
security-host)
security_host
;;
security-trivy)
security_trivy
;;
security-secrets)
security_secrets
;;
security-nuclei)
security_nuclei
;;
security-web)
security_web
;;
security-logs)
security_logs
;;
security-runtime)
security_runtime
;;
security-attack-path)
security_attack_path "$@"
;;
prompt-injection-lab)
prompt_injection_lab "$@"
;;
red-blue)
red_blue_loop "$@"
;;
openwrt)
openwrt
;;
nuke)
record_change_journal "nuke" "$@"
require_debian_server "nuke"
jeannie_log_start "nuke"
jeannie_step_plan 1
run_step "Nuke homelab cluster state" nuke
echo "Log: ${JEANNIE_LOG_FILE}"
;;
*)
printf 'Unknown command: %s\n\n' "$1" >&2
print_usage >&2
exit 1
;;
esac