Skip to content

Commit

Permalink
Extend the Timezone DBus module
Browse files Browse the repository at this point in the history
Extend the Timezone DBus module API to provide new APIs
needed by the Date and time Screen in the Web UI.

The new API will make it possible to monitor NTP service status,
query and set local system time and get a listing of valid timezones.
  • Loading branch information
M4rtinK committed Jun 19, 2023
1 parent decb65a commit 4cd5fd0
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 0 deletions.
57 changes: 57 additions & 0 deletions pyanaconda/modules/timezone/timezone.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
# License and may only be used or replicated with the express permission of
# Red Hat, Inc.
#

import datetime

from pykickstart.errors import KickstartParseError

from pyanaconda.core.i18n import _
Expand All @@ -34,8 +37,11 @@
from pyanaconda.modules.timezone.initialization import GeolocationTask
from pyanaconda.modules.timezone.installation import ConfigureHardwareClockTask, \
ConfigureNTPTask, ConfigureTimezoneTask
from pyanaconda.modules.timezone.runtime import GetSystemDateTimeTask, \
SetSystemDateTimeTask, GetTimezonesTask
from pyanaconda.modules.timezone.kickstart import TimezoneKickstartSpecification
from pyanaconda.modules.timezone.timezone_interface import TimezoneInterface
from pyanaconda.timezone import get_timezone, set_system_date_time, get_all_regions_and_timezones

from pyanaconda.anaconda_loggers import get_module_logger
log = get_module_logger(__name__)
Expand Down Expand Up @@ -167,6 +173,20 @@ def set_timezone_with_priority(self, timezone, priority):
self.timezone_changed.emit()
log.debug("Timezone is set to %s.", timezone)

def get_timezones(self):
"""Get all valid timezones.
:return: list of valid timezones
:rtype: list of str
"""
timezone_dict = get_all_regions_and_timezones()
# convert to a dict of lists for easier transfer over DBus
# - change the nested sets to lists
new_timezone_dict = {}
for region in timezone_dict:
new_timezone_dict[region] = list(timezone_dict[region])
return new_timezone_dict

@property
def is_utc(self):
"""Is the hardware clock set to UTC?"""
Expand All @@ -189,6 +209,12 @@ def set_ntp_enabled(self, ntp_enabled):
self.ntp_enabled_changed.emit()
log.debug("NTP is set to %s.", ntp_enabled)

@property
def ntp_status(self):
"""Current status of the NTP service."""
# FIXME: hook the ntp_status_changed signal
return self._ntp_status

@property
def time_sources(self):
"""Return a list of time sources."""
Expand Down Expand Up @@ -259,3 +285,34 @@ def geolocation_result(self):
:return GeolocationData: result of the lookup, empty if not ready yet
"""
return self._geoloc_result

def get_system_date_time(self):
"""Get system time as a ISO 8601 formatted string.
:return: system time as ISO 8601 formatted string
:rtype: str
"""
# FIXME: check if this is correct to do ?
if self._timezone is None:
timezone = "America/New_York"
else:
timezone = self._timezone
return datetime.datetime.now(timezone).isoformat()

def set_system_date_time(self, date_time_spec):
"""Set system time based on a ISO 8601 formatted string.
:param str date_time_spec: ISO 8601 time specification to use
"""
log.debug("Setting system time to: %s, with timezone: %s", date_time_spec, self._timezone)
# first convert the ISO 8601 time string to a Python date object
date = datetime.datetime.fromisoformat(self._date_time_spec)
# set the date to the system
set_system_date_time(
year=date.year,
month=date.month,
day=date.day,
hour=date.hour,
minute=date.minute,
tz=self._timezone
)
40 changes: 40 additions & 0 deletions pyanaconda/modules/timezone/timezone_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def connect_signals(self):
self.watch_property("Timezone", self.implementation.timezone_changed)
self.watch_property("IsUTC", self.implementation.is_utc_changed)
self.watch_property("NTPEnabled", self.implementation.ntp_enabled_changed)
self.watch_property("NTPStatus", self.implementation.ntp_status_changed)
self.watch_property("TimeSources", self.implementation.time_sources_changed)
self.watch_property("GeolocationResult", self.implementation.geolocation_result_changed)

Expand Down Expand Up @@ -79,6 +80,15 @@ def SetTimezoneWithPriority(self, timezone: Str, priority: UInt16):
"""
self.implementation.set_timezone_with_priority(timezone, priority)

def GetTimezones(self) -> Dict[Str, List[Str]]:
"""Get valid timezones.
Return a dictionary, where keys are region ids and values are lists of timezone names in the region.
:return: a list of timezones
"""
return self.implementation.get_timezones()

@property
def IsUTC(self) -> Bool:
"""Is the hardware clock set to UTC?
Expand Down Expand Up @@ -116,6 +126,22 @@ def NTPEnabled(self, ntp_enabled: Bool):
"""
self.implementation.set_ntp_enabled(ntp_enabled)

@property
@emits_properties_changed
def NTPStatus(self) -> Str:
"""The status of the NTP service.
Valid values:
IN_PROGRESS The status is being checked right now.
DISABLED The NTP service is disabled.
OFFLINE It is necessary to set up networking first.
NO_SOURCES There are no working time sources configured.
SYNCHRONIZED The time is synchronized by the NTP service.
:return: a string representation of the NTP status
"""
# FIXME: Check what kind of info we are able to get from chronyd.
# Change the valid values if necessary, it is just a suggestion.
return self.implementation.ntp_status

@property
def TimeSources(self) -> List[Structure]:
"""A list of time sources.
Expand Down Expand Up @@ -157,3 +183,17 @@ def GeolocationResult(self) -> Structure:
return GeolocationData.to_structure(
self.implementation.geolocation_result
)

def GetSystemDateTime(self) -> Str:
"""Get the current local date and time of the system.
The timezone set via the Timezone property affects the returned data.
:return: a string representing the date and time in ISO 8601 format
"""
return self.implementation.get_system_date_time()

def SetSystemDateTime(self, date_time_spec: Str):
"""Set the current local date and time of the system.
The timezone set via the Timezone property will be applied to the received data.
:param date_time_spec: a string representing the date and time in ISO 8601 format
"""
self.implementation.set_system_date_time(date_time_spec)

0 comments on commit 4cd5fd0

Please sign in to comment.