datetime: Handle timesyncd service runs conditionally

systemd-timesyncd service does not run if we have another NTP daemon installed
or FreedomBox runs inside a container where the host manages the time. In this
case, make the application as unmanaged - app can't be disabled, no app
diagnostics is shown and enable/disable functional tests are skipped.

Closes #1616

Tests performed:
- Run FreedomBox inside a KVM virtualization module, check that
  systemd-timesyncd is running, datetime app can be disabled and all
  diagnostics and date_and_time functional tests pass.
- Run FreedomBox inside a systemd-nspawn container, check that
  systemd-timesyncd is not running, datetime app can't be disabled,
  the diagnostics button is not shown and two date_and_time functional tests
  are skipped.

Signed-off-by: Veiko Aasa <veiko17@disroot.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Veiko Aasa 2020-04-24 09:38:05 +03:00 committed by James Valleroy
parent a327bf650b
commit 7d77a26761
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
4 changed files with 51 additions and 5 deletions

View File

@ -8,12 +8,14 @@ Background:
Given I'm a logged in user
Scenario: Disable network time application
Given the network time application is enabled
Given the network time application can be disabled
And the network time application is enabled
When I disable the network time application
Then the network time service should not be running
Scenario: Enable network time application
Given the network time application is disabled
Given the network time application can be disabled
And the network time application is disabled
When I enable the network time application
Then the network time service should be running

View File

@ -33,6 +33,12 @@ def ntp_is_disabled(session_browser):
application.disable(session_browser, 'ntp')
@given(parsers.parse('the network time application can be disabled'))
def ntp_can_be_disabled(session_browser):
if not application.can_be_disabled(session_browser, 'ntp'):
pytest.skip(f'network time application can\'t be disabled')
@when(parsers.parse('I set the time zone to {time_zone:S}'))
def time_zone_set(session_browser, time_zone):
application.time_zone_set(session_browser, time_zone)

View File

@ -121,6 +121,13 @@ def disable(browser, app_name):
_change_app_status(browser, app_name, 'disabled')
def can_be_disabled(browser, app_name):
"""Return whether the application can be disabled."""
interface.nav_to_module(browser, get_app_module(app_name))
button = browser.find_by_css('button[name="app_enable_disable_button"]')
return bool(button)
def wait_for_config_update(browser, app_name):
while browser.is_element_present_by_css('.running-status.loading'):
sleep(0.1)

View File

@ -29,11 +29,13 @@ _description = [
app = None
class DateTimeApp(app_module.App):
"""FreedomBox app for date and time."""
class UnmanagedDateTimeApp(app_module.App):
"""FreedomBox app for date and time if time syncronization is unmanaged."""
app_id = 'datetime'
can_be_disabled = False
def __init__(self):
"""Create components for the app."""
super().__init__()
@ -48,6 +50,16 @@ class DateTimeApp(app_module.App):
'datetime:index', parent_url_name='system')
self.add(menu_item)
class ManagedDateTimeApp(UnmanagedDateTimeApp):
"""FreedomBox app for date and time if time syncronization is managed."""
can_be_disabled = True
def __init__(self):
"""Create components for the app."""
super().__init__()
daemon = Daemon('daemon-datetime', managed_services[0])
self.add(daemon)
@ -61,7 +73,12 @@ class DateTimeApp(app_module.App):
def init():
"""Initialize the date/time module."""
global app
app = DateTimeApp()
if _is_time_managed():
app = ManagedDateTimeApp()
else:
app = UnmanagedDateTimeApp()
if app.is_enabled():
app.set_enabled(True)
@ -83,3 +100,17 @@ def _diagnose_time_synchronized():
pass
return [_('Time synchronized to NTP server'), result]
def _is_time_managed():
"""Check whether time should be syncronized by the systemd-timesyncd.
systemd-timesyncd does not run if we have another NTP daemon installed or
FreedomBox runs inside a container where the host manages the time.
"""
output = subprocess.check_output([
'systemctl', 'show', '--property=ConditionResult', '--value',
'systemd-timesyncd'
])
return 'yes' in output.decode()