From 61fe3f12215bceebde71c35dc7ef14dbc17bb4d7 Mon Sep 17 00:00:00 2001
From: Vendula Poncova <vponcova@redhat.com>
Date: Fri, 3 Jul 2020 18:29:33 +0200
Subject: [PATCH] Add support for the timesource kickstart command

The Timezone module should handle the timesource kickstart command.
---
 anaconda.spec.in                              |  2 +-
 pyanaconda/core/kickstart/commands.py         |  4 +-
 pyanaconda/kickstart.py                       |  1 +
 pyanaconda/modules/timezone/kickstart.py      |  5 ++
 pyanaconda/modules/timezone/timezone.py       | 69 +++++++++++++---
 .../pyanaconda_tests/module_timezone_test.py  | 79 ++++++++++++++++++-
 6 files changed, 141 insertions(+), 19 deletions(-)

diff --git a/anaconda.spec.in b/anaconda.spec.in
index 83adeb9089..c76181d363 100644
--- a/anaconda.spec.in
+++ b/anaconda.spec.in
@@ -33,7 +33,7 @@ Source0: %{name}-%{version}.tar.bz2
 %define libxklavierver 5.4
 %define mehver 0.23-1
 %define nmver 1.0
-%define pykickstartver 3.25-1
+%define pykickstartver 3.27-1
 %define pypartedver 2.5-2
 %define rpmver 4.10.0
 %define simplelinever 1.1-1
diff --git a/pyanaconda/core/kickstart/commands.py b/pyanaconda/core/kickstart/commands.py
index 590027dd33..3c3eed03e2 100644
--- a/pyanaconda/core/kickstart/commands.py
+++ b/pyanaconda/core/kickstart/commands.py
@@ -76,7 +76,8 @@
 from pykickstart.commands.sshpw import F24_SshPw as SshPw
 from pykickstart.commands.sshkey import F22_SshKey as SshKey
 from pykickstart.commands.syspurpose import RHEL8_Syspurpose as Syspurpose
-from pykickstart.commands.timezone import F32_Timezone as Timezone
+from pykickstart.commands.timezone import F33_Timezone as Timezone
+from pykickstart.commands.timesource import F33_Timesource as Timesource
 from pykickstart.commands.updates import F7_Updates as Updates
 from pykickstart.commands.url import F30_Url as Url
 from pykickstart.commands.user import F24_User as User
@@ -107,6 +108,7 @@
 from pykickstart.commands.snapshot import F26_SnapshotData as SnapshotData
 from pykickstart.commands.sshpw import F24_SshPwData as SshPwData
 from pykickstart.commands.sshkey import F22_SshKeyData as SshKeyData
+from pykickstart.commands.timesource import F33_TimesourceData as TimesourceData
 from pykickstart.commands.user import F19_UserData as UserData
 from pykickstart.commands.volgroup import F21_VolGroupData as VolGroupData
 from pykickstart.commands.zfcp import F14_ZFCPData as ZFCPData
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
index d2fcaab44d..946da8bc95 100644
--- a/pyanaconda/kickstart.py
+++ b/pyanaconda/kickstart.py
@@ -372,6 +372,7 @@ def finalize(self):
     "sshkey" : UselessCommand,
     "skipx": UselessCommand,
     "snapshot": UselessCommand,
+    "timesource": UselessCommand,
     "timezone": UselessCommand,
     "url": UselessCommand,
     "user": UselessCommand,
diff --git a/pyanaconda/modules/timezone/kickstart.py b/pyanaconda/modules/timezone/kickstart.py
index 7115322677..b94e4129c3 100644
--- a/pyanaconda/modules/timezone/kickstart.py
+++ b/pyanaconda/modules/timezone/kickstart.py
@@ -24,4 +24,9 @@ class TimezoneKickstartSpecification(KickstartSpecification):
 
     commands = {
         "timezone": COMMANDS.Timezone,
+        "timesource": COMMANDS.Timesource,
+    }
+
+    commands_data = {
+        "TimesourceData": COMMANDS.TimesourceData,
     }
diff --git a/pyanaconda/modules/timezone/timezone.py b/pyanaconda/modules/timezone/timezone.py
index ff89d1ea77..b7fd5b6430 100644
--- a/pyanaconda/modules/timezone/timezone.py
+++ b/pyanaconda/modules/timezone/timezone.py
@@ -17,8 +17,11 @@
 # License and may only be used or replicated with the express permission of
 # Red Hat, Inc.
 #
+from pykickstart.errors import KickstartParseError
+
+from pyanaconda.core.i18n import _
 from pyanaconda.core.configuration.anaconda import conf
-from pyanaconda.core.constants import TIME_SOURCE_SERVER
+from pyanaconda.core.constants import TIME_SOURCE_SERVER, TIME_SOURCE_POOL
 from pyanaconda.core.dbus import DBus
 from pyanaconda.core.signal import Signal
 from pyanaconda.modules.common.base import KickstartService
@@ -73,29 +76,69 @@ def process_kickstart(self, data):
         self.set_is_utc(data.timezone.isUtc)
         self.set_ntp_enabled(not data.timezone.nontp)
 
-        servers = []
+        sources = []
 
         for hostname in data.timezone.ntpservers:
-            server = TimeSourceData()
-            server.type = TIME_SOURCE_SERVER
-            server.hostname = hostname
-            server.options = ["iburst"]
-            servers.append(server)
-
-        self.set_time_sources(servers)
+            source = TimeSourceData()
+            source.type = TIME_SOURCE_SERVER
+            source.hostname = hostname
+            source.options = ["iburst"]
+            sources.append(source)
+
+        for source_data in data.timesource.dataList():
+            if source_data.ntp_disable:
+                self.set_ntp_enabled(False)
+                continue
+
+            source = TimeSourceData()
+            source.options = ["iburst"]
+
+            if source_data.ntp_server:
+                source.type = TIME_SOURCE_SERVER
+                source.hostname = source_data.ntp_server
+            elif source_data.ntp_pool:
+                source.type = TIME_SOURCE_POOL
+                source.hostname = source_data.ntp_pool
+            else:
+                KickstartParseError(
+                    _("Invalid time source."),
+                    lineno=source_data.lineno
+                )
+
+            if source_data.nts:
+                source.options.append("nts")
+
+            sources.append(source)
+
+        self.set_time_sources(sources)
 
     def setup_kickstart(self, data):
         """Set up the kickstart data."""
         data.timezone.timezone = self.timezone
         data.timezone.isUtc = self.is_utc
-        data.timezone.nontp = not self.ntp_enabled
+        source_data_list = data.timesource.dataList()
 
         if not self.ntp_enabled:
+            source_data = data.TimesourceData()
+            source_data.ntp_disable = True
+            source_data_list.append(source_data)
             return
 
-        data.timezone.ntpservers = [
-            server.hostname for server in self.time_sources
-        ]
+        for source in self.time_sources:
+            source_data = data.TimesourceData()
+
+            if source.type == TIME_SOURCE_SERVER:
+                source_data.ntp_server = source.hostname
+            elif source.type == TIME_SOURCE_POOL:
+                source_data.ntp_pool = source.hostname
+            else:
+                log.warning("Skipping %s.", source)
+                continue
+
+            if "nts" in source.options:
+                source_data.nts = True
+
+            source_data_list.append(source_data)
 
     @property
     def timezone(self):
diff --git a/tests/nosetests/pyanaconda_tests/module_timezone_test.py b/tests/nosetests/pyanaconda_tests/module_timezone_test.py
index bb751d6f4b..dab857e034 100644
--- a/tests/nosetests/pyanaconda_tests/module_timezone_test.py
+++ b/tests/nosetests/pyanaconda_tests/module_timezone_test.py
@@ -65,7 +65,7 @@ def _check_dbus_property(self, *args, **kwargs):
 
     def kickstart_properties_test(self):
         """Test kickstart properties."""
-        self.assertEqual(self.timezone_interface.KickstartCommands, ["timezone"])
+        self.assertEqual(self.timezone_interface.KickstartCommands, ["timezone", "timesource"])
         self.assertEqual(self.timezone_interface.KickstartSections, [])
         self.assertEqual(self.timezone_interface.KickstartAddons, [])
         self.callback.assert_not_called()
@@ -143,19 +143,90 @@ def kickstart2_test(self):
         timezone --utc --nontp Europe/Prague
         """
         ks_out = """
+        timesource --ntp-disable
         # System timezone
-        timezone Europe/Prague --utc --nontp
+        timezone Europe/Prague --utc
         """
         self._test_kickstart(ks_in, ks_out)
 
     def kickstart3_test(self):
-        """Test the timezone command with ntp servers.."""
+        """Test the timezone command with ntp servers."""
         ks_in = """
         timezone --ntpservers ntp.cesnet.cz Europe/Prague
         """
         ks_out = """
+        timesource --ntp-server=ntp.cesnet.cz
         # System timezone
-        timezone Europe/Prague --ntpservers=ntp.cesnet.cz
+        timezone Europe/Prague
+        """
+        self._test_kickstart(ks_in, ks_out)
+
+    def kickstart_timesource_ntp_disabled_test(self):
+        """Test the timesource command with ntp disabled."""
+        ks_in = """
+        timesource --ntp-disable
+        """
+        ks_out = """
+        timesource --ntp-disable
+        """
+        self._test_kickstart(ks_in, ks_out)
+
+    def kickstart_timesource_ntp_server_test(self):
+        """Test the timesource command with ntp servers."""
+        ks_in = """
+        timesource --ntp-server ntp.cesnet.cz
+        """
+        ks_out = """
+        timesource --ntp-server=ntp.cesnet.cz
+        """
+        self._test_kickstart(ks_in, ks_out)
+
+    def kickstart_timesource_ntp_pool_test(self):
+        """Test the timesource command with ntp pools."""
+        ks_in = """
+        timesource --ntp-pool ntp.cesnet.cz
+        """
+        ks_out = """
+        timesource --ntp-pool=ntp.cesnet.cz
+        """
+        self._test_kickstart(ks_in, ks_out)
+
+    def kickstart_timesource_nts_test(self):
+        """Test the timesource command with the nts option."""
+        ks_in = """
+        timesource --ntp-pool ntp.cesnet.cz --nts
+        """
+        ks_out = """
+        timesource --ntp-pool=ntp.cesnet.cz --nts
+        """
+        self._test_kickstart(ks_in, ks_out)
+
+    def kickstart_timesource_all_test(self):
+        """Test the timesource commands."""
+        ks_in = """
+        timesource --ntp-server ntp.cesnet.cz
+        timesource --ntp-pool 0.fedora.pool.ntp.org
+        """
+        ks_out = """
+        timesource --ntp-server=ntp.cesnet.cz
+        timesource --ntp-pool=0.fedora.pool.ntp.org
+        """
+        self._test_kickstart(ks_in, ks_out)
+
+    def kickstart_timezone_timesource_test(self):
+        """Test the combination of timezone and timesource commands."""
+        ks_in = """
+        timezone --ntpservers ntp.cesnet.cz,0.fedora.pool.ntp.org Europe/Prague
+        timesource --ntp-server ntp.cesnet.cz --nts
+        timesource --ntp-pool 0.fedora.pool.ntp.org
+        """
+        ks_out = """
+        timesource --ntp-server=ntp.cesnet.cz
+        timesource --ntp-server=0.fedora.pool.ntp.org
+        timesource --ntp-server=ntp.cesnet.cz --nts
+        timesource --ntp-pool=0.fedora.pool.ntp.org
+        # System timezone
+        timezone Europe/Prague
         """
         self._test_kickstart(ks_in, ks_out)
 
--
2.23.0
