Publish curated ITWorx-ModelForge source from 990401737f96c8d46a9f7b0d84994516cadcb6a0

This commit is contained in:
Public Source Publisher committed 2026-09-30 09:23:17 +00:00
1 parent 7082ab955a
commit 848f0d8f8a
434 files changed
+67298 -4315

No files matched your search

+75 -127
View File
@@ -14,7 +14,6 @@ from pathlib import Path
REPOSITORY_ROOT = Path(__file__).resolve().parents[2]
DEPLOY_WORKFLOW = REPOSITORY_ROOT / ".gitea" / "workflows" / "unraid-deploy.yml"
VALIDATION_WORKFLOW = REPOSITORY_ROOT / ".gitea" / "workflows" / "managed-validation.yml"
@@ -62,110 +61,15 @@ def _run_script(step: str) -> str:
class ProductionDeployPolicyTests(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
cls.deploy = DEPLOY_WORKFLOW.read_text(encoding="utf-8")
cls.validation = VALIDATION_WORKFLOW.read_text(encoding="utf-8")
def test_deployment_has_no_automatic_trigger(self) -> None:
trigger = _indented_block(self.deploy, "on:")
trigger_keys = re.findall(r"^ ([a-z_]+):", trigger, flags=re.MULTILINE)
self.assertEqual(trigger_keys, ["workflow_dispatch"])
self.assertNotRegex(trigger, r"(?m)^\s+push:")
def test_dispatch_inputs_are_required_and_fail_safe(self) -> None:
inputs = _indented_block(self.deploy, " inputs:")
input_names = re.findall(r"^ ([a-z_]+):", inputs, flags=re.MULTILINE)
self.assertEqual(input_names, ["release_tag", "release_commit", "action"])
for input_name in ("release_tag", "release_commit"):
block = _indented_block(self.deploy, f" {input_name}:")
self.assertRegex(block, r"(?m)^ required: true$")
self.assertRegex(block, r"(?m)^ type: string$")
action = _indented_block(self.deploy, " action:")
self.assertRegex(action, r"(?m)^ required: true$")
self.assertRegex(action, r"(?m)^ default: VERIFY_ONLY$")
self.assertRegex(action, r"(?m)^ type: choice$")
options = re.findall(r"^ - (\S+)$", action, flags=re.MULTILINE)
self.assertEqual(options, ["VERIFY_ONLY", "DEPLOY_STABLE_TO_PRODUCTION"])
def test_inputs_are_validated_before_checkout(self) -> None:
validation = _named_step(self.deploy, "Validate immutable dispatch inputs")
checkout = _named_step(self.deploy, "Check out the exact release commit with full history")
self.assertLess(self.deploy.index(validation), self.deploy.index(checkout))
self.assertIn('"refs/heads/master"', validation)
self.assertIn(
r"^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$",
validation,
def test_legacy_production_delivery_workflow_is_retired(self) -> None:
self.assertFalse(
(REPOSITORY_ROOT / ".gitea" / "workflows" / "unraid-deploy.yml").exists()
)
self.assertIn(r"^[0-9a-f]{40}$", validation)
self.assertIn("VERIFY_ONLY|DEPLOY_STABLE_TO_PRODUCTION", validation)
tag_pattern = re.search(r'RELEASE_TAG\}" =~ (\^.*\$) \]\]', validation)
commit_pattern = re.search(r'RELEASE_COMMIT\}" =~ (\^.*\$) \]\]', validation)
self.assertIsNotNone(tag_pattern)
self.assertIsNotNone(commit_pattern)
assert tag_pattern is not None and commit_pattern is not None
for valid_tag in ("v0.0.0", "v1.2.1", "v10.20.30"):
self.assertRegex(valid_tag, tag_pattern.group(1))
for invalid_tag in ("1.2.1", "v01.2.1", "v1.2.1-rc.1", "v1.2.1+build", "master"):
self.assertNotRegex(invalid_tag, tag_pattern.group(1))
self.assertRegex("0" * 40, commit_pattern.group(1))
for invalid_commit in ("0" * 39, "A" * 40, "g" * 40, "master"):
self.assertNotRegex(invalid_commit, commit_pattern.group(1))
def test_checkout_is_pinned_to_the_validated_commit_with_full_history(self) -> None:
checkout = _named_step(self.deploy, "Check out the exact release commit with full history")
self.assertRegex(checkout, r"actions/checkout@[0-9a-f]{40}")
self.assertIn("ref: ${{ inputs.release_commit }}", checkout)
self.assertIn("fetch-depth: 0", checkout)
self.assertIn("persist-credentials: true", checkout)
def test_release_provenance_is_verified_and_exported(self) -> None:
provenance = _named_step(self.deploy, "Verify stable release provenance")
required_fragments = (
"git fetch --force --no-recurse-submodules origin",
'git cat-file -t "${tag_ref}"',
'git rev-parse "${tag_ref}^{tag}"',
'git rev-parse "${tag_ref}^{commit}"',
"git rev-parse HEAD",
"< VERSION",
"git merge-base --is-ancestor",
"refs/remotes/origin/master",
"DEPLOY_COMMIT=%s",
'>> "${GITHUB_ENV}"',
)
for fragment in required_fragments:
with self.subTest(fragment=fragment):
self.assertIn(fragment, provenance)
self.assertNotIn("GITHUB_SHA", self.deploy)
def test_all_production_shell_blocks_parse(self) -> None:
names = (
"Validate immutable dispatch inputs",
"Verify stable release provenance",
"Verification-only result",
"Deploy verified stable release to production",
)
for name in names:
script = _run_script(_named_step(self.deploy, name))
result = subprocess.run(
["bash", "-n"],
input=script.encode("utf-8"),
capture_output=True,
check=False,
)
with self.subTest(step=name):
self.assertEqual(result.returncode, 0, result.stderr.decode("utf-8", "replace"))
def test_deployment_requires_the_explicit_action_and_verified_commit(self) -> None:
deploy = _named_step(self.deploy, "Deploy verified stable release to production")
self.assertIn("inputs.action == 'DEPLOY_STABLE_TO_PRODUCTION'", deploy)
self.assertIn('test -n "${DEPLOY_COMMIT:-}"', deploy)
self.assertIn('"${GITHUB_REPOSITORY}" "${DEPLOY_COMMIT}"', deploy)
self.assertEqual(self.deploy.count("/opt/gitea-deploy/deploy.py deploy"), 1)
verify_only = _named_step(self.deploy, "Verification-only result")
self.assertIn("inputs.action == 'VERIFY_ONLY'", verify_only)
def test_managed_validation_uses_the_shared_validation_pool(self) -> None:
self.assertRegex(self.validation, r"(?m)^\s*runs-on:\s*linux-validation\s*$")
def test_managed_validation_runs_policy_before_profile_work(self) -> None:
policy_step = _named_step(self.validation, "Production delivery policy")
@@ -176,39 +80,83 @@ class ProductionDeployPolicyTests(unittest.TestCase):
self.validation.index(" - name: Validate the requested profile"),
)
def test_security_profile_runs_fail_closed_scanners(self) -> None:
step = _named_step(self.validation, "Security — secrets and vulnerable dependencies")
self.assertIn("env.PROFILE == 'security'", step)
self.assertIn("env.PROFILE == 'full'", step)
script = _run_script(step)
self.assertIn("gitleaks git .", script)
self.assertIn("pip_audit --strict --skip-editable", script)
self.assertIn("npm audit --audit-level=high --omit=dev", script)
self.assertNotRegex(script, r"(?m)(?:\|\|\s*true|continue-on-error)")
def test_full_validation_uses_a_disposable_managed_postgres_boundary(self) -> None:
job = _indented_block(self.validation, " full:")
boundary = _named_step(self.validation, "Managed PostgreSQL boundary")
cleanup = _named_step(self.validation, "Remove managed PostgreSQL boundary")
toolchain = _named_step(self.validation, "Toolchain")
toolchain_script = _run_script(toolchain)
self.assertIn("command -v gitleaks", toolchain_script)
self.assertIn("exit 1", toolchain_script)
for variable in ("VALIDATION_COMPOSE_PROJECT", "MODELFORGE_POSTGRES_PORT"):
self.assertRegex(job, rf"(?m)^ {variable}: .+$")
self.assertIn("modelforge-validation-${{ gitea.run_id }}", job)
self.assertIn('MODELFORGE_POSTGRES_PORT: "0"', job)
self.assertIn("env.PROFILE == 'full'", boundary)
self.assertIn("export MODELFORGE_MIGRATION_DATABASE_URL=", boundary)
self.assertIn("export MODELFORGE_RUNTIME_DATABASE_URL=", boundary)
self.assertIn("up --detach --wait postgres", boundary)
self.assertIn('validation_network="${VALIDATION_COMPOSE_PROJECT}_default"', boundary)
self.assertIn('job_container="$(hostname)"', boundary)
self.assertIn('docker network connect "${validation_network}" "${job_container}"', boundary)
self.assertIn('socket.create_connection(("postgres", 5432)', boundary)
self.assertNotIn("port postgres 5432", boundary)
for variable in (
"MODELFORGE_TEST_POSTGRES_URL",
"MODELFORGE_TEST_POSTGRES_OWNER_URL",
"MODELFORGE_TEST_POSTGRES_RUNTIME_URL",
):
self.assertIn(f'echo "{variable}=', boundary)
self.assertIn('>> "${GITHUB_ENV}"', boundary)
self.assertNotIn("SKIPPED", boundary)
self.assertIn("always() && env.PROFILE == 'full'", cleanup)
self.assertIn("docker network disconnect", cleanup)
self.assertIn('"$(hostname)"', cleanup)
self.assertIn("down --volumes --remove-orphans", cleanup)
self.assertIn("export MODELFORGE_MIGRATION_DATABASE_URL=", cleanup)
self.assertIn("export MODELFORGE_RUNTIME_DATABASE_URL=", cleanup)
def test_compose_validation_renders_the_production_projection(self) -> None:
step = _named_step(self.validation, "Compose projections")
script = _run_script(step)
self.assertIn(
"for overlay in backup dr gpu node-agent node-recovery production runtime-worker",
script,
def test_full_validation_traverses_the_live_schema_and_tests_the_built_console(self) -> None:
backend = _named_step(self.validation, "Backend — install, lint, typecheck, test")
console = _named_step(self.validation, "Console — install frozen, typecheck, test, build")
boundary = _named_step(self.validation, "Managed PostgreSQL boundary")
self.assertIn('MODELFORGE_MIGRATION_DATABASE_URL="${MODELFORGE_TEST_POSTGRES_OWNER_URL}"', backend)
upgrade_commands = re.findall(
r'"\$\{BACKEND_VENV\}/bin/python" -m alembic ([^\n]+)',
backend,
)
self.assertEqual(
upgrade_commands,
["upgrade head", "downgrade 20260828_0022", "upgrade head"],
)
self.assertLess(self.validation.index(console), self.validation.index(boundary))
self.assertLess(self.validation.index(boundary), self.validation.index(backend))
def test_managed_postgres_shell_blocks_parse(self) -> None:
for name in (
"Managed PostgreSQL boundary",
"Backend — install, lint, typecheck, test",
"Remove managed PostgreSQL boundary",
):
script = _run_script(_named_step(self.validation, name))
result = subprocess.run(
["bash", "-n"],
input=script.encode("utf-8"),
capture_output=True,
check=False,
)
with self.subTest(step=name):
self.assertEqual(result.returncode, 0, result.stderr.decode("utf-8", "replace"))
def test_compose_projection_uses_explicit_non_secret_validation_inputs(self) -> None:
projection = _named_step(self.validation, "Compose projections")
for variable in (
"MODELFORGE_POSTGRES_ADMIN_PASSWORD",
"MODELFORGE_MIGRATION_DATABASE_URL",
"MODELFORGE_MIGRATION_DB_PASSWORD",
"MODELFORGE_RUNTIME_DB_PASSWORD",
"MODELFORGE_RUNTIME_DATABASE_URL",
"MODELFORGE_OPERATOR_API_KEY",
"MODELFORGE_BACKUP_ENCRYPTION_KEY",
"MODELFORGE_CORS_ORIGINS",
"VITE_API_BASE_URL",
"MODELFORGE_MIGRATION_DATABASE_URL",
):
with self.subTest(variable=variable):
self.assertIn(f"export {variable}=", script)
self.assertIn(f"export {variable}=", projection)
self.assertIn("docker compose --env-file .env.example", projection)
if __name__ == "__main__":
+118 -1
View File
@@ -2,12 +2,13 @@
from __future__ import annotations
import hashlib
import json
import subprocess
import tempfile
import unittest
from pathlib import Path
REPOSITORY_ROOT = Path(__file__).resolve().parents[2]
EXPORTER = REPOSITORY_ROOT / "scripts" / "export-public-source.mjs"
VALIDATOR = REPOSITORY_ROOT / "scripts" / "validate-public-source.mjs"
@@ -28,8 +29,36 @@ class PublicSourceExportTests(unittest.TestCase):
"SECURITY.md": "# Security\n",
"CONTRIBUTING.md": "# Contributing\n",
"docker-compose.yml": "services: {}\n",
"docker-compose.validation-tls.yml": "services: {}\n",
"deploy/validation/Caddyfile": "https://modelforge.example.test:8443 {}\n",
"backend/Dockerfile": (
'LABEL org.opencontainers.image.source="https://git.example.com/'
'Jens/ITWorx-ModelForge"\n'
),
"frontend/Dockerfile": (
'LABEL org.opencontainers.image.source="https://git.example.com/'
'Jens/ITWorx-ModelForge"\n'
),
"node-agent/Dockerfile": (
'LABEL org.opencontainers.image.source="https://git.example.com/'
'Jens/ITWorx-ModelForge"\n'
),
"runtime-worker/Dockerfile": (
'LABEL org.opencontainers.image.source="https://git.example.com/'
'Jens/ITWorx-ModelForge"\n'
),
"VERSION": "1.2.1\n",
"backend/pyproject.toml": "[project]\nname = 'fixture-api'\n",
"clients/README.md": "# Client usage\n",
"clients/python/modelforge_client.py": "# Python client\n",
"clients/typescript/modelforge-client.mjs": "// JavaScript client\n",
"clients/typescript/modelforge-client.d.mts": "// TypeScript declarations\n",
"scripts/m16_chaos.py": "# Chaos scenarios\n",
"scripts/m16_invariants.py": "# Invariant checks\n",
"scripts/m16_soak.py": "# Soak checks\n",
"scripts/operator_identity.py": "# Operator identities\n",
"scripts/rc_isolation_preflight.py": "# RC isolation\n",
"scripts/rc_stack_retention.py": "# RC retention\n",
"frontend/package.json": '{"name":"fixture-web"}\n',
"node-agent/pyproject.toml": "[project]\nname = 'fixture-agent'\n",
"runtime-worker/pyproject.toml": "[project]\nname = 'fixture-worker'\n",
@@ -104,6 +133,59 @@ class PublicSourceExportTests(unittest.TestCase):
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
validation = self._validate(output)
self.assertEqual(validation.returncode, 0, validation.stdout + validation.stderr)
self.assertTrue((output / "clients/python/modelforge_client.py").is_file())
self.assertTrue((output / "clients/typescript/modelforge-client.mjs").is_file())
manifest = json.loads((output / "PUBLIC_SOURCE_MANIFEST.json").read_text())
self.assertEqual(
manifest["sourceRepository"], "https://git.example.com/example/modelforge"
)
bound_paths = {entry["path"] for entry in manifest["files"]}
for relative_path in (
"backend/Dockerfile",
"frontend/Dockerfile",
"node-agent/Dockerfile",
"runtime-worker/Dockerfile",
):
self.assertIn(relative_path, bound_paths)
self.assertIn(
'org.opencontainers.image.source="https://git.example.com/example/modelforge"',
(output / relative_path).read_text(),
)
dockerfile_path = output / "backend/Dockerfile"
original_dockerfile = dockerfile_path.read_bytes()
dockerfile_entry = next(
entry for entry in manifest["files"] if entry["path"] == "backend/Dockerfile"
)
forged_dockerfile = original_dockerfile.replace(
b"https://git.example.com/example/modelforge",
b"https://attacker.invalid/repository",
)
dockerfile_path.write_bytes(forged_dockerfile)
dockerfile_entry["bytes"] = len(forged_dockerfile)
dockerfile_entry["sha256"] = hashlib.sha256(forged_dockerfile).hexdigest()
(output / "PUBLIC_SOURCE_MANIFEST.json").write_text(
json.dumps(manifest), encoding="utf-8"
)
identity_tampering = self._validate(output)
self.assertNotEqual(identity_tampering.returncode, 0)
self.assertIn("source label does not match", identity_tampering.stderr)
dockerfile_path.write_bytes(original_dockerfile)
original_manifest = json.loads(
(output / "PUBLIC_SOURCE_MANIFEST.json").read_text(encoding="utf-8")
)
original_manifest["files"] = [
{
"path": entry["path"],
"bytes": len((output / entry["path"]).read_bytes()),
"sha256": hashlib.sha256((output / entry["path"]).read_bytes()).hexdigest(),
}
for entry in manifest["files"]
]
(output / "PUBLIC_SOURCE_MANIFEST.json").write_text(
json.dumps(original_manifest), encoding="utf-8"
)
original_readme = (output / "README.md").read_bytes()
(output / "README.md").write_text("tampered\n", encoding="utf-8")
@@ -127,6 +209,41 @@ class PublicSourceExportTests(unittest.TestCase):
self.assertNotEqual(result.returncode, 0)
self.assertIn("commit the exact source tree", result.stderr)
def test_private_owner_inventory_is_excluded_from_public_source(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
repository = self._repository(root)
private_files = {
"scripts/portfolio_gitea_snapshot.py": "ExampleRAG owner inventory\n",
"scripts/portfolio_gitea_repository_ids.json": '{"private-repo": 12}\n',
"backend/tests/test_portfolio_gitea_snapshot.py": "192." + "168.1.40\n",
"docs/operations/PORTFOLIO_GITEA_SNAPSHOT.md": "Private owner audit\n",
}
for relative_path, contents in private_files.items():
destination = repository / relative_path
destination.parent.mkdir(parents=True, exist_ok=True)
destination.write_text(contents, encoding="utf-8")
public_script = repository / "scripts/public.py"
public_script.write_text("print('public')\n", encoding="utf-8")
with (repository / "public-source.allowlist").open("a", encoding="utf-8") as allowlist:
allowlist.write("scripts/**\nbackend/**\ndocs/operations/**\n")
subprocess.run(["git", "add", "."], cwd=repository, check=True)
subprocess.run(
[
"git", "-c", "user.name=ModelForge test", "-c", "user.email=test@example.invalid",
"commit", "-qm", "private inventory fixture",
],
cwd=repository,
check=True,
)
output = root / "public"
result = self._export(repository, output)
self.assertEqual(result.returncode, 0, result.stdout + result.stderr)
self.assertEqual(self._validate(output).returncode, 0)
self.assertTrue((output / "scripts/public.py").is_file())
for relative_path in private_files:
self.assertFalse((output / relative_path).exists())
def test_sanitized_destination_collisions_fail_before_writing(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
+157 -4
View File
@@ -2,13 +2,15 @@
from __future__ import annotations
import subprocess
import importlib.util
import json
import os
import signal
import subprocess
import tempfile
import unittest
from pathlib import Path
from unittest import mock
ROOT = Path(__file__).resolve().parents[2]
WORKFLOW = ROOT / ".gitea" / "workflows" / "public-candidate-acceptance.yml"
@@ -39,9 +41,23 @@ class RcAcceptancePolicyTests(unittest.TestCase):
def test_exact_source_and_docker_are_required(self) -> None:
self.assertIn(r"^[0-9a-f]{40}$", self.workflow)
self.assertIn("ref: ${{ inputs.source_commit }}", self.workflow)
self.assertIn("--canonical-source-commit", self.workflow)
self.assertIn('"--canonical-source-commit", canonical_commit', self.acceptance)
self.assertIn('"source_commit": canonical_commit', self.acceptance)
self.assertIn("docker version", self.workflow)
self.assertNotIn("SKIPPED: no docker", self.workflow)
def test_optional_candidate_freeze_retains_only_a_verified_transport_bundle(self) -> None:
self.assertIn("retain_image_bundle:", self.workflow)
self.assertIn("RETAIN_IMAGE_BUNDLE: ${{ inputs.retain_image_bundle }}", self.workflow)
self.assertIn("--retain-image-bundle", self.workflow)
self.assertIn("--image-bundle", self.acceptance)
self.assertIn("acceptance-evidence/release/*.tar", self.workflow)
self.assertIn("acceptance-evidence/release/*.tar.gz", self.workflow)
self.assertIn("atexit.register(cleanup_candidate_images", self.acceptance)
self.assertIn('canonical_commit="${{ inputs.source_commit }}"', self.workflow)
self.assertNotIn("candidate_commit=", self.workflow)
def test_security_tools_are_downloaded_with_exact_checksums(self) -> None:
self.assertIn("GITLEAKS_VERSION: 8.30.1", self.workflow)
self.assertIn(
@@ -78,18 +94,38 @@ class RcAcceptancePolicyTests(unittest.TestCase):
self.assertIn("apt-get purge --yes linux-libc-dev", self.runtime_dockerfile)
self.assertNotIn("apt-get autoremove", self.runtime_dockerfile)
self.assertIn("pip check", self.runtime_dockerfile)
self.assertIn("python -m pip uninstall --yes pip setuptools wheel", self.runtime_dockerfile)
for dependency in (
"filelock==3.20.3",
"h2==4.4.1",
"idna==3.15",
"lief==0.17.2",
"Pillow==12.3.0",
"Pygments==2.20.0",
"protobuf==5.29.6",
"requests==2.33.0",
"sentencepiece==0.2.2",
"sentence-transformers==6.0.1",
"transformers==5.16.1",
"urllib3==2.7.0",
):
self.assertIn(dependency, self.runtime_pyproject)
self.assertNotIn("'filelock==3.20.3'", self.runtime_dockerfile)
def test_runtime_worker_has_only_group_read_access_to_the_agent_credential(self) -> None:
self.assertIn(
"groupadd --system --gid 101 modelforge-agent", self.runtime_dockerfile
)
self.assertIn(
"--groups modelforge-agent --home /app modelforge-runtime",
self.runtime_dockerfile,
)
def test_compose_project_is_isolated_and_always_removed(self) -> None:
self.assertIn('project = f"modelforge-rc-', self.acceptance)
self.assertIn('project = f"modelforge-validation-', self.acceptance)
self.assertIn('"MODELFORGE_SOURCE_REFERENCE": "validation-acceptance"', self.acceptance)
self.assertIn('project="modelforge-validation-${suffix}"', self.workflow)
self.assertNotIn('project = f"modelforge-rc-', self.acceptance)
self.assertIn('"MODELFORGE_API_BIND": "127.0.0.1"', self.acceptance)
self.assertIn('"MODELFORGE_API_PUBLISHED_PORT": "0"', self.acceptance)
self.assertIn('"production_changed": False', self.acceptance)
@@ -100,6 +136,123 @@ class RcAcceptancePolicyTests(unittest.TestCase):
self.assertNotIn("docker-compose.runtime-worker.yml", self.acceptance)
self.assertNotIn("docker-compose.node-agent.yml", self.acceptance)
def test_acceptance_override_disables_restarts_for_every_service(self) -> None:
spec = importlib.util.spec_from_file_location("rc_server_acceptance", ACCEPTANCE)
assert spec and spec.loader
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
write_override = getattr(module, "write_acceptance_compose_override", None)
self.assertIsNotNone(
write_override,
"acceptance must expose the same override writer used by the RC run",
)
with tempfile.TemporaryDirectory() as directory:
override = Path(directory) / "acceptance-compose.override.yml"
write_override(override)
env = os.environ.copy()
env.update(
{
"MODELFORGE_VERSION": "9.9.9-test",
"MODELFORGE_COMMIT": "a" * 40,
"MODELFORGE_BUILT_AT": "2099-01-01T00:00:00+00:00",
"MODELFORGE_POSTGRES_DB": "modelforge_validation_test",
"MODELFORGE_POSTGRES_ADMIN_PASSWORD": "admin-test-password",
"MODELFORGE_MIGRATION_DB_PASSWORD": "owner-test-password",
"MODELFORGE_RUNTIME_DB_PASSWORD": "runtime-test-password",
"MODELFORGE_MIGRATION_DATABASE_URL": (
"postgresql+psycopg://modelforge:owner-test-password@"
"postgres:5432/modelforge_validation_test"
),
"MODELFORGE_RUNTIME_DATABASE_URL": (
"postgresql+psycopg://modelforge_runtime:runtime-test-password@"
"postgres:5432/modelforge_validation_test"
),
"MODELFORGE_BACKUP_ENCRYPTION_KEY": "acceptance-test-key",
"MODELFORGE_CORS_ORIGINS": "https://modelforge.example.test",
"VITE_API_BASE_URL": "https://modelforge.example.test",
}
)
result = subprocess.run(
[
"docker",
"compose",
"-f",
str(ROOT / "docker-compose.yml"),
"-f",
str(ROOT / "docker-compose.production.yml"),
"-f",
str(override),
"config",
"--format",
"json",
],
cwd=ROOT,
env=env,
text=True,
capture_output=True,
check=False,
)
self.assertEqual(result.returncode, 0, result.stderr)
services = json.loads(result.stdout)["services"]
self.assertTrue(services)
self.assertEqual(
{name: service.get("restart") for name, service in services.items()},
{name: "no" for name in services},
)
def test_compose_cleanup_runs_when_acceptance_receives_sigterm(self) -> None:
spec = importlib.util.spec_from_file_location("rc_server_acceptance_cleanup", ACCEPTANCE)
assert spec and spec.loader
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
managed_cleanup = getattr(module, "managed_compose_cleanup", None)
self.assertIsNotNone(
managed_cleanup,
"acceptance must guard its RC project with interruption-safe cleanup",
)
compose = ("docker", "compose", "-p", "modelforge-validation-test")
env = {"COMPOSE_PROJECT_NAME": "modelforge-validation-test"}
commands: list[tuple[tuple[str, ...], dict[str, object]]] = []
registered: list[object] = []
unregistered: list[object] = []
handlers: dict[int, object] = {}
def fake_run(*args: str, **kwargs: object) -> str:
commands.append((args, kwargs))
return ""
def fake_signal(signum: int, handler: object) -> object:
previous = handlers.get(signum, signal.SIG_DFL)
handlers[signum] = handler
return previous
with (
mock.patch.object(module, "run", side_effect=fake_run),
mock.patch.object(module.atexit, "register", side_effect=registered.append),
mock.patch.object(module.atexit, "unregister", side_effect=unregistered.append),
mock.patch.object(module.signal, "signal", side_effect=fake_signal),
self.assertRaises(SystemExit) as raised,
managed_cleanup(compose, env),
):
handler = handlers[signal.SIGTERM]
assert callable(handler)
handler(signal.SIGTERM, None)
self.assertEqual(raised.exception.code, 128 + signal.SIGTERM)
self.assertEqual(
commands,
[
(
compose + ("down", "--volumes", "--remove-orphans"),
{"env": env, "check": False},
)
],
)
self.assertEqual(len(registered), 1)
self.assertEqual(unregistered, registered)
def test_clean_install_bootstraps_roles_across_a_remote_docker_daemon(self) -> None:
self.assertIn("def provision_database_roles(", self.acceptance)
self.assertIn('run("docker", "cp", str(bootstrap)', self.acceptance)
@@ -152,7 +305,7 @@ class RcAcceptancePolicyTests(unittest.TestCase):
self.assertNotIn("docker system prune", cleanup)
def test_python_entrypoints_compile(self) -> None:
for path in (ACCEPTANCE, TRIVY_VALIDATOR):
for path in (ACCEPTANCE, TRIVY_VALIDATOR, ROOT / "scripts" / "release_build.py"):
result = subprocess.run(
["python", "-m", "py_compile", str(path)],
capture_output=True,
+215
View File
@@ -0,0 +1,215 @@
"""Unit tests for the fail-closed P12 RC isolation preflight."""
from __future__ import annotations
import importlib.util
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
ROOT = Path(__file__).resolve().parents[2]
SPEC = importlib.util.spec_from_file_location("rc_isolation_preflight", ROOT / "scripts" / "rc_isolation_preflight.py")
assert SPEC is not None and SPEC.loader is not None
preflight = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(preflight)
PROJECT = "modelforge-validation-p12a"
def compose_plan(root: Path) -> dict[str, object]:
return {
"services": {
"api": {
"networks": ["default"],
"volumes": [
{"type": "volume", "source": "postgres-data", "target": "/data"},
{"type": "bind", "source": str(root / "config"), "target": "/app/config", "read_only": True},
],
"ports": [{"host_ip": "127.0.0.1", "published": "0", "target": 8000}],
},
"node-agent": {
"networks": ["default"],
"volumes": [{"type": "volume", "source": "node-state", "target": "/data/state"}],
},
},
"volumes": {
"postgres-data": {"name": f"{PROJECT}_postgres-data"},
"node-state": {"name": f"{PROJECT}_node-state"},
},
"networks": {"default": {"name": f"{PROJECT}_default"}},
}
class RcIsolationPreflightTests(unittest.TestCase):
def plan_root(self, *, with_manifest: bool = True) -> tempfile.TemporaryDirectory[str]:
temporary = tempfile.TemporaryDirectory()
config = Path(temporary.name, "config")
config.mkdir()
if with_manifest:
manifest = config / "models" / "initial-candidates.yaml"
manifest.parent.mkdir()
manifest.write_text("candidates: []\n", encoding="utf-8")
self.addCleanup(temporary.cleanup)
return temporary
def validate(
self,
plan: dict[str, object],
root: Path,
*,
ports: set[int] | None = None,
names: set[str] | None = None,
) -> dict[str, object]:
return preflight.validate_compose(
plan,
project=PROJECT,
candidate_root=root,
protected_ports=ports or set(),
protected_resource_names=names or set(),
)
def test_valid_validation_compose_plan_is_accepted(self) -> None:
temporary = self.plan_root()
root = Path(temporary.name)
result = self.validate(
compose_plan(root), root, ports={18000, 13000}, names={"modelforge-postgres-1"}
)
self.assertEqual(result["project"], PROJECT)
self.assertEqual(result["published_ports"], [])
def test_project_validation_rejects_production_and_legacy_rc_names(self) -> None:
for project in (
"modelforge",
"modelforge-rc-p12a",
"modelforge-validation-",
"modelforge-validation-prod-",
):
with self.subTest(project=project), self.assertRaises(preflight.IsolationError):
preflight.validate_project(project)
def test_missing_bind_source_is_rejected(self) -> None:
temporary = self.plan_root(with_manifest=False)
root = Path(temporary.name)
plan = compose_plan(root)
(root / "config").rmdir()
with self.assertRaisesRegex(preflight.IsolationError, "missing bind source"):
self.validate(plan, root)
def test_config_manifest_must_exist_under_exact_bind_source(self) -> None:
temporary = self.plan_root(with_manifest=False)
root = Path(temporary.name)
plan = compose_plan(root)
# A manifest elsewhere in the candidate tree cannot satisfy this bind's contract.
manifest = root / "models" / "initial-candidates.yaml"
manifest.parent.mkdir()
manifest.write_text("candidates: []\n", encoding="utf-8")
with self.assertRaisesRegex(preflight.IsolationError, "missing models/initial-candidates.yaml under its source"):
self.validate(plan, root)
def test_rendered_compose_network_mapping_is_accepted(self) -> None:
temporary = self.plan_root()
root = Path(temporary.name)
plan = compose_plan(root)
plan["services"]["api"]["networks"] = {"default": None} # type: ignore[index]
self.assertEqual(self.validate(plan, root)["declared_networks"], ["default"])
def test_unsafe_compose_plans_are_rejected(self) -> None:
cases = [
(lambda plan: plan["services"]["api"].update(network_mode="host"), "host network"),
(lambda plan: plan["services"]["api"].update(container_name="modelforge-api-1"), "global container name"),
(lambda plan: plan["services"]["api"]["ports"].__setitem__(0, {"host_ip": "0.0.0.0", "published": "19000", "target": 8000}), "non-loopback"),
(lambda plan: plan["services"]["api"]["ports"].__setitem__(0, {"host_ip": "127.0.0.1", "published": "18000", "target": 8000}), "protected host port"),
(lambda plan: plan["services"]["api"]["volumes"].__setitem__(1, {"type": "bind", "source": "/mnt/user/appdata/modelforge", "target": "/data", "read_only": True}), "escapes the candidate root"),
(lambda plan: plan["services"]["api"]["volumes"].__setitem__(1, {"type": "bind", "source": "config", "target": "/app/config", "read_only": False}), "writable bind mount"),
(lambda plan: plan["volumes"]["postgres-data"].update(external=True), "is external"),
(lambda plan: plan["networks"]["default"].update(name="modelforge_default"), "non-project name"),
]
for mutate, message in cases:
with self.subTest(message=message):
temporary = self.plan_root()
root = Path(temporary.name)
plan = compose_plan(root)
mutate(plan)
with self.assertRaisesRegex(preflight.IsolationError, message):
self.validate(plan, root, ports={18000})
def test_protected_resource_reference_is_rejected(self) -> None:
temporary = self.plan_root()
root = Path(temporary.name)
plan = compose_plan(root)
plan["services"]["api"]["environment"] = {"UNSAFE": "modelforge-postgres-1"} # type: ignore[index]
with self.assertRaisesRegex(preflight.IsolationError, "protected resources"):
self.validate(plan, root, names={"modelforge-postgres-1"})
def test_only_isolated_tls_service_can_publish_test_port(self) -> None:
temporary = self.plan_root()
root = Path(temporary.name)
source = root / "source" / "deploy" / "validation"
source.mkdir(parents=True)
(source / "Caddyfile").write_text("https://modelforge.example.com:8443 {}\n", encoding="utf-8")
certificates = root / "tls"
certificates.mkdir()
(certificates / "fullchain.pem").write_text("certificate", encoding="utf-8")
(certificates / "privkey.pem").write_text("key", encoding="utf-8")
plan = compose_plan(root)
plan["networks"]["ingress"] = {"name": f"{PROJECT}_ingress"}
plan["services"]["tls"] = {
"image": "caddy:2.10-alpine@sha256:4c6e91c6ed0e2fa03efd5b44747b625fec79bc9cd06ac5235a779726618e530d",
"networks": ["ingress"], "read_only": True, "cap_drop": ["ALL"],
"security_opt": ["no-new-privileges:true"],
"volumes": [
{"type": "bind", "source": str(source / "Caddyfile"), "target": "/etc/caddy/Caddyfile", "read_only": True},
{"type": "bind", "source": str(certificates / "fullchain.pem"), "target": "/run/tls/fullchain.pem", "read_only": True},
{"type": "bind", "source": str(certificates / "privkey.pem"), "target": "/run/tls/privkey.pem", "read_only": True},
],
"ports": [{"host_ip": "0.0.0.0", "published": "18444", "target": 8443, "protocol": "tcp"}],
}
with self.assertRaisesRegex(preflight.IsolationError, "non-loopback"):
self.validate(plan, root)
self.assertEqual(preflight.validate_compose(
plan, project=PROJECT, candidate_root=root,
protected_ports={443, 8443}, protected_resource_names=set(), public_tls_port=18444,
)["published_ports"], [18444])
plan["services"]["api"]["ports"][0] = {"host_ip": "0.0.0.0", "published": "18444", "target": 8000}
with self.assertRaisesRegex(preflight.IsolationError, "non-loopback"):
preflight.validate_compose(
plan, project=PROJECT, candidate_root=root,
protected_ports=set(), protected_resource_names=set(), public_tls_port=18444,
)
def test_observed_resources_require_exact_labels_and_project_names(self) -> None:
observed = {
"containers": [{"name": f"{PROJECT}-api-1", "labels": {"com.docker.compose.project": PROJECT}}],
"volumes": [{"name": f"{PROJECT}_postgres-data", "labels": {"com.docker.compose.project": PROJECT}}],
"networks": [{"name": f"{PROJECT}_default", "labels": {"com.docker.compose.project": PROJECT}}],
}
self.assertEqual(preflight.validate_observed_resources(observed, project=PROJECT)["containers"], [f"{PROJECT}-api-1"])
observed["volumes"][0]["labels"] = {}
with self.assertRaisesRegex(preflight.IsolationError, "no exact project label"):
preflight.validate_observed_resources(observed, project=PROJECT)
def test_docker_resource_collection_uses_exact_inspection(self) -> None:
label = {"com.docker.compose.project": PROJECT}
responses = {
("container", "ls", "--all", "--quiet", "--filter", f"label=com.docker.compose.project={PROJECT}"): "container-id\n",
("volume", "ls", "--quiet", "--filter", f"label=com.docker.compose.project={PROJECT}"): "volume-id\n",
("network", "ls", "--quiet", "--filter", f"label=com.docker.compose.project={PROJECT}"): "network-id\n",
("container", "inspect", "container-id"): '[{"Name":"/' + PROJECT + '-api-1","Config":{"Labels":{"com.docker.compose.project":"' + PROJECT + '"}}}]',
("volume", "inspect", "volume-id"): '[{"Name":"' + PROJECT + '_data","Labels":{"com.docker.compose.project":"' + PROJECT + '"}}]',
("network", "inspect", "network-id"): '[{"Name":"' + PROJECT + '_default","Labels":{"com.docker.compose.project":"' + PROJECT + '"}}]',
}
def run(command, **_kwargs):
self.assertEqual(command[0], "docker")
return type("Result", (), {"returncode": 0, "stdout": responses[tuple(command[1:])]})()
with patch.object(preflight.subprocess, "run", run):
observed = preflight.collect_observed_resources(PROJECT)
self.assertEqual(observed["containers"][0]["labels"], label)
self.assertEqual(
preflight.validate_observed_resources(observed, project=PROJECT)["networks"],
[f"{PROJECT}_default"],
)
+316
View File
@@ -0,0 +1,316 @@
"""Focused tests for RC stack inventory and stop-only retention guard."""
from __future__ import annotations
import importlib.util
import io
import json
import tempfile
import unittest
from contextlib import redirect_stdout
from datetime import UTC, datetime
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import patch
ROOT = Path(__file__).resolve().parents[2]
SPEC = importlib.util.spec_from_file_location(
"rc_stack_retention", ROOT / "scripts" / "rc_stack_retention.py"
)
assert SPEC is not None and SPEC.loader is not None
retention = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(retention)
PROJECT = "modelforge-validation-123271"
NOW = datetime(2026, 9, 23, 10, 0, tzinfo=UTC)
CREATED = "2026-09-20T10:00:00Z"
class MockDocker:
def __init__(self, containers: dict[str, dict[str, object]]) -> None:
self.containers = containers
self.calls: list[tuple[str, ...]] = []
def run(self, command: tuple[str, ...], **_kwargs: object) -> SimpleNamespace:
self.assert_docker(command)
args = tuple(command[1:])
self.calls.append(args)
if args[:4] == (
"container", "ls", "--all", "--quiet"
):
return SimpleNamespace(
returncode=0,
stdout="\n".join(self.containers) + "\n",
stderr="",
)
if args[:2] == ("container", "inspect"):
identifier = args[2]
return SimpleNamespace(
returncode=0,
stdout=json.dumps([self.containers[identifier]]),
stderr="",
)
if args[:1] == ("stop",):
identifiers = args[3:]
for identifier in identifiers:
state = self.containers[identifier]["State"]
assert isinstance(state, dict)
state["Status"] = "exited"
return SimpleNamespace(returncode=0, stdout="\n".join(identifiers), stderr="")
raise AssertionError(f"unexpected Docker command: {args}")
@staticmethod
def assert_docker(command: tuple[str, ...]) -> None:
if command[0] != "docker":
raise AssertionError(f"unexpected executable: {command[0]}")
def docker_container(
identifier: str,
project: str,
service: str,
*,
status: str = "exited",
source: str | None = None,
created: str = CREATED,
oneoff: str = "False",
) -> dict[str, object]:
mounts: list[dict[str, str]] = []
if source is not None:
mounts.append({"Type": "bind", "Source": source, "Destination": "/app/config"})
return {
"Id": identifier,
"Name": f"/{project}-{service}-1",
"Created": created,
"Config": {
"Labels": {
retention.PROJECT_LABEL: project,
retention.SERVICE_LABEL: service,
retention.ONEOFF_LABEL: oneoff,
}
},
"State": {"Status": status, "Running": status == "running"},
"Mounts": mounts,
}
class RcStackRetentionTests(unittest.TestCase):
def fixture(self, *, api_status: str = "exited", service: str = "postgres", oneoff: str = "False") -> tuple[MockDocker, tempfile.TemporaryDirectory[str]]:
temporary = tempfile.TemporaryDirectory()
config = Path(temporary.name) / "config"
config.mkdir()
containers = {
"validation-api-id": docker_container("validation-api-id", PROJECT, "api", source=str(config)),
"validation-db-id": docker_container(
"validation-db-id", PROJECT, service, status="running", oneoff=oneoff
),
"prod-api-id": docker_container("prod-api-id", "modelforge", "api", status="running"),
"other-api-id": docker_container(
"other-api-id", "staging", "api", status="running"
),
}
if api_status != "exited":
containers["validation-api-id"]["State"] = {"Status": api_status, "Running": True}
return MockDocker(containers), temporary
@staticmethod
def write_evidence(path: Path, project: str = PROJECT) -> None:
path.write_text(
json.dumps(
{
"schema_version": 1,
"project": project,
"retained": True,
"evidence_reference": "acceptance-run-2026-09-20",
}
),
encoding="utf-8",
)
def test_inventory_scopes_validation_projects_and_flags_manifest_and_age(self) -> None:
docker, temporary = self.fixture()
self.addCleanup(temporary.cleanup)
with patch.object(retention.subprocess, "run", docker.run):
projects = retention.collect_projects(now=NOW, stale_after_hours=24)
self.assertEqual([row["project"] for row in projects], [PROJECT])
self.assertTrue(projects[0]["stale"])
self.assertEqual(len(projects[0]["missing_manifests"]), 1)
self.assertEqual(projects[0]["missing_bind_sources"], [])
self.assertNotIn("volumes", projects[0])
self.assertNotIn("images", projects[0])
self.assertTrue(all(call[:1] != ("stop",) for call in docker.calls))
self.assertTrue(all(call[:1] != ("rm",) for call in docker.calls))
def test_inventory_ignores_non_validation_partial_compose_labels(self) -> None:
docker, temporary = self.fixture()
self.addCleanup(temporary.cleanup)
docker.containers["unrelated-id"] = {
"Id": "unrelated-id",
"Name": "/projectbrain-worker-1",
"Config": {"Labels": {retention.PROJECT_LABEL: "projectbrain"}},
"State": {"Status": "exited"},
}
with patch.object(retention.subprocess, "run", docker.run):
projects = retention.collect_projects(now=NOW, stale_after_hours=24)
self.assertEqual([row["project"] for row in projects], [PROJECT])
def test_inventory_fails_closed_for_validation_container_missing_service_label(self) -> None:
docker, temporary = self.fixture()
self.addCleanup(temporary.cleanup)
labels = docker.containers["validation-api-id"]["Config"]["Labels"]
assert isinstance(labels, dict)
del labels[retention.SERVICE_LABEL]
with patch.object(retention.subprocess, "run", docker.run), self.assertRaisesRegex(
retention.RetentionError, "Compose service label is missing"
):
retention.collect_projects(now=NOW, stale_after_hours=24)
def test_default_cli_is_read_only(self) -> None:
docker, temporary = self.fixture()
self.addCleanup(temporary.cleanup)
output = io.StringIO()
with patch.object(retention.subprocess, "run", docker.run), redirect_stdout(output):
status = retention.main([])
result = json.loads(output.getvalue())
self.assertEqual(status, 0)
self.assertEqual(result["mode"], "read-only")
self.assertTrue(all(call[:1] != ("stop",) for call in docker.calls))
def test_docker_errors_and_ambiguous_inspection_fail_closed(self) -> None:
failed = SimpleNamespace(returncode=1, stdout="", stderr="daemon unavailable")
with patch.object(retention.subprocess, "run", return_value=failed), self.assertRaisesRegex(
retention.RetentionError, "Docker command failed"
):
retention.collect_projects(now=NOW)
docker, temporary = self.fixture()
self.addCleanup(temporary.cleanup)
docker.containers["validation-api-id"]["Id"] = "different-id"
with patch.object(retention.subprocess, "run", docker.run), self.assertRaisesRegex(
retention.RetentionError, "different container"
):
retention.collect_projects(now=NOW)
def test_project_validation_rejects_production_and_ambiguous_names(self) -> None:
for project in (
"modelforge",
"modelforge-rc-prod-",
"modelforge-validation-",
"modelforge-validation-prod-",
):
with self.subTest(project=project), self.assertRaises(retention.RetentionError):
retention.validate_project(project)
def test_stop_requires_explicit_exact_project_confirmation_and_evidence(self) -> None:
docker, temporary = self.fixture()
self.addCleanup(temporary.cleanup)
empty_record = Path(temporary.name) / "empty.json"
empty_record.write_text("", encoding="utf-8")
with patch.object(retention.subprocess, "run", docker.run):
with self.assertRaisesRegex(retention.RetentionError, "exact project name"):
retention.stop_project(
PROJECT,
confirm_stop=None,
confirm_no_active_jobs=True,
evidence_record=Path("evidence.json"),
stale_after_hours=24,
now=NOW,
)
with self.assertRaisesRegex(retention.RetentionError, "nonempty regular file"):
retention.stop_project(
PROJECT,
confirm_stop=PROJECT,
confirm_no_active_jobs=True,
evidence_record=empty_record,
stale_after_hours=24,
now=NOW,
)
mismatch = Path(temporary.name) / "mismatch.json"
self.write_evidence(mismatch, project="modelforge-validation-someone-else")
with patch.object(retention.subprocess, "run", docker.run), self.assertRaisesRegex(
retention.RetentionError, "identify this project"
):
retention.stop_project(
PROJECT,
confirm_stop=PROJECT,
confirm_no_active_jobs=True,
evidence_record=mismatch,
stale_after_hours=24,
now=NOW,
)
self.assertEqual(docker.calls, [])
def test_stop_only_targets_inspected_project_container_ids(self) -> None:
docker, temporary = self.fixture()
self.addCleanup(temporary.cleanup)
evidence = Path(temporary.name) / "evidence.json"
self.write_evidence(evidence)
with patch.object(retention.subprocess, "run", docker.run):
result = retention.stop_project(
PROJECT,
confirm_stop=PROJECT,
confirm_no_active_jobs=True,
evidence_record=evidence,
stale_after_hours=24,
now=NOW,
)
self.assertEqual(result["stopped_container_ids"], ["validation-db-id"])
self.assertFalse(result["volumes_or_images_removed"])
stop_calls = [call for call in docker.calls if call[:1] == ("stop",)]
self.assertEqual(stop_calls, [("stop", "--time", "30", "validation-db-id")])
self.assertTrue(all("prod-api-id" not in call for call in stop_calls))
self.assertTrue(all(call[:1] not in {("rm",), ("rmi",), ("volume",)} for call in docker.calls))
def test_stop_fails_if_api_or_oneoff_job_is_running(self) -> None:
for options, message in (
({"api_status": "running"}, "API is running"),
({"api_status": "restarting"}, "API is running"),
({"oneoff": "True"}, "one-off job container"),
({"service": "migrate"}, "service activity is unknown"),
):
with self.subTest(message=message):
docker, temporary = self.fixture(**options)
self.addCleanup(temporary.cleanup)
evidence = Path(temporary.name) / "evidence.json"
self.write_evidence(evidence)
with patch.object(retention.subprocess, "run", docker.run), self.assertRaisesRegex(
retention.RetentionError, message
):
retention.stop_project(
PROJECT,
confirm_stop=PROJECT,
confirm_no_active_jobs=True,
evidence_record=evidence,
stale_after_hours=24,
now=NOW,
)
self.assertTrue(all(call[:1] != ("stop",) for call in docker.calls))
def test_stop_requires_job_attestation(self) -> None:
docker, temporary = self.fixture()
self.addCleanup(temporary.cleanup)
evidence = Path(temporary.name) / "evidence.json"
self.write_evidence(evidence)
with patch.object(retention.subprocess, "run", docker.run), self.assertRaisesRegex(
retention.RetentionError, "--confirm-no-active-jobs"
):
retention.stop_project(
PROJECT,
confirm_stop=PROJECT,
confirm_no_active_jobs=False,
evidence_record=evidence,
stale_after_hours=24,
now=NOW,
)
self.assertEqual(docker.calls, [])
if __name__ == "__main__":
unittest.main()
+111
View File
@@ -0,0 +1,111 @@
from __future__ import annotations
import os
import re
import shutil
import subprocess
import unittest
from pathlib import Path
from urllib.parse import urlsplit
ROOT = Path(__file__).resolve().parents[2]
WORKFLOW = ROOT / ".gitea" / "workflows" / "managed-validation.yml"
CANONICAL_ORIGIN = "https://git.example.com"
def _origin_case_script() -> str:
text = WORKFLOW.read_text(encoding="utf-8")
match = re.search(
r'(?ms)^ case "\$\{GITHUB_SERVER_URL%/\}" in\n'
r'.*?^ esac$',
text,
)
if match is None:
raise AssertionError("managed validation has no GITHUB_SERVER_URL case policy")
# Remove workflow indentation before executing only the bounded origin policy.
return "\n".join(line[10:] for line in match.group(0).splitlines())
def _evaluate_origin(origin: str) -> subprocess.CompletedProcess[str]:
script = (
"set -euo pipefail\n"
+ _origin_case_script()
+ "\nprintf '%s\\n' \"${SOURCE_SERVER_URL}\"\n"
)
env = os.environ.copy()
env["GITHUB_SERVER_URL"] = origin
bash = shutil.which("bash") or "bash"
if os.name == "nt":
# System32/bash.exe starts WSL, which does not inherit arbitrary Windows environment
# variables. Git Bash runs natively and tests the exact environment used by this fixture.
git = shutil.which("git")
git_bash = Path(git).resolve().parents[1] / "bin" / "bash.exe" if git else None
if git_bash is None or not git_bash.is_file():
raise RuntimeError("Git Bash is required for Windows origin policy tests")
bash = str(git_bash)
return subprocess.run(
[bash, "--noprofile", "--norc", "-c", script],
cwd=ROOT,
env=env,
check=False,
capture_output=True,
text=True,
)
def _safe_origin(value: str) -> str:
parsed = urlsplit(value)
hostname = parsed.hostname or "(missing-host)"
port = f":{parsed.port}" if parsed.port is not None else ""
return f"{parsed.scheme or '(missing-scheme)'}://{hostname}{port}"
class SecurityOriginPolicyTests(unittest.TestCase):
def test_known_runner_and_public_origins_canonicalize_to_https(self) -> None:
accepted = (
"https://git.example.com",
"https://git.example.com/",
"http://git.example.com",
"http://git.example.com/",
"http://192.0.2.10:3000",
"http://192.0.2.10:3000/",
"http://gitea:3000",
"http://gitea:3000/",
"http://Gitea:3000",
"http://Gitea:3000/",
"http://gitea-runner-internal:3000",
"http://gitea-runner-internal:3000/",
)
for origin in accepted:
with self.subTest(origin=origin):
result = _evaluate_origin(origin)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual(result.stdout.strip(), CANONICAL_ORIGIN)
def test_unknown_http_and_https_origins_fail_closed(self) -> None:
for origin in (
"http://untrusted.invalid",
"https://untrusted.invalid",
"http://192.0.2.151:3000",
"http://gitea:3001",
):
with self.subTest(origin=origin):
result = _evaluate_origin(origin)
self.assertNotEqual(result.returncode, 0)
self.assertIn("Untrusted Gitea server URL", result.stderr)
def test_live_runner_origin_is_explicitly_covered_when_present(self) -> None:
origin = os.environ.get("GITHUB_SERVER_URL")
if not origin:
self.skipTest("GITHUB_SERVER_URL is only expected inside the managed runner")
result = _evaluate_origin(origin)
self.assertEqual(
result.returncode,
0,
f"managed runner origin is not covered: {_safe_origin(origin)}; {result.stderr.strip()}",
)
if __name__ == "__main__":
unittest.main()
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,6 +1,6 @@
name: Public candidate server acceptance
# Builds only an exact, curated public-source commit in a disposable Compose namespace. This job
# Builds only an exact, curated public-source commit in a disposable validation Compose namespace. This job
# never calls the Unraid deploy controller and cannot select the production deployment action.
on:
workflow_dispatch:
@@ -14,6 +14,11 @@ on:
required: true
default: https://modelforge.example.test
type: string
retain_image_bundle:
description: Retain the verified four-image Docker bundle for P12-P15 qualification
required: false
default: false
type: boolean
workflow_call:
inputs:
source_commit:
@@ -24,6 +29,11 @@ on:
description: Bare API origin compiled into the candidate Console image
required: true
type: string
retain_image_bundle:
description: Retain the verified four-image Docker bundle for P12-P15 qualification
required: false
default: false
type: boolean
permissions:
contents: read
@@ -140,14 +150,23 @@ jobs:
shell: bash
env:
PUBLIC_API_ORIGIN: ${{ inputs.public_api_origin }}
RETAIN_IMAGE_BUNDLE: ${{ inputs.retain_image_bundle }}
SOURCE_COMMIT: ${{ inputs.source_commit }}
run: |
set -euo pipefail
cd "${PUBLIC_SOURCE}"
python3 scripts/rc_server_acceptance.py \
--public-api-origin "${PUBLIC_API_ORIGIN}" \
--trivy "${TRIVY}" \
--output acceptance-evidence \
arguments=(
--public-api-origin "${PUBLIC_API_ORIGIN}"
--canonical-source-commit "${SOURCE_COMMIT}"
--trivy "${TRIVY}"
--output acceptance-evidence
--project-suffix "${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
)
if [[ "${RETAIN_IMAGE_BUNDLE}" == "true" ]]; then
arguments+=(--retain-image-bundle)
fi
python3 scripts/rc_server_acceptance.py \
"${arguments[@]}"
- name: Always remove acceptance Docker resources
if: always()
@@ -157,7 +176,7 @@ jobs:
cleanup_failed=0
suffix="$(printf '%s' "${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" \
| tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:]' | tail -c 24)"
project="modelforge-rc-${suffix}"
project="modelforge-validation-${suffix}"
for kind in container volume network; do
while IFS= read -r resource; do
[[ -n "${resource}" ]] || continue
@@ -171,7 +190,7 @@ jobs:
done
if [[ -n "${PUBLIC_SOURCE:-}" && -d "${PUBLIC_SOURCE}/.git" ]]; then
candidate_commit="$(git -C "${PUBLIC_SOURCE}" rev-parse HEAD 2>/dev/null)"
canonical_commit="${{ inputs.source_commit }}"
version="$(tr -d '\r\n' < "${PUBLIC_SOURCE}/VERSION" 2>/dev/null)"
for image in modelforge-api modelforge-web modelforge-node-agent \
modelforge-runtime-worker; do
@@ -179,7 +198,7 @@ jobs:
revision="$(docker inspect --format \
'{{index .Config.Labels "org.opencontainers.image.revision"}}' \
"${tag}" 2>/dev/null)"
if [[ -n "${candidate_commit}" && "${revision}" == "${candidate_commit}" ]]; then
if [[ "${revision}" == "${canonical_commit}" ]]; then
docker image rm --force "${tag}" || cleanup_failed=1
fi
done
@@ -208,6 +227,8 @@ jobs:
${{ env.PUBLIC_SOURCE }}/acceptance-evidence/*.json
${{ env.PUBLIC_SOURCE }}/acceptance-evidence/*.txt
${{ env.PUBLIC_SOURCE }}/acceptance-evidence/release/*.json
${{ env.PUBLIC_SOURCE }}/acceptance-evidence/release/*.tar
${{ env.PUBLIC_SOURCE }}/acceptance-evidence/release/*.tar.gz
${{ env.PUBLIC_SOURCE }}/acceptance-evidence/release/*SHA256SUMS
if-no-files-found: warn
retention-days: 90
-132
View File
@@ -1,132 +0,0 @@
name: Unraid stable release deployment
on:
workflow_dispatch:
inputs:
release_tag:
description: Annotated stable release tag (for example, v1.2.1)
required: true
type: string
release_commit:
description: Exact lowercase 40-character commit SHA referenced by the tag
required: true
type: string
action:
description: Verify provenance only, or deploy the verified stable release
required: true
default: VERIFY_ONLY
type: choice
options:
- VERIFY_ONLY
- DEPLOY_STABLE_TO_PRODUCTION
concurrency:
group: unraid-production-itworx-modelforge
cancel-in-progress: false
permissions:
contents: read
jobs:
deploy:
name: Verify and optionally deploy a stable release
runs-on: unraid-deploy
timeout-minutes: 180
steps:
- name: Validate immutable dispatch inputs
shell: bash
env:
RELEASE_TAG: ${{ inputs.release_tag }}
RELEASE_COMMIT: ${{ inputs.release_commit }}
DEPLOY_ACTION: ${{ inputs.action }}
run: |
set -euo pipefail
if [[ "${GITHUB_REF:-}" != "refs/heads/master" ]]; then
echo "Stable production deployment must be dispatched from refs/heads/master" >&2
exit 2
fi
if [[ ! "${RELEASE_TAG}" =~ ^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; then
echo "release_tag must be a strict stable SemVer tag such as v1.2.1" >&2
exit 2
fi
if [[ ! "${RELEASE_COMMIT}" =~ ^[0-9a-f]{40}$ ]]; then
echo "release_commit must be an exact lowercase 40-character SHA" >&2
exit 2
fi
case "${DEPLOY_ACTION}" in
VERIFY_ONLY|DEPLOY_STABLE_TO_PRODUCTION) ;;
*) echo "action is not allowlisted: ${DEPLOY_ACTION}" >&2; exit 2 ;;
esac
- name: Check out the exact release commit with full history
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ inputs.release_commit }}
fetch-depth: 0
# The following provenance step performs an authenticated exact-ref fetch.
persist-credentials: true
- name: Verify stable release provenance
shell: bash
env:
RELEASE_TAG: ${{ inputs.release_tag }}
RELEASE_COMMIT: ${{ inputs.release_commit }}
run: |
set -euo pipefail
git fetch --force --no-recurse-submodules origin \
"refs/tags/${RELEASE_TAG}:refs/tags/${RELEASE_TAG}" \
"refs/heads/master:refs/remotes/origin/master"
tag_ref="refs/tags/${RELEASE_TAG}"
if [[ "$(git cat-file -t "${tag_ref}")" != "tag" ]]; then
echo "${RELEASE_TAG} must be an annotated tag" >&2
exit 1
fi
tag_object="$(git rev-parse "${tag_ref}^{tag}")"
tag_commit="$(git rev-parse "${tag_ref}^{commit}")"
head_commit="$(git rev-parse HEAD)"
if [[ "${tag_commit}" != "${RELEASE_COMMIT}" ]]; then
echo "Tag commit ${tag_commit} does not match release_commit ${RELEASE_COMMIT}" >&2
exit 1
fi
if [[ "${head_commit}" != "${RELEASE_COMMIT}" ]]; then
echo "Checked-out HEAD ${head_commit} does not match release_commit ${RELEASE_COMMIT}" >&2
exit 1
fi
if [[ ! -f VERSION ]]; then
echo "VERSION is missing at the release commit" >&2
exit 1
fi
version="$(tr -d '\r\n' < VERSION)"
expected_version="${RELEASE_TAG#v}"
if [[ "${version}" != "${expected_version}" ]]; then
echo "VERSION ${version} does not match release tag ${RELEASE_TAG}" >&2
exit 1
fi
if ! git merge-base --is-ancestor "${RELEASE_COMMIT}" refs/remotes/origin/master; then
echo "Release commit ${RELEASE_COMMIT} is not an ancestor of origin/master" >&2
exit 1
fi
printf 'DEPLOY_COMMIT=%s\n' "${RELEASE_COMMIT}" >> "${GITHUB_ENV}"
echo "Verified annotated ${RELEASE_TAG} object ${tag_object} at immutable commit ${RELEASE_COMMIT}"
- name: Verification-only result
if: ${{ inputs.action == 'VERIFY_ONLY' }}
shell: bash
run: echo "Stable release provenance verified; production was not changed."
- name: Deploy verified stable release to production
if: ${{ inputs.action == 'DEPLOY_STABLE_TO_PRODUCTION' }}
shell: bash
run: |
set -euo pipefail
test -n "${DEPLOY_COMMIT:-}"
docker exec gitea-deploy-control \
/opt/gitea-deploy/deploy.py deploy \
"${GITHUB_REPOSITORY}" "${DEPLOY_COMMIT}"