#!/usr/bin/env python3 """Plan-bound production adapter for releases newer than the legacy baseline. All identity comes from the already verified executor request. The adapter has no Git/ref/tag authority and refuses a missing candidate/release-plan binding. """ from __future__ import annotations import hashlib, json, os, shutil, subprocess, sys, tempfile, urllib.error, urllib.request from pathlib import Path from typing import Any, Mapping class AdapterBlocked(RuntimeError): pass ALLOWED_SERVICE_PORTS = {"aios-v2r2c2-production.service": 18928} def _safe(value: str) -> str: if not value or any(ch not in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-" for ch in value): raise AdapterBlocked("invalid_release_identity") return value def _run(*args: str, check: bool = True) -> subprocess.CompletedProcess[str]: result = subprocess.run(args, check=False, capture_output=True, text=True, timeout=60, env={"PATH": os.environ.get("PATH", "")}) if check and result.returncode != 0: raise AdapterBlocked(result.stderr.strip() or "system_command_failed") return result def _sha(path: Path) -> str: if path.is_symlink() or not path.is_file(): raise AdapterBlocked("artifact_must_be_regular_file") digest=hashlib.sha256() with path.open("rb") as stream: for block in iter(lambda: stream.read(1024*1024), b""): digest.update(block) return digest.hexdigest() def _binding(value: Mapping[str, Any]) -> dict[str, Any]: required=("version","target_oid","artifact_sha256","artifact_path","artifact_size","production_service","production_port","candidate_id","release_plan_sha256") if any(key not in value for key in required): raise AdapterBlocked("trusted_binding_incomplete") if str(value["version"]).startswith("V2R1") or not value["candidate_id"] or not value["release_plan_sha256"]: raise AdapterBlocked("legacy_or_unbound_release_rejected") service = str(value["production_service"]) port = int(value["production_port"]) if ALLOWED_SERVICE_PORTS.get(service) != port: raise AdapterBlocked("production_adapter_policy_rejected") return {key:value[key] for key in required} def _paths(binding: Mapping[str, Any]) -> dict[str, Path]: version=_safe(str(binding["version"])); service=_safe(str(binding["production_service"])) root=Path(os.environ.get("AIOS_RELEASE_ROOT", "/opt/aios/releases")) slug=version.lower() return {"release_dir":root/(version+"-"+str(binding["target_oid"])[:12]+"-"+str(binding["artifact_sha256"])[:12]),"current_link":Path("/opt/aios")/slug,"env_file":Path("/etc/aios")/(slug+".env"),"state_file":Path("/var/lib/aios")/slug/"deployment-state.json","unit_file":Path("/etc/systemd/system")/(service+".service" if not service.endswith(".service") else service),"health_url":f"http://127.0.0.1:{int(binding['production_port'])}/health"} def _health(url: str, binding: Mapping[str, Any], *, runtime_verifier=None) -> dict[str, Any]: try: with urllib.request.urlopen(url, timeout=5) as response: body=json.loads(response.read().decode()); status=response.status except (OSError, ValueError, urllib.error.URLError): return {"status":"UNAVAILABLE"} exact=(status==200 and body.get("version")==binding["version"] and body.get("commit_oid")==binding["target_oid"] and body.get("artifact_sha256")==binding["artifact_sha256"] and body.get("deployment_state")=="ACTIVE" and body.get("production_deployed") is True) if str(binding["version"]).startswith("V2R2C6"): # Health bodies are untrusted declarations; even a body containing PASS # cannot certify itself. A host-owned independent verifier must bind # the response to the exact candidate and fresh observed runtime. try: independently_verified = callable(runtime_verifier) and runtime_verifier(binding, body) is True except Exception: independently_verified = False result_status = "ACTIVE_VERIFIED" if exact and independently_verified else "UNKNOWN" else: result_status = "ACTIVE_VERIFIED" if exact else "CONFLICT" return {**body, "status": result_status, "http_status": status} def _extract(artifact: Path, destination: Path) -> None: import tarfile with tarfile.open(artifact, "r:*") as archive: for member in archive.getmembers(): name=Path(member.name) if name.is_absolute() or ".." in name.parts or member.issym() or member.islnk() or not member.isfile() or not member.name.startswith("payload/"): raise AdapterBlocked("unsafe_artifact_member") rel=name.relative_to("payload"); target=destination/rel; target.parent.mkdir(parents=True,exist_ok=True) source=archive.extractfile(member) if source is None: raise AdapterBlocked("artifact_member_unreadable") target.write_bytes(source.read()); os.chmod(target,0o755 if rel.parts and rel.parts[0]=="scripts" else 0o644) def probe(value: Mapping[str, Any]) -> dict[str, Any]: binding=_binding(value); p=_paths(binding); active=_run("systemctl","is-active","--quiet",str(binding["production_service"]),check=False).returncode==0 return _health(str(p["health_url"]),binding) if active else {"status":"NOT_APPLIED","version":binding["version"],"target_oid":binding["target_oid"],"artifact_sha256":binding["artifact_sha256"],"production_deployed":False,"deployment_state":"ABSENT"} def apply(value: Mapping[str, Any]) -> dict[str, Any]: binding=_binding(value) if str(binding["version"]).startswith("V2R2C6"): # This adapter installs exactly one legacy health service. A C6 # multi-component payload requires the governed component host binding; # do not report a health-only installation as a C6 deployment. raise AdapterBlocked("component_host_binding_required") p=_paths(binding); p["release_dir"].parent.mkdir(parents=True, exist_ok=True); artifact=Path(str(binding["artifact_path"])) if artifact.stat().st_size != int(binding["artifact_size"]) or _sha(artifact)!=binding["artifact_sha256"]: raise AdapterBlocked("artifact_binding_mismatch") marker={"schema":"aios.trusted-runtime-release-binding.v1",**binding} marker_path=p["release_dir"]/"DEPLOYMENT-BINDING.json" if p["release_dir"].exists(): if not marker_path.is_file() or json.loads(marker_path.read_text())!=marker: raise AdapterBlocked("existing_release_binding_conflict") else: temp=Path(tempfile.mkdtemp(prefix=p["release_dir"].name+".",dir=str(p["release_dir"].parent))) try: _extract(artifact,temp); (temp/"DEPLOYMENT-BINDING.json").write_text(json.dumps(marker,sort_keys=True,separators=(",",":"))+"\n"); os.rename(temp,p["release_dir"]) except Exception: shutil.rmtree(temp,ignore_errors=True); raise version_file=p["release_dir"] / "VERSION" if not version_file.is_file() or version_file.read_text().strip()!=binding["version"]: raise AdapterBlocked("release_version_mismatch") unit_source=p["release_dir"] / "deploy" / "aios-v2" / "systemd" / str(binding["production_service"]) if not unit_source.is_file(): raise AdapterBlocked("release_unit_missing") p["unit_file"].parent.mkdir(parents=True,exist_ok=True); shutil.copyfile(unit_source,p["unit_file"]) p["current_link"].parent.mkdir(parents=True,exist_ok=True) if p["current_link"].exists() and not p["current_link"].is_symlink(): raise AdapterBlocked("current_release_path_conflict") if not p["current_link"].is_symlink(): p["current_link"].symlink_to(p["release_dir"]) p["state_file"].parent.mkdir(parents=True,exist_ok=True); p["state_file"].write_text(json.dumps({"version":binding["version"],"commit_oid":binding["target_oid"],"artifact_sha256":binding["artifact_sha256"],"candidate_id":binding["candidate_id"],"release_plan_sha256":binding["release_plan_sha256"],"deployment_state":"ACTIVE","production_deployed":True},sort_keys=True)+"\n") env=(f"RELEASE_VERSION={binding['version']}\n" f"TARGET_OID={binding['target_oid']}\n" f"ARTIFACT_SHA256={binding['artifact_sha256']}\n" f"CANDIDATE_ID={binding['candidate_id']}\n" f"RELEASE_PLAN_SHA256={binding['release_plan_sha256']}\n" f"DEPLOYMENT_STATE=ACTIVE\n" f"DEPLOYMENT_STATE_FILE={p['state_file']}\n" f"AIOS_V2R2C2_PORT={binding['production_port']}\n" "AIOS_GITOPS_WRITES_ENABLED=false\n") p["env_file"].parent.mkdir(parents=True,exist_ok=True); p["env_file"].write_text(env) _run("systemctl","daemon-reload"); _run("systemctl","enable",str(binding["production_service"])); _run("systemctl","restart",str(binding["production_service"])) result=_health(str(p["health_url"]),binding) if result["status"]!="ACTIVE_VERIFIED": raise AdapterBlocked("production_health_binding_mismatch") return result def rollback(value: Mapping[str, Any]) -> dict[str, Any]: binding=_binding(value); _run("systemctl","stop",str(binding["production_service"]),check=False); _run("systemctl","disable",str(binding["production_service"]),check=False) p=_paths(binding); p["state_file"].parent.mkdir(parents=True,exist_ok=True); p["state_file"].write_text(json.dumps({"version":binding["version"],"commit_oid":binding["target_oid"],"artifact_sha256":binding["artifact_sha256"],"deployment_state":"ROLLED_BACK","production_deployed":False},sort_keys=True)+"\n") return {"status":"ROLLED_BACK","version":binding["version"],"target_oid":binding["target_oid"],"artifact_sha256":binding["artifact_sha256"],"production_deployed":False,"deployment_state":"ROLLED_BACK"} def main() -> int: value=json.loads(sys.stdin.read()); operation=value.get("operation") result=probe(value) if operation=="probe" else apply(value) if operation=="apply" else rollback(value) if operation=="rollback" else (_ for _ in ()).throw(AdapterBlocked("unsupported_operation")) print(json.dumps(result,sort_keys=True)); return 0 if __name__=="__main__": try: raise SystemExit(main()) except Exception as exc: print(json.dumps({"status":"FAIL_CLOSED","error":type(exc).__name__,"reason":str(exc)},sort_keys=True)); raise SystemExit(2)