Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions scripts/nvx_tools/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -988,15 +988,25 @@ def _guest_release_inputs(
):
artifact = artifact_path(artifact_name)
document = _read_json_object(manifest, f"{artifact_name} manifest")
if (
document.get("format") != UbuntuBuildConstants.PACKAGE_MANIFEST_VERSION
or document.get("guest") != UbuntuBuildConstants.GUEST_NAME
or document.get("artifact") != artifact.name
or document.get("artifact_sha256") != sha256_file(artifact)
or document.get("input_sha256") != expected_input_sha256
):
expected = {
"format": UbuntuBuildConstants.PACKAGE_MANIFEST_VERSION,
"guest": UbuntuBuildConstants.GUEST_NAME,
"artifact": artifact.name,
"artifact_sha256": sha256_file(artifact),
"input_sha256": expected_input_sha256,
}
mismatches = []
for field, expected_value in expected.items():
actual = document.get(field)
if actual != expected_value:
actual_display = "missing" if field not in document else actual
mismatches.append(
f"{field} {actual_display} (expected {expected_value})"
)
if mismatches:
raise ScriptError(
f"Ubuntu artifact manifest does not match {artifact_name}"
f"Ubuntu artifact manifest does not match {artifact_name}: "
f"{manifest.name} has " + "; ".join(mismatches)
)
return guest_names, alpine_manifests, ubuntu_manifests, azurelinux_manifests

Expand Down
53 changes: 46 additions & 7 deletions scripts/test_nvx_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -21213,12 +21213,12 @@ def test_guest_release_inputs_reject_stale_ubuntu_artifacts(self):
"artifact_path",
side_effect=build_dir.joinpath,
),
self.assertRaisesRegex(
common.ScriptError,
"Ubuntu artifact manifest does not match",
),
self.assertRaises(common.ScriptError) as raised,
):
release._guest_release_inputs(include_azurelinux=True)
message = str(raised.exception)
self.assertIn("artifact_sha256", message)
self.assertNotIn("input_sha256", message)

def test_guest_release_inputs_reject_stale_azurelinux_initramfs(self):
with tempfile.TemporaryDirectory() as temporary:
Expand Down Expand Up @@ -21356,12 +21356,51 @@ def test_guest_release_inputs_reject_stale_ubuntu_source_inputs(self):
"artifact_path",
side_effect=build_dir.joinpath,
),
self.assertRaisesRegex(
common.ScriptError,
"Ubuntu artifact manifest does not match",
self.assertRaises(common.ScriptError) as raised,
):
release._guest_release_inputs(include_azurelinux=True)
message = str(raised.exception)
self.assertIn("input_sha256", message)
self.assertNotIn("artifact_sha256", message)

def test_guest_release_inputs_report_multiple_mismatches_and_missing_fields(
self,
):
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
paths, _kernel_inputs, _revision = _write_release_fixture(root)
build_dir = paths["build"]
manifest_path = build_dir / "initramfs-ubuntu.cpio.gz.packages.json"
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
manifest["format"] = 2
manifest["input_sha256"] = "0" * 64
manifest_path.write_text(json.dumps(manifest), encoding="utf-8")
with (
patch.object(
release,
"artifact_path",
side_effect=build_dir.joinpath,
),
self.assertRaises(common.ScriptError) as raised,
):
release._guest_release_inputs(include_azurelinux=True)
message = str(raised.exception)
self.assertIn("initramfs-ubuntu.cpio.gz.packages.json", message)
self.assertIn("format", message)
self.assertIn("input_sha256", message)

del manifest["artifact_sha256"]
manifest_path.write_text(json.dumps(manifest), encoding="utf-8")
with (
patch.object(
release,
"artifact_path",
side_effect=build_dir.joinpath,
),
self.assertRaises(common.ScriptError) as raised,
):
release._guest_release_inputs(include_azurelinux=True)
self.assertIn("artifact_sha256 missing", str(raised.exception))

def test_package_rejects_tampered_source_metadata_without_replacing_output(self):
cases: tuple[tuple[str, str, object, str], ...] = (
Expand Down