Files
ProxMenux/web/components/oci/stackDependencyHookSource.ts
T
MacRimiandClaude Opus 5.5 4437a671d2 ProxMenux 1.2.6.2-beta: OCI containers in the Monitor, docs and fixes
OCI manager Apps
- App tab: containers installed from an OCI image are identified from their
  installation record; the application and image versions are shown and an
  update is detected by image digest; repository link; Refresh data.
- Updates tab for OCI containers: Update and Recreate run the same flow as the
  OCI menu in the Monitor terminal; the pre-update backup can be kept in a
  backup storage; scheduled image updates with an optional minimum age.
- Logs tab: console output of the application, kept on the host
  (lxc.console.logfile + logrotate) and followed live.
- The Proxmox console opens a shell (cmode: shell) when the image has one.
- A damaged image download is fetched again before failing.
- Multi-container applications open at their LAN address; volume mount
  points on block storage report their usage.

Monitor
- Proxmox notifications are delivered to a loopback-only HTTP listener when
  HTTPS is enabled, so they no longer fail certificate verification.
- Log persistence counts recurring patterns only; an ended burst is not
  reported as persistent and its warning clears on its own (#386).
- Proxmox notification config backups are deduplicated and capped at three.
- The update icon on the Apps page opens the container on its Updates tab.
- Version 1.2.6.2-beta and its release notes in every Monitor language.

Docs
- OCI manager Apps and Audit & Report rebuilt as per-page message files,
  with a new page for OCI containers in the Monitor.
- Seven pages fixed where rich-text tags were missing from t.rich.

Translations
- Spanish fixes across the OCI engine, the Monitor and the TUI menus.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 21:51:12 +02:00

5 lines
4.5 KiB
TypeScript

// Generated documentation snapshot of oci/remote/stack_dependency_hook.sh.
// Keep this file synchronized when the installed hook changes.
export const STACK_DEPENDENCY_HOOK_SOURCE = "#!/usr/bin/env bash\nset -Eeuo pipefail\n\nPATH=/usr/sbin:/usr/bin:/sbin:/bin\n\ndie() {\n printf 'ERROR: %s\\n' \"$*\" >&2\n exit 1\n}\n\nfind_snippet_storage() {\n local storage\n if pvesm status --content snippets 2>/dev/null \\\n | awk 'NR > 1 && $1 == \"local\" && $3 == \"active\" {found=1} END {exit !found}'; then\n printf 'local'\n return\n fi\n storage=$(pvesm status --content snippets 2>/dev/null \\\n | awk 'NR > 1 && $3 == \"active\" {print $1; exit}')\n [[ -n $storage ]] || die \"No active storage supports snippets\"\n printf '%s' \"$storage\"\n}\n\ninstall_hook() {\n local main_id=${1:?missing main VMID} source_config=${2:?missing lifecycle JSON}\n local storage hook_volume hook_path target_config\n [[ $main_id =~ ^[0-9]+$ ]] || die \"Invalid main VMID\"\n jq -e '\n .schema == 1 and\n (.dependencies | type == \"array\") and\n (.dependencies | length > 0) and\n (all(.dependencies[];\n (.vmid | type == \"number\") and\n (.label | type == \"string\") and\n (.healthcheck.type | IN(\"exec\", \"http\", \"running\")) and\n (.healthcheck.timeout_seconds | type == \"number\")\n ))\n ' \"$source_config\" >/dev/null || die \"Invalid dependency contract\"\n\n storage=$(find_snippet_storage)\n hook_volume=\"${storage}:snippets/proxmenux-stack-dependencies.sh\"\n hook_path=$(pvesm path \"$hook_volume\")\n install -D -m 0755 \"$0\" \"$hook_path\"\n\n target_config=\"/etc/pve/priv/proxmenux-stack-${main_id}.json\"\n umask 077\n cat \"$source_config\" >\"$target_config\"\n pct set \"$main_id\" --hookscript \"$hook_volume\" >/dev/null\n printf 'Proxmox hookscript installed: CT %s starts its dependencies through %s\\n' \\\n \"$main_id\" \"$hook_volume\"\n}\n\ndependency_is_healthy() {\n local id=$1 healthcheck=$2 type url\n type=$(jq -r '.type' <<<\"$healthcheck\")\n case \"$type\" in\n running)\n [[ $(pct status \"$id\" 2>/dev/null || true) == \"status: running\" ]]\n ;;\n exec)\n local -a command=()\n mapfile -t command < <(jq -r '.argv[]' <<<\"$healthcheck\")\n ((${#command[@]} > 0)) || return 1\n pct exec \"$id\" -- \"${command[@]}\" >/dev/null 2>&1\n ;;\n http)\n url=$(jq -r '.url' <<<\"$healthcheck\")\n curl -fsS --max-time 3 \"$url\" >/dev/null 2>&1\n ;;\n *) return 1 ;;\n esac\n}\n\nstart_dependencies() {\n local main_id=$1 config=\"/etc/pve/priv/proxmenux-stack-${1}.json\"\n local encoded dependency id label healthcheck timeout elapsed\n [[ -r $config ]] || die \"Missing dependency contract for main CT $main_id\"\n\n exec 9>\"/run/lock/proxmenux-stack-${main_id}.lock\"\n flock 9\n while IFS= read -r encoded; do\n [[ -n $encoded ]] || continue\n dependency=$(base64 -d <<<\"$encoded\")\n id=$(jq -r '.vmid' <<<\"$dependency\")\n label=$(jq -r '.label' <<<\"$dependency\")\n healthcheck=$(jq -c '.healthcheck' <<<\"$dependency\")\n timeout=$(jq -r '.healthcheck.timeout_seconds' <<<\"$dependency\")\n [[ $id =~ ^[0-9]+$ && $timeout =~ ^[0-9]+$ && $timeout -gt 0 ]] \\\n || die \"Invalid dependency in $config\"\n pct config \"$id\" >/dev/null 2>&1 \\\n || die \"Dependency $label (CT $id) does not exist\"\n\n if [[ $(pct status \"$id\" 2>/dev/null || true) != \"status: running\" ]]; then\n printf 'Starting dependency %s (CT %s)...\\n' \"$label\" \"$id\"\n pct start \"$id\" || die \"Could not start $label (CT $id)\"\n else\n printf 'Dependency %s (CT %s) was already running.\\n' \"$label\" \"$id\"\n fi\n\n elapsed=0\n while (( elapsed < timeout )); do\n if dependency_is_healthy \"$id\" \"$healthcheck\"; then\n printf 'Dependency %s (CT %s): ready.\\n' \"$label\" \"$id\"\n break\n fi\n [[ $(pct status \"$id\" 2>/dev/null || true) == \"status: running\" ]] \\\n || die \"$label (CT $id) stopped while starting\"\n sleep 2\n elapsed=$((elapsed + 2))\n done\n (( elapsed < timeout )) \\\n || die \"$label (CT $id) did not pass its health check within ${timeout}s\"\n done < <(jq -r '.dependencies[] | @base64' \"$config\")\n}\n\nif [[ ${1:-} == \"--install\" ]]; then\n shift\n install_hook \"$@\"\n exit 0\nfi\n\nvmid=${1:?missing VMID}\nphase=${2:?missing lifecycle phase}\ncase \"$phase\" in\n pre-start) start_dependencies \"$vmid\" ;;\n post-start|pre-stop|post-stop) ;;\n *) die \"Unknown lifecycle phase: $phase\" ;;\nesac\n"