From 40e72860e6a7d8876731cc1cfda4e499d119f2a1 Mon Sep 17 00:00:00 2001 From: Daniel Watkins Date: Fri, 19 Jun 2020 12:03:53 -0400 Subject: [PATCH] util: add ensure_dir_exists parameter to write_file (#443) This allows us to disable the `ensure_dir` call when it isn't appropriate. --- cloudinit/util.py | 16 ++++++++++++++-- tests/unittests/test_util.py | 11 +++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/cloudinit/util.py b/cloudinit/util.py index 23d24c4cbb9..81369652861 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -1800,7 +1800,15 @@ def chmod(path, mode): os.chmod(path, real_mode) -def write_file(filename, content, mode=0o644, omode="wb", preserve_mode=False): +def write_file( + filename, + content, + mode=0o644, + omode="wb", + preserve_mode=False, + *, + ensure_dir_exists=True +): """ Writes a file with the given content and sets the file mode as specified. Restores the SELinux context if possible. @@ -1811,6 +1819,9 @@ def write_file(filename, content, mode=0o644, omode="wb", preserve_mode=False): @param omode: The open mode used when opening the file (w, wb, a, etc.) @param preserve_mode: If True and `filename` exists, preserve `filename`s current mode instead of applying `mode`. + @param ensure_dir_exists: If True (the default), ensure that the directory + containing `filename` exists before writing to + the file. """ if preserve_mode: @@ -1820,7 +1831,8 @@ def write_file(filename, content, mode=0o644, omode="wb", preserve_mode=False): except OSError: pass - ensure_dir(os.path.dirname(filename)) + if ensure_dir_exists: + ensure_dir(os.path.dirname(filename)) if 'b' in omode.lower(): content = encode_text(content) write_type = 'bytes' diff --git a/tests/unittests/test_util.py b/tests/unittests/test_util.py index 0821341fcb2..409dba61c52 100644 --- a/tests/unittests/test_util.py +++ b/tests/unittests/test_util.py @@ -98,6 +98,17 @@ def test_dir_is_created_if_required(self): self.assertTrue(os.path.isdir(dirname)) self.assertTrue(os.path.isfile(path)) + def test_dir_is_not_created_if_ensure_dir_false(self): + """Verify directories are not created if ensure_dir_exists is False.""" + dirname = os.path.join(self.tmp, "subdir") + path = os.path.join(dirname, "NewFile.txt") + contents = "Hey there" + + with self.assertRaises(FileNotFoundError): + util.write_file(path, contents, ensure_dir_exists=False) + + self.assertFalse(os.path.isdir(dirname)) + def test_explicit_mode(self): """Verify explicit file mode works properly.""" path = os.path.join(self.tmp, "NewFile.txt")