Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update hostcfgd to start chrony instead of ntp-config or ntpd #170

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 16 additions & 23 deletions scripts/hostcfgd
Original file line number Diff line number Diff line change
Expand Up @@ -1180,12 +1180,12 @@ class KdumpCfg(object):
class NtpCfg(object):
"""
NtpCfg Config Daemon
1) ntp-config.service handles the configuration updates and then starts ntp.service
2) Both of them start after all the feature services start
1) chrony.service's ExecStartPre handles the configuration updates
2) They start after all the feature services start
3) Purpose of this daemon is to propagate runtime config changes in
NTP, NTP_SERVER, NTP_KEY, and LOOPBACK_INTERFACE
"""
NTP_CONF_RESTART = ['systemctl', 'restart', 'ntp-config']
CHRONY_RESTART = ['systemctl', 'restart', 'chrony']

def __init__(self):
self.cache = {}
Expand All @@ -1195,7 +1195,7 @@ class NtpCfg(object):
"""Load initial NTP configuration

Force load cache on init. NTP config should be taken at boot-time by
ntp and ntp-config services. So loading whole config here.
chrony services. So loading whole config here.

Args:
ntp_global_conf: Global configuration
Expand All @@ -1209,7 +1209,7 @@ class NtpCfg(object):
ntp_global_conf = {}

# Force load cache on init.
# NTP config should be taken at boot-time by ntp and ntp-config
# NTP config should be taken at boot-time by chrony
# services.
self.cache = {
'global': ntp_global_conf.get('global', {}),
Expand All @@ -1228,19 +1228,19 @@ class NtpCfg(object):
if intf_name not in ifs:
return

# Just restart ntp config
# Just restart chrony
try:
run_cmd(self.NTP_CONF_RESTART, True, True)
run_cmd(self.CHRONY_RESTART, True, True)
except Exception:
syslog.syslog(syslog.LOG_ERR, 'NtpCfg: Failed to restart '
'ntp-config service')
'chrony service')
return

def ntp_global_update(self, key: str, data: dict):
"""Update NTP global configuration

The table holds NTP global configuration. It has some configs that
require reloading only but some other require restarting ntp daemon.
require reloading only but some other require restarting chrony daemon.
Handle each of them accordingly.

Args:
Expand All @@ -1260,18 +1260,12 @@ class NtpCfg(object):
new_dhcp = data.get('dhcp')
new_vrf = data.get('vrf')

restart_ntpd = False
if new_dhcp != old_dhcp or new_vrf != old_vrf:
restart_ntpd = True

# Restarting the service
try:
run_cmd(self.NTP_CONF_RESTART, True, True)
if restart_ntpd:
run_cmd(['systemctl', 'restart', 'ntp'], True, True)
run_cmd(self.CHRONY_RESTART, True, True)
except Exception:
syslog.syslog(syslog.LOG_ERR, f'NtpCfg: Failed to restart ntp '
'services')
syslog.syslog(syslog.LOG_ERR, f'NtpCfg: Failed to restart chrony'
'service')
return

# Update the Local Cache
Expand Down Expand Up @@ -1309,10 +1303,10 @@ class NtpCfg(object):

# Restarting the service
try:
run_cmd(self.NTP_CONF_RESTART, True, True)
run_cmd(self.CHRONY_RESTART, True, True)
except Exception:
syslog.syslog(syslog.LOG_ERR, f'NtpCfg: Failed to restart '
'ntp-config service')
'chrony service')
return

# Updating the cache
Expand Down Expand Up @@ -1504,7 +1498,6 @@ class MgmtIfaceCfg(object):
f'config {cfg} for {iface}')
try:
run_cmd(['sudo', 'systemctl', 'restart', 'interfaces-config'], True, True)
run_cmd(['sudo', 'systemctl', 'restart', 'ntp-config'], True, True)
except subprocess.CalledProcessError:
syslog.syslog(syslog.LOG_ERR, f'Failed to restart management '
'interface services')
Expand All @@ -1527,9 +1520,9 @@ class MgmtIfaceCfg(object):

