[PATCH] Support for getting NTP servers from DHCP

Martin Kolman mkolman at gmail.com
Thu May 9 13:54:21 UTC 2013


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 at 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
 
-- 
1.8.1.4



More information about the anaconda-patches mailing list