Publish curated Unraid-AppOps-Gateway source from 2e6cf771e11a9cdc8b2e2453586a16d518adf40b
This commit is contained in:
1 parent
5d598db0df
commit
631b846397
10 files changed
+4709
-8
No files matched your search
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import pytest
|
||||
@@ -110,6 +111,235 @@ def run(docker, git):
|
||||
)
|
||||
|
||||
|
||||
_MOUNT_ORDERS = {
|
||||
("name", 1): (3, 0, 4, 1, 2),
|
||||
("name", 2): (4, 2, 0, 3, 1),
|
||||
("name", 3): (1, 3, 0, 4, 2),
|
||||
("id", 1): (2, 4, 1, 0, 3),
|
||||
("id", 2): (4, 1, 3, 2, 0),
|
||||
}
|
||||
|
||||
|
||||
def configure_reinspection(
|
||||
docker,
|
||||
*,
|
||||
drift=None,
|
||||
drift_reference="id",
|
||||
drift_pair=1,
|
||||
identifier=FAILED_ID,
|
||||
):
|
||||
"""Model Docker returning the same inspect with independent mount ordering."""
|
||||
original_inspect = docker.inspect_container
|
||||
counts = {"name": 0, "id": 0}
|
||||
reads = []
|
||||
|
||||
def inspect(reference):
|
||||
if reference == bootstrap.MODERN_HELPER_NAME:
|
||||
scope = "name"
|
||||
elif reference == identifier:
|
||||
scope = "id"
|
||||
else:
|
||||
return original_inspect(reference)
|
||||
|
||||
counts[scope] += 1
|
||||
reads.append((scope, counts[scope]))
|
||||
if docker.existing_child is None:
|
||||
return None
|
||||
|
||||
snapshot = copy.deepcopy(docker.existing_child)
|
||||
order = _MOUNT_ORDERS.get((scope, counts[scope]))
|
||||
if order is not None:
|
||||
snapshot["Mounts"] = [snapshot["Mounts"][index] for index in order]
|
||||
|
||||
pair_number = (
|
||||
1
|
||||
if (scope == "name" and counts[scope] == 2)
|
||||
or (scope == "id" and counts[scope] == 1)
|
||||
else 2
|
||||
if (scope == "name" and counts[scope] == 3)
|
||||
or (scope == "id" and counts[scope] == 2)
|
||||
else None
|
||||
)
|
||||
is_drift_read = pair_number == drift_pair and (
|
||||
drift_reference == "both" or scope == drift_reference
|
||||
)
|
||||
if drift is not None and is_drift_read:
|
||||
mount = snapshot["Mounts"][0]
|
||||
if drift == "mount_type":
|
||||
mount["Type"] = "volume"
|
||||
elif drift == "mount_source":
|
||||
mount["Source"] = "/tmp/changed-source"
|
||||
elif drift == "mount_destination":
|
||||
mount["Destination"] = "/tmp/changed-destination"
|
||||
elif drift == "mount_rw":
|
||||
mount["RW"] = not mount["RW"]
|
||||
elif drift == "mount_propagation":
|
||||
mount["Propagation"] = "shared"
|
||||
elif drift == "mount_name":
|
||||
mount["Name"] = "unexpected-volume"
|
||||
elif drift == "missing_mount":
|
||||
snapshot["Mounts"].pop()
|
||||
elif drift == "extra_mount":
|
||||
extra = copy.deepcopy(mount)
|
||||
extra["Destination"] = "/unexpected"
|
||||
snapshot["Mounts"].append(extra)
|
||||
elif drift == "duplicate_destination":
|
||||
snapshot["Mounts"].append(copy.deepcopy(mount))
|
||||
elif drift == "metadata_field":
|
||||
cache_mount = next(
|
||||
item
|
||||
for item in snapshot["Mounts"]
|
||||
if item["Destination"] == "/mnt/cache"
|
||||
)
|
||||
cache_mount["Mode"] = "ro"
|
||||
elif drift == "environment_order":
|
||||
snapshot["Config"]["Env"] = list(reversed(snapshot["Config"]["Env"]))
|
||||
elif drift == "binds_order":
|
||||
snapshot["HostConfig"]["Binds"] = list(
|
||||
reversed(snapshot["HostConfig"]["Binds"])
|
||||
)
|
||||
elif drift == "state_drift":
|
||||
snapshot["State"]["ExitCode"] = 2
|
||||
else:
|
||||
raise AssertionError(f"unhandled test drift: {drift}")
|
||||
return snapshot
|
||||
|
||||
docker.inspect_container = inspect
|
||||
return counts, reads
|
||||
|
||||
|
||||
def historical_inputs():
|
||||
helper_source = (
|
||||
original.ROOT / "backend/app/services/controller_artifact_helper_spec.py"
|
||||
).read_text(encoding="utf-8")
|
||||
child = original._retired_failed_child(helper_source)
|
||||
docker = original.FakeDocker(
|
||||
original._legacy_helper_spec(), existing_child=child
|
||||
)
|
||||
docker.containers["gitea-deploy-control"] = original._modern_controller_source_inspect(
|
||||
bootstrap.MODERN_CONTROLLER_REVISION
|
||||
)
|
||||
git = original.FakeProtectedGit(helper_source)
|
||||
return docker, git
|
||||
|
||||
|
||||
def run_historical(docker, git):
|
||||
return original._run_bootstrap(
|
||||
docker,
|
||||
git,
|
||||
health_sequence=[
|
||||
original._modern_baseline_health(),
|
||||
original._modern_baseline_health(),
|
||||
original._modern_baseline_health(),
|
||||
original._modern_baseline_health(),
|
||||
original._health(),
|
||||
original._health(),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def test_failed_child_inspect_ignores_mount_order_across_name_and_id_reads():
|
||||
docker, git, _child = inputs()
|
||||
counts, reads = configure_reinspection(docker)
|
||||
|
||||
result = run(docker, git)
|
||||
|
||||
assert result["status"] == "promoted"
|
||||
assert counts == {"name": 4, "id": 2}
|
||||
assert reads[:5] == [
|
||||
("name", 1),
|
||||
("name", 2),
|
||||
("id", 1),
|
||||
("name", 3),
|
||||
("id", 2),
|
||||
]
|
||||
assert docker.removed == [FAILED_ID]
|
||||
assert len(docker.created) == len(docker.started) == 1
|
||||
|
||||
|
||||
def test_historical_failed_child_mount_order_is_ignored_across_name_and_id_reads():
|
||||
docker, git = historical_inputs()
|
||||
counts, reads = configure_reinspection(
|
||||
docker, identifier=original.RETIRED_HELPER_ID
|
||||
)
|
||||
|
||||
result = run_historical(docker, git)
|
||||
|
||||
assert result["status"] == "promoted"
|
||||
assert counts == {"name": 4, "id": 2}
|
||||
assert reads[:5] == [
|
||||
("name", 1),
|
||||
("name", 2),
|
||||
("id", 1),
|
||||
("name", 3),
|
||||
("id", 2),
|
||||
]
|
||||
assert docker.removed == [original.RETIRED_HELPER_ID]
|
||||
assert len(docker.created) == len(docker.started) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize("drift_pair", [1, 2])
|
||||
def test_historical_failed_child_rejects_mount_metadata_change_from_initial_snapshot(
|
||||
drift_pair,
|
||||
):
|
||||
docker, git = historical_inputs()
|
||||
configure_reinspection(
|
||||
docker,
|
||||
drift="metadata_field",
|
||||
drift_reference="both",
|
||||
drift_pair=drift_pair,
|
||||
identifier=original.RETIRED_HELPER_ID,
|
||||
)
|
||||
|
||||
with pytest.raises(bootstrap.BootstrapError):
|
||||
run_historical(docker, git)
|
||||
|
||||
assert docker.removed == docker.created == docker.started == []
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"drift",
|
||||
[
|
||||
"mount_type",
|
||||
"mount_source",
|
||||
"mount_destination",
|
||||
"mount_rw",
|
||||
"mount_propagation",
|
||||
"mount_name",
|
||||
"missing_mount",
|
||||
"extra_mount",
|
||||
"duplicate_destination",
|
||||
"metadata_field",
|
||||
"environment_order",
|
||||
"binds_order",
|
||||
"state_drift",
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("drift_reference", ["name", "id"])
|
||||
def test_failed_child_reinspection_rejects_any_non_mount_order_drift(
|
||||
drift, drift_reference
|
||||
):
|
||||
docker, git, _child = inputs()
|
||||
# Make the environment order check meaningful while keeping the initial
|
||||
# image and child Config.Env identical.
|
||||
docker.existing_child["Config"]["Env"] = ["PATH=/usr/bin", "LANG=C"]
|
||||
docker.images[bootstrap.LEGACY_CONTROLLER_IMAGE_ID]["Config"]["Env"] = [
|
||||
"PATH=/usr/bin",
|
||||
"LANG=C",
|
||||
]
|
||||
_counts, _reads = configure_reinspection(
|
||||
docker, drift=drift, drift_reference=drift_reference
|
||||
)
|
||||
|
||||
if drift == "binds_order":
|
||||
assert len(docker.existing_child["HostConfig"]["Binds"]) > 1
|
||||
|
||||
with pytest.raises(bootstrap.BootstrapError):
|
||||
run(docker, git)
|
||||
|
||||
assert docker.removed == docker.created == docker.started == []
|
||||
|
||||
|
||||
def test_noncurrent_protected_ancestor_failure_releases_only_its_verified_name():
|
||||
docker, git, child = inputs()
|
||||
result = run(docker, git)
|
||||
@@ -274,13 +504,20 @@ def test_delete_adapter_rejects_noncanonical_full_container_identity(
|
||||
def test_git_ancestor_proof_reads_original_protected_objects(
|
||||
tmp_path, monkeypatch, scenario
|
||||
):
|
||||
def git(*args):
|
||||
def git(*args, allow_replace_objects=False):
|
||||
environment = None
|
||||
if allow_replace_objects:
|
||||
# Only the attack demonstration opts out of the inherited guard.
|
||||
# The production proof still reads original protected Git objects.
|
||||
environment = dict(os.environ)
|
||||
environment.pop("GIT_NO_REPLACE_OBJECTS", None)
|
||||
return (
|
||||
subprocess.run(
|
||||
["git", "-C", str(tmp_path), *args],
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
env=environment,
|
||||
)
|
||||
.stdout.decode()
|
||||
.strip()
|
||||
@@ -302,7 +539,7 @@ def test_git_ancestor_proof_reads_original_protected_objects(
|
||||
proof = bootstrap.ProtectedGitRepository()
|
||||
if scenario == "replace_ref":
|
||||
git("replace", old, current)
|
||||
assert git("rev-parse", f"{old}^{{tree}}") != tree
|
||||
assert git("rev-parse", f"{old}^{{tree}}", allow_replace_objects=True) != tree
|
||||
if scenario == "unrelated":
|
||||
git("checkout", "-qb", "side", old)
|
||||
path.write_text("unrelated child")
|
||||
|
||||
Reference in new issue
Block a user