feat(signage): scaffold bare Debian VM module
New src/apps/signage: Debian 13 VM, 1 core / 1G / 16G (vmid 816), deps cluster:vm + templates:debian + backup:vm. update.sh confirms the VM is up and records a version marker; signage software layered on in a later pass. Registered in module-catalog.json.
This commit is contained in:
parent
be50a7d900
commit
8b981ecdea
6 changed files with 203 additions and 0 deletions
26
src/apps/signage/README.md
Normal file
26
src/apps/signage/README.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# signage — digital signage host
|
||||
|
||||
A Debian 13 VM intended to run digital-signage software. **Current state: bare
|
||||
VM scaffold** — the VM shape and module plumbing are in place; the signage
|
||||
service itself is not chosen/installed yet.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| VM | 1 core · 1024 MB · 16 G disk · `tanka1` · `lan` bridge |
|
||||
| Image | `debian-13-generic-amd64.qcow2` (cloud-init) |
|
||||
| vmid | 816 |
|
||||
| Depends on | `cluster:vm`, `templates:debian`, `backup:vm` |
|
||||
| Target env | `omStaging` (installs as `signage-omStaging`) |
|
||||
|
||||
## Files
|
||||
|
||||
- `signage.json` — module config (VM shape + dependencies)
|
||||
- `install.sh` — thin wrapper → `update.sh`
|
||||
- `update.sh` — confirms the VM is up, records a version marker (no service yet)
|
||||
- `test.sh` — checks the VM resolves, is reachable, and carries the marker
|
||||
|
||||
## Next steps
|
||||
|
||||
Pick the signage software and extend `update.sh`/`test.sh` accordingly. If it
|
||||
exposes a web UI, add `network:proxy` (and `identity:identity` for OIDC login)
|
||||
to `dependsOn` and a matching `config` block.
|
||||
15
src/apps/signage/install.sh
Executable file
15
src/apps/signage/install.sh
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# signage module install — thin wrapper.
|
||||
#
|
||||
# The VM is created by the cluster:vm provider (Debian 13 cloud image) and
|
||||
# OS-prepped by templates:debian. This script applies the module-specific step;
|
||||
# all real work lives in update.sh (install == update for this module).
|
||||
#
|
||||
# Usage: install.sh <module-name>
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
exec "${SCRIPT_DIR}/update.sh" "$@"
|
||||
29
src/apps/signage/signage.json
Normal file
29
src/apps/signage/signage.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"description": "Digital signage host — bare Debian VM scaffold (signage software TBD)",
|
||||
"version": "0.0.1",
|
||||
"appVersion": "TBD",
|
||||
"releaseDate": "2026-09-01",
|
||||
"maintainer": "@larsrossen",
|
||||
"status": "Development",
|
||||
"vmname": "signage",
|
||||
"vmid": 816,
|
||||
"vmtag": "TAPPaaS,MakerFLOSS",
|
||||
"ports": [],
|
||||
"dependsOn": ["cluster:vm", "templates:debian", "backup:vm"],
|
||||
"provides": [],
|
||||
"config": {
|
||||
"cluster:vm": {
|
||||
"bios": "seabios",
|
||||
"ostype": "l26",
|
||||
"cores": 1,
|
||||
"memory": "1024",
|
||||
"diskSize": "16G",
|
||||
"storage": "tanka1",
|
||||
"imageType": "img",
|
||||
"image": "debian-13-generic-amd64.qcow2",
|
||||
"imageLocation": "https://cdimage.debian.org/cdimage/cloud/trixie/latest",
|
||||
"cloudInit": "true",
|
||||
"bridge0": "lan"
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/apps/signage/test.sh
Executable file
66
src/apps/signage/test.sh
Executable file
|
|
@ -0,0 +1,66 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# signage module test — health checks for the bare Debian VM.
|
||||
#
|
||||
# Verifies (from tappaas-cicd, over the Proxmox guest agent + SSH):
|
||||
# - the VM's IP resolves via the guest agent
|
||||
# - the VM is reachable over SSH
|
||||
# - the version marker written by update.sh is present
|
||||
#
|
||||
# As the signage software is layered on later, add its checks here.
|
||||
#
|
||||
# Usage: test.sh <module-name>
|
||||
#
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
. /home/tappaas/bin/common-install-routines.sh
|
||||
|
||||
MODULE="${1:-signage}"
|
||||
readonly MGMT="mgmt"
|
||||
readonly MARKER="/etc/tappaas-signage.version"
|
||||
VMID="$(get_config_value 'vmid')"
|
||||
VMNAME="$(get_config_value 'vmname' "${MODULE}")"
|
||||
|
||||
PASS=0; FAIL=0
|
||||
ok() { info " ${GN}✓${CL} $1"; PASS=$((PASS+1)); }
|
||||
no() { error " ✗ $1"; FAIL=$((FAIL+1)); }
|
||||
|
||||
[[ -n "${VMID}" && "${VMID}" != "null" ]] || die "no vmid for ${MODULE}"
|
||||
|
||||
PRIMARY="$(get_primary_node_fqdn 2>/dev/null || echo "tappaas1.${MGMT}.internal")"
|
||||
NODE="$(ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new "root@${PRIMARY}" \
|
||||
"pvesh get /cluster/resources --type vm --output-format json 2>/dev/null" \
|
||||
| jq -r --arg v "${VMID}" '.[] | select(.vmid==($v|tonumber)) | .node' 2>/dev/null | head -1)"
|
||||
[[ -n "${NODE}" ]] || NODE="$(get_config_value 'node' "$(get_node_hostname 0)")"
|
||||
|
||||
IP="$(ssh -o BatchMode=yes "root@${NODE}.${MGMT}.internal" \
|
||||
"qm guest cmd ${VMID} network-get-interfaces" 2>/dev/null \
|
||||
| jq -r '.[] | select(.name | test("^lo$") | not) | ."ip-addresses"[]? | select(."ip-address-type"=="ipv4") | ."ip-address"' 2>/dev/null \
|
||||
| grep -v '^127\.' | head -1)"
|
||||
|
||||
info "${BOLD}signage test${CL} (${VMNAME}, VM ${VMID} on ${NODE})"
|
||||
if [[ -z "${IP}" ]]; then
|
||||
no "could not resolve VM IP via guest agent"
|
||||
info "Result: ${PASS} passed, ${FAIL} failed"
|
||||
exit 1
|
||||
fi
|
||||
ok "VM IP resolved (${IP})"
|
||||
|
||||
vm() { ssh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 "tappaas@${IP}" "$@"; }
|
||||
|
||||
if vm "true"; then
|
||||
ok "VM reachable over SSH"
|
||||
else
|
||||
no "VM not reachable over SSH"
|
||||
fi
|
||||
|
||||
if vm "test -f ${MARKER}"; then
|
||||
ok "version marker present ($(vm "cat ${MARKER} 2>/dev/null" | tr -d '\r'))"
|
||||
else
|
||||
no "version marker ${MARKER} missing (update.sh did not run?)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
info "Result: ${PASS} passed, ${FAIL} failed"
|
||||
[[ "${FAIL}" -eq 0 ]]
|
||||
58
src/apps/signage/update.sh
Executable file
58
src/apps/signage/update.sh
Executable file
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# signage module update — a bare Debian VM (scaffold).
|
||||
#
|
||||
# The VM is created by the cluster:vm provider (Debian 13 cloud image) and
|
||||
# OS-prepped by templates:debian. This module currently only confirms the VM is
|
||||
# up and records a version marker — the signage software will be layered on in a
|
||||
# later pass. install == update for this module.
|
||||
#
|
||||
# Runs on tappaas-cicd: resolves the VM's IP via the Proxmox guest agent, then
|
||||
# drives the VM over SSH. Idempotent.
|
||||
#
|
||||
# Usage: update.sh <module-name>
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
. /home/tappaas/bin/common-install-routines.sh
|
||||
|
||||
MODULE="${1:-signage}"
|
||||
readonly MGMT="mgmt"
|
||||
readonly MARKER="/etc/tappaas-signage.version" # on the VM: module version we applied
|
||||
|
||||
VMNAME="$(get_config_value 'vmname' "${MODULE}")"
|
||||
VMID="$(get_config_value 'vmid')"
|
||||
VERSION="$(get_config_value 'version' '0.0.1')"
|
||||
[[ -n "${VMID}" && "${VMID}" != "null" ]] || die "no vmid for ${MODULE}"
|
||||
|
||||
# ── Locate the node hosting the VM (HA-safe) and resolve its IP ───────
|
||||
PRIMARY="$(get_primary_node_fqdn 2>/dev/null || echo "tappaas1.${MGMT}.internal")"
|
||||
NODE="$(ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new "root@${PRIMARY}" \
|
||||
"pvesh get /cluster/resources --type vm --output-format json 2>/dev/null" \
|
||||
| jq -r --arg v "${VMID}" '.[] | select(.vmid==($v|tonumber)) | .node' 2>/dev/null | head -1)"
|
||||
[[ -n "${NODE}" ]] || NODE="$(get_config_value 'node' "$(get_node_hostname 0)")"
|
||||
[[ -n "${NODE}" ]] || die "could not locate the node hosting VM ${VMID}"
|
||||
|
||||
get_vm_ip() {
|
||||
ssh -o BatchMode=yes "root@${NODE}.${MGMT}.internal" \
|
||||
"qm guest cmd ${VMID} network-get-interfaces" 2>/dev/null \
|
||||
| jq -r '.[] | select(.name | test("^lo$") | not) | ."ip-addresses"[]? | select(."ip-address-type"=="ipv4") | ."ip-address"' 2>/dev/null \
|
||||
| grep -v '^127\.' | head -1
|
||||
}
|
||||
|
||||
info "${BOLD}Updating signage${CL} on ${VMNAME} (VM ${VMID}, node ${NODE})"
|
||||
|
||||
IP=""
|
||||
for _ in $(seq 1 18); do IP="$(get_vm_ip)"; [[ -n "${IP}" ]] && break; sleep 10; done
|
||||
[[ -n "${IP}" ]] || die "could not resolve an IPv4 for VM ${VMID} via the guest agent"
|
||||
info " VM IP: ${IP}"
|
||||
|
||||
vm() { ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 "tappaas@${IP}" "$@"; }
|
||||
|
||||
# Confirm SSH is up and record the version marker. Nothing else to install yet —
|
||||
# this is a bare Debian scaffold; the signage service comes in a later pass.
|
||||
vm "true" || die "VM ${VMNAME} (${IP}) not reachable over SSH"
|
||||
vm "echo '${VERSION}' | sudo tee ${MARKER} >/dev/null" || warn "could not write version marker"
|
||||
|
||||
info " ${GN}✓${CL} signage VM is up (bare Debian scaffold — no service installed yet)"
|
||||
|
|
@ -19,6 +19,15 @@
|
|||
"stack": "infrastructure",
|
||||
"category": "containers",
|
||||
"status": "incomplete"
|
||||
},
|
||||
{
|
||||
"moduleName": "signage",
|
||||
"repo": "community",
|
||||
"moduleJson": "src/apps/signage/signage.json",
|
||||
"vmid": 816,
|
||||
"stack": "application",
|
||||
"category": "signage",
|
||||
"status": "incomplete"
|
||||
}
|
||||
],
|
||||
"proxmoxTemplates": [],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue