# 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// + 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"