This patch adds support for harvesting NTP server addresses from DHCP server responses. The NTP server addresses are converted to hostnames and saved to ksdata.timezone.ntpservers, provided no NTP servers were set from kickstart. This is just the non-GUI part and another patch will add support for using the data in the NTP configuration GUI.
Martin Kolman (1): Support for getting NTP servers from DHCP
pyanaconda/network.py | 24 ++++++++++++++++++++++++ pyanaconda/nm.py | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-)
The DHCP server returns various options back to the client, which may contain a list of NTP servers. This commit adds support for checking the response if it contains some NTP servers. If there are some, they will be stored in ksdata.timezone.ntpservers (only if no NTP servers were specified by kickstart).
Signed-off-by: Martin Kolman mkolman@gmail.com --- pyanaconda/network.py | 24 ++++++++++++++++++++++++ pyanaconda/nm.py | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/pyanaconda/network.py b/pyanaconda/network.py index 7487f32..6f73143 100644 --- a/pyanaconda/network.py +++ b/pyanaconda/network.py @@ -769,6 +769,9 @@ def wait_for_connecting_NM(): """If NM is in connecting state, wait for connection. Return value: NM has got connection."""
+ if nm.nm_is_connected: + return True + if nm.nm_is_connecting(): log.debug("waiting for connecting NM (dhcp?)") else: @@ -888,8 +891,29 @@ def networkInitialize(ksdata): hostname = getHostname() update_hostname_data(ksdata, hostname)
+def _get_ntp_servers_from_dhcp(ksdata): + """Check if some NTP servers were returned from DHCP and set them + to ksdata (if not NTP servers were specified in the kickstart)""" + ntp_servers = nm.nm_ntp_servers_from_dhcp() + log.info("got %d NTP servers from DHCP" % len(ntp_servers)) + hostnames = [] + for server_address in ntp_servers: + try: + hostname = socket.gethostbyaddr(server_address)[0] + except socket.error: + # getting hostname failed, just use the address returned from DHCP + log.debug("getting NTP server hostname failed for address: %s" + % server_address) + hostname = server_address + hostnames.append(hostname) + # check if some NTP servers were specified from kickstart + if not ksdata.timezone.ntpservers: + # no NTP servers were specified, add those from DHCP + ksdata.timezone.ntpservers = hostnames + def wait_for_connecting_NM_thread(ksdata): # connection (e.g. auto default dhcp) is activated by NM service if wait_for_connecting_NM(): hostname = getHostname() update_hostname_data(ksdata, hostname) + _get_ntp_servers_from_dhcp(ksdata) diff --git a/pyanaconda/nm.py b/pyanaconda/nm.py index 55e1a7f..90a93c3 100644 --- a/pyanaconda/nm.py +++ b/pyanaconda/nm.py @@ -24,7 +24,7 @@ from gi.repository import NetworkManager import struct import socket
-from pyanaconda.constants import DEFAULT_DBUS_TIMEOUT +DEFAULT_DBUS_TIMEOUT = 30
device_type_interfaces = { NetworkManager.DeviceType.ETHERNET: "org.freedesktop.NetworkManager.Device.Wired", @@ -263,6 +263,38 @@ def nm_device_ip_addresses(name, version=4):
return retval
+def nm_ntp_servers_from_dhcp(): + """Return a list of NTP servers that were specified the reply of the + DHCP server or empty list if no NTP servers were returned. + The return_hostnames parameter specifies if the NTP server IP + addresses from the DHCP reply should be converted to hostnames. + """ + ntp_servers = [] + # get paths for all actively connected interfaces + active_devices = nm_activated_devices() + for device in active_devices: + # harvest NTP server addresses from DHCPv4 + dhcp4_path = nm_device_property(device, "Dhcp4Config") + dhcp4_proxy = _get_proxy(object_path=dhcp4_path, + interface_name="org.freedesktop.NetworkManager.DHCP4Config") + options = dhcp4_proxy.get_cached_property("Options") + if options and 'ntp_servers' in options.unpack(): + # NTP server addresses returned by DHCP are whitespace delimited + ntp_servers_string = options.unpack()["ntp_servers"] + for ip in ntp_servers_string.split(" "): + ntp_servers.append(ip) + + # harvest NTP servers from DHCPv6 + dhcp6_path = nm_device_property(device, "Dhcp6Config") + dhcp6_proxy = _get_proxy(object_path=dhcp6_path, + interface_name="org.freedesktop.NetworkManager.DHCP6Config") + options = dhcp6_proxy.get_cached_property("Options") + if options is not None: + # NTP server addresses returned by DHCP are whitespace delimited + for ip in options.unpack().split(" "): + ntp_servers.append(ip) + return ntp_servers + def _device_settings(name): """Return object path of device setting
The DHCP server returns various options back to the client, which may contain a list of NTP servers. This commit adds support for checking the response if it contains some NTP servers. If there are some, they will be stored in ksdata.timezone.ntpservers (only if no NTP servers were specified by kickstart).
Oh, great idea. I've just got a couple points to me.
@@ -888,8 +891,29 @@ def networkInitialize(ksdata): hostname = getHostname() update_hostname_data(ksdata, hostname)
+def _get_ntp_servers_from_dhcp(ksdata):
- """Check if some NTP servers were returned from DHCP and set them
- to ksdata (if not NTP servers were specified in the kickstart)"""
- ntp_servers = nm.nm_ntp_servers_from_dhcp()
- log.info("got %d NTP servers from DHCP" % len(ntp_servers))
- hostnames = []
- for server_address in ntp_servers:
try:
hostname = socket.gethostbyaddr(server_address)[0]
except socket.error:
# getting hostname failed, just use the address returned from DHCP
log.debug("getting NTP server hostname failed for address: %s"
% server_address)
hostname = server_address
hostnames.append(hostname)
- # check if some NTP servers were specified from kickstart
- if not ksdata.timezone.ntpservers:
# no NTP servers were specified, add those from DHCP
ksdata.timezone.ntpservers = hostnames
I think you should put this test at the beginning of the function, and invert it like so:
if ksdata.timezone.ntpservers: return
That way, you're not going through all the work of resolving those addresses just to potentially throw it away.
@@ -263,6 +263,38 @@ def nm_device_ip_addresses(name, version=4):
return retval
+def nm_ntp_servers_from_dhcp():
- """Return a list of NTP servers that were specified the reply of the
^
I think you're missing a word there.
DHCP server or empty list if no NTP servers were returned.
The return_hostnames parameter specifies if the NTP server IP
addresses from the DHCP reply should be converted to hostnames.
- """
There's no return_hostnames parameter in this function.
- Chris
anaconda-patches@lists.fedorahosted.org