import json import os import subprocess import time import uuid from pathlib import Path import oci def write_json(path: Path, value: dict) -> None: temporary_path = path.with_suffix(f"{path.suffix}.{uuid.uuid4().hex}.tmp") temporary_path.write_text( json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8", ) temporary_path.replace(path) def main() -> None: if oci.__version__ != "2.160.3": raise RuntimeError(f"unsupported OCI SDK version {oci.__version__}") manifest_path = Path(os.environ["OCI_IMAGE_MANIFEST_PATH"]) pending_path = manifest_path.with_suffix(f"{manifest_path.suffix}.pending") if manifest_path.exists() or pending_path.exists(): raise FileExistsError(f"image manifest already exists for {manifest_path}") secret = json.loads( subprocess.run( [ "vault", "kv", "get", "-format=json", os.environ["OCI_OPERATOR_API_VAULT_PATH"], ], check=True, capture_output=True, text=True, ).stdout )["data"]["data"] config = { "region": secret["region"], "tenancy": secret["tenancy_ocid"], "user": secret["user_ocid"], "fingerprint": secret["fingerprint"], "key_file": "/dev/null", } signer = oci.signer.Signer( secret["tenancy_ocid"], secret["user_ocid"], secret["fingerprint"], None, private_key_content=secret["private_key"], ) client = oci.core.ComputeClient(config, signer=signer) response = client.create_image( oci.core.models.CreateImageDetails( compartment_id=os.environ["OCI_IMAGE_COMPARTMENT_ID"], display_name=os.environ["OCI_IMAGE_NAME"], freeform_tags={ "managed-by": "packer", "service": "oci-l4-relay", }, instance_id=os.environ["OCI_IMAGE_INSTANCE_ID"], ) ) run_uuid = str(uuid.uuid4()) build = { "artifact_id": f"{secret['region']}:{response.data.id}", "build_time": int(time.time()), "builder_type": "oracle-oci", "custom_data": { "admission_sha256": os.environ["OCI_IMAGE_ADMISSION_SHA256"], "base_image_ocid": os.environ["OCI_IMAGE_BASE_IMAGE_OCID"], "guest_sha256": os.environ["OCI_IMAGE_GUEST_SHA256"], "image_revision_sha256": os.environ["OCI_IMAGE_REVISION_SHA256"], "smtp_deny_sha256": os.environ["OCI_IMAGE_SMTP_DENY_SHA256"], "smtp_evidence_sha256": os.environ["OCI_IMAGE_SMTP_EVIDENCE_SHA256"], "vlagent_sha256": os.environ["OCI_IMAGE_VLAGENT_SHA256"], }, "name": "relay", "packer_run_uuid": run_uuid, } write_json( pending_path, { "builds": [build], "last_run_uuid": run_uuid, "lifecycle_state": response.data.lifecycle_state, }, ) image = oci.wait_until( client, client.get_image(response.data.id), "lifecycle_state", "AVAILABLE", max_wait_seconds=1800, ).data write_json( manifest_path, { "builds": [build], "last_run_uuid": run_uuid, "lifecycle_state": image.lifecycle_state, }, ) pending_path.unlink() if __name__ == "__main__": main()