diff options
| -rw-r--r-- | data/templates/chrony/chrony.conf.j2 | 58 | ||||
| -rw-r--r-- | data/templates/chrony/override.conf.j2 (renamed from data/templates/ntp/override.conf.j2) | 5 | ||||
| -rw-r--r-- | data/templates/ntp/ntpd.conf.j2 | 49 | ||||
| -rw-r--r-- | data/templates/telegraf/telegraf.j2 | 2 | ||||
| -rw-r--r-- | debian/control | 3 | ||||
| -rw-r--r-- | interface-definitions/include/version/ntp-version.xml.i | 2 | ||||
| -rw-r--r-- | interface-definitions/ntp.xml.in | 25 | ||||
| -rw-r--r-- | op-mode-definitions/date.xml.in | 22 | ||||
| -rw-r--r-- | op-mode-definitions/monitor-log.xml.in | 6 | ||||
| -rw-r--r-- | op-mode-definitions/show-log.xml.in | 6 | ||||
| -rw-r--r-- | op-mode-definitions/show-ntp.xml.in | 17 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_service_ntp.py (renamed from smoketest/scripts/cli/test_system_ntp.py) | 66 | ||||
| -rwxr-xr-x | src/conf_mode/ntp.py | 23 | ||||
| -rwxr-xr-x | src/migration-scripts/ntp/1-to-2 | 67 | ||||
| -rwxr-xr-x | src/op_mode/show_ntp.sh | 31 | 
15 files changed, 229 insertions, 153 deletions
| diff --git a/data/templates/chrony/chrony.conf.j2 b/data/templates/chrony/chrony.conf.j2 new file mode 100644 index 000000000..b3bfc8c0c --- /dev/null +++ b/data/templates/chrony/chrony.conf.j2 @@ -0,0 +1,58 @@ +### Autogenerated by ntp.py ### + +# This would step the system clock if the adjustment is larger than 0.1 seconds, +# but only in the first three clock updates. +makestep 1.0 3 + +# The rtcsync directive enables a mode where the system time is periodically +# copied to the RTC and chronyd does not try to track its drift. This directive +# cannot be used with the rtcfile directive. On Linux, the RTC copy is performed +# by the kernel every 11 minutes. +rtcsync + +# This directive specifies the maximum amount of memory that chronyd is allowed +# to allocate for logging of client accesses and the state that chronyd as an +# NTP server needs to support the interleaved mode for its clients. +clientloglimit 1048576 + +driftfile /run/chrony/drift +dumpdir /run/chrony +pidfile {{ config_file | replace('.conf', '.pid') }} + +# Determine when will the next leap second occur and what is the current offset +leapsectz right/UTC + +user {{ user }} + +# NTP servers to reach out to +{% if server is vyos_defined %} +{%     for server, config in server.items() %} +{%         set association = 'server' %} +{%         if config.pool is vyos_defined %} +{%             set association = 'pool' %} +{%         endif %} +{{ association }} {{ server | replace('_', '-') }} iburst {{ 'noselect' if config.noselect is vyos_defined }} {{ 'prefer' if config.prefer is vyos_defined }} +{%     endfor %} +{% endif %} + +# Allowed clients configuration +{% if allow_client.address is vyos_defined %} +{%     for address in allow_client.address %} +allow {{ address }} +{%     endfor %} +{% endif %} +deny all + +{% if listen_address is vyos_defined or interface is vyos_defined %} +# NTP should listen on configured addresses only +{%     if listen_address is vyos_defined %} +{%         for address in listen_address %} +bindaddress {{ address }} +{%         endfor %} +{%     endif %} +{%     if interface is vyos_defined %} +{%         for ifname in interface %} +binddevice {{ ifname }} +{%         endfor %} +{%     endif %} +{% endif %} diff --git a/data/templates/ntp/override.conf.j2 b/data/templates/chrony/override.conf.j2 index 6fed9d7d2..9eaea7608 100644 --- a/data/templates/ntp/override.conf.j2 +++ b/data/templates/chrony/override.conf.j2 @@ -5,10 +5,13 @@ ConditionPathExists={{ config_file }}  After=vyos-router.service  [Service] +EnvironmentFile=  ExecStart= -ExecStart={{ vrf_command }}/usr/sbin/ntpd -g -p {{ config_file | replace('.conf', '.pid') }} -c {{ config_file }} -u ntp:ntp +ExecStart={{ vrf_command }}/usr/sbin/chronyd -F 1 -f {{ config_file }}  PIDFile=  PIDFile={{ config_file | replace('.conf', '.pid') }}  Restart=always  RestartSec=10 +# Required for VRF support +ProtectControlGroups=No diff --git a/data/templates/ntp/ntpd.conf.j2 b/data/templates/ntp/ntpd.conf.j2 deleted file mode 100644 index 8921826fa..000000000 --- a/data/templates/ntp/ntpd.conf.j2 +++ /dev/null @@ -1,49 +0,0 @@ -### Autogenerated by ntp.py ### - -# -# Non-configurable defaults -# -driftfile /var/lib/ntp/ntp.drift -# By default, only allow ntpd to query time sources, ignore any incoming requests -restrict default noquery nopeer notrap nomodify -# Allow pool associations -restrict source nomodify notrap noquery -# Local users have unrestricted access, allowing reconfiguration via ntpdc -restrict 127.0.0.1 -restrict -6 ::1 - -# -# Configurable section -# -{% if server is vyos_defined %} -{%     for server, config in server.items() %} -{%         set association = 'server' %} -{%         if config.pool is vyos_defined %} -{%             set association = 'pool' %} -{%         endif %} -{{ association }} {{ server | replace('_', '-') }} iburst {{ 'noselect' if config.noselect is vyos_defined }} {{ 'preempt' if config.preempt is vyos_defined }} {{ 'prefer' if config.prefer is vyos_defined }} -{%     endfor %} -{% endif %} - -{% if allow_clients.address is vyos_defined %} -# Allowed clients configuration -restrict default ignore -{%     for address in allow_clients.address %} -restrict {{ address | address_from_cidr }} mask {{ address | netmask_from_cidr }} nomodify notrap nopeer -{%     endfor %} -{% endif %} - -{% if listen_address is vyos_defined or interface is vyos_defined %} -# NTP should listen on configured addresses only -interface ignore wildcard -{%     if listen_address is vyos_defined %} -{%         for address in listen_address %} -interface listen {{ address }} -{%         endfor %} -{%     endif %} -{%     if interface is vyos_defined %} -{%         for ifname in interface %} -interface listen {{ ifname }} -{%         endfor %} -{%     endif %} -{% endif %} diff --git a/data/templates/telegraf/telegraf.j2 b/data/templates/telegraf/telegraf.j2 index 36571ce98..c9f402281 100644 --- a/data/templates/telegraf/telegraf.j2 +++ b/data/templates/telegraf/telegraf.j2 @@ -102,7 +102,7 @@    dirs = ["/proc/sys/net/ipv4/netfilter","/proc/sys/net/netfilter"]  [[inputs.ethtool]]    interface_include = {{ interfaces_ethernet }} -[[inputs.ntpq]] +[[inputs.chrony]]    dns_lookup = true  [[inputs.internal]]  [[inputs.nstat]] diff --git a/debian/control b/debian/control index a477bffec..1e593d378 100644 --- a/debian/control +++ b/debian/control @@ -101,8 +101,7 @@ Depends:    nfct,    nftables (>= 0.9.3),    nginx-light, -  ntp, -  ntpdate, +  chrony,    nvme-cli,    ocserv,    opennhrp, diff --git a/interface-definitions/include/version/ntp-version.xml.i b/interface-definitions/include/version/ntp-version.xml.i index cc4ff9a1c..9eafbf7f0 100644 --- a/interface-definitions/include/version/ntp-version.xml.i +++ b/interface-definitions/include/version/ntp-version.xml.i @@ -1,3 +1,3 @@  <!-- include start from include/version/ntp-version.xml.i --> -<syntaxVersion component='ntp' version='1'></syntaxVersion> +<syntaxVersion component='ntp' version='2'></syntaxVersion>  <!-- include end --> diff --git a/interface-definitions/ntp.xml.in b/interface-definitions/ntp.xml.in index 85636a50f..65e40ee32 100644 --- a/interface-definitions/ntp.xml.in +++ b/interface-definitions/ntp.xml.in @@ -1,7 +1,7 @@  <?xml version="1.0"?>  <!-- NTP configuration -->  <interfaceDefinition> -  <node name="system"> +  <node name="service">      <children>        <node name="ntp" owner="${vyos_conf_scripts_dir}/ntp.py">          <properties> @@ -43,12 +43,6 @@                    <valueless/>                  </properties>                </leafNode> -              <leafNode name="preempt"> -                <properties> -                  <help>Specifies the association as preemptable rather than the default persistent</help> -                  <valueless/> -                </properties> -              </leafNode>                <leafNode name="prefer">                  <properties>                    <help>Marks the server as preferred</help> @@ -57,24 +51,33 @@                </leafNode>              </children>            </tagNode> -          <node name="allow-clients"> +          <node name="allow-client">              <properties> -              <help>Network Time Protocol (NTP) server options</help> +              <help>Specify NTP clients allowed to access the server</help>              </properties>              <children>                <leafNode name="address">                  <properties>                    <help>IP address</help>                    <valueHelp> +                    <format>ipv4</format> +                    <description>Allowed IPv4 address</description> +                  </valueHelp> +                  <valueHelp>                      <format>ipv4net</format> -                    <description>IP address and prefix length</description> +                    <description>Allowed IPv4 prefix</description> +                  </valueHelp> +                  <valueHelp> +                    <format>ipv6</format> +                    <description>Allowed IPv6 address</description>                    </valueHelp>                    <valueHelp>                      <format>ipv6net</format> -                    <description>IPv6 address and prefix length</description> +                    <description>Allowed IPv6 prefix</description>                    </valueHelp>                    <multi/>                    <constraint> +                    <validator name="ip-address"/>                      <validator name="ip-prefix"/>                    </constraint>                  </properties> diff --git a/op-mode-definitions/date.xml.in b/op-mode-definitions/date.xml.in index 15a69dbd9..6d8586025 100644 --- a/op-mode-definitions/date.xml.in +++ b/op-mode-definitions/date.xml.in @@ -37,28 +37,6 @@          </properties>          <command>/bin/date "$3"</command>        </tagNode> -      <node name="date"> -        <properties> -          <help>Set system date and time</help> -        </properties> -        <children> -          <node name="ntp"> -            <properties> -              <help>Set system date and time from NTP server (default: 0.pool.ntp.org)</help> -            </properties> -            <command>/usr/sbin/ntpdate -u 0.pool.ntp.org</command> -          </node> -          <tagNode name="ntp"> -            <properties> -              <help>Set system date and time from NTP server</help> -              <completionHelp> -                <script>${vyos_completion_dir}/list_ntp_servers.sh</script> -              </completionHelp> -            </properties> -            <command>/usr/sbin/ntpdate -u "$4"</command> -          </tagNode> -        </children> -      </node>      </children>    </node>  </interfaceDefinition> diff --git a/op-mode-definitions/monitor-log.xml.in b/op-mode-definitions/monitor-log.xml.in index 95d5ecf96..d616bfc08 100644 --- a/op-mode-definitions/monitor-log.xml.in +++ b/op-mode-definitions/monitor-log.xml.in @@ -105,6 +105,12 @@              </properties>              <command>journalctl --no-hostname --boot --follow --unit opennhrp.service</command>            </leafNode> +          <leafNode name="ntp"> +            <properties> +              <help>Monitor last lines of Network Time Protocol (NTP) log</help> +            </properties> +            <command>journalctl --no-hostname --boot --follow --unit chrony.service</command> +          </leafNode>            <node name="pppoe">              <properties>                <help>Monitor last lines of PPPoE log</help> diff --git a/op-mode-definitions/show-log.xml.in b/op-mode-definitions/show-log.xml.in index 2984c467c..6608ea0d8 100644 --- a/op-mode-definitions/show-log.xml.in +++ b/op-mode-definitions/show-log.xml.in @@ -220,6 +220,12 @@              </properties>              <command>journalctl --no-hostname --boot --unit opennhrp.service</command>            </leafNode> +          <leafNode name="ntp"> +            <properties> +              <help>Show log for Network Time Protocol (NTP)</help> +            </properties> +            <command>journalctl --no-hostname --boot --unit chrony.service</command> +          </leafNode>            <node name="macsec">              <properties>                <help>Show log for MACsec</help> diff --git a/op-mode-definitions/show-ntp.xml.in b/op-mode-definitions/show-ntp.xml.in index 01f4477d8..0907722af 100644 --- a/op-mode-definitions/show-ntp.xml.in +++ b/op-mode-definitions/show-ntp.xml.in @@ -6,22 +6,13 @@          <properties>            <help>Show peer status of NTP daemon</help>          </properties> -        <command>${vyos_op_scripts_dir}/show_ntp.sh --basic</command> +        <command>${vyos_op_scripts_dir}/show_ntp.sh --sourcestats</command>          <children> -          <tagNode name="server"> +          <node name="system">              <properties> -              <help>Show date and time of specified NTP server</help> -              <completionHelp> -                <script>${vyos_completion_dir}/list_ntp_servers.sh</script> -              </completionHelp> +              <help>Show parameters about the system clock performance</help>              </properties> -            <command>${vyos_op_scripts_dir}/show_ntp.sh --server "$4"</command> -          </tagNode> -          <node name="info"> -            <properties> -              <help>Show NTP operational summary</help> -            </properties> -            <command>${vyos_op_scripts_dir}/show_ntp.sh --info</command> +            <command>${vyos_op_scripts_dir}/show_ntp.sh --tracking</command>            </node>          </children>        </node> diff --git a/smoketest/scripts/cli/test_system_ntp.py b/smoketest/scripts/cli/test_service_ntp.py index a0806acf0..d4793adb6 100755 --- a/smoketest/scripts/cli/test_system_ntp.py +++ b/smoketest/scripts/cli/test_service_ntp.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2019-2022 VyOS maintainers and contributors +# Copyright (C) 2019-2023 VyOS maintainers and contributors  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as @@ -19,14 +19,12 @@ import unittest  from base_vyostest_shim import VyOSUnitTestSHIM  from vyos.configsession import ConfigSessionError -from vyos.template import address_from_cidr -from vyos.template import netmask_from_cidr -from vyos.util import read_file +from vyos.util import cmd  from vyos.util import process_named_running -PROCESS_NAME = 'ntpd' -NTP_CONF = '/run/ntpd/ntpd.conf' -base_path = ['system', 'ntp'] +PROCESS_NAME = 'chronyd' +NTP_CONF = '/run/chrony/chrony.conf' +base_path = ['service', 'ntp']  class TestSystemNTP(VyOSUnitTestSHIM.TestCase):      @classmethod @@ -38,6 +36,8 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase):          cls.cli_delete(cls, base_path)      def tearDown(self): +        self.assertTrue(process_named_running(PROCESS_NAME)) +          self.cli_delete(base_path)          self.cli_commit() @@ -46,7 +46,7 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase):      def test_01_ntp_options(self):          # Test basic NTP support with multiple servers and their options          servers = ['192.0.2.1', '192.0.2.2'] -        options = ['noselect', 'preempt', 'prefer'] +        options = ['noselect', 'prefer']          pools = ['pool.vyos.io']          for server in servers: @@ -61,12 +61,14 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase):          self.cli_commit()          # Check generated configuration -        config = read_file(NTP_CONF) -        self.assertIn('driftfile /var/lib/ntp/ntp.drift', config) -        self.assertIn('restrict default noquery nopeer notrap nomodify', config) -        self.assertIn('restrict source nomodify notrap noquery', config) -        self.assertIn('restrict 127.0.0.1', config) -        self.assertIn('restrict -6 ::1', config) +        # this file must be read with higher permissions +        config = cmd(f'sudo cat {NTP_CONF}') +        self.assertIn('driftfile /run/chrony/drift', config) +        self.assertIn('dumpdir /run/chrony', config) +        self.assertIn('clientloglimit 1048576', config) +        self.assertIn('rtcsync', config) +        self.assertIn('makestep 1.0 3', config) +        self.assertIn('leapsectz right/UTC', config)          for server in servers:              self.assertIn(f'server {server} iburst ' + ' '.join(options), config) @@ -80,9 +82,9 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase):          for listen in listen_address:              self.cli_set(base_path + ['listen-address', listen]) -        networks = ['192.0.2.0/24', '2001:db8:1000::/64'] +        networks = ['192.0.2.0/24', '2001:db8:1000::/64', '100.64.0.0', '2001:db8::ffff']          for network in networks: -            self.cli_set(base_path + ['allow-clients', 'address', network]) +            self.cli_set(base_path + ['allow-client', 'address', network])          # Verify "NTP server not configured" verify() statement          with self.assertRaises(ConfigSessionError): @@ -95,18 +97,14 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase):          self.cli_commit()          # Check generated client address configuration -        config = read_file(NTP_CONF) -        self.assertIn('restrict default ignore', config) - +        # this file must be read with higher permissions +        config = cmd(f'sudo cat {NTP_CONF}')          for network in networks: -            network_address = address_from_cidr(network) -            network_netmask = netmask_from_cidr(network) -            self.assertIn(f'restrict {network_address} mask {network_netmask} nomodify notrap nopeer', config) +            self.assertIn(f'allow {network}', config)          # Check listen address -        self.assertIn('interface ignore wildcard', config)          for listen in listen_address: -            self.assertIn(f'interface listen {listen}', config) +            self.assertIn(f'bindaddress {listen}', config)      def test_03_ntp_interface(self):          interfaces = ['eth0', 'eth1'] @@ -120,10 +118,24 @@ class TestSystemNTP(VyOSUnitTestSHIM.TestCase):          self.cli_commit()          # Check generated client address configuration -        config = read_file(NTP_CONF) -        self.assertIn('interface ignore wildcard', config) +        # this file must be read with higher permissions +        config = cmd(f'sudo cat {NTP_CONF}')          for interface in interfaces: -            self.assertIn(f'interface listen {interface}', config) +            self.assertIn(f'binddevice {interface}', config) + +    def test_04_ntp_vrf(self): +        vrf_name = 'vyos-mgmt' + +        self.cli_set(['vrf', 'name', vrf_name, 'table', '12345']) +        self.cli_set(base_path + ['vrf', vrf_name]) + +        servers = ['time1.vyos.net', 'time2.vyos.net'] +        for server in servers: +            self.cli_set(base_path + ['server', server]) + +        self.cli_commit() + +        self.cli_delete(['vrf', 'name', vrf_name])  if __name__ == '__main__':      unittest.main(verbosity=2) diff --git a/src/conf_mode/ntp.py b/src/conf_mode/ntp.py index 0ecb4d736..92cb73aab 100755 --- a/src/conf_mode/ntp.py +++ b/src/conf_mode/ntp.py @@ -1,6 +1,6 @@  #!/usr/bin/env python3  # -# Copyright (C) 2018-2022 VyOS maintainers and contributors +# Copyright (C) 2018-2023 VyOS maintainers and contributors  #  # This program is free software; you can redistribute it and/or modify  # it under the terms of the GNU General Public License version 2 or later as @@ -21,26 +21,29 @@ from vyos.configdict import is_node_changed  from vyos.configverify import verify_vrf  from vyos.configverify import verify_interface_exists  from vyos.util import call +from vyos.util import chmod_750  from vyos.util import get_interface_config  from vyos.template import render  from vyos import ConfigError  from vyos import airbag  airbag.enable() -config_file = r'/run/ntpd/ntpd.conf' -systemd_override = r'/etc/systemd/system/ntp.service.d/override.conf' +config_file = r'/run/chrony/chrony.conf' +systemd_override = r'/run/systemd/system/chrony.service.d/override.conf' +user_group = '_chrony'  def get_config(config=None):      if config:          conf = config      else:          conf = Config() -    base = ['system', 'ntp'] +    base = ['service', 'ntp']      if not conf.exists(base):          return None      ntp = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)      ntp['config_file'] = config_file +    ntp['user'] = user_group      tmp = is_node_changed(conf, base + ['vrf'])      if tmp: ntp.update({'restart_required': {}}) @@ -52,7 +55,7 @@ def verify(ntp):      if not ntp:          return None -    if 'allow_clients' in ntp and 'server' not in ntp: +    if 'server' not in ntp:          raise ConfigError('NTP server not configured')      verify_vrf(ntp) @@ -77,13 +80,17 @@ def generate(ntp):      if not ntp:          return None -    render(config_file, 'ntp/ntpd.conf.j2', ntp) -    render(systemd_override, 'ntp/override.conf.j2', ntp) +    render(config_file, 'chrony/chrony.conf.j2', ntp, user=user_group, group=user_group) +    render(systemd_override, 'chrony/override.conf.j2', ntp, user=user_group, group=user_group) + +    # Ensure proper permission for chrony command socket +    config_dir = os.path.dirname(config_file) +    chmod_750(config_dir)      return None  def apply(ntp): -    systemd_service = 'ntp.service' +    systemd_service = 'chrony.service'      # Reload systemd manager configuration      call('systemctl daemon-reload') diff --git a/src/migration-scripts/ntp/1-to-2 b/src/migration-scripts/ntp/1-to-2 new file mode 100755 index 000000000..1faf0b0e6 --- /dev/null +++ b/src/migration-scripts/ntp/1-to-2 @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2023 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program.  If not, see <http://www.gnu.org/licenses/>. + +# T3008: move from ntpd to chrony and migrate "system ntp" to "service ntp" + +import sys + +from vyos.configtree import ConfigTree + +if (len(sys.argv) < 1): +    print("Must specify file name!") +    sys.exit(1) + +file_name = sys.argv[1] + +with open(file_name, 'r') as f: +    config_file = f.read() + +config = ConfigTree(config_file) + +base_path = ['system', 'ntp'] +new_base_path = ['service', 'ntp'] +if not config.exists(base_path): +    # Nothing to do +    sys.exit(0) + +# copy "system ntp" to "service ntp" +config.copy(base_path, new_base_path) +config.delete(base_path) + +# chrony does not support the preempt option, drop it +for server in config.list_nodes(new_base_path + ['server']): +    server_base =  new_base_path + ['server', server] +    if config.exists(server_base + ['preempt']): +        config.delete(server_base + ['preempt']) + +# Rename "allow-clients" -> "allow-client" +if config.exists(new_base_path + ['allow-clients']): +    config.rename(new_base_path + ['allow-client']) + +# By default VyOS 1.3 allowed NTP queries for all networks - in chrony we +# explicitly disable this behavior and clients need to be specified using the +# allow-client CLI option. In order to be fully backwards compatible, we specify +# 0.0.0.0/0 and ::/0 as allow networks if not specified otherwise explicitly. +if not config.exists(new_base_path + ['allow-client']): +    config.set(new_base_path + ['allow-client', 'address'], value='0.0.0.0/0', replace=False) +    config.set(new_base_path + ['allow-client', 'address'], value='::/0', replace=False) + +try: +    with open(file_name, 'w') as f: +        f.write(config.to_string()) +except OSError as e: +    print("Failed to save the modified config: {}".format(e)) +    sys.exit(1) diff --git a/src/op_mode/show_ntp.sh b/src/op_mode/show_ntp.sh index e9dd6c5c9..85f8eda15 100755 --- a/src/op_mode/show_ntp.sh +++ b/src/op_mode/show_ntp.sh @@ -1,39 +1,34 @@  #!/bin/sh -basic=0 -info=0 +sourcestats=0 +tracking=0  while [[ "$#" -gt 0 ]]; do      case $1 in -        --info) info=1 ;; -        --basic) basic=1 ;; -        --server) server=$2; shift ;; +        --sourcestats) sourcestats=1 ;; +        --tracking) tracking=1 ;;          *) echo "Unknown parameter passed: $1" ;;      esac      shift  done -if ! ps -C ntpd &>/dev/null; then +if ! ps -C chronyd &>/dev/null; then      echo NTP daemon disabled      exit 1  fi -PID=$(pgrep ntpd) -VRF_NAME=$(ip vrf identify ${PID}) +PID=$(pgrep chronyd | head -n1) +VRF_NAME=$(ip vrf identify )  if [ ! -z ${VRF_NAME} ]; then      VRF_CMD="sudo ip vrf exec ${VRF_NAME}"  fi -if [ $basic -eq 1 ]; then -    $VRF_CMD ntpq -n -c peers -elif [ $info -eq 1 ]; then -    echo "=== sysingo ===" -    $VRF_CMD ntpq -n -c sysinfo -    echo -    echo "=== kerninfo ===" -    $VRF_CMD ntpq -n -c kerninfo -elif [ ! -z $server ]; then -    $VRF_CMD /usr/sbin/ntpdate -q $server +if [ $sourcestats -eq 1 ]; then +    $VRF_CMD chronyc sourcestats -v +elif [ $tracking -eq 1 ]; then +    $VRF_CMD chronyc tracking -v +else +    echo "Unknown option"  fi | 
