6cf63cb064
Verification layers: Structural: PASS (all scripts executable, syntax clean, Dockerfile valid) Behavioral: PASS (121 bats, 77 pytest, docker build succeeds, compose valid) Security: PASS (no secrets committed, .dockerignore excludes .env*, env_file pattern) Quality: PASS (coreci patterns followed, no coreci refs, G-104/G-105/G-106 verified) P0 issues found and auto-fixed: 1. docker-compose.yml: removed invalid restart_policy key, fixed env_file syntax 2. pyproject.toml: added fastapi + uvicorn deps (v0.1 gap exposed by Dockerfile) 3. timing.sh: renamed coreci_deploy_timing → praxis_deploy_timing (TASK-03-07) 4. firstboot-hook.sh: fixed idempotency check (/opt/praxis/.git not /usr/local/bin/praxis-deploy) P1+ issues: 8 (1 fixed: lxc-config.sh default alignment, 7 noted for post-hoc review) REQ coverage: 18/20 covered, 2 deferred (live first-boot timing + live E2E require cluster) Must-haves: 25/28 pass, 2 partial (comment-only diffs, no Makefile), 1 deferred ---ci--- project: praxis phase: 1 milestone: v0.2 status: verify ---/ci---
87 lines
3.0 KiB
Bash
Executable File
87 lines
3.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# Praxis — Proxmox LXC first-boot hookscript.
|
|
#
|
|
# Adapted from coreci/scripts/proxmox/firstboot-hook.sh.
|
|
# Coreci fetches a pre-built Go binary + pct-pushes it; praxis installs
|
|
# Docker inside the CT, clones the repo from Gitea, builds the image,
|
|
# and starts the service via systemd (D-022, D-028, D-029).
|
|
#
|
|
# Referenced by lxc-config.sh via hookscript=local:snippets/praxis-firstboot.sh.
|
|
# Proxmox invokes this script at CT lifecycle phases on the PVE HOST
|
|
# (not inside the CT). The `post-start` phase does the work.
|
|
#
|
|
# G-101 FIX: GITEA_TOKEN is baked into this snippet by stage-snippet.sh
|
|
# (the hookscript runs on the PVE host where lxc.environment is invisible).
|
|
# The token is used to clone the private Gitea repo inside the CT.
|
|
#
|
|
# Proxmox passes: $1 = VMID, $2 = phase
|
|
# Environment (baked in by stage-snippet.sh):
|
|
# GITEA_TOKEN — bearer token for the private Gitea repo
|
|
# PRAXIS_VERSION — git ref (default: main)
|
|
# GITEA_HOST — Gitea hostname (default: git.cloudinit.dev)
|
|
|
|
set -eu
|
|
|
|
vmid="${1:-}"
|
|
phase="${2:-}"
|
|
|
|
log() { printf '[praxis-hook %s] %s\n' "$phase" "$*" >&2; }
|
|
|
|
case "$phase" in
|
|
post-start) : ;;
|
|
*) exit 0 ;;
|
|
esac
|
|
|
|
log "VMID=${vmid} — first-boot praxis install (Docker-in-LXC)"
|
|
|
|
VERSION="${PRAXIS_VERSION:-main}"
|
|
GITEA_HOST="${GITEA_HOST:-git.cloudinit.dev}"
|
|
GITEA_ORG="coreci"
|
|
GITEA_REPO="praxis"
|
|
CLONE_URL="https://${GITEA_TOKEN}@${GITEA_HOST}/${GITEA_ORG}/${GITEA_REPO}.git"
|
|
|
|
# Idempotency: skip if praxis is already installed and running.
|
|
# Check for the repo clone + active service (not a binary — praxis uses
|
|
# docker compose, not a /usr/local/bin binary like coreci).
|
|
if pct exec "$vmid" -- sh -c '[ -d /opt/praxis/.git ] && systemctl is-active --quiet praxis' 2>/dev/null; then
|
|
log "praxis already installed and active — skipping"
|
|
exit 0
|
|
fi
|
|
|
|
# Step 1: Install Docker + docker-compose-v2 inside the CT (D-028).
|
|
# Debian 12 standard template + nesting=1 supports Docker.
|
|
log "installing Docker inside CT ${vmid}"
|
|
pct exec "$vmid" -- sh -c '
|
|
set -e
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
apt-get update -qq
|
|
apt-get install -y -qq docker.io docker-compose-v2 git curl
|
|
systemctl enable --now docker
|
|
'
|
|
|
|
# Step 2: Clone the praxis repo inside the CT (D-029).
|
|
# Clone to /opt/praxis (persistent across container restarts).
|
|
log "cloning praxis repo (ref=${VERSION}) into CT"
|
|
pct exec "$vmid" -- sh -c "
|
|
set -e
|
|
mkdir -p /opt/praxis
|
|
cd /opt/praxis
|
|
git clone --depth 1 --branch '${VERSION}' '${CLONE_URL}' . 2>&1 || {
|
|
# If the specific branch doesn't exist, fall back to main
|
|
log 'falling back to main branch'
|
|
git clone --depth 1 '${CLONE_URL}' . 2>&1
|
|
}
|
|
"
|
|
|
|
# Step 3: Write the env file from lxc.environment (passed via the CT's env).
|
|
# The lxc.environment vars are available inside the CT's environment.
|
|
# install-service.sh writes /etc/praxis/server.env from these.
|
|
log "running install-service inside CT"
|
|
pct exec "$vmid" -- sh -c '
|
|
set -e
|
|
cd /opt/praxis
|
|
sh scripts/install-service.sh
|
|
'
|
|
|
|
log "praxis installed and started in CT ${vmid}"
|
|
exit 0 |