Publish curated Unraid-AppOps-Gateway source from ba66029223865607deddc234e283c11127324eb8
This commit is contained in:
1 parent
820244dbb3
commit
8dd4b40252
52 files changed
+11814
-288
No files matched your search
@@ -194,6 +194,266 @@ def test_run_identity_requires_exact_protected_push_and_no_pull_request(modules)
|
||||
assert not importer._run_matches({**run, **change}, revision)
|
||||
|
||||
|
||||
def test_connector_ingestion_binding_is_scoped_to_authenticated_run_attempt(modules):
|
||||
controller = modules.controller
|
||||
revision = "a" * 40
|
||||
run_id, attempt = 21531, 2
|
||||
repository = controller.MCP_HUB_OWNED_IMAGE_REPOSITORIES["connector-ingestion"]
|
||||
archive_ref = f"{repository}:{revision}-run-{run_id}-attempt-{attempt}"
|
||||
digest = "d" * 64
|
||||
image_ref = f"{archive_ref}@sha256:{digest}"
|
||||
image_id = "sha256:" + "e" * 64
|
||||
|
||||
binding = controller.mcp_hub_connector_ingestion_binding(
|
||||
revision, run_id, attempt, image_ref, image_id
|
||||
)
|
||||
|
||||
assert binding == {
|
||||
"workflowRunId": run_id,
|
||||
"workflowRunAttempt": attempt,
|
||||
"archiveRef": archive_ref,
|
||||
"imageRef": image_ref,
|
||||
"imageId": image_id,
|
||||
}
|
||||
for invalid_ref in (
|
||||
f"{repository}:{revision}-run-{run_id}@sha256:{digest}",
|
||||
f"{repository}:{revision}-run-{run_id}-attempt-1@sha256:{digest}",
|
||||
f"attacker.example/{repository.rsplit('/', 1)[-1]}:{revision}-run-{run_id}-attempt-{attempt}@sha256:{digest}",
|
||||
f"{archive_ref}@sha256:{'F' * 64}",
|
||||
f"{archive_ref}@sha256:{digest}:extra",
|
||||
):
|
||||
with pytest.raises(controller.DeployError):
|
||||
controller.mcp_hub_connector_ingestion_binding(
|
||||
revision, run_id, attempt, invalid_ref, image_id
|
||||
)
|
||||
with pytest.raises(controller.DeployError):
|
||||
controller.mcp_hub_connector_ingestion_binding(
|
||||
revision, run_id, 0, image_ref, image_id
|
||||
)
|
||||
|
||||
|
||||
def test_candidate_ingestion_binding_overrides_only_fixed_hub_render_environment(
|
||||
modules,
|
||||
):
|
||||
controller = modules.controller
|
||||
revision, tree = "a" * 40, "b" * 40
|
||||
run_id, attempt = 21531, 2
|
||||
repository = controller.MCP_HUB_OWNED_IMAGE_REPOSITORIES["connector-ingestion"]
|
||||
archive_ref = f"{repository}:{revision}-run-{run_id}-attempt-{attempt}"
|
||||
image_ref = f"{archive_ref}@sha256:{'d' * 64}"
|
||||
binding = controller.mcp_hub_connector_ingestion_binding(
|
||||
revision, run_id, attempt, image_ref, "sha256:" + "e" * 64
|
||||
)
|
||||
project = {
|
||||
"compose_project": controller.MCP_HUB_PROJECT,
|
||||
"_mcp_hub_contract": controller.MCP_HUB_TOPOLOGY_CONTRACT,
|
||||
"_mcp_hub_connector_ingestion_binding": binding,
|
||||
"environment": {"CONNECTOR_INGESTION_IMAGE": "attacker.invalid/image:latest"},
|
||||
}
|
||||
metadata = {
|
||||
"id": revision[:12],
|
||||
"repository": controller.MCP_HUB_REPOSITORY,
|
||||
"revision": revision,
|
||||
"tree": tree,
|
||||
"treeDigest": hashlib.sha256(f"git-tree:{tree}".encode()).hexdigest(),
|
||||
"builtAt": "2026-10-03T12:00:00.000Z",
|
||||
}
|
||||
|
||||
environment = controller.deployment_environment(
|
||||
project, revision, controller.MCP_HUB_REPOSITORY, metadata
|
||||
)
|
||||
|
||||
assert environment["CONNECTOR_INGESTION_IMAGE"] == image_ref
|
||||
|
||||
project["_mcp_hub_connector_ingestion_binding"]["archiveRef"] += "-tampered"
|
||||
with pytest.raises(controller.DeployError):
|
||||
controller.deployment_environment(
|
||||
project, revision, controller.MCP_HUB_REPOSITORY, metadata
|
||||
)
|
||||
|
||||
|
||||
def test_registered_hub_cannot_supply_private_ingestion_binding(modules):
|
||||
controller = modules.controller
|
||||
raw = {
|
||||
"branch": "main",
|
||||
"slug": controller.MCP_HUB_PROJECT,
|
||||
"compose_project": controller.MCP_HUB_PROJECT,
|
||||
"containers": list(controller.MCP_HUB_LEGACY_CONTAINERS),
|
||||
"source_dir": (
|
||||
controller.MCP_HUB_APPDATA_ROOT / "deployment" / "repository"
|
||||
).as_posix(),
|
||||
"compose_dir": "infrastructure/compose",
|
||||
"compose_files": list(controller.MCP_HUB_LEGACY_COMPOSE_FILES),
|
||||
"env_source": (controller.MCP_HUB_APPDATA_ROOT / "deploy.env").as_posix(),
|
||||
"_mcp_hub_connector_ingestion_binding": {"imageRef": "attacker.invalid/x"},
|
||||
}
|
||||
|
||||
effective = controller.effective_mcp_hub_project(
|
||||
controller.MCP_HUB_REPOSITORY, raw
|
||||
)
|
||||
|
||||
assert "_mcp_hub_connector_ingestion_binding" not in effective
|
||||
|
||||
|
||||
def test_import_manifest_ingestion_binding_rejects_wrong_run_or_archive_tag(modules):
|
||||
importer = modules.importer
|
||||
revision, tree = "a" * 40, "b" * 40
|
||||
run = {"id": 21531, "run_attempt": 2}
|
||||
repository = importer.controller.MCP_HUB_OWNED_IMAGE_REPOSITORIES[
|
||||
"connector-ingestion"
|
||||
]
|
||||
archive_ref = f"{repository}:{revision}-run-{run['id']}-attempt-{run['run_attempt']}"
|
||||
row = {
|
||||
"imageRef": f"{archive_ref}@sha256:{'d' * 64}",
|
||||
"archiveRef": archive_ref,
|
||||
"imageId": "sha256:" + "e" * 64,
|
||||
}
|
||||
manifest = {
|
||||
"schema": importer.ARTIFACT_SCHEMA,
|
||||
"repository": importer.REPOSITORY,
|
||||
"sourceRevision": revision,
|
||||
"sourceTree": tree,
|
||||
"workflowPath": importer.WORKFLOW_PATH,
|
||||
"workflowRunId": run["id"],
|
||||
"artifactName": importer.ARTIFACT_PREFIX + revision,
|
||||
"images": {
|
||||
service: row if service == "connector-ingestion" else {}
|
||||
for service in importer.controller.MCP_HUB_SERVICES
|
||||
},
|
||||
}
|
||||
|
||||
binding = importer._manifest_ingestion_binding(
|
||||
manifest, revision=revision, tree=tree, run=run
|
||||
)
|
||||
assert binding["imageRef"] == row["imageRef"]
|
||||
assert binding["archiveRef"] == archive_ref
|
||||
|
||||
for changed in (
|
||||
{**manifest, "workflowRunId": run["id"] + 1},
|
||||
{
|
||||
**manifest,
|
||||
"images": {
|
||||
**manifest["images"],
|
||||
"connector-ingestion": {
|
||||
**row,
|
||||
"archiveRef": archive_ref.replace("-attempt-2", "-attempt-1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
):
|
||||
with pytest.raises(importer.CandidateRejected):
|
||||
importer._manifest_ingestion_binding(
|
||||
changed, revision=revision, tree=tree, run=run
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("drift", [None, "image_id", "repo_digest", "provenance"])
|
||||
def test_import_immutably_pulls_and_reads_back_connector_ingestion(
|
||||
modules, monkeypatch, drift
|
||||
):
|
||||
importer = modules.importer
|
||||
controller = modules.controller
|
||||
revision, tree, run_id, attempt = "a" * 40, "b" * 40, 21531, 2
|
||||
built_at = "2026-10-03T12:00:00.000Z"
|
||||
build = {
|
||||
"id": revision[:12],
|
||||
"repository": controller.MCP_HUB_REPOSITORY,
|
||||
"revision": revision,
|
||||
"tree": tree,
|
||||
"treeDigest": hashlib.sha256(f"git-tree:{tree}".encode()).hexdigest(),
|
||||
"builtAt": built_at,
|
||||
}
|
||||
labels = {
|
||||
"org.opencontainers.image.source": controller.MCP_HUB_OCI_IMAGE_SOURCE,
|
||||
"org.opencontainers.image.revision": revision,
|
||||
"org.opencontainers.image.source-tree": tree,
|
||||
"org.opencontainers.image.version": revision[:12],
|
||||
"org.opencontainers.image.created": built_at,
|
||||
"org.opencontainers.image.source-date-epoch": "1790985600",
|
||||
}
|
||||
images = {}
|
||||
for index, service in enumerate(controller.MCP_HUB_SERVICES, start=1):
|
||||
external = importer.EXTERNAL_IMAGES.get(service)
|
||||
if external:
|
||||
image_ref, archive_ref = external[0], external[1]
|
||||
elif service == "connector-ingestion":
|
||||
repo = controller.MCP_HUB_OWNED_IMAGE_REPOSITORIES[service]
|
||||
archive_ref = f"{repo}:{revision}-run-{run_id}-attempt-{attempt}"
|
||||
image_ref = f"{archive_ref}@sha256:{'d' * 64}"
|
||||
elif service == "contextforge":
|
||||
image_ref = archive_ref = f"itworx-mcp-hub/contextforge-schema:{revision}"
|
||||
else:
|
||||
image_ref = archive_ref = f"fixture/{service}:{revision}"
|
||||
images[service] = {
|
||||
"imageRef": image_ref,
|
||||
"archiveRef": archive_ref,
|
||||
"imageId": "sha256:" + f"{index:064x}",
|
||||
}
|
||||
ingestion = images["connector-ingestion"]
|
||||
immutable_ref = ingestion["imageRef"]
|
||||
repo = controller.MCP_HUB_OWNED_IMAGE_REPOSITORIES["connector-ingestion"]
|
||||
immutable_inspect = {
|
||||
"Id": ingestion["imageId"],
|
||||
"RepoDigests": [f"{repo}@sha256:{'d' * 64}"],
|
||||
"Config": {"User": "10001:10001", "Labels": dict(labels)},
|
||||
}
|
||||
tagged_inspect = {"Id": ingestion["imageId"], "Config": {"Labels": dict(labels)}}
|
||||
if drift == "image_id":
|
||||
immutable_inspect["Id"] = "sha256:" + "f" * 64
|
||||
elif drift == "repo_digest":
|
||||
immutable_inspect["RepoDigests"] = []
|
||||
elif drift == "provenance":
|
||||
immutable_inspect["Config"]["Labels"][
|
||||
"org.opencontainers.image.source-tree"
|
||||
] = "c" * 40
|
||||
monkeypatch.setattr(
|
||||
importer,
|
||||
"_inspect_image",
|
||||
lambda ref: tagged_inspect if ref == ingestion["archiveRef"] else immutable_inspect,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
importer,
|
||||
"_require_loaded_image",
|
||||
lambda _service, row, **_kwargs: {
|
||||
"Id": row["imageId"],
|
||||
"Config": {"User": "10001:10001", "Labels": dict(labels)},
|
||||
},
|
||||
)
|
||||
docker_calls = []
|
||||
monkeypatch.setattr(
|
||||
importer,
|
||||
"_fixed_docker",
|
||||
lambda *args, **kwargs: docker_calls.append((args, kwargs)),
|
||||
)
|
||||
|
||||
if drift is None:
|
||||
result = importer._verify_loaded_images(
|
||||
images,
|
||||
revision,
|
||||
build,
|
||||
"1790985600",
|
||||
pull_external=True,
|
||||
ingestion_run_id=run_id,
|
||||
ingestion_run_attempt=attempt,
|
||||
)
|
||||
assert result["connector-ingestion"] == ingestion["imageId"]
|
||||
assert any(
|
||||
call[0] == ("pull", immutable_ref)
|
||||
for call in docker_calls
|
||||
)
|
||||
else:
|
||||
with pytest.raises(importer.CandidateRejected):
|
||||
importer._verify_loaded_images(
|
||||
images,
|
||||
revision,
|
||||
build,
|
||||
"1790985600",
|
||||
pull_external=True,
|
||||
ingestion_run_id=run_id,
|
||||
ingestion_run_attempt=attempt,
|
||||
)
|
||||
|
||||
|
||||
def test_selected_run_and_jobs_accept_the_live_gitea_job_shape(modules):
|
||||
importer = modules.importer
|
||||
revision = "a" * 40
|
||||
@@ -353,12 +613,15 @@ def test_fake_local_import_publishes_candidate_and_requires_review_for_findings(
|
||||
images = {}
|
||||
for index, service in enumerate(controller.MCP_HUB_SERVICES, start=1):
|
||||
external = importer.EXTERNAL_IMAGES.get(service)
|
||||
image_ref = (
|
||||
external[0]
|
||||
if external is not None
|
||||
else f"registry.example/itworx/{service}:{revision[:12]}"
|
||||
)
|
||||
archive_ref = external[1] if external is not None else image_ref
|
||||
if external is not None:
|
||||
image_ref, archive_ref = external[0], external[1]
|
||||
elif service == "connector-ingestion":
|
||||
repository = controller.MCP_HUB_OWNED_IMAGE_REPOSITORIES[service]
|
||||
archive_ref = f"{repository}:{revision}-run-21531-attempt-2"
|
||||
image_ref = f"{archive_ref}@sha256:{'f' * 64}"
|
||||
else:
|
||||
image_ref = f"registry.example/itworx/{service}:{revision[:12]}"
|
||||
archive_ref = image_ref
|
||||
model_services[service] = {"image": image_ref}
|
||||
images[service] = {
|
||||
"imageRef": image_ref,
|
||||
@@ -449,8 +712,8 @@ def test_fake_local_import_publishes_candidate_and_requires_review_for_findings(
|
||||
)
|
||||
monkeypatch.setattr(importer, "_remote_main_tree", lambda *_args: tree)
|
||||
monkeypatch.setattr(importer, "_fixed_workflow", lambda *_args: None)
|
||||
run = {"id": 21531, "run_attempt": 1}
|
||||
run_state = {"attempt": 1}
|
||||
run = {"id": 21531, "run_attempt": 2}
|
||||
run_state = {"attempt": 2}
|
||||
monkeypatch.setattr(
|
||||
importer,
|
||||
"_selected_run",
|
||||
@@ -467,14 +730,35 @@ def test_fake_local_import_publishes_candidate_and_requires_review_for_findings(
|
||||
monkeypatch.setattr(importer, "_candidate_artifact", lambda *_args: artifact)
|
||||
monkeypatch.setattr(importer, "_docker_root", lambda: tmp_path)
|
||||
monkeypatch.setattr(importer, "_check_disk_headroom", lambda **_kwargs: None)
|
||||
monkeypatch.setattr(importer, "_parse_artifact_zip", lambda *_args, **_kwargs: (
|
||||
{},
|
||||
report_data,
|
||||
hashlib.sha256(artifact_bytes).hexdigest(),
|
||||
"d" * 64,
|
||||
"e" * 64,
|
||||
123,
|
||||
))
|
||||
artifact_manifest = {
|
||||
"schema": importer.ARTIFACT_SCHEMA,
|
||||
"repository": importer.REPOSITORY,
|
||||
"sourceRevision": revision,
|
||||
"sourceTree": tree,
|
||||
"workflowPath": importer.WORKFLOW_PATH,
|
||||
"workflowRunId": run["id"],
|
||||
"artifactName": importer.ARTIFACT_PREFIX + revision,
|
||||
"images": {
|
||||
service: {
|
||||
"imageRef": row["imageRef"],
|
||||
"imageId": row["imageId"],
|
||||
"archiveRef": row["archiveRef"],
|
||||
}
|
||||
for service, row in images.items()
|
||||
},
|
||||
}
|
||||
|
||||
def fake_parse_artifact(*_args, **_kwargs):
|
||||
return (
|
||||
artifact_manifest,
|
||||
report_data,
|
||||
hashlib.sha256(artifact_bytes).hexdigest(),
|
||||
"d" * 64,
|
||||
"e" * 64,
|
||||
123,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(importer, "_parse_artifact_zip", fake_parse_artifact)
|
||||
monkeypatch.setattr(
|
||||
importer,
|
||||
"_validate_manifest",
|
||||
@@ -486,11 +770,17 @@ def test_fake_local_import_publishes_candidate_and_requires_review_for_findings(
|
||||
|
||||
def fake_fixed_docker(*args, **_kwargs):
|
||||
if rerun_during_load and args and args[0] == "load":
|
||||
run_state["attempt"] = 2
|
||||
run_state["attempt"] = 3
|
||||
return object()
|
||||
|
||||
monkeypatch.setattr(importer, "_fixed_docker", fake_fixed_docker)
|
||||
monkeypatch.setattr(importer, "_verify_loaded_images", lambda *_args, **_kwargs: {})
|
||||
verified_runs = []
|
||||
|
||||
def verify_loaded(_images, _revision, _build, _epoch, **kwargs):
|
||||
verified_runs.append(kwargs)
|
||||
return {}
|
||||
|
||||
monkeypatch.setattr(importer, "_verify_loaded_images", verify_loaded)
|
||||
monkeypatch.setattr(
|
||||
controller,
|
||||
"_mcp_hub_check_candidate_exceptions",
|
||||
@@ -502,7 +792,18 @@ def test_fake_local_import_publishes_candidate_and_requires_review_for_findings(
|
||||
lambda *_args: draft,
|
||||
)
|
||||
|
||||
def fake_plan(_repository, _revision, *, built_at, staging_directory, **_kwargs):
|
||||
planned_bindings = []
|
||||
|
||||
def fake_plan(
|
||||
_repository,
|
||||
_revision,
|
||||
*,
|
||||
built_at,
|
||||
staging_directory,
|
||||
connector_ingestion_binding,
|
||||
**_kwargs,
|
||||
):
|
||||
planned_bindings.append(connector_ingestion_binding)
|
||||
Path(staging_directory).mkdir(mode=0o700)
|
||||
frozen = {
|
||||
"schema": prepare.BUILD_SCHEMA,
|
||||
@@ -519,7 +820,15 @@ def test_fake_local_import_publishes_candidate_and_requires_review_for_findings(
|
||||
|
||||
monkeypatch.setattr(prepare, "plan_candidate", fake_plan)
|
||||
|
||||
def fake_capture(_repository, _revision, *, staging_directory, **_kwargs):
|
||||
def fake_capture(
|
||||
_repository,
|
||||
_revision,
|
||||
*,
|
||||
staging_directory,
|
||||
connector_ingestion_binding,
|
||||
**_kwargs,
|
||||
):
|
||||
assert connector_ingestion_binding == planned_bindings[0]
|
||||
image_rows = {
|
||||
service: {
|
||||
"imageRef": images[service]["imageRef"],
|
||||
@@ -570,6 +879,15 @@ def test_fake_local_import_publishes_candidate_and_requires_review_for_findings(
|
||||
_private_file(destination, artifact_bytes)
|
||||
return None
|
||||
|
||||
def fake_no_overwrite_publish(stage, final_directory):
|
||||
if final_directory.exists() or final_directory.is_symlink():
|
||||
importer._reject(
|
||||
"MCP Hub candidate destination already exists; import never overwrites"
|
||||
)
|
||||
final_directory.parent.mkdir(mode=0o700, parents=True, exist_ok=True)
|
||||
stage.rename(final_directory)
|
||||
|
||||
monkeypatch.setattr(importer, "_publish_candidate", fake_no_overwrite_publish)
|
||||
candidate_directory = state_root / "mcp-hub-release-candidates" / revision
|
||||
if rerun_during_load:
|
||||
with pytest.raises(importer.CandidateRejected, match="run changed"):
|
||||
@@ -589,7 +907,22 @@ def test_fake_local_import_publishes_candidate_and_requires_review_for_findings(
|
||||
download_artifact=download_artifact,
|
||||
)
|
||||
assert candidate_directory.is_dir()
|
||||
assert stat.S_IMODE(candidate_directory.stat().st_mode) == 0o700
|
||||
assert planned_bindings[0]["workflowRunId"] == run["id"]
|
||||
assert planned_bindings[0]["workflowRunAttempt"] == run["run_attempt"]
|
||||
assert verified_runs == [
|
||||
{
|
||||
"pull_external": True,
|
||||
"ingestion_run_id": run["id"],
|
||||
"ingestion_run_attempt": run["run_attempt"],
|
||||
},
|
||||
{
|
||||
"pull_external": False,
|
||||
"ingestion_run_id": run["id"],
|
||||
"ingestion_run_attempt": run["run_attempt"],
|
||||
},
|
||||
]
|
||||
if importer.os.name != "nt":
|
||||
assert stat.S_IMODE(candidate_directory.stat().st_mode) == 0o700
|
||||
candidate_before_review = (candidate_directory / "candidate.json").read_bytes()
|
||||
receipt_before_review = (candidate_directory / "import-receipt.json").read_bytes()
|
||||
collision_stage = tmp_path / "second-candidate"
|
||||
|
||||
Reference in new issue
Block a user