3"""Stage and run declared fleet plays inside a Windows host's WSL distro."""
5from __future__
import annotations
16from dataclasses
import dataclass
17from pathlib
import Path
18from typing
import Any, Protocol
20import fleet_model
as fm
21import fleet_reach
as fr
22import fleet_typed_vars
as ftv
23import fleet_wsl_stage
as fws
27WSL_STAGE = fws.WSL_STAGE
28WSL_RUNNER_IMAGE_CACHE = fws.WSL_RUNNER_IMAGE_CACHE
29WSL_MANAGED_ROOT =
"/opt/ra8-python-tools"
30WSL_MANAGED_CACHE =
"/opt/ra8-python-tools-cache"
31WSL_ANSIBLE_PLAYBOOK =
"/opt/ra8-python-tools/bin/ansible-playbook"
32WSL_SYSTEM_PYTHON =
"/usr/bin/python3"
33APPLY_REQUIRED_STATUS = 4
34FATAL_VERIFIER_STATUS = 2
35FAKE_ANSIBLE_FAILURE_STATUS = 23
36FAKE_UV_FAILURE_STATUS = 31
37FAKE_UV_ARGV_FAILURE_STATUS = 93
40class CommandRunner(Protocol):
41 """Signature of fleet.py's streaming command runner."""
46 stdin: str | bytes |
None =
None,
47 cwd: Path |
None =
None,
49 """Run one command with optional streamed stdin and working directory."""
53def _fail(message: str) -> int:
54 """Print one transport failure and return the fleet precondition status."""
55 print(f
"fleet: error: {message}", file=sys.stderr)
59def _command_output(argv: list[str]) -> tuple[int, str]:
60 """Run a read-only probe and return its status and stripped stdout."""
61 proc = subprocess.run(
68 sys.stderr.write(proc.stderr)
69 return proc.returncode, proc.stdout.strip()
72@dataclass(frozen=True)
73class _RunnerImageTransfer:
74 """Carry one verified runner-image stream between declared fleet hosts."""
78 target: dict[str, Any]
84def _stream_runner_image(transfer: _RunnerImageTransfer) -> int:
85 """Stream one canonical archive into the WSL cache's staging path."""
86 source_ssh = transfer.source_ssh
87 target_ssh = transfer.target_ssh
88 target = transfer.target
89 distro = transfer.distro
90 source_archive = transfer.source_archive
92 source = subprocess.Popen(
93 [*source_ssh,
"/usr/bin/sudo",
"-n",
"/usr/bin/cat",
"--", source_archive],
94 stdout=subprocess.PIPE,
96 if source.stdout
is None:
98 return _fail(
"could not open the canonical archive stream")
99 receive = fws.cache_receive_command(distro)
100 sink = subprocess.Popen(
101 [*target_ssh, receive], stdin=source.stdout
103 source.stdout.close()
104 sink_rc = sink.wait()
105 source_rc = source.wait()
106 if source_rc
or sink_rc:
108 [*target_ssh, fm.remote_shell(target)],
109 stdin=fws.cache_cleanup_script(),
111 return _fail(f
"runner image stream failed (source rc={source_rc}, target rc={sink_rc})")
115def _sync_runner_image(data: dict[str, Any], name: str, run: CommandRunner) -> int:
116 """Stream the canonical runner archive into a WSL-local durable cache."""
117 image = data[
"runner_image"]
118 source_name = str(image[
"source_host"])
119 source_archive = str(image[
"archive"])
120 source_ssh = fr.ssh_target(data, source_name)
121 target_ssh = fr.ssh_target(data, name)
122 target = data[
"hosts"][name]
123 distro = str(target[
"connect"][
"distro"])
124 rc, source_line = _command_output(
125 [*source_ssh,
"/usr/bin/sudo",
"-n",
"/usr/bin/sha256sum",
"--", source_archive]
127 if rc
or not source_line:
128 return _fail(f
"cannot checksum canonical runner archive on {source_name}")
129 source_sha = source_line.split()[0]
131 [*target_ssh, fm.remote_shell(target)],
132 stdin=fws.cache_prepare_script(),
137 f
"wsl -d {shlex.quote(distro)} -u root -e /usr/bin/env -i "
138 "HOME=/root PATH=/usr/bin:/bin /usr/bin/sha256sum -- "
139 f
"{shlex.quote(WSL_RUNNER_IMAGE_CACHE)}"
141 cache_rc, cache_line = _command_output([*target_ssh, cache_probe])
142 if cache_rc == 0
and cache_line.split()[0] == source_sha:
143 print(f
"==> WSL runner image cache already matches {source_name} ({source_sha[:12]})")
145 print(f
"==> streaming canonical runner image {source_name} -> {name}")
146 transfer = _RunnerImageTransfer(
154 rc = _stream_runner_image(transfer)
158 [*target_ssh, fm.remote_shell(target)],
159 stdin=fws.cache_publish_script(source_sha),
163@dataclass(frozen=True)
165 """Describe one validated WSL converge without exposing secret values."""
171 typed_vars: ftv.TypedVars |
None
173 stage: str = WSL_STAGE
174 ansible_playbook: str = WSL_ANSIBLE_PLAYBOOK
175 system_python: str = WSL_SYSTEM_PYTHON
176 managed_root: str = WSL_MANAGED_ROOT
177 managed_cache: str = WSL_MANAGED_CACHE
180def _isolation_lines() -> list[str]:
181 """Render the inherited environment scrubbing boundary."""
184 "while IFS='=' read -r name _; do",
185 ' case "$name" in ANSIBLE_*) unset "$name" ;; esac',
186 ' case "$name" in PYTHONHOME|PYTHONPATH|PYTHONNOUSERSITE) unset "$name" ;; esac',
187 ' case "$name" in UV_*) unset "$name" ;; esac',
189 "export PYTHONNOUSERSITE=1",
193def _managed_authority_paths(stage: str) -> tuple[tuple[str, ...], tuple[str, ...]]:
194 """Return the managed directories and files proven by the WSL payload."""
198 f
"{stage}/infra/ansible",
200 f
"{stage}/.ansible/collections",
202 f
"{stage}/.tools/uv",
205 f
"{stage}/infra/ansible/ansible.cfg",
206 f
"{stage}/infra/ansible/requirements.yml",
207 f
"{stage}/pyproject.toml",
209 f
"{stage}/scripts/dev/bootstrap_uv.py",
210 f
"{stage}/scripts/dev/bootstrap_uv_exec.py",
211 f
"{stage}/scripts/dev/fleet_runner_maintenance.py",
212 f
"{stage}/scripts/dev/fleet_path_authority.py",
213 f
"{stage}/scripts/dev/uv_release.json",
214 f
"{stage}/scripts/dev/verify_locked_environment.py",
215 f
"{stage}/scripts/checks/check_ansible_collections.py",
220def _proof_function_lines() -> list[str]:
221 """Render reusable no-link, metadata, mount, and durability shell helpers."""
223 "require_real_dir() {",
224 ' [ -d "$1" ] && [ ! -L "$1" ] && [ "$(readlink -f -- "$1")" = "$1" ] || {',
225 ' echo "unsafe or missing managed directory: $1" >&2; exit 1;',
228 "require_exact_dir() {",
229 ' require_real_dir "$1"',
230 ' [ "$(stat -c %u -- "$1")" = "$authority_uid" ] &&',
231 ' [ "$(stat -c %a -- "$1")" = 755 ] || {',
232 ' echo "unsafe managed directory metadata: $1" >&2; exit 1;',
235 "require_real_file() {",
236 ' [ -f "$1" ] && [ ! -L "$1" ] && [ "$(readlink -f -- "$1")" = "$1" ] || {',
237 ' echo "unsafe or missing managed file: $1" >&2; exit 1;',
240 "require_managed_python() {",
241 ' [ -L "$1" ] && [ "$(readlink -- "$1")" = python ] || {',
242 ' echo "unsafe managed Python entry: $1" >&2; exit 1;',
244 ' python_link="$(dirname -- "$1")/python"',
245 ' [ -L "$python_link" ] && [ "$(readlink -- "$python_link")" = "$2" ] &&',
246 ' [ "$(readlink -f -- "$1")" = "$(readlink -f -- "$2")" ] || {',
247 ' echo "managed Python does not resolve to its pinned system interpreter" >&2; exit 1;',
250 "require_exact_file() {",
251 ' require_real_file "$1"',
252 ' [ "$(stat -c %a -- "$1")" = "$2" ] || {',
253 ' echo "wrong managed file mode: $1" >&2; exit 1;',
255 ' file_digest="$(sha256sum -- "$1")"',
256 ' [ "${file_digest%% *}" = "$3" ] || {',
257 ' echo "changed managed file bytes: $1" >&2; exit 1;',
261 ' ! /usr/bin/mountpoint -q -- "$1" || {',
262 ' echo "refusing managed mount point: $1" >&2; exit 1;',
266 " /usr/bin/python3 -I -S -c 'import os,sys; "
267 "f=os.open(sys.argv[1],os.O_RDONLY|os.O_NOFOLLOW); "
268 'os.fsync(f); os.close(f)\' "$1"',
271 " /usr/bin/python3 -I -S -c 'import os,sys; "
272 "f=os.open(sys.argv[1],os.O_RDONLY|os.O_DIRECTORY); "
273 'os.fsync(f); os.close(f)\' "$1"',
278def _path_proof_lines(stage: str, managed_root: str, managed_cache: str) -> list[str]:
279 """Render exact no-link checks for every executable authority."""
280 source_root = fm.REPO_ROOT
if stage == WSL_STAGE
else Path(stage)
281 bootstrap = source_root /
"scripts/dev/bootstrap_uv.py"
282 helper = source_root /
"scripts/dev/bootstrap_uv_exec.py"
283 bootstrap_digest = hashlib.sha256(bootstrap.read_bytes()).hexdigest()
284 helper_digest = hashlib.sha256(helper.read_bytes()).hexdigest()
285 paths, files = _managed_authority_paths(stage)
287 *_proof_function_lines(),
288 *[f
"require_real_dir {shlex.quote(path)}" for path
in paths],
289 *[f
"require_real_file {shlex.quote(path)}" for path
in files],
290 f
"require_exact_file {shlex.quote(stage + '/' + fws.OWNER_FILE)} 644 "
291 f
"{hashlib.sha256((fws.STAGE_OWNER + chr(10)).encode('ascii')).hexdigest()}",
292 f
"require_exact_file {shlex.quote(stage + '/scripts/dev/bootstrap_uv.py')} "
293 f
"755 {bootstrap_digest}",
294 f
"require_exact_file {shlex.quote(stage + '/scripts/dev/bootstrap_uv_exec.py')} "
295 f
"644 {helper_digest}",
296 f
"authority_uid=$(stat -c %u -- {shlex.quote(stage)})",
297 f
"managed_root={shlex.quote(managed_root)}",
298 f
"managed_cache={shlex.quote(managed_cache)}",
299 'require_real_dir "$(dirname "$managed_root")"',
300 'require_real_dir "$(dirname "$managed_cache")"',
304def _apply_environment_lines(sync_flags: str) -> list[str]:
305 """Render the mutable managed-environment half of a toolchain sync."""
307 ' if [ -e "$managed_root" ] || [ -L "$managed_root" ]; then',
308 ' require_exact_dir "$managed_root"',
309 ' refuse_mount "$managed_root"',
311 ' install -d -m 0755 -- "$managed_root"',
312 ' refuse_mount "$managed_root"',
314 ' if [ -e "$managed_cache" ] || [ -L "$managed_cache" ]; then',
315 ' require_exact_dir "$managed_cache"',
316 ' refuse_mount "$managed_cache"',
318 ' install -d -m 0755 -- "$managed_cache"',
319 ' refuse_mount "$managed_cache"',
321 ' UV_PROJECT_ENVIRONMENT="$managed_root" UV_PYTHON_DOWNLOADS=never '
322 'UV_CACHE_DIR="$managed_cache" uv_run '
327def _check_environment_lines(sync_flags: str) -> list[str]:
328 """Render safe-drift classification and read-only environment verification."""
330 ' if [ ! -e "$managed_root" ] && [ ! -L "$managed_root" ]; then',
331 f
' echo "managed WSL Python environment is missing; apply required" >&2; '
332 f
"exit {fws.REMOTE_APPLY_REQUIRED_STATUS}",
334 ' require_exact_dir "$managed_root"',
335 ' refuse_mount "$managed_root"',
336 ' lock_marker="$managed_root/.ra8-infra-lock.sha256"',
337 ' if [ ! -e "$lock_marker" ] && [ ! -L "$lock_marker" ]; then',
338 f
' echo "managed WSL Python environment is stale; apply required" >&2; '
339 f
"exit {fws.REMOTE_APPLY_REQUIRED_STATUS}",
341 ' [ -f "$lock_marker" ] && [ ! -L "$lock_marker" ] &&',
342 ' [ "$(stat -c %u -- "$lock_marker")" = "$authority_uid" ] &&',
343 ' [ "$(stat -c %a -- "$lock_marker")" = 644 ] || {',
344 ' echo "unsafe managed WSL Python environment marker" >&2; exit 1;',
346 ' if [ "$(cat "$lock_marker")" != "$authority_digest" ]; then',
347 f
' echo "managed WSL Python environment is stale; apply required" >&2; '
348 f
"exit {fws.REMOTE_APPLY_REQUIRED_STATUS}",
350 ' if [ ! -e "$managed_cache" ] && [ ! -L "$managed_cache" ]; then',
351 f
' echo "managed WSL cache is missing; apply required" >&2; '
352 f
"exit {fws.REMOTE_APPLY_REQUIRED_STATUS}",
354 ' require_exact_dir "$managed_cache"',
355 ' refuse_mount "$managed_cache"',
357 ' UV_PROJECT_ENVIRONMENT="$managed_root" UV_PYTHON_DOWNLOADS=never '
358 'UV_CACHE_DIR="$managed_cache" uv_run --offline --no-cache '
359 f
"{sync_flags} --check || sync_status=$?",
360 ' if [ "$sync_status" -eq 1 ]; then',
361 f
' echo "managed WSL Python environment differs; apply required" >&2; '
362 f
"exit {fws.REMOTE_APPLY_REQUIRED_STATUS}",
364 ' [ "$sync_status" -eq 0 ] || exit "$sync_status"',
368def _toolchain_sync_lines(stage: str, mode: str, system_python: str) -> list[str]:
369 """Render apply-only lock sync and read-only verification for other modes."""
370 if mode
not in {
"apply",
"check",
"remove"}:
371 message = f
"unsupported WSL convergence mode: {mode}"
372 raise ValueError(message)
373 bootstrap = f
"{stage}/scripts/dev/bootstrap_uv.py"
374 manifest = f
"{stage}/scripts/dev/uv_release.json"
375 uv_cache = f
"{stage}/.tools/uv"
377 f
"--no-config --directory {shlex.quote(stage)} sync --locked --only-group infra "
378 "--no-install-project "
379 f
"--python {shlex.quote(system_python)}"
382 f
"mode={shlex.quote(mode)}",
383 f
"cd {shlex.quote(stage)}",
385 f
" {shlex.quote(system_python)} {shlex.quote(bootstrap)} "
386 f
"--manifest {shlex.quote(manifest)} --cache-root {shlex.quote(uv_cache)} "
389 'authority_digest="$(sha256sum -- '
390 f
"{shlex.quote(stage + '/pyproject.toml')} {shlex.quote(stage + '/uv.lock')} "
391 f
"{shlex.quote(manifest)} {shlex.quote(stage + '/infra/ansible/requirements.yml')} "
393 "authority_digest=${authority_digest%% *}",
394 'if [ "$mode" = apply ]; then',
395 *_apply_environment_lines(sync_flags),
397 *_check_environment_lines(sync_flags),
402def _toolchain_verify_lines(stage: str, ansible_playbook: str, system_python: str) -> list[str]:
403 """Render exact-set, collection, and durable-authority verification."""
404 verifier = f
"{stage}/scripts/dev/verify_locked_environment.py"
405 collection_checker = f
"{stage}/scripts/checks/check_ansible_collections.py"
407 f
'require_managed_python "$managed_root/bin/python3" {shlex.quote(system_python)}',
408 f
"require_real_file {shlex.quote(ansible_playbook)}",
409 'require_real_file "$managed_root/bin/ansible-galaxy"',
411 " pipeline_status=(0 0)",
412 " uv_run --no-config --directory "
414 +
" export --locked --offline --only-group infra "
415 "--no-emit-project --no-header | "
416 '"$managed_root/bin/python3" '
417 + shlex.quote(verifier)
418 +
' /dev/stdin || pipeline_status=("${PIPESTATUS[@]}")',
419 ' [ "${pipeline_status[0]}" -eq 0 ] || exit "${pipeline_status[0]}"',
420 ' if [ "${pipeline_status[1]}" -eq 1 ] && [ "$mode" = check ]; then',
421 f
' echo "managed WSL package set differs; apply required" >&2; '
422 f
"exit {fws.REMOTE_APPLY_REQUIRED_STATUS}",
424 ' [ "${pipeline_status[1]}" -eq 0 ] || exit "${pipeline_status[1]}"',
426 "ANSIBLE_COLLECTIONS_PATH=" + shlex.quote(stage +
"/.ansible/collections") +
" "
427 '"$managed_root/bin/ansible-galaxy" collection list --format json | '
428 '"$managed_root/bin/python3" '
429 + shlex.quote(collection_checker)
431 + shlex.quote(stage +
"/.ansible/collections"),
432 'if [ "$mode" = apply ]; then',
433 ' marker="$managed_root/.ra8-infra-lock.sha256.tmp.$$"',
434 " trap 'rm -f -- \"$marker\"' EXIT",
435 ' printf \'%s\\n\' "$authority_digest" >"$marker"',
436 ' chmod 0644 "$marker"',
437 ' mv -f -- "$marker" "$managed_root/.ra8-infra-lock.sha256"',
438 ' sync_file "$managed_root/.ra8-infra-lock.sha256"',
439 ' sync_dir "$managed_root"',
442 f
"cd {shlex.quote(stage + '/infra/ansible')}",
443 'export ANSIBLE_CONFIG="$PWD/ansible.cfg"',
444 'export ANSIBLE_COLLECTIONS_PATH="$PWD/../../.ansible/collections"',
445 "export ANSIBLE_COLLECTIONS_SCAN_SYS_PATH=false",
449def _ansible_environment_lines(spec: ConvergeSpec) -> list[str]:
450 """Render the exact remote managed-tool and Ansible boundary."""
453 *_path_proof_lines(spec.stage, spec.managed_root, spec.managed_cache),
454 *_toolchain_sync_lines(spec.stage, spec.mode, spec.system_python),
455 *_toolchain_verify_lines(spec.stage, spec.ansible_playbook, spec.system_python),
459def render_converge(spec: ConvergeSpec) -> tuple[str, list[str]]:
460 """Render the stdin script and secret-free summaries for a WSL converge."""
465 typed_vars = spec.typed_vars
467 ansible_playbook = spec.ansible_playbook
468 role_variables = fm.role_vars(data, name, data[
"hosts"][name])
469 role_variables[
"ci_runner_docker_image_source_local_archive"] = WSL_RUNNER_IMAGE_CACHE
470 role_variables[
"fleet_capacity_state_group"] =
"root"
471 lines = _ansible_environment_lines(spec)
472 if typed_vars
is not None:
473 encoded = base64.b64encode(typed_vars.content).decode(
"ascii")
474 lines.extend([
"trap 'exit 130' INT",
"trap 'exit 143' TERM HUP"])
475 if spec.mode ==
"check":
478 "exec {ra8_vars_fd}< <(base64 -d <<'RA8_TYPED_VARS_EOF'",
479 *textwrap.wrap(encoded, width=76),
480 "RA8_TYPED_VARS_EOF",
482 'typed_args=(-e "@/dev/fd/$ra8_vars_fd")',
489 f
'ra8_vars_file="$(mktemp {shlex.quote(stage + "/.ansible-vars.XXXXXX")})"',
490 'cleanup_ra8_vars() { rm -f -- "$ra8_vars_file"; }',
491 "trap cleanup_ra8_vars EXIT",
492 "base64 -d >\"$ra8_vars_file\" <<'RA8_TYPED_VARS_EOF'",
493 *textwrap.wrap(encoded, width=76),
494 "RA8_TYPED_VARS_EOF",
495 'typed_args=(-e "@$ra8_vars_file")',
499 lines.append(
"typed_args=()")
500 summaries: list[str] = []
502 playbook = fm.PLAYS[play].playbook
505 "--connection=local",
508 f
"playbooks/{playbook}",
510 json.dumps(role_variables),
512 f
"wsl_ci_host_id={name}",
514 f
"fleet_capacity_src={stage}/scripts/ci/fleet_capacity.sh",
517 lines.append(shlex.join(argv) +
' "${typed_args[@]}"')
518 summaries.append(f
"ansible-playbook {playbook} (WSL host {name})")
519 return "\n".join(lines) +
"\n", summaries
527 """Stage and run WSL plays without putting secret values in process argv."""
530 host = data[
"hosts"][name]
532 if spec.mode ==
"check":
533 rc = fws.verify_stage_sources(
"check")
535 generation = fws.stage_generation()
537 rc, generation = fws.prepare(data, name, spec.mode, run)
541 rc = _sync_runner_image(data, name, run)
544 [*fr.ssh_target(data, name), fm.remote_shell(host)],
545 stdin=fws.stage_cleanup_script(),
548 converge_script, summaries = render_converge(spec)
549 prefix = [
"set -euo pipefail", *fws.transaction_lock_lines(spec.mode !=
"check")]
550 if spec.mode ==
"check":
551 prefix.extend(fws.stage_probe_lines(generation))
553 prefix.append(fws.stage_publish_script(generation=generation))
554 script =
"\n".join([*prefix, converge_script])
555 for summary
in summaries:
556 print(f
"==> {summary}")
557 rc = run([*fr.ssh_target(data, name), fm.remote_shell(host)], stdin=script)
558 if spec.mode !=
"check":
560 [*fr.ssh_target(data, name), fm.remote_shell(host)],
561 stdin=fws.stage_cleanup_script(),
563 if spec.mode ==
"check" and rc == fws.REMOTE_APPLY_REQUIRED_STATUS:
564 return APPLY_REQUIRED_STATUS
568@dataclass(frozen=True)
569class _SelftestFixture:
570 """Paths used to observe one offline WSL transport simulation."""
582 hostile_executed: Path
585def _write_executable(path: Path, source: str) ->
None:
586 """Write one executable selftest helper."""
587 path.write_text(source, encoding=
"ascii")
591def _remote_boundary_selftest(data: dict[str, Any], root: Path) -> list[str]:
592 """Prove BASH_ENV cannot execute before the streamed WSL payload."""
593 failures: list[str] = []
594 marker = root /
"bash-env-ran"
595 startup = root /
"hostile-bash-env"
596 startup.write_text(f
"touch {shlex.quote(str(marker))}\n", encoding=
"ascii")
597 boundary = fm.remote_shell(data[
"hosts"][
"win-ci"])
598 expected =
"-u root -e /usr/bin/env -i HOME=/root PATH=/usr/bin:/bin /bin/bash -s"
599 if expected
not in boundary:
600 failures.append(
"WSL actual remote boundary is not env-empty before Bash")
601 result = subprocess.run(
606 "PATH=/usr/bin:/bin",
611 env={
"BASH_ENV": str(startup),
"PATH":
"/hostile"},
615 if result.returncode
or marker.exists():
616 failures.append(
"env-empty Bash boundary executed hostile BASH_ENV")
620def _write_stage_authorities(stage: Path) ->
None:
621 """Create the exact authority shape consumed by the rendered shell."""
622 (stage /
"infra" /
"ansible").mkdir(parents=
True)
623 (stage /
".ansible" /
"collections").mkdir(parents=
True)
624 (stage /
".tools" /
"uv").mkdir(parents=
True)
625 for relative, content
in (
626 (
"infra/ansible/ansible.cfg",
"[defaults]\n"),
627 (
"infra/ansible/requirements.yml",
"collections: []\n"),
628 (
"pyproject.toml",
"[project]\nname='fixture'\n"),
629 (
"uv.lock",
"version = 1\n"),
630 (
"scripts/dev/bootstrap_uv.py",
"# fixture\n"),
631 (
"scripts/dev/bootstrap_uv_exec.py",
"# fixture\n"),
632 (
"scripts/dev/fleet_runner_maintenance.py",
"# fixture\n"),
633 (
"scripts/dev/fleet_path_authority.py",
"# fixture\n"),
634 (
"scripts/dev/uv_release.json",
"{}\n"),
635 (
"scripts/dev/verify_locked_environment.py",
"# fixture\n"),
636 (
"scripts/checks/check_ansible_collections.py",
"# fixture\n"),
638 path = stage / relative
639 path.parent.mkdir(parents=
True, exist_ok=
True)
640 path.write_text(content, encoding=
"ascii")
641 (stage /
"scripts/dev/bootstrap_uv.py").chmod(0o755)
642 (stage /
"scripts/dev/bootstrap_uv_exec.py").chmod(0o644)
643 (stage / fws.OWNER_FILE).write_text(f
"{fws.STAGE_OWNER}\n", encoding=
"ascii")
646def _write_fake_toolchain(root: Path, fixture: _SelftestFixture) ->
None:
647 """Create fake uv/Python/Ansible programs with observation logs."""
648 managed_bin = fixture.managed_root /
"bin"
649 managed_bin.mkdir(parents=
True)
650 fake_uv = root /
"verified-uv"
652 fixture.system_python,
653 "#!/usr/bin/env bash\nset -eu\n"
654 '[ -z "${UV_CONFIG_FILE:-}" ]\n[ -z "${UV_INDEX_URL:-}" ]\n'
656 " *verify_locked_environment.py) "
657 'printf \'%s\\n\' "$*" >>"$RA8_TEST_PYTHON_LOG"; cat >/dev/null; '
658 'exit "${RA8_TEST_VERIFY_STATUS:-0}" ;;\n'
659 " *check_ansible_collections.py) "
660 'printf \'%s\\n\' "$*" >>"$RA8_TEST_PYTHON_LOG"; cat >/dev/null; exit 0 ;;\n'
662 '[ "$1" = "$RA8_TEST_STAGE/scripts/dev/bootstrap_uv.py" ]\nshift\n'
663 '[ "$1" = --manifest ]\n'
664 '[ "$2" = "$RA8_TEST_STAGE/scripts/dev/uv_release.json" ]\nshift 2\n'
665 '[ "$1" = --cache-root ]\n'
666 '[ "$2" = "$RA8_TEST_STAGE/.tools/uv" ]\nshift 2\n'
667 '[ "$1" = --run ]\nshift\n(($#))\n'
668 'exec "$RA8_TEST_UV" "$@"\n',
672 "#!/usr/bin/python3\n"
675 "from pathlib import Path\n"
676 "stage = os.environ['RA8_TEST_STAGE']\n"
677 "args = sys.argv[1:]\n"
678 "if Path.cwd().resolve() != Path(stage).resolve():\n"
679 " raise SystemExit(92)\n"
680 "base = ['--no-config', '--directory', stage]\n"
681 "system_python = os.environ['RA8_TEST_SYSTEM_PYTHON']\n"
682 "sync = [*base, 'sync', '--locked', '--only-group', 'infra', "
683 "'--no-install-project', '--python', system_python]\n"
684 "check = ['--offline', '--no-cache', *sync, '--check']\n"
685 "export = [*base, 'export', '--locked', '--offline', '--only-group', "
686 "'infra', '--no-emit-project', '--no-header']\n"
687 "if args not in (sync, check, export):\n"
688 f
" raise SystemExit({FAKE_UV_ARGV_FAILURE_STATUS})\n"
689 "operation = 'export' if args == export else 'sync'\n"
690 "with Path(os.environ['RA8_TEST_UV_LOG']).open('a', encoding='ascii') as stream:\n"
691 " stream.write('|'.join(args) + '\\n')\n"
692 "if os.environ.get('RA8_TEST_UV_FAIL') == operation:\n"
693 f
" raise SystemExit({FAKE_UV_FAILURE_STATUS})\n"
694 "if os.environ.get('RA8_TEST_UV_FAIL') == 'sync-drift' and args == check:\n"
695 " raise SystemExit(1)\n"
696 "if operation == 'export':\n"
697 " for index in range(10):\n"
698 " print(f'package-{index}==1.{index} \\\\')\n"
699 " print(f' --hash=sha256:{index:064d}')\n",
701 (managed_bin /
"python").symlink_to(fixture.system_python)
702 (managed_bin /
"python3").symlink_to(
"python")
703 galaxy = managed_bin /
"ansible-galaxy"
704 _write_executable(galaxy,
"#!/usr/bin/env bash\nprintf '{}\\n'\n")
707def _write_fake_playbook(fixture: _SelftestFixture, sentinel: str) ->
None:
708 """Create the managed failing Ansible executable used by the transport test."""
709 fake = fixture.managed_root /
"bin" /
"ansible-playbook"
712 "#!/usr/bin/env bash\nset -eu\n"
713 ': >"$RA8_TEST_ARGS"\nvars_file=\nfor arg in "$@"; do\n'
714 ' printf \'%s\\n\' "$arg" >>"$RA8_TEST_ARGS"\n'
715 ' case "$arg" in @*) vars_file=${arg#@} ;; esac\ndone\n'
716 '[ -n "$vars_file" ]\n'
717 'printf \'%s\\n\' "$vars_file" >"$RA8_TEST_VARS_PATH"\n'
718 'stat -c \'%a\' "$vars_file" >"$RA8_TEST_MODE"\n'
719 '[ "$ANSIBLE_CONFIG" = "$PWD/ansible.cfg" ]\n'
720 '[ "$ANSIBLE_COLLECTIONS_PATH" = "$PWD/../../.ansible/collections" ]\n'
721 '[ "$ANSIBLE_COLLECTIONS_SCAN_SYS_PATH" = false ]\n'
722 '[ "$PYTHONNOUSERSITE" = 1 ]\n'
723 '[ -z "${PYTHONHOME:-}" ]\n[ -z "${PYTHONPATH:-}" ]\n'
724 '[ -z "${ANSIBLE_ROLES_PATH:-}" ]\n'
725 f
'grep -q {shlex.quote(sentinel)} "$vars_file"\n'
726 f
"exit {FAKE_ANSIBLE_FAILURE_STATUS}\n",
730def _make_fixture(root: Path, sentinel: str) -> _SelftestFixture:
731 """Create a fake failing Ansible executable and its observation paths."""
732 stage = root /
"stage with spaces"
733 _write_stage_authorities(stage)
734 managed_root = root /
"managed tools"
735 managed_cache = root /
"managed cache" /
"uv"
736 managed_cache.mkdir(parents=
True)
737 system_bin = root /
"system"
739 fixture = _SelftestFixture(
743 system_bin /
"python3",
745 root /
"vars-path.log",
749 root /
"SHOULD_NOT_EXIST",
750 root /
"HOSTILE_PATH_RAN",
752 _write_fake_toolchain(root, fixture)
753 _write_fake_playbook(fixture, sentinel)
754 hostile_bin = root /
"hostile"
757 hostile_bin /
"ansible-playbook",
758 f
"#!/bin/sh\ntouch {shlex.quote(str(fixture.hostile_executed))}\nexit 99\n",
765 fixture: _SelftestFixture,
766 uv_failure: str =
"",
767 expected_system_python: str =
"",
768 verifier_status: int = 0,
769) -> subprocess.CompletedProcess[str]:
770 """Run the offline WSL shell with only a fake Ansible executable."""
773 "PATH": f
"{fixture.stage.parent / 'hostile'}:/usr/bin:/bin",
774 "RA8_TEST_ARGS": str(fixture.args_log),
775 "RA8_TEST_SYSTEM_PYTHON": expected_system_python
or str(fixture.system_python),
776 "RA8_TEST_VARS_PATH": str(fixture.vars_path_log),
777 "RA8_TEST_MODE": str(fixture.mode_log),
778 "RA8_TEST_UV": str(fixture.stage.parent /
"verified-uv"),
779 "RA8_TEST_UV_LOG": str(fixture.uv_log),
780 "RA8_TEST_UV_FAIL": uv_failure,
781 "RA8_TEST_VERIFY_STATUS": str(verifier_status),
782 "RA8_TEST_STAGE": str(fixture.stage),
783 "RA8_TEST_PYTHON_LOG": str(fixture.python_log),
784 "ANSIBLE_CONFIG": str(fixture.stage.parent /
"hostile.cfg"),
785 "ANSIBLE_ROLES_PATH": str(fixture.stage.parent /
"hostile-roles"),
786 "PYTHONHOME": str(fixture.stage.parent /
"hostile-python-home"),
787 "PYTHONPATH": str(fixture.stage.parent /
"hostile-python-path"),
788 "UV_CONFIG_FILE": str(fixture.stage.parent /
"hostile-uv.toml"),
789 "UV_INDEX_URL":
"https://hostile.invalid/simple",
791 return subprocess.run(
792 [
"/bin/bash"], input=script, text=
True, env=env, capture_output=
True, check=
False
797 result: subprocess.CompletedProcess[str],
798 fixture: _SelftestFixture,
801 expected_mode: str =
"600",
803 """Check argv integrity, mode, redaction, and cleanup after fake failure."""
804 if result.returncode != FAKE_ANSIBLE_FAILURE_STATUS:
806 f
"fake failing Ansible returned {result.returncode}, "
807 f
"expected {FAKE_ANSIBLE_FAILURE_STATUS}"
810 failures: list[str] = []
811 argv_text = fixture.args_log.read_text(encoding=
"utf-8")
812 if attack
not in argv_text.splitlines()
or fixture.injected_path.exists():
813 failures.append(
"WSL argument quoting did not preserve a metacharacter-bearing tag")
814 if sentinel
in argv_text:
815 failures.append(
"WSL secret appeared in ansible-playbook argv")
816 if '"fleet_capacity_state_group": "root"' not in argv_text:
817 failures.append(
"WSL capacity state group did not bind to its root executor")
818 remote_vars = Path(fixture.vars_path_log.read_text(encoding=
"utf-8").strip())
819 if fixture.mode_log.read_text(encoding=
"utf-8").strip() != expected_mode:
820 failures.append(f
"WSL temporary vars transport was not mode 0{expected_mode}")
821 if remote_vars.exists():
822 failures.append(
"WSL temporary vars transport survived Ansible failure")
823 if fixture.hostile_executed.exists():
824 failures.append(
"WSL used a hostile PATH ansible-playbook")
829 data: dict[str, Any], fixture: _SelftestFixture, typed: ftv.TypedVars, attack: str, mode: str
830) -> tuple[str, list[str]]:
831 """Render one offline WSL converge against only fixture-owned paths."""
840 str(fixture.managed_root /
"bin" /
"ansible-playbook"),
841 str(fixture.system_python),
842 str(fixture.managed_root),
843 str(fixture.managed_cache),
845 return render_converge(spec)
848def _environment_drift_selftest(check_script: str, fixture: _SelftestFixture) -> list[str]:
849 """Prove only safely authenticated environment drift requests apply."""
850 failures: list[str] = []
851 sync_drift = _run_script(check_script, fixture,
"sync-drift")
852 if sync_drift.returncode != fws.REMOTE_APPLY_REQUIRED_STATUS:
853 failures.append(
"safe WSL sync drift was not classified apply-required")
854 package_drift = _run_script(check_script, fixture, verifier_status=1)
855 if package_drift.returncode != fws.REMOTE_APPLY_REQUIRED_STATUS:
856 failures.append(
"safe WSL package drift was not classified apply-required")
857 verifier_failure = _run_script(check_script, fixture, verifier_status=FATAL_VERIFIER_STATUS)
858 if verifier_failure.returncode != FATAL_VERIFIER_STATUS:
859 failures.append(
"fatal WSL package authentication failure was classified as drift")
860 marker = fixture.managed_root /
".ra8-infra-lock.sha256"
862 unsafe = _run_script(check_script, fixture)
864 if unsafe.returncode != 1:
865 failures.append(
"unsafe WSL environment marker was classified as drift")
869def _toolchain_mode_selftest(
870 data: dict[str, Any], fixture: _SelftestFixture, typed: ftv.TypedVars, attack: str
871) -> tuple[list[str], str, list[str], str]:
872 """Exercise apply sync, check-only verification, and uv failure handling."""
873 failures: list[str] = []
874 apply_script, summaries = _render_fixture(data, fixture, typed, attack,
"apply")
875 apply_result = _run_script(apply_script, fixture)
876 failures.extend(_check_result(apply_result, fixture, attack,
"fleet-secret-sentinel"))
877 marker = fixture.managed_root /
".ra8-infra-lock.sha256"
878 if not marker.is_file()
or marker.is_symlink():
879 failures.append(
"WSL apply did not publish its exact lock marker")
880 check_script, _ = _render_fixture(data, fixture, typed, attack,
"check")
881 check_result = _run_script(check_script, fixture)
882 if list(fixture.managed_root.glob(
".ra8-infra-export.*")):
883 failures.append(
"WSL check left a durable lock-export file")
884 if ".ra8-infra-export." in check_script
or '>"$locked_export"' in check_script:
885 failures.append(
"WSL check still renders a durable lock-export write")
891 "fleet-secret-sentinel",
895 if fixture.uv_log.is_file():
898 for line
in fixture.uv_log.read_text(encoding=
"ascii").splitlines()
901 expected_sync_calls = 2
903 len(sync_calls) != expected_sync_calls
904 or "--check" in sync_calls[0]
905 or "--check" not in sync_calls[1]
908 "WSL apply/check modes did not preserve sync versus verify-only behavior"
911 failures.append(
"WSL apply/check did not invoke the authenticated uv fixture")
912 hardcoded_python = _run_script(
915 expected_system_python=
"/usr/bin/python3",
917 if hardcoded_python.returncode != FAKE_UV_ARGV_FAILURE_STATUS:
919 "WSL did not reject a hardcoded system Python path: "
920 f
"expected {FAKE_UV_ARGV_FAILURE_STATUS}, got "
921 f
"{hardcoded_python.returncode}"
923 sync_failure = _run_script(apply_script, fixture,
"sync")
924 if sync_failure.returncode != FAKE_UV_FAILURE_STATUS:
925 failures.append(
"WSL masked an authenticated uv sync failure")
926 export_failure = _run_script(check_script, fixture,
"export")
927 if export_failure.returncode != FAKE_UV_FAILURE_STATUS:
928 failures.append(
"WSL masked an authenticated uv export failure")
929 return failures, apply_script, summaries, check_script
932def _toolchain_authority_selftest(
933 fixture: _SelftestFixture,
934 mode_result: tuple[list[str], str, list[str], str],
935) -> tuple[list[str], str, list[str]]:
936 """Exercise bootstrap-helper identity and staged-config link rejection."""
937 failures, apply_script, summaries, check_script = mode_result
938 failures.extend(_environment_drift_selftest(check_script, fixture))
940 helper = fixture.stage /
"scripts/dev/bootstrap_uv_exec.py"
942 wrong_mode = _run_script(check_script, fixture)
943 if wrong_mode.returncode == FAKE_ANSIBLE_FAILURE_STATUS:
944 failures.append(
"WSL accepted a wrong-mode bootstrap execution helper")
946 original_helper = helper.read_bytes()
947 helper.write_bytes(original_helper + b
"changed\n")
948 changed_helper = _run_script(check_script, fixture)
949 if changed_helper.returncode == FAKE_ANSIBLE_FAILURE_STATUS:
950 failures.append(
"WSL accepted changed bootstrap execution-helper bytes")
951 helper.write_bytes(original_helper)
954 config = fixture.stage /
"infra" /
"ansible" /
"ansible.cfg"
955 real_config = config.with_name(
"real.cfg")
956 config.rename(real_config)
957 config.symlink_to(real_config)
958 linked_result = _run_script(check_script, fixture)
959 if linked_result.returncode == FAKE_ANSIBLE_FAILURE_STATUS:
960 failures.append(
"WSL accepted a symlinked staged Ansible config")
961 return failures, apply_script, summaries
964def _toolchain_selftest(
965 data: dict[str, Any], fixture: _SelftestFixture, typed: ftv.TypedVars, attack: str
966) -> tuple[list[str], str, list[str]]:
967 """Exercise managed-tool modes and authority rejection in original order."""
968 mode_result = _toolchain_mode_selftest(data, fixture, typed, attack)
969 return _toolchain_authority_selftest(fixture, mode_result)
972def run_selftest(data: dict[str, Any]) -> list[str]:
973 """Exercise quoted WSL transport, redaction, and failure cleanup."""
974 sentinel =
"fleet-secret-sentinel"
975 content = f
"ci_runner_docker_registration_token: {sentinel}\n".encode()
976 typed = ftv.TypedVars(Path(
"/captured/registration.yml"), content)
977 stage_failures = fws.run_selftest()
978 with tempfile.TemporaryDirectory(prefix=
"ra8-fleet-wsl-")
as scratch:
979 fixture = _make_fixture(Path(scratch), sentinel)
980 attack = f
"capacity; touch {fixture.injected_path}"
981 failures, script, summaries = _toolchain_selftest(data, fixture, typed, attack)
982 if not fixture.uv_log.is_file():
983 failures.append(
"WSL managed-tool mode selftest did not execute")
984 config = fixture.stage /
"infra" /
"ansible" /
"ansible.cfg"
985 if not config.is_symlink():
986 failures.append(
"WSL managed-authority selftest did not execute")
987 failures.extend(_remote_boundary_selftest(data, Path(scratch)))
988 failures[:0] = stage_failures
989 encoded = base64.b64encode(content).decode(
"ascii")
990 summary =
"\n".join(summaries)
991 if sentinel
in script
or sentinel
in summary
or encoded
in summary:
992 failures.append(
"WSL secret appeared in raw script text or rendered summaries")