From 099796a61d17ff40a6973060df234d203ce9bf45 Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 6 Jul 2026 10:09:46 +0300 Subject: [PATCH] Register DC CMS in deploy runner --- infra/deploy-runner/nodedc-deploy | 96 +++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/infra/deploy-runner/nodedc-deploy b/infra/deploy-runner/nodedc-deploy index e7115b1..e992558 100755 --- a/infra/deploy-runner/nodedc-deploy +++ b/infra/deploy-runner/nodedc-deploy @@ -134,7 +134,29 @@ COMPONENTS = { "healthchecks": ( "http://127.0.0.1:18100/api/auth/session", ), - } + }, + "dc-cms": { + "payload_root": Path("/volume1/docker/dc-cms/source"), + "compose_root": Path("/volume1/docker/dc-cms/source/infra"), + "compose_env_file": Path("/volume1/docker/dc-cms/source/infra/.env.synology"), + "compose_files": ( + Path("/volume1/docker/dc-cms/source/infra/docker-compose.yml"), + ), + "bootstrap_root": True, + "compose_build": True, + "compose_no_deps": True, + "services": ("postgresql-authentik", "authentik-server", "authentik-worker", "cms-app", "reverse-proxy"), + "healthchecks": ( + { + "url": "http://172.22.0.222:9918/healthz", + "headers": {"Host": "cms.dcserve.ru"}, + }, + { + "url": "http://172.22.0.222:9919/", + "headers": {"Host": "auth.dcserve.ru"}, + }, + ), + }, } @@ -435,6 +457,11 @@ def denied_payload_path(component, rel): "converter/Dockerfile", ): pass + elif component == "dc-cms" and rel in ( + "Dockerfile", + "infra/docker-compose.yml", + ): + pass elif base in (".env", "dockerfile", "docker-compose.yml", "compose.yml"): return "sensitive or infrastructure filename" @@ -535,6 +562,29 @@ def denied_payload_path(component, rel): return "bim-viewer env file" if rel.startswith(("docker-compose.beam.yml.bak",)): return "bim-viewer backup file" + elif component == "dc-cms": + runtime_prefixes = ( + "admin/uploads", + "infra/authentik/certs", + "infra/authentik/data", + "infra/authentik/media", + "infra/authentik/postgresql", + "server/data", + "server/logs", + "server/storage", + "sites", + ) + if rel == ".env" or rel.startswith(".env."): + return "dc-cms root env file" + if rel in ("infra/.env", "infra/.env.synology"): + return "dc-cms env file" + if rel.startswith("infra/.env.") and rel not in ( + "infra/.env.example", + "infra/.env.synology.example", + ): + return "dc-cms env file" + if rel.startswith(("Dockerfile.bak", "infra/docker-compose.yml.bak")): + return "dc-cms backup file" if any(rel == prefix or rel.startswith(prefix + "/") for prefix in runtime_prefixes): return "runtime data path" @@ -677,6 +727,29 @@ def allowed_payload_path(component, rel): )): return True + if component == "dc-cms": + if rel in ( + ".dockerignore", + ".gitignore", + "Dockerfile", + "README.md", + "package.json", + "package-lock.json", + "infra/.env.example", + "infra/.env.synology.example", + "infra/docker-compose.yml", + "infra/authentik/bootstrap-cms.py", + ): + return True + if rel.startswith(( + "admin/", + "infra/authentik/custom-templates/", + "infra/reverse-proxy/", + "projects/", + "server/", + )): + return True + die(f"path allowlist rejected: {rel}") @@ -1080,6 +1153,10 @@ def run_compose(component, services): def prepare_component_runtime(component): + if component == "dc-cms": + (Path("/volume1/docker/dc-cms/sites") / "nodedc").mkdir(parents=True, exist_ok=True) + return + if component != "bim-viewer": return @@ -1165,6 +1242,7 @@ def apply_artifact(artifact): component = manifest["component"] root = component_root(component) compose_root = component_compose_root(component) + bootstrap_root = bool(COMPONENTS[component].get("bootstrap_root")) services = component_services(component, entries) if state_has_sha(sha): @@ -1172,14 +1250,24 @@ def apply_artifact(artifact): if state_has_patch_id(patch_id): die(f"patch id already applied: {patch_id}") if not root.is_dir(): - die(f"component payload root not found: {root}") + if bootstrap_root: + root.mkdir(parents=True, exist_ok=True) + else: + die(f"component payload root not found: {root}") if not compose_root.is_dir(): - die(f"component compose root not found: {compose_root}") + if bootstrap_root and is_relative_to(compose_root.resolve(strict=False), root.resolve(strict=False)): + compose_root.mkdir(parents=True, exist_ok=True) + else: + die(f"component compose root not found: {compose_root}") compose_files = component_compose_files(component) if compose_files: for compose_file in compose_files: if not compose_file.is_file(): - die(f"compose file not found: {compose_file}") + compose_entry = None + if is_relative_to(compose_file.resolve(strict=False), root.resolve(strict=False)): + compose_entry = compose_file.resolve(strict=False).relative_to(root.resolve(strict=False)).as_posix() + if not bootstrap_root or compose_entry not in entries: + die(f"compose file not found: {compose_file}") elif not (compose_root / "docker-compose.yml").is_file(): die(f"docker-compose.yml not found in component compose root: {compose_root}") compose_env_file = component_compose_env_file(component)