Initial curated ITWorx_MCP_Hub source from 368fba691ea8d23403b4d56b53b5ec670d7c5020
This commit is contained in:
commit
cb5be898ea
663 files changed
+82674
No files matched your search
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate a CycloneDX SBOM per owned image using trivy, plus a digest index."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
OWNED_SERVICES = (
|
||||
"control-api",
|
||||
"worker",
|
||||
"dataplane-router",
|
||||
"web",
|
||||
"connector-knowledge",
|
||||
"connector-gitea",
|
||||
"connector-unraid",
|
||||
"connector-mobilityops",
|
||||
"connector-projectbrain",
|
||||
"connector-appops",
|
||||
"connector-stitch",
|
||||
"docker-read-broker",
|
||||
"observability-collector",
|
||||
)
|
||||
|
||||
|
||||
def _image_id(tag: str) -> str:
|
||||
command = ["docker", "inspect", "--format", "{{.Id}}", tag]
|
||||
return subprocess.run( # noqa: S603
|
||||
command,
|
||||
cwd=ROOT,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
).stdout.strip()
|
||||
|
||||
|
||||
def generate_for_image(tag: str, service: str, output_dir: Path) -> dict[str, Any]:
|
||||
sbom_path = output_dir / f"{service}.cdx.json"
|
||||
command = ["trivy", "image", "--format", "cyclonedx", "--output", str(sbom_path), tag]
|
||||
subprocess.run( # noqa: S603
|
||||
command,
|
||||
cwd=ROOT,
|
||||
check=True,
|
||||
)
|
||||
sbom = json.loads(sbom_path.read_text(encoding="utf-8"))
|
||||
return {
|
||||
"service": service,
|
||||
"tag": tag,
|
||||
"imageId": _image_id(tag),
|
||||
"sbomPath": str(sbom_path.relative_to(ROOT)),
|
||||
"componentCount": len(sbom.get("components", [])),
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"--tag-prefix",
|
||||
default="local/itworx-mcp-hub-",
|
||||
help="image tag prefix; service name and ':dev' are appended",
|
||||
)
|
||||
parser.add_argument("--output-dir", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
args.output_dir = args.output_dir.resolve()
|
||||
args.output_dir.mkdir(parents=True, exist_ok=True)
|
||||
index = []
|
||||
# docs/09-release/PRODUCTION_PROMOTION_RUNBOOK.md is the authoritative
|
||||
# naming source (WP-190 corrected an earlier "control" repository-name
|
||||
# mismatch -- the real pushed/deployed image is "control-api", matching
|
||||
# its SERVICE_NAME build arg, not a shortened alias). Only
|
||||
# dataplane-router and observability-collector use a distinct,
|
||||
# deliberately shorter tag name.
|
||||
tag_service_overrides = {
|
||||
"dataplane-router": "dataplane",
|
||||
"observability-collector": "observability",
|
||||
}
|
||||
for service in OWNED_SERVICES:
|
||||
tag_service = tag_service_overrides.get(service, service)
|
||||
tag = f"{args.tag_prefix}{tag_service}:dev"
|
||||
index.append(generate_for_image(tag, service, args.output_dir))
|
||||
(args.output_dir / "INDEX.json").write_text(
|
||||
json.dumps({"schemaVersion": "1.0", "images": index}, indent=2, sort_keys=True) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
print(f"wrote {len(index)} image SBOMs to {args.output_dir}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in new issue
Block a user