Publish curated Unraid-AppOps-Gateway source from a506550ef83ef2d81651e37c98a89f7ee330c730
This commit is contained in:
1 parent
2facb8de34
commit
767e66921e
68 files changed
+15924
-313
No files matched your search
@@ -57,6 +57,109 @@ def test_only_the_exact_local_volume_is_accepted():
|
||||
module.validate_volume(volume())
|
||||
|
||||
|
||||
def writer_inventory(inherited_labels):
|
||||
identifier = "c" * 64
|
||||
spec = module._writer_spec(IMAGE_ID, REVISION, kind="config")
|
||||
return {
|
||||
"Id": identifier, "Name": f"/{module.WRITER_NAME}", "Image": IMAGE_ID,
|
||||
"Config": {
|
||||
"Image": IMAGE_ID, "User": "0:0", "Entrypoint": ["python3"], "Cmd": spec[-2:],
|
||||
"Labels": {**inherited_labels, module.WRITER_LABEL: "true",
|
||||
module.WRITER_TARGET_LABEL: "config", module.WRITER_REVISION_LABEL: REVISION},
|
||||
},
|
||||
"HostConfig": {
|
||||
"NetworkMode": "none", "Binds": [], "Privileged": False, "ReadonlyRootfs": True,
|
||||
"CpuQuota": module.WRITER_CPU_QUOTA, "CpuPeriod": module.WRITER_CPU_PERIOD,
|
||||
"Memory": module.WRITER_MEMORY_BYTES, "PidsLimit": module.WRITER_PIDS_LIMIT,
|
||||
"CapDrop": ["ALL"], "Tmpfs": {"/tmp": "rw,nosuid,nodev,size=16777216,mode=1777"},
|
||||
"SecurityOpt": ["no-new-privileges:true"],
|
||||
},
|
||||
"Mounts": [{"Type": "volume", "Name": module.VOLUME,
|
||||
"Source": module.MOUNTPOINT.as_posix(), "Destination": module.TARGET, "RW": True}],
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("damage", [None, "changed_image_label", "extra_label", "reserved_image_label", "falsey_labels"])
|
||||
def test_writer_labels_are_bound_to_exact_image_inheritance(monkeypatch, damage):
|
||||
inherited = {"org.opencontainers.image.revision": "d" * 40, "io.buildah.version": "1.40.0"}
|
||||
item = writer_inventory(inherited)
|
||||
if damage == "changed_image_label":
|
||||
item["Config"]["Labels"]["org.opencontainers.image.revision"] = "e" * 40
|
||||
elif damage == "extra_label":
|
||||
item["Config"]["Labels"]["unexpected"] = "value"
|
||||
elif damage == "reserved_image_label":
|
||||
inherited[module.WRITER_LABEL] = "inherited-marker"
|
||||
elif damage == "falsey_labels":
|
||||
inherited = []
|
||||
|
||||
def run(arguments, **kwargs):
|
||||
if arguments == ["docker", "inspect", item["Id"]]:
|
||||
return json.dumps([item]).encode()
|
||||
assert arguments == ["docker", "image", "inspect", IMAGE_ID]
|
||||
return json.dumps([{"Id": IMAGE_ID, "Config": {"Labels": inherited}}]).encode()
|
||||
|
||||
monkeypatch.setattr(module, "_run", run)
|
||||
if damage:
|
||||
with pytest.raises(module.VolumeTransitionError, match="writer_.*invalid"):
|
||||
module._inspect_writer(item["Id"], IMAGE_ID, REVISION, kind="config")
|
||||
else:
|
||||
assert module._inspect_writer(item["Id"], IMAGE_ID, REVISION, kind="config") == item
|
||||
|
||||
|
||||
@pytest.mark.parametrize("damage", [None, "tmpfs_projection", "extra_bind", "wrong_volume", "read_only"])
|
||||
def test_writer_accepts_declared_tmpfs_without_inspect_mount_projection(monkeypatch, damage):
|
||||
item = writer_inventory({})
|
||||
if damage == "tmpfs_projection":
|
||||
item["Mounts"].append({"Type": "tmpfs", "Destination": "/tmp"})
|
||||
elif damage == "extra_bind":
|
||||
item["Mounts"].append({"Type": "bind", "Destination": "/foreign"})
|
||||
elif damage == "wrong_volume":
|
||||
item["Mounts"][0]["Name"] = "foreign-volume"
|
||||
elif damage == "read_only":
|
||||
item["Mounts"][0]["RW"] = False
|
||||
|
||||
def run(arguments, **kwargs):
|
||||
if arguments == ["docker", "inspect", item["Id"]]:
|
||||
return json.dumps([item]).encode()
|
||||
assert arguments == ["docker", "image", "inspect", IMAGE_ID]
|
||||
return json.dumps([{"Id": IMAGE_ID, "Config": {"Labels": None}}]).encode()
|
||||
|
||||
monkeypatch.setattr(module, "_run", run)
|
||||
if damage in {"extra_bind", "wrong_volume", "read_only"}:
|
||||
with pytest.raises(module.VolumeTransitionError, match="writer_mount_invalid"):
|
||||
module._inspect_writer(item["Id"], IMAGE_ID, REVISION, kind="config")
|
||||
else:
|
||||
module._inspect_writer(item["Id"], IMAGE_ID, REVISION, kind="config")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("name", ["foreign-project", "", None, "${COMPOSE_PROJECT_NAME}"])
|
||||
def test_source_compose_name_cannot_be_overridden_by_fixed_project_flag(monkeypatch, name):
|
||||
def never_compose(*args, **kwargs):
|
||||
pytest.fail("Foreign source project reached Compose")
|
||||
|
||||
monkeypatch.setattr(module, "_run", never_compose)
|
||||
source = f"name: {json.dumps(name)}\nservices:\n deploy-control:\n image: immutable-controller\n".encode()
|
||||
with pytest.raises(module.VolumeTransitionError, match="project_invalid"):
|
||||
module.rendered_model(source, REVISION, IMAGE_ID)
|
||||
|
||||
|
||||
def test_compose_without_explicit_name_retains_canonical_project(monkeypatch):
|
||||
def run(arguments, *, data=None, **kwargs):
|
||||
if arguments[:3] == ["docker", "image", "inspect"]:
|
||||
return IMAGE_ID.encode()
|
||||
normalized = model()
|
||||
normalized["name"] = (
|
||||
arguments[arguments.index("--project-name") + 1]
|
||||
if "--project-name" in arguments else "data"
|
||||
)
|
||||
return json.dumps(normalized).encode()
|
||||
|
||||
monkeypatch.setattr(module, "_run", run)
|
||||
original = b"services:\n deploy-control:\n image: immutable-controller\n"
|
||||
rendered = json.loads(module.rendered_model(original, REVISION, IMAGE_ID))
|
||||
assert rendered["name"] == "gitea-deploy-runners"
|
||||
|
||||
|
||||
def model():
|
||||
return {
|
||||
"name": "gitea-deploy-runners",
|
||||
@@ -146,12 +249,30 @@ def test_compose_uses_protected_code_and_two_config_views(compose):
|
||||
]
|
||||
assert compose_calls
|
||||
assert all("--project-directory" in arguments for arguments in compose_calls)
|
||||
assert all(module.MOUNTPOINT.as_posix() in arguments for arguments in compose_calls)
|
||||
assert module.ROOT.as_posix() in compose_calls[0]
|
||||
assert all(module.MOUNTPOINT.as_posix() in arguments for arguments in compose_calls[1:])
|
||||
assert all("--env-file" in arguments and "/dev/null" in arguments for arguments in compose_calls)
|
||||
assert all("-f" in arguments and "-" in arguments for arguments in compose_calls)
|
||||
assert calls[0][1] == ORIGINAL_COMPOSE
|
||||
|
||||
|
||||
def test_source_relative_controller_bind_uses_original_compose_directory(monkeypatch):
|
||||
def run(arguments, *, data=None, **kwargs):
|
||||
if arguments[:3] == ["docker", "image", "inspect"]:
|
||||
return IMAGE_ID.encode()
|
||||
normalized = model()
|
||||
directory = arguments[arguments.index("--project-directory") + 1]
|
||||
if arguments[-2:] == ["--format", "json"]:
|
||||
normalized["services"][module.SERVICE]["volumes"][1]["source"] = directory + "/controller"
|
||||
return json.dumps(normalized).encode()
|
||||
|
||||
monkeypatch.setattr(module, "_run", run)
|
||||
original = ORIGINAL_COMPOSE + b" volumes:\n - ./controller:/opt/gitea-deploy:ro\n"
|
||||
rendered = json.loads(module.rendered_model(original, REVISION, IMAGE_ID))
|
||||
mounts = rendered["services"][module.SERVICE]["volumes"]
|
||||
assert next(m["source"] for m in mounts if m["target"] == module.EXECUTABLE_TARGET) == module._mount_source_for_revision(REVISION)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("damage", ["target_collision", "foreign_volume", "graph_rw", "relative_bind", "env_file"])
|
||||
def test_compose_rejects_unsafe_or_unpinned_activation_inputs(compose, damage):
|
||||
baseline, _ = compose
|
||||
@@ -191,6 +312,55 @@ def test_compose_tag_replacement_cannot_change_controller_startup_image(compose,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("damage", [None, "foreign_reference", "wrong_project", "wrong_service", "unhealthy", "digest_reference", "wrong_image", "normalized_reference", "interpolation"])
|
||||
def test_drifted_tag_requires_healthy_current_controller_provenance(compose, monkeypatch, damage):
|
||||
baseline, calls = compose
|
||||
reference = "registry.example/controller:stable"
|
||||
if damage == "digest_reference":
|
||||
reference = "registry.example/controller@sha256:" + "c" * 64
|
||||
baseline["services"][module.SERVICE]["image"] = reference
|
||||
current = {
|
||||
"Image": IMAGE_ID,
|
||||
"Config": {"Image": reference, "Labels": {
|
||||
"com.docker.compose.project": "gitea-deploy-runners",
|
||||
"com.docker.compose.service": module.SERVICE,
|
||||
}},
|
||||
"State": {"Health": {"Status": "healthy"}},
|
||||
}
|
||||
if damage == "foreign_reference":
|
||||
current["Config"]["Image"] = "registry.example/foreign:stable"
|
||||
elif damage == "wrong_project":
|
||||
current["Config"]["Labels"]["com.docker.compose.project"] = "foreign"
|
||||
elif damage == "wrong_service":
|
||||
current["Config"]["Labels"]["com.docker.compose.service"] = "foreign"
|
||||
elif damage == "unhealthy":
|
||||
current["State"]["Health"]["Status"] = "unhealthy"
|
||||
elif damage == "wrong_image":
|
||||
current["Image"] = "sha256:" + "c" * 64
|
||||
original_run = module._run
|
||||
|
||||
def drifted_tag(arguments, **kwargs):
|
||||
if arguments[:3] == ["docker", "image", "inspect"]:
|
||||
return ("sha256:" + "c" * 64).encode("ascii")
|
||||
return original_run(arguments, **kwargs)
|
||||
|
||||
monkeypatch.setattr(module, "_run", drifted_tag)
|
||||
source_reference = reference
|
||||
if damage == "normalized_reference":
|
||||
source_reference = "registry.example/foreign:stable"
|
||||
elif damage == "interpolation":
|
||||
source_reference = "${CONTROLLER_IMAGE}"
|
||||
original = f"name: gitea-deploy-runners\nservices:\n deploy-control:\n image: {source_reference}\n".encode()
|
||||
if damage:
|
||||
with pytest.raises(module.VolumeTransitionError, match="image_reference_(changed|invalid)"):
|
||||
module.rendered_model(original, REVISION, IMAGE_ID, current_container=current)
|
||||
else:
|
||||
rendered = json.loads(module.rendered_model(original, REVISION, IMAGE_ID, current_container=current))
|
||||
assert rendered["services"][module.SERVICE]["image"] == IMAGE_ID
|
||||
assert rendered["services"][module.SERVICE]["pull_policy"] == "never"
|
||||
assert not any("up" in arguments or "pull" in arguments for arguments, _ in calls)
|
||||
|
||||
|
||||
def test_config_snapshot_has_exact_allowlist_and_broker_token():
|
||||
entries = {
|
||||
"projects.json": (b"{}", 0o600),
|
||||
@@ -482,7 +652,7 @@ def test_installer_release_order_matches_renderer_contract():
|
||||
renderer_spec.loader.exec_module(renderer)
|
||||
assert tuple(module.RELEASE_FILES) == tuple(renderer._ARTIFACT_FILES)
|
||||
assert module.RELEASE_FILES[:3] == (
|
||||
"controller_paths.py", "mcp_hub_release_store.py", "deploy.py"
|
||||
"controller_paths.py", "mcp_hub_release_store.py", "hub_permission_preparation.py"
|
||||
)
|
||||
|
||||
|
||||
@@ -566,11 +736,12 @@ def test_private_stage_rejects_symlinked_source_directory():
|
||||
shutil.rmtree(work)
|
||||
|
||||
|
||||
def test_source_compose_preflight_rejects_host_file_reads_before_compose(compose):
|
||||
@pytest.mark.parametrize("directive", ["env_file", "label_file"])
|
||||
def test_source_compose_preflight_rejects_host_file_reads_before_compose(compose, directive):
|
||||
_baseline, calls = compose
|
||||
unsafe = (
|
||||
b"name: gitea-deploy-runners\nservices:\n deploy-control:\n"
|
||||
b" image: x\n env_file: /tmp/secret\n"
|
||||
+ f" image: x\n {directive}: /tmp/secret\n".encode()
|
||||
)
|
||||
with pytest.raises(module.VolumeTransitionError, match="external_source_invalid"):
|
||||
module.rendered_model(unsafe, REVISION, IMAGE_ID)
|
||||
|
||||
Reference in new issue
Block a user