fix(security): stage multi-platform runtime image
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m16s
CD Pipeline / build-and-deploy (push) Failing after 4m9s
CD Pipeline / post-deploy-checks (push) Has been skipped
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m16s
CD Pipeline / build-and-deploy (push) Failing after 4m9s
CD Pipeline / post-deploy-checks (push) Has been skipped
This commit is contained in:
@@ -603,9 +603,25 @@ def _registry_descriptor(image_ref: str) -> RegistryDescriptor | None:
|
||||
)
|
||||
|
||||
|
||||
def _local_config_digest(image_ref: str) -> str:
|
||||
output = _run(["docker", "image", "inspect", "--format={{.Id}}", image_ref]).stdout
|
||||
return _require_digest((output or "").strip(), "local_config_digest")
|
||||
def _local_platform_digest(image_ref: str, platform: str) -> str:
|
||||
output = _run(
|
||||
[
|
||||
"docker",
|
||||
"image",
|
||||
"inspect",
|
||||
"--platform",
|
||||
platform,
|
||||
"--format={{json .Descriptor}}",
|
||||
image_ref,
|
||||
]
|
||||
).stdout
|
||||
try:
|
||||
descriptor = json.loads(output or "{}")
|
||||
except json.JSONDecodeError as exc:
|
||||
raise ControllerError("local_platform_descriptor_invalid") from exc
|
||||
if not isinstance(descriptor, dict):
|
||||
raise ControllerError("local_platform_descriptor_invalid")
|
||||
return _require_digest(descriptor.get("digest"), "local_platform_digest")
|
||||
|
||||
|
||||
def _local_image_present(image_ref: str) -> bool:
|
||||
@@ -675,14 +691,30 @@ def mirror_images(
|
||||
if not _archive_contains_digest(archive, image.platform_digest):
|
||||
raise ControllerError("runtime_cache_export_digest_missing")
|
||||
_run(
|
||||
["docker", "load", "--input", str(archive)],
|
||||
[
|
||||
"docker",
|
||||
"load",
|
||||
"--platform",
|
||||
policy.platform,
|
||||
"--input",
|
||||
str(archive),
|
||||
],
|
||||
quiet=True,
|
||||
)
|
||||
_run(
|
||||
["docker", "tag", source_ref, image.push_ref],
|
||||
quiet=True,
|
||||
)
|
||||
_run(["docker", "push", image.push_ref], quiet=True)
|
||||
_run(
|
||||
[
|
||||
"docker",
|
||||
"push",
|
||||
"--platform",
|
||||
policy.platform,
|
||||
image.push_ref,
|
||||
],
|
||||
quiet=True,
|
||||
)
|
||||
finally:
|
||||
_remove_local_image(image.push_ref)
|
||||
if not source_preexisting:
|
||||
@@ -763,17 +795,40 @@ def stage_images(
|
||||
cache.export(source_ref, archive)
|
||||
if not _archive_contains_digest(archive, image.platform_digest):
|
||||
raise ControllerError("runtime_cache_export_digest_missing")
|
||||
if not _archive_contains_digest(archive, source_config_digest):
|
||||
raise ControllerError(
|
||||
"runtime_cache_export_config_digest_missing"
|
||||
)
|
||||
_run(
|
||||
["docker", "load", "--input", str(archive)],
|
||||
[
|
||||
"docker",
|
||||
"load",
|
||||
"--platform",
|
||||
policy.platform,
|
||||
"--input",
|
||||
str(archive),
|
||||
],
|
||||
quiet=True,
|
||||
)
|
||||
if _local_config_digest(source_ref) != source_config_digest:
|
||||
raise ControllerError("local_image_config_digest_mismatch")
|
||||
if (
|
||||
_local_platform_digest(source_ref, policy.platform)
|
||||
!= image.platform_digest
|
||||
):
|
||||
raise ControllerError("local_image_platform_digest_mismatch")
|
||||
_run(
|
||||
["docker", "tag", source_ref, image.push_ref],
|
||||
quiet=True,
|
||||
)
|
||||
_run(["docker", "push", image.push_ref], quiet=True)
|
||||
_run(
|
||||
[
|
||||
"docker",
|
||||
"push",
|
||||
"--platform",
|
||||
policy.platform,
|
||||
image.push_ref,
|
||||
],
|
||||
quiet=True,
|
||||
)
|
||||
finally:
|
||||
_remove_local_image(image.push_ref)
|
||||
if not source_preexisting:
|
||||
|
||||
Reference in New Issue
Block a user