coulomb-social/scripts/backup_install_runtime.py
tegwick 7077ca9db0
Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 2m27s
Prepare supervised inactive backup installation and record custody blockers
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3
2026-10-31 12:16:03 +01:00

339 lines
12 KiB
Python

"""Remote, attended source installation; never captures, sends or starts a unit."""
from __future__ import annotations
import base64
import fcntl
import hashlib
import json
import os
import stat
import subprocess
import types
from contextlib import contextmanager
from datetime import UTC, datetime
from pathlib import Path
ROOT = Path("/")
STATE = Path("/var/lib/coulomb-social-backup")
ATTEMPTS = Path("/var/lib/coulomb-social-backup-installations")
ROUTE_ROOT = Path("/var/lib/rapp-telemetry/backup-route-releases")
CLUSTER_UID = "a553c742-0115-43d4-99a4-a5ca56fe0786"
UNITS = (
"coulomb-social-paired-backup.service",
"coulomb-social-paired-backup.timer",
"coulomb-social-backup-freshness.service",
"coulomb-social-backup-freshness.timer",
"coulomb-social-backup-alert@coulomb-social-paired-backup.service.service",
)
PROFILE = dict(
maximum_new_file_bytes=1024**3,
state_budget_bytes=8 * 1024**3,
minimum_free_bytes=8 * 1024**3,
minimum_free_inodes=1024,
control_margin_bytes=16 * 1024**2,
)
class Refused(ValueError):
pass
def require(condition, reason):
if not condition:
raise Refused(reason)
def sha(raw):
return hashlib.sha256(raw).hexdigest()
def canonical(value):
return json.dumps(value, sort_keys=True, separators=(",", ":")).encode()
def module(source, name):
result = types.ModuleType(name)
exec(compile(source, "<reviewed-" + name + ">", "exec"), result.__dict__)
return result
def command(args, timeout=30):
result = subprocess.run(
args,
capture_output=True,
timeout=timeout,
env=dict(os.environ, KUBECONFIG="/etc/rancher/k3s/k3s.yaml"),
)
require(
result.returncode == 0 and len(result.stdout) < 16 * 1024 * 1024, "bounded_command_failed"
)
return result.stdout
def cluster_identity():
namespace = json.loads(
command(["k3s", "kubectl", "get", "namespace", "kube-system", "-o", "json"])
)
require(namespace["metadata"]["uid"] == CLUSTER_UID, "primary_cluster_mismatch")
def inactive_units():
rows = {}
# This host's list-jobs does not implement JSON output; no-legend emits
# empty output for no jobs, otherwise JOB UNIT TYPE STATE rows.
jobs = command(["systemctl", "list-jobs", "--no-legend", "--no-pager", "--plain"])
jobs = [line.split() for line in jobs.decode().splitlines() if line.strip()]
require(all(len(row) == 4 and row[0].isdecimal() for row in jobs), "job_listing_unrecognized")
require(
not any(row[1].startswith("coulomb-social-") for row in jobs),
"queued_coulomb_unit_job",
)
# Also reject an already running alternative instance of the alert template.
listing = json.loads(
command(
["systemctl", "list-units", "--all", "--output=json", "--no-pager", "coulomb-social-*"]
)
)
require(all(x.get("active") == "inactive" for x in listing), "coulomb_unit_active_or_failed")
for unit in UNITS:
raw = command(
[
"systemctl",
"show",
unit,
"--property=LoadState,ActiveState,SubState,UnitFileState,FragmentPath",
]
)
row = dict(line.split("=", 1) for line in raw.decode().splitlines() if "=" in line)
require(row["ActiveState"] == "inactive" and row["SubState"] == "dead", "unit_not_inactive")
require(
row["LoadState"] in ("loaded", "not-found")
and row.get("UnitFileState", "") in ("", "disabled", "static"),
"unit_enabled_or_unexpected",
)
if row["LoadState"] == "loaded":
fragment = unit if "@" not in unit else "coulomb-social-backup-alert@.service"
require(
row["FragmentPath"] == "/etc/systemd/system/" + fragment, "foreign_unit_fragment"
)
rows[unit] = row
return rows
@contextmanager
def locks():
handles = []
try:
info = STATE.lstat()
require(
stat.S_ISDIR(info.st_mode) and info.st_uid == os.geteuid() and not info.st_mode & 0o077,
"private_backup_state_required",
)
for name in ("backup.lock", "snapshot.lock"):
# Existing lock only; no truncation, replacement or lock-file creation.
fd = os.open(STATE / name, os.O_RDONLY | os.O_NOFOLLOW)
handles.append(fd)
info = os.fstat(fd)
require(
stat.S_ISREG(info.st_mode)
and info.st_uid == os.geteuid()
and info.st_nlink == 1
and not info.st_mode & 0o077,
"unsafe_lock_file",
)
fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
yield
finally:
for fd in reversed(handles):
os.close(fd)
def verified_payload(packet):
require(__debug__, "optimized_python_refused")
plan = packet["plan"]
require(
packet["proposal_digest"] == "sha256:" + sha(canonical(plan)), "proposal_digest_differs"
)
require(
plan["capacity_profile"] == PROFILE and plan["cluster_uid"] == CLUSTER_UID,
"operating_scope_differs",
)
sources = {}
for key in ("installer", "route_verifier"):
raw = base64.b64decode(packet[key], validate=True)
require(sha(raw) == plan[key + "_sha256"], "source_digest_differs")
sources[key] = raw
archive = base64.b64decode(packet["archive"], validate=True)
installer = module(sources["installer"], "backup_install")
manifest, contents = installer.read_bundle(
archive, plan["archive_sha256"], plan["manifest_sha256"]
)
require(
plan["route_packet"]["execution_digest"] == plan["route_execution_digest"],
"route_digest_differs",
)
return installer, manifest, contents, sources
def route_verified(plan, source):
path = ROUTE_ROOT / plan["route_execution_digest"].split(":")[1] / "receipt.json"
require(path.is_file() and not path.is_symlink(), "route_receipt_missing")
info = path.stat()
require(
info.st_uid == 0 and not info.st_mode & 0o077 and info.st_size < 65536,
"route_receipt_not_private",
)
receipt = json.loads(path.read_bytes())
require(
receipt["status"] == "backup_email_route_deployed_verified"
and receipt["execution_digest"] == plan["route_execution_digest"],
"route_not_verified",
)
verifier = module(source, "backup_route_runtime")
revision = verifier.verify_return(plan["route_packet"], after=True)
require(revision == receipt["helm_revision"], "route_revision_differs")
return {"helm_revision": revision, "runtime_and_complete_resources_verified": True}
def capacity(contents):
guard = module(contents["consumer/backup_capacity.py"], "backup_capacity")
require(
(
guard.FILE_LIMIT,
guard.STATE_BUDGET,
guard.MINIMUM_FREE,
guard.MINIMUM_INODES,
guard.CONTROL_MARGIN,
)
== tuple(PROFILE.values()),
"capacity_profile_differs",
)
try:
report = guard.reserve_plan(STATE, require_file_limit=False)
except guard.Refused as error:
raise Refused(str(error)) from None
require(not report["reasons"], "capacity_headroom_refused")
return {
k: report[k]
for k in (
"state_bytes",
"state_reserve_bytes",
"disk_reserve_bytes",
"free_bytes",
"free_inodes",
"filesystem_blocks_reserved",
)
}
def runtime_dependencies():
code = (
"import json,boto3,botocore; print(json.dumps(dict(boto3=boto3.__version__,"
"botocore=botocore.__version__)))"
)
actual = json.loads(command(["/opt/railiance-platform/backup-venv/bin/python", "-c", code]))
require(actual == {"boto3": "1.40.18", "botocore": "1.40.76"}, "sdk_dependency_drift")
# Check credential references' custody, without reading their contents.
for name in ("primary.env", "recipient.env"):
path = Path("/etc/coulomb-social-backup") / name
info = path.lstat()
require(
stat.S_ISREG(info.st_mode)
and info.st_uid == 0
and info.st_nlink == 1
and not info.st_mode & 0o077,
"credential_reference_custody_differs",
)
return actual
def preflight(plan, installer, contents, source):
cluster_identity()
units = inactive_units()
before = installer.observe(ROOT)
require(before == plan["expected_before"], "native_preimage_changed")
require(not (ATTEMPTS / plan["attempt_id"]).exists(), "existing_attempt_requires_inspection")
profile = capacity(contents)
sdk = runtime_dependencies()
route = route_verified(plan, source)
return dict(units=units, capacity=profile, sdk=sdk, route=route)
def run(packet, action):
require(action in ("preflight", "install", "rollback"), "unknown_action")
require(os.geteuid() == 0, "root_owner_execution_required")
installer, manifest, contents, sources = verified_payload(packet)
plan = packet["plan"]
directory = ATTEMPTS / plan["attempt_id"]
require(
len(plan["attempt_id"]) == 16 and all(c in "0123456789abcdef" for c in plan["attempt_id"]),
"invalid_attempt_id",
)
installer.trusted_parents(ROOT, directory / "receipt.json")
with locks():
if action == "rollback":
cluster_identity()
inactive_units()
require(directory.is_dir() and not directory.is_symlink(), "attempt_missing")
prior = json.loads((directory / "receipt.json").read_text())
require(
prior["proposal_digest"] == packet["proposal_digest"], "attempt_proposal_differs"
)
record = json.loads((directory / "files/receipt.json").read_text())
prior.update(status="rollback_in_progress", updated_at=datetime.now(UTC).isoformat())
installer.journal(directory, prior)
installer.restore(
ROOT, directory / "files", record, lambda: command(["systemctl", "daemon-reload"])
)
inactive_units()
prior.update(status="prior_files_restored_units_inactive_verified")
installer.journal(directory, prior)
return prior
result = preflight(plan, installer, contents, sources["route_verifier"])
receipt = dict(
schema="coulomb.backup-source-supervised-installation.v1",
proposal_digest=packet["proposal_digest"],
status="preflight_verified",
preflight=result,
timers_activated=False,
capture_executed=False,
email_sent=False,
retained_data_deleted=False,
)
if action == "preflight":
return receipt
directory.mkdir(mode=0o700, parents=True, exist_ok=False)
receipt.update(
status="installing",
started_at=datetime.now(UTC).isoformat(),
capacity_profile=PROFILE,
founder_confirmed_profile_and_installation=True,
)
installer.journal(directory, receipt)
try:
files = installer.install(
manifest,
contents,
plan["expected_before"],
directory / "files",
root=ROOT,
reload_manager=lambda: command(["systemctl", "daemon-reload"]),
verify_inactive=inactive_units,
)
# Recheck the external dependency after installation, without a send.
receipt["route_postflight"] = route_verified(plan, sources["route_verifier"])
receipt.update(
status="sources_installed_units_inactive_verified",
verified_targets=files["verified_targets"],
units=inactive_units(),
)
except Exception as error:
receipt.update(
status="installation_requires_inspection", failure_type=type(error).__name__
)
raise
finally:
receipt["updated_at"] = datetime.now(UTC).isoformat()
installer.journal(directory, receipt)
return receipt