Publish curated Unraid-AppOps-Gateway source from 1e4c6557cffe03959a4837cda9bc9ad6b35cf6bc

This commit is contained in:
Public Source Publisher committed 2026-10-13 09:08:00 +00:00
1 parent 3edb084a91
commit 28f691b77e
3 files changed
+158 -6

No files matched your search

+1 -1
View File
@@ -1,3 +1,3 @@
# Public source export # Public source export
This source snapshot was generated from the private canonical repository at revision `d013be0be977c530311fae02934026709d8a952f`. It contains no private Git history or operational evidence. Changes are published from the canonical repository. This source snapshot was generated from the private canonical repository at revision `1e4c6557cffe03959a4837cda9bc9ad6b35cf6bc`. It contains no private Git history or operational evidence. Changes are published from the canonical repository.
+3 -3
View File
@@ -1,6 +1,6 @@
{ {
"schemaVersion": 1, "schemaVersion": 1,
"sourceRevision": "d013be0be977c530311fae02934026709d8a952f", "sourceRevision": "1e4c6557cffe03959a4837cda9bc9ad6b35cf6bc",
"files": [ "files": [
{ {
"path": ".dockerignore", "path": ".dockerignore",
@@ -1619,8 +1619,8 @@
}, },
{ {
"path": "backend/tests/test_runner_build_launcher_refresh.py", "path": "backend/tests/test_runner_build_launcher_refresh.py",
"sha256": "887c1efb5a51e4c63eecd09a7927dfa4048e66a0dce4ceaf77b11f49f59eae5c", "sha256": "2268e8e71c8c049cfc8d98539ab09cd6db1db4acefdd7ab00187410fbc57641a",
"bytes": 22199 "bytes": 30038
}, },
{ {
"path": "backend/tests/test_runner_capacity_controller.py", "path": "backend/tests/test_runner_capacity_controller.py",
@@ -122,7 +122,7 @@ def launcher(monkeypatch, tmp_path):
monkeypatch.setattr(module, "_guard_state_unchanged", lambda _j: True) monkeypatch.setattr(module, "_guard_state_unchanged", lambda _j: True)
monkeypatch.setattr(module, "_fresh_recovery_host_gate", lambda: None) monkeypatch.setattr(module, "_fresh_recovery_host_gate", lambda: None)
monkeypatch.setattr(module, "_resource_proof", lambda *_a: {"ready": True}) monkeypatch.setattr(module, "_resource_proof", lambda *_a: {"ready": True})
monkeypatch.setattr(module, "verify_profile_task_images", lambda *_a: True) monkeypatch.setattr(module, "verify_profile_task_images", lambda *_a, **_k: True)
monkeypatch.setattr( monkeypatch.setattr(
module, module,
"verified_topology", "verified_topology",
@@ -181,7 +181,10 @@ def launcher(monkeypatch, tmp_path):
if args[:3] == ["docker", "image", "inspect"]: if args[:3] == ["docker", "image", "inspect"]:
return json.dumps([{"Id": args[-1]}]) return json.dumps([{"Id": args[-1]}])
if args[:2] == ["docker", "inspect"]: if args[:2] == ["docker", "inspect"]:
result = [item for item in containers.values() if item["Id"] == args[-1]] result = [
item for name, item in containers.items()
if name in args[2:] or item["Id"] in args[2:]
]
if not result: if not result:
raise module.RunnerFleetSpecializeError( raise module.RunnerFleetSpecializeError(
"runner_fleet_specialization_command_failed" "runner_fleet_specialization_command_failed"
@@ -230,6 +233,155 @@ def launcher(monkeypatch, tmp_path):
return module, containers, rows, admission, effects, model return module, containers, rows, admission, effects, model
def test_refresh_uses_real_outer_image_postcondition_in_created_phase(launcher, monkeypatch):
module, containers, rows, _, _, _ = launcher
before = copy.deepcopy(containers)
registrations = copy.deepcopy(rows)
monkeypatch.setattr(
module, "verify_profile_task_images",
lambda profiles, **kwargs: module._verify_specialized_outer_images(profiles, **kwargs),
)
preflight = module._build_launcher_preflight("refresh")
result = module._apply_build_launcher("refresh", preflight["preflightSha256"])
assert result["status"] == "applied"
assert rows == registrations
for name in before:
if name != "itworx-ci-build":
assert containers[name] == before[name]
@pytest.mark.parametrize("change", [
"forged_receipt", "partial_profiles", "changed_release", "wrong_stage",
"running_candidate", "foreign_candidate_id", "wrong_candidate_image",
"wrong_operation_label", "changed_mount", "running_backup", "changed_other_limit",
])
def test_created_launcher_scope_rejects_drift_and_keeps_normal_admission_blocked(launcher, monkeypatch, change):
module, containers, _, _, effects, _ = launcher
def checked(profiles, **kwargs):
receipt = module._build_launcher_receipt()
if receipt is None or receipt["status"] != "created":
return module._verify_specialized_outer_images(profiles, **kwargs)
assert module._verify_specialized_outer_images(profiles) is False
assert module.verified_topology()["ready"] is False
assert module._verify_specialized_outer_images(profiles, **kwargs) is True
original_containers = copy.deepcopy(containers)
original_receipt = copy.deepcopy(receipt)
release = sys.modules["status_server"]._require_controller_release()
original_release = copy.deepcopy(release)
effects_before = copy.deepcopy(effects)
candidate = containers["itworx-ci-build"]
scoped = dict(kwargs)
selected = profiles
if change == "forged_receipt":
scoped["pending_build_launcher"] = {**receipt, "operationId": "9" * 64}
elif change == "partial_profiles":
selected = ("build",)
elif change == "changed_release":
release["sourceRevision"] = "9" * 40
elif change == "wrong_stage":
modified = {**receipt, "status": "prepared"}
module._write_private_atomic(module._build_launcher_receipt_path(), module._canonical_bytes(modified))
scoped["pending_build_launcher"] = modified
elif change == "running_candidate":
candidate["State"]["Running"] = True
elif change == "foreign_candidate_id":
candidate["Id"] = "9" * 64
elif change == "wrong_candidate_image":
candidate["Image"] = module.RUNNER_IMAGE_ID
elif change == "wrong_operation_label":
candidate["Config"]["Labels"]["tech.itworx.ci.launcher-operation"] = "9" * 64
elif change == "changed_mount":
candidate["Mounts"][1]["RW"] = True
elif change == "running_backup":
containers[receipt["backupName"]]["State"]["Running"] = True
else:
containers["itworx-ci-backend"]["HostConfig"]["Memory"] += 1
try:
assert module._verify_specialized_outer_images(selected, **scoped) is False
assert effects == effects_before
finally:
containers.clear()
containers.update(original_containers)
release.clear()
release.update(original_release)
module._write_private_atomic(module._build_launcher_receipt_path(), module._canonical_bytes(original_receipt))
return module._verify_specialized_outer_images(profiles, **kwargs)
monkeypatch.setattr(module, "verify_profile_task_images", checked)
preflight = module._build_launcher_preflight("refresh")
result = module._apply_build_launcher("refresh", preflight["preflightSha256"])
assert result["status"] == "applied"
def test_final_created_snapshot_refuses_other_runner_identity_change(launcher, monkeypatch):
module, containers, _, _, _, _ = launcher
def check_then_drift(profiles, **kwargs):
valid = module._verify_specialized_outer_images(profiles, **kwargs)
if kwargs.get("pending_build_launcher") is not None:
containers["itworx-ci-backend"]["Id"] = "9" * 64
return valid
monkeypatch.setattr(module, "verify_profile_task_images", check_then_drift)
preflight = module._build_launcher_preflight("refresh")
with pytest.raises(module.RunnerFleetSpecializeError, match="runner_build_launcher_outcome_unknown"):
module._apply_build_launcher("refresh", preflight["preflightSha256"])
assert module._build_launcher_receipt()["status"] == "rollback_unknown"
receipt = module._build_launcher_receipt()
diagnostic = json.loads((module.SPECIALIZED_STATE_ROOT / ("build-launcher-failure-" + receipt["operationId"] + ".json")).read_bytes())
assert diagnostic["failureStage"] == "final_fences"
assert diagnostic["failureCode"] == "runner_build_launcher_recovery_fleet_changed"
@pytest.mark.parametrize("failure,expected_code", [
("runner_build_launcher_postcondition_failed", "runner_build_launcher_postcondition_failed"),
("synthetic_private_detail_not_for_receipts", "runner_build_launcher_internal_failure"),
])
def test_private_rollback_diagnostics_retain_only_finite_codes(launcher, monkeypatch, failure, expected_code):
module, _, _, _, _, _ = launcher
def fail_after_creation(_profiles, **kwargs):
if kwargs.get("pending_build_launcher") is not None:
raise RuntimeError(failure)
return True
monkeypatch.setattr(module, "verify_profile_task_images", fail_after_creation)
preflight = module._build_launcher_preflight("refresh")
with pytest.raises(module.RunnerFleetSpecializeError, match="runner_build_launcher_failed_rolled_back"):
module._apply_build_launcher("refresh", preflight["preflightSha256"])
receipt = module._build_launcher_receipt()
assert receipt["status"] == "rolled_back"
diagnostic = json.loads((module.SPECIALIZED_STATE_ROOT / ("build-launcher-failure-" + receipt["operationId"] + ".json")).read_bytes())
assert diagnostic["failureStage"] == "task_images"
assert diagnostic["failureCode"] == expected_code
assert "failureStage" not in receipt and "failureCode" not in receipt
assert "synthetic_private_detail_not_for_receipts" not in module._build_launcher_receipt_path().read_text()
def test_diagnostic_storage_failure_does_not_prevent_guarded_rollback(launcher, monkeypatch):
module, containers, _, _, _, _ = launcher
before = copy.deepcopy(containers)
original_write = module._write_private_atomic
def write_without_diagnostics(path, raw):
if path.name.startswith("build-launcher-failure-"):
raise OSError("synthetic_private_storage_detail")
original_write(path, raw)
def fail_after_creation(_profiles, **kwargs):
return kwargs.get("pending_build_launcher") is None
monkeypatch.setattr(module, "_write_private_atomic", write_without_diagnostics)
monkeypatch.setattr(module, "verify_profile_task_images", fail_after_creation)
preflight = module._build_launcher_preflight("refresh")
with pytest.raises(module.RunnerFleetSpecializeError, match="runner_build_launcher_failed_rolled_back"):
module._apply_build_launcher("refresh", preflight["preflightSha256"])
assert module._build_launcher_receipt()["status"] == "rolled_back"
assert containers == before
assert not list(module.SPECIALIZED_STATE_ROOT.glob("build-launcher-failure-*.json"))
def test_refresh_and_explicit_rollback_preserve_fleet_and_archived_model(launcher): def test_refresh_and_explicit_rollback_preserve_fleet_and_archived_model(launcher):
module, containers, rows, _, effects, model = launcher module, containers, rows, _, effects, model = launcher
before = copy.deepcopy(containers) before = copy.deepcopy(containers)