mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 19:56:53 +00:00
main rejects a moving runner label since52ad8549e0, because ubuntu-latest moved to 26.04 in the middle of run 39166850273 and every job that landed on the new image met a different OS.9bdecaa794pinned the three places on this branch that still carried the moving label, but the matrix generator was a fourth and kept emitting it for every amd64 row. It was missed for the reason that commit names: the updater ofb055eece05raises a bare runs-on: ubuntu-NN.NN and leaves everything else alone, and here the label lives in a Python dict rather than on a runs-on line. That is the same blind spot9bdecaa794describes for the architecture ternary of call-images-build-ci.yml, which it also had to raise by hand. tests/lint/repository/test_workflow_runner_pinned.py does not reach this file either: it passed with ubuntu-latest in place. The drift is visible in the runs. On this fork ubuntu-latest resolves to 24.04, whose system Python is 3.12, while main requests 26.04 and runs 3.14, and .github/workflows/README.md documents 26.04 for amd64. The branch is uniformly about twice as slow per ansible task as main at every percentile, and the interpreter is one of three candidates for that alongside the new controller-side code and the fork-versus-upstream difference. Pinning the generator makes the platforms comparable, which is what lets that question be answered at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
89 lines
2.9 KiB
Python
89 lines
2.9 KiB
Python
"""What the deploy axes may draw from, and how they draw.
|
|
|
|
Separate from :mod:`utils.github.variant.axes` because it answers a narrower
|
|
question: ``axes`` decides which value a given row takes, this module owns the
|
|
value sets themselves, the narrowing a run may apply to them, and the rotation
|
|
that walks them.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
from utils.distros import distro_names
|
|
|
|
if TYPE_CHECKING:
|
|
from collections.abc import Sequence
|
|
|
|
MODES = ("compose", "swarm", "host")
|
|
|
|
DISTROS = distro_names()
|
|
|
|
FILESYSTEMS = ("zfs", "btrfs", "ext4")
|
|
|
|
ARCHITECTURES = ("amd64", "arm64")
|
|
|
|
RUNNERS = {"amd64": "ubuntu-26.04", "arm64": "ubuntu-24.04-arm"}
|
|
"""The runner label each architecture deploys on."""
|
|
|
|
|
|
def resolve_pool(
|
|
raw: str | None, declared: Sequence[str], axis: str
|
|
) -> tuple[str, ...]:
|
|
"""The values one axis may draw from this run.
|
|
|
|
Args:
|
|
raw: the run's input, space- or comma-separated. Empty means the whole
|
|
declared set, the same way ``--modes auto`` opens the mode axis.
|
|
declared: every value the axis knows, in declaration order.
|
|
axis: what to call the axis in the refusal.
|
|
|
|
Raises:
|
|
SystemExit: a token naming no declared value. A typo has to abort the
|
|
run rather than narrow it to a set nobody asked for.
|
|
"""
|
|
tokens = (raw or "").replace(",", " ").split()
|
|
if not tokens:
|
|
return tuple(declared)
|
|
unknown = [token for token in tokens if token not in declared]
|
|
if unknown:
|
|
raise SystemExit(
|
|
f"unknown {axis}(s): {' '.join(unknown)}; expected {', '.join(declared)}"
|
|
)
|
|
return tuple(value for value in declared if value in tokens)
|
|
|
|
|
|
def resolve_distros(raw: str | None) -> tuple[str, ...]:
|
|
"""The distributions this run spreads its rows over; empty means all."""
|
|
return resolve_pool(raw, DISTROS, "distro")
|
|
|
|
|
|
def resolve_filesystems(raw: str | None) -> tuple[str, ...]:
|
|
"""The docker data-root kinds this run spreads its rows over; empty means
|
|
all."""
|
|
return resolve_pool(raw, FILESYSTEMS, "filesystem")
|
|
|
|
|
|
def resolve_architectures(raw: str | None) -> tuple[str, ...]:
|
|
"""The CPU architectures this run spreads its rows over; empty means
|
|
both."""
|
|
return resolve_pool(raw, ARCHITECTURES, "architecture")
|
|
|
|
|
|
def runner_of(architecture: str) -> str:
|
|
"""The runner label *architecture* deploys on.
|
|
|
|
Raises:
|
|
KeyError: the architecture has no label. Falling back to the amd64
|
|
runner would deploy an arm64 row on amd64 hardware and report it
|
|
green under an arm64 job title.
|
|
"""
|
|
return RUNNERS[architecture]
|
|
|
|
|
|
def rotate(pool: Sequence[str], position: int, sweep: int) -> str:
|
|
"""The value a row draws from *pool* this sweep: a plain rotation over the
|
|
row's global position, so consecutive rows spread across the pool and
|
|
consecutive sweeps move every row on to the next value."""
|
|
return pool[(position + sweep) % len(pool)]
|