host-install v1.4.0: appliance CPU/RAM cap passthrough (--cores/--memory)
Optional --cores N / --memory M (MiB) passed through to the agent's --selftest=provision as -cores/-memory ONLY when set (0/unset = golden default; avoids unknown-flag death on an agent < v0.52.0). Pre-flight soft WARN when a cap exceeds host nproc/MemTotal. Validated dry-run on felhom-pve. bash -n + shellcheck clean. Deploy dependency: hub artifact manifest must serve agent >= v0.52.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,26 @@
|
||||
# Felhom scripts — Changelog
|
||||
|
||||
## felhom-host-install.sh v1.4.0 — appliance CPU/RAM cap passthrough (`--cores` / `--memory`) (2026-07-01)
|
||||
|
||||
Colleague-safety batch #3 (host-install half; the mechanism is agent v0.52.0). Lets an operator cap the
|
||||
provisioned guest so a trial appliance on a SHARED production Proxmox doesn't pressure the colleague's
|
||||
existing guests.
|
||||
|
||||
- **`--cores N` / `--memory M` (MiB)** — optional; passed through to the agent's `--selftest=provision`
|
||||
as `-cores`/`-memory`. `0`/unset = keep the golden's baked sizes (unchanged behaviour). New vars
|
||||
`CPU_CORES`/`MEM_MIB`; `usage()` header gains an "Appliance cap (optional)" group.
|
||||
- **Conditional passthrough** — `step_provision` builds a `cap_args` array and appends the flags to BOTH
|
||||
the dry-run log and the real agent call **only when set**. An agent < v0.52.0 would reject an unknown
|
||||
flag, so the flags are never sent unless the operator opts in (see the deploy dependency below).
|
||||
- **Pre-flight sanity WARN (soft, provision only)** — if `--cores` > host `nproc` or `--memory` > host
|
||||
`MemTotal`, `log_warn` "the cap won't protect other guests"; never `die` (the operator may know better).
|
||||
- **Deploy dependency:** a fresh install using `--cores`/`--memory` needs the hub artifact manifest to
|
||||
serve **agent ≥ v0.52.0**.
|
||||
- **Validated dry-run on felhom-pve:** `--cores 2 --memory 4096 --dry-run` → provision command shows
|
||||
`-cores 2 -memory 4096`; without the flags → neither present; `--cores 64 --memory 65536` → both WARN
|
||||
lines (host 4 cores / ~15771 MiB). `bash -n` + `shellcheck` clean (0 new warnings; the 2 pre-existing
|
||||
SC2015 in `step_verify` unchanged).
|
||||
|
||||
## felhom-host-install.sh v1.3.0 — `--uninstall` (clean revert) + pre-flight guards (2026-07-01)
|
||||
|
||||
Colleague-safety batch #1+#2. Adds a first-class, guarded **`--uninstall`** teardown so an operator can
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
#===============================================================================
|
||||
# felhom-host-install.sh v1.3.0
|
||||
# felhom-host-install.sh v1.4.0
|
||||
# Day-0 host-bootstrap for a Felhom Proxmox host (operator-deploy model).
|
||||
#
|
||||
# Run by the operator on a FRESHLY-PVE-INSTALLED box (after a manual PVE install
|
||||
@@ -45,6 +45,11 @@
|
||||
# --rootfs-grow N grow OS rootfs by N GiB (default: auto-compute)
|
||||
# --datavol-grow N grow Docker-data vol by N GiB (default: auto-compute)
|
||||
# --sysdata-grow N grow user-data vol by N GiB (default: auto-compute)
|
||||
#
|
||||
# Appliance cap (optional — protect a SHARED host's other guests; needs agent >= v0.52.0):
|
||||
# --cores N cap the guest to N CPU cores (0/unset = golden default)
|
||||
# --memory M cap the guest RAM to M MiB (0/unset = golden default)
|
||||
#
|
||||
# --passphrase-file PATH read the retrieval passphrase from a 0600 file
|
||||
# (default: secure no-echo prompt)
|
||||
# --preserve-from PATH merge non-Day-0 sections (privileged/storage/backup/
|
||||
@@ -85,7 +90,7 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_VERSION="1.3.0"
|
||||
SCRIPT_VERSION="1.4.0"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Logging (mirrors felhom-controller/scripts/docker-setup.sh)
|
||||
@@ -118,6 +123,8 @@ BRIDGE_ADDR=""
|
||||
ROOTFS_GROW=""
|
||||
DATAVOL_GROW=""
|
||||
SYSDATA_GROW=""
|
||||
CPU_CORES="" # --cores: optional appliance CPU-core cap (empty/unset = golden default)
|
||||
MEM_MIB="" # --memory: optional appliance RAM cap in MiB (empty/unset = golden default)
|
||||
PASSPHRASE_FILE=""
|
||||
PRESERVE_FROM=""
|
||||
PRESERVE_STATE_FROM="" # dir holding a prior local-api.{crt,key} + local-tokens.log to carry over (keeps the pin stable across a reinstall)
|
||||
@@ -166,7 +173,7 @@ ART_GOLDEN_SHA=""
|
||||
#-------------------------------------------------------------------------------
|
||||
# Helpers
|
||||
#-------------------------------------------------------------------------------
|
||||
usage() { sed -n '2,75p' "$0" | sed 's/^# \{0,1\}//'; exit 0; }
|
||||
usage() { sed -n '2,80p' "$0" | sed 's/^# \{0,1\}//'; exit 0; }
|
||||
|
||||
run() { # simple (no pipes/redirects) mutating command
|
||||
if $DRY_RUN; then log_dry "$*"; else "$@"; fi
|
||||
@@ -478,6 +485,8 @@ while [[ $# -gt 0 ]]; do
|
||||
--rootfs-grow) ROOTFS_GROW="$2"; shift 2 ;;
|
||||
--datavol-grow) DATAVOL_GROW="$2"; shift 2 ;;
|
||||
--sysdata-grow) SYSDATA_GROW="$2"; shift 2 ;;
|
||||
--cores) CPU_CORES="$2"; shift 2 ;;
|
||||
--memory) MEM_MIB="$2"; shift 2 ;;
|
||||
--passphrase-file) PASSPHRASE_FILE="$2"; shift 2 ;;
|
||||
--preserve-from) PRESERVE_FROM="$2"; shift 2 ;;
|
||||
--preserve-state-from) PRESERVE_STATE_FROM="$2"; shift 2 ;;
|
||||
@@ -621,6 +630,23 @@ step_preflight() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# Appliance-cap sanity (soft): a cap that EXCEEDS host resources won't protect other guests. WARN,
|
||||
# never die — the operator may know better (e.g. capping below a future hardware upgrade).
|
||||
if ! $SKIP_PROVISION; then
|
||||
if [[ -n "$CPU_CORES" ]]; then
|
||||
local host_cores; host_cores=$(nproc 2>/dev/null || echo 0)
|
||||
if [[ "${host_cores:-0}" -gt 0 && "$CPU_CORES" -gt "$host_cores" ]]; then
|
||||
log_warn " requested cap (${CPU_CORES} cores) exceeds host cores (${host_cores}); the cap won't protect other guests."
|
||||
fi
|
||||
fi
|
||||
if [[ -n "$MEM_MIB" ]]; then
|
||||
local host_mem_mib; host_mem_mib=$(awk '/^MemTotal:/{print int($2/1024)}' /proc/meminfo 2>/dev/null || echo 0)
|
||||
if [[ "${host_mem_mib:-0}" -gt 0 && "$MEM_MIB" -gt "$host_mem_mib" ]]; then
|
||||
log_warn " requested cap (${MEM_MIB} MiB) exceeds host RAM (~${host_mem_mib} MiB); the cap won't protect other guests."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# archive-storage-exists guard (provision only — the golden lives there + the restore reads it).
|
||||
if ! $SKIP_PROVISION; then
|
||||
if pvesm status --storage "$ARCHIVE_STORAGE" >/dev/null 2>&1; then
|
||||
@@ -1100,15 +1126,21 @@ step_provision() {
|
||||
log_step "8/8 provision guest $VMID"
|
||||
# NOTE: -hub-password is passed on argv (the agent's only input for it) — briefly
|
||||
# visible in ps. Tracked as an Observation (candidate: env/stdin in the agent).
|
||||
# Optional operator CPU/RAM cap — passed to the agent ONLY when set (an agent < v0.52.0 would
|
||||
# reject the unknown flag and die; opt-in means no one hits that until they intentionally cap).
|
||||
local -a cap_args=()
|
||||
[[ -n "$CPU_CORES" ]] && cap_args+=(-cores "$CPU_CORES")
|
||||
[[ -n "$MEM_MIB" ]] && cap_args+=(-memory "$MEM_MIB")
|
||||
if $DRY_RUN; then
|
||||
log_dry "felhom-agent --config $AGENT_CONFIG --selftest=provision -archive $GOLDEN_VOLID -vmid $VMID -customer-id $CUSTOMER_ID -hub-password <pass> -rootfs-grow $ROOTFS_GROW -datavol-grow $DATAVOL_GROW -sysdata-grow $SYSDATA_GROW"
|
||||
log_dry "felhom-agent --config $AGENT_CONFIG --selftest=provision -archive $GOLDEN_VOLID -vmid $VMID -customer-id $CUSTOMER_ID -hub-password <pass> -rootfs-grow $ROOTFS_GROW -datavol-grow $DATAVOL_GROW -sysdata-grow $SYSDATA_GROW ${cap_args[*]}"
|
||||
log_dry "record provisioned_vmid=$VMID in $STATE_FILE (for a later automatic --uninstall)"
|
||||
_state_mark provision; return 0
|
||||
fi
|
||||
if ! felhom-agent --config "$AGENT_CONFIG" --selftest=provision \
|
||||
-archive "$GOLDEN_VOLID" -vmid "$VMID" \
|
||||
-customer-id "$CUSTOMER_ID" -hub-password "$PASSPHRASE" \
|
||||
-rootfs-grow "$ROOTFS_GROW" -datavol-grow "$DATAVOL_GROW" -sysdata-grow "$SYSDATA_GROW"; then
|
||||
-rootfs-grow "$ROOTFS_GROW" -datavol-grow "$DATAVOL_GROW" -sysdata-grow "$SYSDATA_GROW" \
|
||||
"${cap_args[@]}"; then
|
||||
die "provision FAILED — see the agent error above. Fix and re-run with --resume."
|
||||
fi
|
||||
log_success " provision completed"
|
||||
|
||||
Reference in New Issue
Block a user