Skip to content
Merged
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
11 changes: 10 additions & 1 deletion src/boot_animation.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,17 @@ def build_runtime_payload(path: str | os.PathLike[str]) -> bytes:
for info in source.infolist():
if info.is_dir():
continue
runtime.writestr(
runtime_info = zipfile.ZipInfo(
info.filename,
date_time=(1980, 1, 1, 0, 0, 0),
)
runtime_info.compress_type = zipfile.ZIP_STORED
runtime_info.create_system = 3
runtime_info.external_attr = (stat.S_IFREG | 0o644) << 16
runtime_info.extra = b""
runtime_info.comment = b""
runtime.writestr(
runtime_info,
_read_member(source, info),
compress_type=zipfile.ZIP_STORED,
)
Expand Down
2 changes: 1 addition & 1 deletion src/ci/selection_variant.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# this helper owns the byte-for-byte representation that is hashed by both the
# build and release preflight paths.

BOOT_ANIMATION_SELECTION_CONTRACT="product-image-root-theme-context-stored-v6"
BOOT_ANIMATION_SELECTION_CONTRACT="product-image-root-theme-context-deterministic-stored-v7"

function selection_variant_manifest() {
local field value
Expand Down
21 changes: 21 additions & 0 deletions tests/boot_animation_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ def write_valid(path: Path, frame: bytes = b"frame") -> None:
archive.writestr("part0/frame.png", frame)


def write_valid_with_timestamp(
path: Path,
timestamp: tuple[int, int, int, int, int, int],
) -> None:
with zipfile.ZipFile(path, "w") as archive:
for name, data in (
("desc.txt", b"1 1 1\np 1 0 part0\n"),
("part0/frame.png", b"frame"),
):
info = zipfile.ZipInfo(name, date_time=timestamp)
info.compress_type = zipfile.ZIP_DEFLATED
archive.writestr(info, data)


def assert_rejected(path: Path, context: str) -> None:
try:
validate_payload(path)
Expand Down Expand Up @@ -84,6 +98,13 @@ def test_runtime_payload_installation() -> None:
files = [info for info in archive.infolist() if not info.is_dir()]
assert files
assert all(info.compress_type == zipfile.ZIP_STORED for info in files)
assert all(info.date_time == (1980, 1, 1, 0, 0, 0) for info in files)

timestamp_a = root / "timestamp-a.zip"
timestamp_b = root / "timestamp-b.zip"
write_valid_with_timestamp(timestamp_a, (2020, 1, 2, 3, 4, 6))
write_valid_with_timestamp(timestamp_b, (2026, 9, 25, 10, 58, 20))
assert build_runtime_payload(timestamp_a) == build_runtime_payload(timestamp_b)

product = FakeExtFs(root / "product-fs")
install_runtime_payload({"product": product}, runtime)
Expand Down
Loading