Implement governed S1 backup recovery loop
Some checks failed
CI Smoke / source-contract (push) Failing after 9s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02994-7685-7940-bf34-3555b8256018
This commit is contained in:
codex 2026-08-23 13:13:13 +02:00
parent 40e295e3bd
commit 295bf43d54
16 changed files with 1623 additions and 95 deletions

View file

@ -0,0 +1,4 @@
---
- name: Reload systemd for S1 backup
ansible.builtin.systemd:
daemon_reload: true

View file

@ -0,0 +1,81 @@
---
- name: Install S1 backup runtime packages
ansible.builtin.package:
name:
- age
- python3
- python3-yaml
state: present
- name: Create bounded S1 backup directories
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
owner: root
group: root
mode: "{{ item.mode }}"
loop:
- {path: /usr/local/lib/railiance-infra/s1-backup/scripts, mode: "0755"}
- {path: /usr/local/lib/railiance-infra/s1-backup/spec, mode: "0755"}
- {path: /opt/backup/railiance/infra, mode: "0700"}
- name: Install S1 backup Python implementation
ansible.builtin.copy:
src: "{{ playbook_dir }}/../../scripts/{{ item }}"
dest: "/usr/local/lib/railiance-infra/s1-backup/scripts/{{ item }}"
owner: root
group: root
mode: "0755"
loop:
- s1_backup.py
- s1_backup_contract.py
- s1_restore.py
- name: Install S1 backup declaration
ansible.builtin.copy:
src: "{{ playbook_dir }}/../../spec/s1-backup.yaml"
dest: /usr/local/lib/railiance-infra/s1-backup/spec/s1-backup.yaml
owner: root
group: root
mode: "0644"
- name: Install public recipient policy metadata
ansible.builtin.copy:
src: "{{ playbook_dir }}/../../.sops.yaml"
dest: /usr/local/lib/railiance-infra/s1-backup/.sops.yaml
owner: root
group: root
mode: "0644"
- name: Install S1 backup command wrapper
ansible.builtin.template:
src: railiance-backup-s1.j2
dest: /usr/local/sbin/railiance-backup-s1
owner: root
group: root
mode: "0755"
- name: Install S1 backup systemd service
ansible.builtin.template:
src: railiance-backup-s1.service.j2
dest: /etc/systemd/system/railiance-backup-s1.service
owner: root
group: root
mode: "0644"
notify: Reload systemd for S1 backup
- name: Install S1 backup systemd timer
ansible.builtin.template:
src: railiance-backup-s1.timer.j2
dest: /etc/systemd/system/railiance-backup-s1.timer
owner: root
group: root
mode: "0644"
notify: Reload systemd for S1 backup
- name: Enable daily S1 backup timer
ansible.builtin.systemd:
name: railiance-backup-s1.timer
enabled: true
state: started
daemon_reload: true

View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail
exec python3 /usr/local/lib/railiance-infra/s1-backup/scripts/s1_backup.py create \
--source-revision "{{ railiance_backup_source_revision }}" "$@"

View file

@ -0,0 +1,18 @@
[Unit]
Description=Encrypted Railiance S1 operating-system backup
Documentation=file:///usr/local/lib/railiance-infra/s1-backup/spec/s1-backup.yaml
After=local-fs.target
ConditionPathIsReadWrite=/opt/backup/railiance/infra
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/railiance-backup-s1
User=root
Group=root
UMask=0077
Nice=10
PrivateTmp=true
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/backup/railiance/infra

View file

@ -0,0 +1,11 @@
[Unit]
Description=Daily encrypted Railiance S1 backup (RAIL-HO-WP-0012-T04)
[Timer]
OnCalendar=*-*-* 02:15:00 UTC
RandomizedDelaySec=30min
Persistent=true
Unit=railiance-backup-s1.service
[Install]
WantedBy=timers.target