feat(nh3-svos): VM 111 on nh3-pve-2 for the new SVOS (svos-dev, Prime); generic cloud-init VM playbook

This commit is contained in:
vh
2026-10-05 18:59:53 -07:00
parent 2c4c7ca9ae
commit d7e845eb64
9 changed files with 291 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
# Base build for nh3-svos (VM 111 on nh3-pve-2, 10.100.50.43): the host for the NEW SVOS operating system
# (corviduo/svoperatingsystem). Requested by svos-dev relaying Prime, 2026-10-05. A SEPARATE instance: the existing
# High Seat (svos.service on nh3-dev :8770) and Miranda are untouched.
# scripts/elway infra-ops@10.100.50.43 --playbook playbooks/nh3-svos-host.yaml
# Order: nh3-pve-2-cloudinit-vm.yaml (on nh3-pve-2) → bootstrap-infra-ops-user.yaml AS vh → this.
#
# Infra owns the box; svos-dev owns the application (install, config, enrollment, acceptance). What this provides:
# - service account `svc-svos` (uid/gid 801, nologin; fleet-conventions § 1.3), the only writer of the data root
# - /var/lib/svos svc-svos 0700, LOCAL ext4 (the root disk on vmstore): SQLite WAL, one writer, never shared/NFS
# - /opt/svos root:svc-svos 2775, the release tree (releases/<id>/ + a `current` link; svos-dev lays it out)
# - Python 3.13 (Debian 13) + venv, sqlite3, qemu-guest-agent (vzdump freeze/thaw), timesyncd checked
# - /etc/qemu/fsfreeze-hook.d/ exists for the application-consistent snapshot hook svos-dev will add (the guest
# agent runs those scripts on vzdump's freeze/thaw)
# No Docker: nothing here needs it.
steps:
- name: take the bootstrap infra-ops key back off vh (vh keeps the operator's keys)
sudo: true
shell: |
set -e
f=/home/vh/.ssh/authorized_keys
grep -v 'infra-ops@pfi-fleet' "$f" > "$f.new"
test -s "$f.new"
chown vh:vh "$f.new"; chmod 600 "$f.new"; mv "$f.new" "$f"
when: "sudo -n grep -q 'infra-ops@pfi-fleet' /home/vh/.ssh/authorized_keys"
- name: timezone America/Los_Angeles
sudo: true
shell: timedatectl set-timezone America/Los_Angeles
when: "[ \"$(timedatectl show -p Timezone --value)\" != America/Los_Angeles ]"
- name: base packages
sudo: true
shell: DEBIAN_FRONTEND=noninteractive apt-get install -y -q qemu-guest-agent python3 python3-venv sqlite3 rsync jq curl ca-certificates
when: "! dpkg -s qemu-guest-agent python3-venv sqlite3 rsync jq >/dev/null 2>&1"
- name: qemu-guest-agent running
sudo: true
shell: systemctl start qemu-guest-agent
when: "! systemctl is-active --quiet qemu-guest-agent"
- name: fsfreeze hook directory for the application-consistent snapshot hook
sudo: true
shell: install -d -o root -g root -m 0755 /etc/qemu/fsfreeze-hook.d
changed_when: "false"
- name: service account svc-svos (uid/gid 801, nologin, home = the data root)
sudo: true
shell: |
set -e
getent group 801 >/dev/null && { echo "gid 801 taken"; exit 1; }
getent passwd 801 >/dev/null && { echo "uid 801 taken"; exit 1; }
groupadd --system --gid 801 svc-svos
useradd --system --uid 801 --gid 801 --shell /usr/sbin/nologin --home-dir /var/lib/svos --no-create-home svc-svos
when: "! getent passwd svc-svos >/dev/null"
- name: data root /var/lib/svos (svc-svos 0700) and release tree /opt/svos (root:svc-svos 2775)
sudo: true
shell: |
install -d -o svc-svos -g svc-svos -m 0700 /var/lib/svos
install -d -o root -g svc-svos -m 2775 /opt/svos /opt/svos/releases
changed_when: "false"
verify:
- name: identities are the fleet pins
shell: |
test "$(id -u vh)" = 1000 && test "$(id -u infra-ops)" = 850 && test "$(id -u svc-svos)" = 801
changed_when: "false"
- name: vh no longer carries the infra-ops key
sudo: true
shell: "! grep -q 'infra-ops@pfi-fleet' /home/vh/.ssh/authorized_keys"
changed_when: "false"
- name: data root is local ext4 and private
sudo: true
shell: |
test "$(findmnt -T /var/lib/svos -no FSTYPE)" = ext4 && test "$(stat -c '%U %a' /var/lib/svos)" = "svc-svos 700"
changed_when: "false"
- name: python, sqlite, guest agent, time sync
shell: |
python3 --version && sqlite3 --version | cut -c1-20 && systemctl is-active qemu-guest-agent && timedatectl show -p NTPSynchronized --value
changed_when: "false"