f2a12f9fed
v0.4 (Operator Tier — Cohort Dashboard + Auth + Postgres) milestone complete. Phases: ✓ P0 pre-execution (planning) → v0.1.6 ✓ P1 operator foundation (Postgres+auth+VC migration) → v0.1.7 ✓ P2 cohort dashboard + aggregation → v0.1.8 ✓ P3 final review + ship → v0.1.9 (= v0.4 milestone release) Requirements covered (8/8): REQ-MT-01 (Postgres store), REQ-MT-02 (aggregation pipeline), REQ-AUTH-01 (operator auth), REQ-DASH-01 (cohort dashboard), REQ-NFR-AUTH-01 (auth NFRs), REQ-NFR-MT-01 (Postgres-in-LXC), REQ-NFR-DASH-01 (k-anonymity ≥10), REQ-NFR-DASH-02 (freshness ≤24h) Grill MUSTs honored (6/6): G-008, G-011, G-027, G-031, G-038, G-041 Tests: 317 pytest pass, 36 skip (Postgres-requiring), 0 fail; 17/17 vitest pass Review: APPROVE_WITH_NOTES (6/6 personas, 0 P0, 8 P1+ carry-forward) Audit: HEALTHY (reconstruction PASS, 8/8 REQ, 6/6 grill) ---ci--- project: praxis phase: 3 milestone: v0.4 status: complete phase_role: final milestone_complete: true milestone_merged_to_main: true tag: v0.1.9 requirements: covered: [REQ-MT-01, REQ-MT-02, REQ-AUTH-01, REQ-DASH-01, REQ-NFR-AUTH-01, REQ-NFR-MT-01, REQ-NFR-DASH-01, REQ-NFR-DASH-02] partial: [] ---/ci---
60 lines
2.0 KiB
Bash
Executable File
60 lines
2.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# Praxis — Create a Proxmox LXC container from a template via REST API.
|
|
#
|
|
# Uses the POST /nodes/{node}/lxc endpoint with ostemplate=<volid>
|
|
# (create-from-template) instead of the storage clone endpoint. The
|
|
# clone endpoint rejects API tokens (`user != root@pam` guard), but
|
|
# the create endpoint accepts them — so this path works end-to-end
|
|
# with a PVEAPIToken. Pure REST, no SSH.
|
|
#
|
|
# Env: PROXMOX_API_URL, PROXMOX_API_TOKEN, PROXMOX_NODE,
|
|
# PROXMOX_STORAGE, PROXMOX_TEMPLATE_VOLID
|
|
# Args: $1 = target VMID (from pve_nextid)
|
|
# Stdout: the new VMID (integer)
|
|
# Exit: 0 on success, 1 on failure
|
|
|
|
set -eu
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
# shellcheck source=api.sh disable=SC1091
|
|
. "${SCRIPT_DIR}/api.sh"
|
|
|
|
pve_env PROXMOX_API_URL PROXMOX_API_TOKEN PROXMOX_NODE \
|
|
PROXMOX_STORAGE PROXMOX_TEMPLATE_VOLID
|
|
|
|
newid="${1:?usage: lxc-clone.sh <newid>}"
|
|
node="${PROXMOX_NODE}"
|
|
storage="${PROXMOX_STORAGE}"
|
|
template_volid="${PROXMOX_TEMPLATE_VOLID}"
|
|
|
|
# POST /nodes/{node}/lxc — create a CT from a template.
|
|
# Body (form-encoded): vmid, ostemplate, hostname, storage, rootfs, ...
|
|
# Returns: UPID (async task). Poll until done.
|
|
create_path="/nodes/${node}/lxc"
|
|
hostname="${PRAXIS_HOSTNAME:-praxis}"
|
|
|
|
echo "lxc-clone: creating VMID ${newid} from ${template_volid}" >&2
|
|
upid=$(pve_curl POST "$create_path" \
|
|
"vmid=${newid}" \
|
|
"ostemplate=${template_volid}" \
|
|
"hostname=${hostname}" \
|
|
"storage=${storage}" \
|
|
"rootfs=${storage}:16" \
|
|
# v0.4: 6144MB default (was 4096 in v0.2). Postgres ~400MB + praxis
|
|
# ~500MB + Docker daemon ~200MB + build headroom ~1GB + margin
|
|
# (REQ-NFR-MT-01). Override with PROXMOX_MEMORY_MB if needed.
|
|
"memory=${PROXMOX_MEMORY_MB:-6144}" \
|
|
"net0=name=eth0,bridge=vmbr0,ip=dhcp" \
|
|
"arch=amd64" \
|
|
"features=nesting=1")
|
|
|
|
if [ -z "$upid" ] || [ "$upid" = "null" ]; then
|
|
echo "lxc-clone: failed to start create (empty UPID)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "lxc-clone: polling create task ${upid}" >&2
|
|
pve_poll "$upid"
|
|
|
|
echo "lxc-clone: CT ${newid} created from ${template_volid}" >&2
|
|
printf '%s\n' "$newid" |