cfg: Read configuration from .d files and multiple locations

- Read configuration files from three different locations.
/usr/share/freedombox/freedombox.config, /etc/plinth/plinth.config and
/etc/freedombox/freedombox.conf. Later listed has higher priority.

- Provide backward compatibility for /etc/plinth/plinth.config files. With lower
priority than /etc/freedombox but higher priority than /usr/share/.

- Read sorted files from config.d directories with the same suffix as original
configuration file. Parse them by priority. This allows administrator/programs
to drop in configuration bits without worry about editing files.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2020-06-23 23:31:29 -07:00 committed by James Valleroy
parent 823735729b
commit aaa306aef5
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
5 changed files with 46 additions and 7 deletions

View File

@ -50,6 +50,19 @@ develop = False
config_files = []
def expand_to_dot_d_paths(file_paths):
"""Expand a list of file paths to include file.d/* also."""
final_list = []
for file_path in file_paths:
final_list.append(str(file_path))
path = pathlib.Path(file_path)
path_d = path.with_suffix(path.suffix + '.d')
for dot_d_file in sorted(path_d.glob('*' + path.suffix)):
final_list.append(str(dot_d_file))
return final_list
def get_develop_config_path():
"""Return config path of current source folder for development mode."""
root_directory = os.path.dirname(os.path.realpath(__file__))
@ -58,15 +71,20 @@ def get_develop_config_path():
return config_path
def get_config_path():
def get_config_paths():
"""Get default config paths."""
return '/etc/freedombox/freedombox.config'
return [
'/usr/share/freedombox/freedombox.config',
'/etc/plinth/plinth.config',
'/etc/freedombox/freedombox.config',
]
def read():
"""Read all configuration files."""
config_path = get_config_path()
read_file(config_path)
config_paths = get_config_paths()
for config_path in expand_to_dot_d_paths(config_paths):
read_file(config_path)
def read_file(config_path):

View File

@ -0,0 +1,2 @@
[Misc]
box_name = FreedomBox01

View File

@ -0,0 +1,2 @@
[Misc]
box_name = FreedomBox02

View File

@ -0,0 +1,2 @@
[Misc]
box_name = FreedomBox03

View File

@ -45,15 +45,30 @@ def test_read_default_config_file():
compare_configurations(parser)
@patch('plinth.cfg.get_config_path')
def test_read_primary_config_file(get_config_path):
@patch('plinth.cfg.get_config_paths')
def test_read_primary_config_file(get_config_paths):
"""Verify that the primary config file is used by default."""
config_path = CONFIG_FILE_WITH_MISSING_OPTIONS
get_config_path.return_value = config_path
get_config_paths.return_value = [config_path]
cfg.read()
assert cfg.config_files[-1] == config_path
@patch('plinth.cfg.get_config_paths')
def test_read_dot_d_config_files(get_config_paths):
"""Verify that the configuration is read from .d directories."""
root_dir = pathlib.Path(__file__).resolve().parent
config_path = root_dir / 'data' / 'configs' / 'freedombox.config'
config_path_d = config_path.with_suffix(config_path.suffix + '.d')
get_config_paths.return_value = [str(config_path)]
cfg.read()
assert cfg.config_files[-3] == str(config_path)
assert cfg.config_files[-2] == str(config_path_d / '01_first.config')
assert cfg.config_files[-1] == str(config_path_d / '02_second.config')
assert cfg.box_name == 'FreedomBox02'
def test_read_develop_config_file():
"""Verify that the correct develop config file is used."""
test_dir = os.path.dirname(os.path.realpath(__file__))