mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-04-29 10:10:19 +00:00
config: Allow overriding target path in dropin config component
- To be used when configuration has to change based on the package version. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
parent
38810e566b
commit
cc0a02ad1c
@ -108,14 +108,12 @@ class DropinConfigs(app_module.FollowerComponent):
|
|||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
@staticmethod
|
def get_target_path(self, path):
|
||||||
def get_target_path(path):
|
|
||||||
"""Return Path object for a target path."""
|
"""Return Path object for a target path."""
|
||||||
target = pathlib.Path(DropinConfigs.ROOT)
|
target = pathlib.Path(self.ROOT)
|
||||||
target /= DropinConfigs.DROPIN_CONFIG_ROOT.lstrip('/')
|
target /= self.DROPIN_CONFIG_ROOT.lstrip('/')
|
||||||
return target / path.lstrip('/')
|
return target / path.lstrip('/')
|
||||||
|
|
||||||
@staticmethod
|
def get_etc_path(self, path):
|
||||||
def get_etc_path(path):
|
|
||||||
"""Return Path object for etc path."""
|
"""Return Path object for etc path."""
|
||||||
return pathlib.Path(DropinConfigs.ROOT) / path.lstrip('/')
|
return pathlib.Path(self.ROOT) / path.lstrip('/')
|
||||||
|
|||||||
@ -10,7 +10,7 @@ from plinth import module_loader
|
|||||||
from plinth.actions import privileged
|
from plinth.actions import privileged
|
||||||
|
|
||||||
|
|
||||||
def _assert_managed_dropin_config(app_id: str, path: str):
|
def _get_managed_dropin_config(app_id: str, path: str):
|
||||||
"""Check that this is a path managed by the specified app."""
|
"""Check that this is a path managed by the specified app."""
|
||||||
module_path = module_loader.get_module_import_path(app_id)
|
module_path = module_loader.get_module_import_path(app_id)
|
||||||
module = importlib.import_module(module_path)
|
module = importlib.import_module(module_path)
|
||||||
@ -25,7 +25,7 @@ def _assert_managed_dropin_config(app_id: str, path: str):
|
|||||||
components = app.get_components_of_type(DropinConfigs)
|
components = app.get_components_of_type(DropinConfigs)
|
||||||
for component in components:
|
for component in components:
|
||||||
if path in component.etc_paths:
|
if path in component.etc_paths:
|
||||||
return
|
return component
|
||||||
|
|
||||||
raise AssertionError('Not a managed drop-in config')
|
raise AssertionError('Not a managed drop-in config')
|
||||||
|
|
||||||
@ -37,10 +37,9 @@ def dropin_is_valid(app_id: str, path: str, copy_only: bool,
|
|||||||
|
|
||||||
Optionally, drop the link if it is invalid.
|
Optionally, drop the link if it is invalid.
|
||||||
"""
|
"""
|
||||||
_assert_managed_dropin_config(app_id, path)
|
component = _get_managed_dropin_config(app_id, path)
|
||||||
from plinth.config import DropinConfigs
|
etc_path = component.get_etc_path(path)
|
||||||
etc_path = DropinConfigs.get_etc_path(path)
|
target = component.get_target_path(path)
|
||||||
target = DropinConfigs.get_target_path(path)
|
|
||||||
if etc_path.exists() or etc_path.is_symlink():
|
if etc_path.exists() or etc_path.is_symlink():
|
||||||
if (not copy_only and etc_path.is_symlink()
|
if (not copy_only and etc_path.is_symlink()
|
||||||
and etc_path.readlink() == target):
|
and etc_path.readlink() == target):
|
||||||
@ -59,10 +58,9 @@ def dropin_is_valid(app_id: str, path: str, copy_only: bool,
|
|||||||
@privileged
|
@privileged
|
||||||
def dropin_link(app_id: str, path: str, copy_only: bool):
|
def dropin_link(app_id: str, path: str, copy_only: bool):
|
||||||
"""Create a symlink from /etc/ to /usr/share/freedombox/etc."""
|
"""Create a symlink from /etc/ to /usr/share/freedombox/etc."""
|
||||||
_assert_managed_dropin_config(app_id, path)
|
component = _get_managed_dropin_config(app_id, path)
|
||||||
from plinth.config import DropinConfigs
|
target = component.get_target_path(path)
|
||||||
target = DropinConfigs.get_target_path(path)
|
etc_path = component.get_etc_path(path)
|
||||||
etc_path = DropinConfigs.get_etc_path(path)
|
|
||||||
etc_path.parent.mkdir(parents=True, exist_ok=True)
|
etc_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
if copy_only:
|
if copy_only:
|
||||||
shutil.copyfile(target, etc_path)
|
shutil.copyfile(target, etc_path)
|
||||||
@ -73,7 +71,6 @@ def dropin_link(app_id: str, path: str, copy_only: bool):
|
|||||||
@privileged
|
@privileged
|
||||||
def dropin_unlink(app_id: str, path: str, missing_ok: bool = False):
|
def dropin_unlink(app_id: str, path: str, missing_ok: bool = False):
|
||||||
"""Remove a symlink in /etc/."""
|
"""Remove a symlink in /etc/."""
|
||||||
_assert_managed_dropin_config(app_id, path)
|
component = _get_managed_dropin_config(app_id, path)
|
||||||
from plinth.config import DropinConfigs
|
etc_path = component.get_etc_path(path)
|
||||||
etc_path = DropinConfigs.get_etc_path(path)
|
|
||||||
etc_path.unlink(missing_ok=missing_ok)
|
etc_path.unlink(missing_ok=missing_ok)
|
||||||
|
|||||||
@ -31,9 +31,10 @@ def fixture_dropin_configs():
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def fixture_assert_dropin_config():
|
def fixture_assert_dropin_config(dropin_configs):
|
||||||
"""Mock asserting dropin config path."""
|
"""Mock asserting dropin config path."""
|
||||||
with patch('plinth.privileged.config._assert_managed_dropin_config'):
|
with patch('plinth.privileged.config._get_managed_dropin_config') as mock:
|
||||||
|
mock.return_value = dropin_configs
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
@ -95,7 +96,7 @@ def test_dropin_configs_enable_disable_symlinks(dropin_configs, tmp_path):
|
|||||||
|
|
||||||
# Enable when a file already exists
|
# Enable when a file already exists
|
||||||
dropin_configs.disable()
|
dropin_configs.disable()
|
||||||
etc_path = DropinConfigs.get_etc_path('/etc/test/path1')
|
etc_path = dropin_configs.get_etc_path('/etc/test/path1')
|
||||||
etc_path.touch()
|
etc_path.touch()
|
||||||
dropin_configs.enable()
|
dropin_configs.enable()
|
||||||
_assert_symlinks(dropin_configs, tmp_path, should_exist=True)
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=True)
|
||||||
@ -108,7 +109,7 @@ def test_dropin_configs_enable_disable_symlinks(dropin_configs, tmp_path):
|
|||||||
|
|
||||||
# When symlink already exists to correct location
|
# When symlink already exists to correct location
|
||||||
dropin_configs.disable()
|
dropin_configs.disable()
|
||||||
target_path = DropinConfigs.get_target_path('/etc/test/path1')
|
target_path = dropin_configs.get_target_path('/etc/test/path1')
|
||||||
etc_path.symlink_to(target_path)
|
etc_path.symlink_to(target_path)
|
||||||
dropin_configs.enable()
|
dropin_configs.enable()
|
||||||
_assert_symlinks(dropin_configs, tmp_path, should_exist=True)
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=True)
|
||||||
@ -119,7 +120,7 @@ def test_dropin_configs_enable_disable_copy_only(dropin_configs, tmp_path):
|
|||||||
with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path):
|
with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path):
|
||||||
dropin_configs.copy_only = True
|
dropin_configs.copy_only = True
|
||||||
for path in ['/etc/test/path1', '/etc/path2']:
|
for path in ['/etc/test/path1', '/etc/path2']:
|
||||||
target = DropinConfigs.get_target_path(path)
|
target = dropin_configs.get_target_path(path)
|
||||||
target.parent.mkdir(parents=True, exist_ok=True)
|
target.parent.mkdir(parents=True, exist_ok=True)
|
||||||
target.write_text('test-config-content')
|
target.write_text('test-config-content')
|
||||||
|
|
||||||
@ -135,7 +136,7 @@ def test_dropin_configs_enable_disable_copy_only(dropin_configs, tmp_path):
|
|||||||
|
|
||||||
# Enable when a file already exists with wrong content
|
# Enable when a file already exists with wrong content
|
||||||
dropin_configs.disable()
|
dropin_configs.disable()
|
||||||
etc_path = DropinConfigs.get_etc_path('/etc/test/path1')
|
etc_path = dropin_configs.get_etc_path('/etc/test/path1')
|
||||||
etc_path.write_text('x-invalid-content')
|
etc_path.write_text('x-invalid-content')
|
||||||
dropin_configs.enable()
|
dropin_configs.enable()
|
||||||
_assert_symlinks(dropin_configs, tmp_path, should_exist=True,
|
_assert_symlinks(dropin_configs, tmp_path, should_exist=True,
|
||||||
@ -182,7 +183,7 @@ def test_dropin_config_diagnose_symlinks(dropin_configs, tmp_path):
|
|||||||
|
|
||||||
# A file exists instead of symlink
|
# A file exists instead of symlink
|
||||||
dropin_configs.disable()
|
dropin_configs.disable()
|
||||||
etc_path = DropinConfigs.get_etc_path('/etc/test/path1')
|
etc_path = dropin_configs.get_etc_path('/etc/test/path1')
|
||||||
etc_path.touch()
|
etc_path.touch()
|
||||||
results = dropin_configs.diagnose()
|
results = dropin_configs.diagnose()
|
||||||
assert results[0].result == 'failed'
|
assert results[0].result == 'failed'
|
||||||
@ -204,7 +205,7 @@ def test_dropin_config_diagnose_copy_only(dropin_configs, tmp_path):
|
|||||||
with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path):
|
with patch('plinth.config.DropinConfigs.ROOT', new=tmp_path):
|
||||||
dropin_configs.copy_only = True
|
dropin_configs.copy_only = True
|
||||||
for path in ['/etc/test/path1', '/etc/path2']:
|
for path in ['/etc/test/path1', '/etc/path2']:
|
||||||
target = DropinConfigs.get_target_path(path)
|
target = dropin_configs.get_target_path(path)
|
||||||
target.parent.mkdir(parents=True, exist_ok=True)
|
target.parent.mkdir(parents=True, exist_ok=True)
|
||||||
target.write_text('test-config-content')
|
target.write_text('test-config-content')
|
||||||
|
|
||||||
@ -221,7 +222,7 @@ def test_dropin_config_diagnose_copy_only(dropin_configs, tmp_path):
|
|||||||
|
|
||||||
# A symlink exists instead of a copied file
|
# A symlink exists instead of a copied file
|
||||||
dropin_configs.disable()
|
dropin_configs.disable()
|
||||||
etc_path = DropinConfigs.get_etc_path('/etc/test/path1')
|
etc_path = dropin_configs.get_etc_path('/etc/test/path1')
|
||||||
etc_path.symlink_to('/blah')
|
etc_path.symlink_to('/blah')
|
||||||
results = dropin_configs.diagnose()
|
results = dropin_configs.diagnose()
|
||||||
assert results[0].result == 'failed'
|
assert results[0].result == 'failed'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user