From 21e70e28b3015c1619dacfad8a2218b09e8109ec Mon Sep 17 00:00:00 2001 From: Corey Bryant Date: Wed, 14 Jun 2017 09:57:23 -0400 Subject: [PATCH] Add snap package paths to default config dirs With snap packaging (see snapcraft.io) the package is installed into a read-only squashfs filesystem, which includes the default config. For example, $SNAP/etc/nova/nova.conf. To override the defaults, a separate writable directory is used, and this directory is also unique to the snap. For example, either $SNAP_COMMON/etc/nova/nova.conf, or $SNAP_COMMON/etc/nova/nova.conf.d/ can be used to override config. This patch adds these snap directories to the default config paths where oslo looks for config. For more details on $SNAP and $SNAP_COMMON please refer to https://snapcraft.io/docs/reference/env. Change-Id: I83627e0f215382aedc7b32163e0303b39e8bccf8 Closes-Bug: 1696830 --- oslo_config/cfg.py | 19 +++++++++++++++++-- oslo_config/tests/test_cfg.py | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/oslo_config/cfg.py b/oslo_config/cfg.py index 94d487e8..b067c2d8 100644 --- a/oslo_config/cfg.py +++ b/oslo_config/cfg.py @@ -613,16 +613,27 @@ def _get_config_dirs(project=None): /etc/${project}/ /etc/ - Otherwise, these directories:: + If a project is specified and installed from a snap package, following + directories are also returned: + + ${SNAP}/etc/${project} + ${SNAP_COMMON}/etc/${project} + + Otherwise, if project is not specified, these directories are returned: ~/ /etc/ """ + snap = os.environ.get('SNAP') + snap_c = os.environ.get('SNAP_COMMON') + cfg_dirs = [ _fixpath(os.path.join('~', '.' + project)) if project else None, _fixpath('~'), os.path.join('/etc', project) if project else None, - '/etc' + '/etc', + os.path.join(snap, "etc", project) if snap and project else None, + os.path.join(snap_c, "etc", project) if snap_c and project else None, ] return [x for x in cfg_dirs if x] @@ -673,6 +684,8 @@ def find_config_files(project=None, prog=None, extension='.conf'): ~/ /etc/${project}/ /etc/ + ${SNAP}/etc/${project} + ${SNAP_COMMON}/etc/${project} We return an absolute path for (at most) one of each the default config files, for the topmost directory it exists in. @@ -703,6 +716,8 @@ def find_config_dirs(project=None, prog=None, extension='.conf.d'): ~/ /etc/${project}/ /etc/ + ${SNAP}/etc/${project} + ${SNAP_COMMON}/etc/${project} We return an absolute path for each of the two config dirs, in the first place we find it (iff we find it). diff --git a/oslo_config/tests/test_cfg.py b/oslo_config/tests/test_cfg.py index 51863424..26093e3a 100644 --- a/oslo_config/tests/test_cfg.py +++ b/oslo_config/tests/test_cfg.py @@ -223,6 +223,18 @@ class FindConfigFilesTestCase(BaseTestCase): self.assertEqual(cfg.find_config_files(project='blaa'), config_files) + def test_find_config_files_snap(self): + config_files = ['/snap/nova/current/etc/blaa/blaa.conf'] + fake_env = {'SNAP': '/snap/nova/current/', + 'SNAP_COMMON': '/var/snap/nova/common/'} + + self.useFixture(fixtures.MonkeyPatch('sys.argv', ['foo'])) + self.useFixture(fixtures.MonkeyPatch('os.path.exists', + lambda p: p in config_files)) + self.useFixture(fixtures.MonkeyPatch('os.environ', fake_env)) + + self.assertEqual(cfg.find_config_files(project='blaa'), config_files) + def test_find_config_files_with_extension(self): config_files = ['/etc/foo.json'] @@ -248,6 +260,18 @@ class FindConfigDirsTestCase(BaseTestCase): self.assertEqual(cfg.find_config_dirs(project='blaa'), config_dirs) + def test_find_config_dirs_snap(self): + config_dirs = ['/var/snap/nova/common/etc/blaa/blaa.conf.d'] + fake_env = {'SNAP': '/snap/nova/current/', + 'SNAP_COMMON': '/var/snap/nova/common/'} + + self.useFixture(fixtures.MonkeyPatch('sys.argv', ['foo'])) + self.useFixture(fixtures.MonkeyPatch('os.path.exists', + lambda p: p in config_dirs)) + self.useFixture(fixtures.MonkeyPatch('os.environ', fake_env)) + + self.assertEqual(cfg.find_config_dirs(project='blaa'), config_dirs) + def test_find_config_dirs_non_exists(self): self.useFixture(fixtures.MonkeyPatch('sys.argv', ['foo'])) self.assertEqual(cfg.find_config_dirs(project='blaa'), [])