From f5b3ad741679cd42d2c145e574168dafe3ac15c1 Mon Sep 17 00:00:00 2001 From: Daniel Watkins Date: Fri, 23 Oct 2020 15:20:18 -0400 Subject: [PATCH] stages: don't reset permissions of cloud-init.log every boot (#624) ensure_file needed modification to support doing this, so this commit also includes the following changes: test_util: add tests for util.ensure_file util: add preserve_mode parameter to ensure_file util: add (partial) type annotations to ensure_file LP: #1900837 --- cloudinit/stages.py | 2 +- cloudinit/tests/test_util.py | 45 ++++++++++++++++++++++++ cloudinit/util.py | 8 +++-- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/cloudinit/stages.py b/cloudinit/stages.py index 765f4aab..0cce6e80 100644 --- a/cloudinit/stages.py +++ b/cloudinit/stages.py @@ -148,7 +148,7 @@ class Init(object): util.ensure_dirs(self._initial_subdirs()) log_file = util.get_cfg_option_str(self.cfg, 'def_log_file') if log_file: - util.ensure_file(log_file) + util.ensure_file(log_file, preserve_mode=True) perms = self.cfg.get('syslog_fix_perms') if not perms: perms = {} diff --git a/cloudinit/tests/test_util.py b/cloudinit/tests/test_util.py index 096a3037..77714928 100644 --- a/cloudinit/tests/test_util.py +++ b/cloudinit/tests/test_util.py @@ -771,4 +771,49 @@ class TestRedirectOutputPreexecFn: assert 0 == m_setgid.call_count +@mock.patch("cloudinit.util.write_file") +class TestEnsureFile: + """Tests for ``cloudinit.util.ensure_file``.""" + + def test_parameters_passed_through(self, m_write_file): + """Test the parameters in the signature are passed to write_file.""" + util.ensure_file( + mock.sentinel.path, + mode=mock.sentinel.mode, + preserve_mode=mock.sentinel.preserve_mode, + ) + + assert 1 == m_write_file.call_count + args, kwargs = m_write_file.call_args + assert (mock.sentinel.path,) == args + assert mock.sentinel.mode == kwargs["mode"] + assert mock.sentinel.preserve_mode == kwargs["preserve_mode"] + + @pytest.mark.parametrize( + "kwarg,expected", + [ + # Files should be world-readable by default + ("mode", 0o644), + # The previous behaviour of not preserving mode should be retained + ("preserve_mode", False), + ], + ) + def test_defaults(self, m_write_file, kwarg, expected): + """Test that ensure_file defaults appropriately.""" + util.ensure_file(mock.sentinel.path) + + assert 1 == m_write_file.call_count + _args, kwargs = m_write_file.call_args + assert expected == kwargs[kwarg] + + def test_static_parameters_are_passed(self, m_write_file): + """Test that the static write_files parameters are passed correctly.""" + util.ensure_file(mock.sentinel.path) + + assert 1 == m_write_file.call_count + _args, kwargs = m_write_file.call_args + assert "" == kwargs["content"] + assert "ab" == kwargs["omode"] + + # vi: ts=4 expandtab diff --git a/cloudinit/util.py b/cloudinit/util.py index e47f1cf6..83727544 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -1804,8 +1804,10 @@ def append_file(path, content): write_file(path, content, omode="ab", mode=None) -def ensure_file(path, mode=0o644): - write_file(path, content='', omode="ab", mode=mode) +def ensure_file(path, mode=0o644, preserve_mode=False): + write_file( + path, content="", omode="ab", mode=mode, copy_mode=preserve_mode + ) def safe_int(possible_int): -- 2.27.0