diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py index b22d12cf28eb..d3dd29147651 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py @@ -88,29 +88,26 @@ class InitrdWithSecretsWriter: initrd_secrets: Path def write_boot_file(self, path: Path) -> None: - if path.exists(): - # TODO: This is for matching old behavior. Previously, we - # appended secrets to initrd every time no matter what, so - # we must continue doing that. One potential alternative - # would be running the secret script on an empty file and - # using the hashed contents of that file as part of the - # key that the path name is based on. - run([self.initrd_secrets, path]) - else: - with tempfile.NamedTemporaryFile( - mode="wb", - dir=path.parent, - delete=False, - prefix=path.name, - suffix=".tmp", - ) as tmp: - with open(self.source, mode="rb") as source_file: - shutil.copyfileobj(source_file, tmp) - tmp.flush() - run([self.initrd_secrets, tmp.name]) - os.fsync(tmp.fileno()) - tmp.close() - os.rename(tmp.name, path) + # Secrets can change between rebuilds, so always rebuild from the + # pristine initrd into a temp file and rename into place. + tmp = tempfile.NamedTemporaryFile( + mode="wb", + dir=path.parent, + delete=False, + prefix=path.name, + suffix=".tmp", + ) + try: + with open(self.source, mode="rb") as source_file: + shutil.copyfileobj(source_file, tmp) + tmp.close() + run([self.initrd_secrets, tmp.name]) + with open(tmp.name, "rb") as f: + os.fsync(f.fileno()) + except BaseException: + os.unlink(tmp.name) + raise + os.rename(tmp.name, path) @dataclass