From ab81cfba7fa68877b2a40e2bb85944544718b50a Mon Sep 17 00:00:00 2001 From: Suvaditya Mukherjee Date: Sun, 29 Aug 2021 20:07:57 +0530 Subject: [PATCH] Fixes #1526 to make the persist_metadata function an atomic operation Co-authored-by: Jussi Kukkonen Signed-off-by: Suvaditya Mukherjee Signed-off-by: Jussi Kukkonen --- tuf/ngclient/updater.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tuf/ngclient/updater.py b/tuf/ngclient/updater.py index a3c7189d..81a5d32e 100644 --- a/tuf/ngclient/updater.py +++ b/tuf/ngclient/updater.py @@ -62,6 +62,7 @@ import logging import os +import tempfile from typing import List, Optional, Set, Tuple from urllib import parse @@ -287,8 +288,17 @@ def _load_local_metadata(self, rolename: str) -> bytes: return f.read() def _persist_metadata(self, rolename: str, data: bytes) -> None: - with open(os.path.join(self._dir, f"{rolename}.json"), "wb") as f: - f.write(data) + """Acts as an atomic write operation to make sure + that if the process of writing is halted, at least the + original data is left intact. + """ + + original_filename = os.path.join(self._dir, f"{rolename}.json") + with tempfile.NamedTemporaryFile( + dir=self._dir, delete=False + ) as temp_file: + temp_file.write(data) + os.replace(temp_file.name, original_filename) def _load_root(self) -> None: """Load remote root metadata.