mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 02:54:26 +00:00
`3c1d5d821` solved the cross-round backbone-abriss problem by making `include` equal the union of every variant's closure for every round. Side-effect: every matrix round then ALSO deployed the full union, so `08_deploy_performance.sh` saw `dashboard.infinito.example` still answering HTTP 200 after a matomo-only `deploy-fresh-purged-apps` — the deploy step was no longer matomo-only at all. Split the two concerns instead: - `include` (PlanEntry[3]) goes back to the per-round variant-closure. Both `init`/`builder` (`--include` for the inventory bake) and `deploy` (`--id` for ansible) consume it. Each round therefore deploys ONLY its own variant-closure again — the pre-`3c1d5d821` semantics. - `purge_set` (PlanEntry[4], new) carries the union across all rounds. `deploy.py` uses it for the inter-round wipe instead of the previous round's include. Result: between rounds the WHOLE matrix footprint is purged, not just the previous round's variant slice — a variant pinning `services.<X>.shared: false` cannot leave its bundled provider on the host for a sibling round that wires the same service shared. The backbone-abriss `3c1d5d821` was hunting stays fixed: whichever round needs the backbone re-deploys it immediately after the wipe (purge runs at the start of each round, not the end). `previous_round_include` tracking is gone. The first iteration skips the purge (nothing to wipe yet), which also covers `total_rounds == 1` and `--variant N` pinned single-folder modes cleanly. Unrelated, but staged together because it is part of the same investigation: - `roles/dev-nix/templates/nix.conf.j2`: enable `keep-derivations` / `keep-outputs`, so `nix-collect-garbage -d` (run by the aggressive prune step) does not drop the build closure of pkgmgr's flake; this was making every deploy re-fetch the build inputs from cache.nixos.org and overshoot pkgmgr's update timeout. - `roles/pkgmgr/tasks/01_core.yml`: raise the pkgmgr update timeout from 600s to 1800s and lower the retry count from 6 to 3, so a slow fetch on a single try no longer pushes total wallclock past three hours. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
67 lines
2.5 KiB
Python
67 lines
2.5 KiB
Python
"""Data types for the development inventory matrix.
|
|
|
|
`DevInventorySpec` is the value type `build_dev_inventory` consumes —
|
|
it carries everything `infinito administration inventory provision`
|
|
needs to materialise one development inventory folder. `PlanEntry` is
|
|
the per-round tuple `plan_dev_inventory_matrix` emits and the deploy
|
|
wrapper iterates.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import TYPE_CHECKING, Any
|
|
|
|
if TYPE_CHECKING:
|
|
from collections.abc import Mapping
|
|
|
|
# (round_index, inventory_dir, round_variants, include, purge_set) — include is the round's variant-closure (what to deploy); purge_set is the union over all rounds (what the inter-round wipe clears).
|
|
PlanEntry = tuple[int, str, dict[str, int], tuple[str, ...], tuple[str, ...]]
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class DevInventorySpec:
|
|
"""Everything `infinito administration inventory provision` needs to
|
|
materialise one development inventory folder.
|
|
|
|
`extra_vars` wins over the implicit `STORAGE_CONSTRAINED` / `RUNTIME`
|
|
overrides so callers (and tests) keep the documented "user-provided
|
|
vars always win" behaviour without re-implementing the merge.
|
|
|
|
`active_variants` is the per-app variant index for the round this
|
|
folder represents. Apps absent from the mapping (or with an out-of-
|
|
range index) fall back to variant 0. The resolved variant payload
|
|
for every app in `include` is baked into the inventory as an
|
|
`applications.<app>` override, so the deploy stage no longer needs
|
|
a runtime variant selector — the inventory itself is variant-resolved.
|
|
"""
|
|
|
|
inventory_dir: str
|
|
include: tuple[str, ...]
|
|
storage_constrained: bool
|
|
runtime: str
|
|
extra_vars: Mapping[str, Any] | None = None
|
|
services_disabled: str = ""
|
|
active_variants: Mapping[str, int] | None = None
|
|
|
|
def __post_init__(self) -> None:
|
|
if not self.include:
|
|
raise ValueError("DevInventorySpec.include must not be empty")
|
|
if not isinstance(self.include, tuple):
|
|
object.__setattr__(self, "include", tuple(self.include))
|
|
|
|
def overrides(self) -> dict[str, Any]:
|
|
merged: dict[str, Any] = {
|
|
"STORAGE_CONSTRAINED": bool(self.storage_constrained),
|
|
"RUNTIME": self.runtime,
|
|
}
|
|
if self.extra_vars:
|
|
merged.update(self.extra_vars)
|
|
return merged
|
|
|
|
def variant_selectors(self) -> dict[str, int]:
|
|
return dict(self.active_variants or {})
|
|
|
|
def inventory_root(self) -> str:
|
|
return str(self.inventory_dir).rstrip("/")
|