# Restart related vrfs services
try:
run_cmd(['service', 'ntp', 'stop'], True, True)
run_cmd(['systemctl', 'stop', 'chrony'], True, True)
run_cmd(['systemctl', 'restart', 'interfaces-config'], True, True)
run_cmd(['service', 'ntp', 'start'], True, True)
run_cmd(['systemctl', 'start', 'chrony'], True, True)
except subprocess.CalledProcessError:
syslog.syslog(syslog.LOG_ERR, f'Failed to restart management vrf '
'services')
Expand Down
19 changes: 8 additions & 11 deletions tests/hostcfgd/hostcfgd_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,13 @@ def test_ntp_update_ntp_keys(self):
ntpcfgd.ntp_global_update(
'global', MockConfigDb.CONFIG_DB['NTP']['global'])
mocked_subprocess.check_call.assert_has_calls([
call(['systemctl', 'restart', 'ntp-config']),
call(['systemctl', 'restart', 'ntp'])
call(['systemctl', 'restart', 'chrony'])
])

mocked_subprocess.check_call.reset_mock()
ntpcfgd.ntp_srv_key_update({}, MockConfigDb.CONFIG_DB['NTP_KEY'])
mocked_subprocess.check_call.assert_has_calls([
call(['systemctl', 'restart', 'ntp-config'])
call(['systemctl', 'restart', 'chrony'])
])

def test_ntp_global_update_ntp_servers(self):
Expand All @@ -75,14 +74,13 @@ def test_ntp_global_update_ntp_servers(self):
ntpcfgd.ntp_global_update(
'global', MockConfigDb.CONFIG_DB['NTP']['global'])
mocked_subprocess.check_call.assert_has_calls([
call(['systemctl', 'restart', 'ntp-config']),
call(['systemctl', 'restart', 'ntp'])
call(['systemctl', 'restart', 'chrony'])
])

mocked_subprocess.check_call.reset_mock()
ntpcfgd.ntp_srv_key_update({'0.debian.pool.ntp.org': {}}, {})
mocked_subprocess.check_call.assert_has_calls([
call(['systemctl', 'restart', 'ntp-config'])
call(['systemctl', 'restart', 'chrony'])
])

def test_ntp_is_caching_config(self):
Expand Down Expand Up @@ -117,7 +115,7 @@ def test_loopback_update(self):

ntpcfgd.handle_ntp_source_intf_chg('eth0')
mocked_subprocess.check_call.assert_has_calls([
call(['systemctl', 'restart', 'ntp-config'])
call(['systemctl', 'restart', 'chrony'])
])


Expand Down Expand Up @@ -192,7 +190,7 @@ def test_loopback_events(self):
daemon.start()
except TimeoutError:
pass
expected = [call(['systemctl', 'restart', 'ntp-config']),
expected = [call(['systemctl', 'restart', 'chrony']),
call(['iptables', '-t', 'mangle', '--append', 'PREROUTING', '-p', 'tcp', '--tcp-flags', 'SYN', 'SYN', '-d', '10.184.8.233', '-j', 'TCPMSS', '--set-mss', '1460']),
call(['iptables', '-t', 'mangle', '--append', 'POSTROUTING', '-p', 'tcp', '--tcp-flags', 'SYN', 'SYN', '-s', '10.184.8.233', '-j', 'TCPMSS', '--set-mss', '1460'])]
mocked_subprocess.check_call.assert_has_calls(expected, any_order=True)
Expand Down Expand Up @@ -312,10 +310,9 @@ def test_mgmtiface_event(self):

expected = [
call(['sudo', 'systemctl', 'restart', 'interfaces-config']),
call(['sudo', 'systemctl', 'restart', 'ntp-config']),
call(['service', 'ntp', 'stop']),
call(['systemctl', 'stop', 'chrony']),
call(['systemctl', 'restart', 'interfaces-config']),
call(['service', 'ntp', 'start']),
call(['systemctl', 'start', 'chrony']),
call(['ip', '-4', 'route', 'del', 'default', 'dev', 'eth0', 'metric', '202'])
]
mocked_subprocess.check_call.assert_has_calls(expected)
Expand Down
Loading