diff --git a/lib/config.py b/lib/config.py index e620c2104d744ae2fe0a9765e932c79871479b67..cda94416846b185b56ce7693be725d1b013e2290 100644 --- a/lib/config.py +++ b/lib/config.py @@ -48,6 +48,7 @@ from ganeti import objects from ganeti import serializer from ganeti import uidpool from ganeti import netutils +from ganeti import runtime _config_lock = locking.SharedLock("ConfigWriter") @@ -134,7 +135,7 @@ class ConfigWriter: @ivar _all_rms: a list of all temporary reservation managers """ - def __init__(self, cfg_file=None, offline=False): + def __init__(self, cfg_file=None, offline=False, _getents=runtime.GetEnts): self.write_count = 0 self._lock = _config_lock self._config_data = None @@ -143,6 +144,7 @@ class ConfigWriter: self._cfg_file = constants.CLUSTER_CONF_FILE else: self._cfg_file = cfg_file + self._getents = _getents self._temporary_ids = TemporaryReservationManager() self._temporary_drbds = {} self._temporary_macs = TemporaryReservationManager() @@ -1342,7 +1344,8 @@ class ConfigWriter: self._BumpSerialNo() txt = serializer.Dump(self._config_data.ToDict()) - utils.WriteFile(destination, data=txt) + getents = self._getents() + utils.WriteFile(destination, data=txt, gid=getents.confd_gid, mode=0640) self.write_count += 1 diff --git a/test/ganeti.config_unittest.py b/test/ganeti.config_unittest.py index 32a8cb84370d195957f567c25d1cc2ffa5697337..984bfff629eb24530f91d7a4c3b359c348be1b48 100755 --- a/test/ganeti.config_unittest.py +++ b/test/ganeti.config_unittest.py @@ -38,6 +38,11 @@ from ganeti import utils from ganeti import netutils import testutils +import mocks + + +def _StubGetEntResolver(): + return mocks.FakeGetentResolver() class TestConfigRunner(unittest.TestCase): @@ -55,7 +60,8 @@ class TestConfigRunner(unittest.TestCase): def _get_object(self): """Returns a instance of ConfigWriter""" - cfg = config.ConfigWriter(cfg_file=self.cfg_file, offline=True) + cfg = config.ConfigWriter(cfg_file=self.cfg_file, offline=True, + _getents=_StubGetEntResolver) return cfg def _init_cluster(self, cfg): diff --git a/test/mocks.py b/test/mocks.py index b2fb1392a90839077ed1f3062c4da47b04897e0a..a5140fb579629d778f086fd5fe57c4d882b4dbe7 100644 --- a/test/mocks.py +++ b/test/mocks.py @@ -21,6 +21,9 @@ """Module implementing a fake ConfigWriter""" + +import os + from ganeti import utils from ganeti import netutils @@ -79,3 +82,24 @@ class FakeContext: self.cfg = FakeConfig() # TODO: decide what features a mock Ganeti Lock Manager must have self.GLM = None + + +class FakeGetentResolver: + """Fake runtime.GetentResolver""" + + def __init__(self): + # As we nomally don't run under root we use our own uid/gid for all + # fields. This way we don't run into permission denied problems. + uid = os.getuid() + gid = os.getgid() + + self.masterd_uid = uid + self.masterd_gid = gid + self.confd_uid = uid + self.confd_gid = gid + self.rapi_uid = uid + self.rapi_gid = gid + self.noded_uid = uid + + self.daemons_gid = gid + self.admin_gid = gid