Skip to content

Commit 48ffbaa

Browse files
committed
Force immediate NTP time sync with chronyd at IPA startup
In order to make sure we have the correct time early, e.g. by the time we create a TLS certificate, this patch proposes to force an immediate NTP update when using chronyd. While the previous approach uses the passed NTP server as well, the update may happen only after chronyd has performed measurements (which may be too late). Story: #2009058 Task: #42843 Change-Id: I6edafe8edeb8549f324959e7a1ec175c3049a515 (cherry picked from commit 5531d5c)
1 parent 97ce08d commit 48ffbaa

File tree

4 files changed

+19
-46
lines changed

4 files changed

+19
-46
lines changed

ironic_python_agent/tests/unit/extensions/test_standby.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,15 +1355,15 @@ def test__sync_clock(self, execute_mock, mock_timemethod):
13551355

13561356
self.agent_extension._sync_clock()
13571357

1358-
calls = [mock.call('chronyd', check_exit_code=[0, 1]),
1359-
mock.call('chronyc', 'add', 'server', '192.168.1.1'),
1360-
mock.call('chronyc', 'makestep'),
1358+
calls = [mock.call('chronyc', 'shutdown', check_exit_code=[0, 1]),
1359+
mock.call("chronyd -q 'server 192.168.1.1 iburst'",
1360+
shell=True),
13611361
mock.call('hwclock', '-v', '--systohc')]
13621362
execute_mock.assert_has_calls(calls)
13631363

13641364
execute_mock.reset_mock()
13651365
execute_mock.side_effect = [
1366-
('', ''), ('', ''), ('', ''),
1366+
('', ''), ('', ''),
13671367
processutils.ProcessExecutionError('boop')
13681368
]
13691369

ironic_python_agent/tests/unit/test_utils.py

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -929,27 +929,8 @@ def test_sync_clock_chrony(self, mock_time_method, mock_execute):
929929
mock_time_method.return_value = 'chronyd'
930930
utils.sync_clock()
931931
mock_execute.assert_has_calls([
932-
mock.call('chronyd', check_exit_code=[0, 1]),
933-
mock.call('chronyc', 'add', 'server', '192.168.1.1'),
934-
mock.call('chronyc', 'makestep'),
935-
])
936-
937-
@mock.patch.object(utils, 'determine_time_method', autospec=True)
938-
def test_sync_clock_chrony_already_present(self, mock_time_method,
939-
mock_execute):
940-
self.config(ntp_server='192.168.1.1')
941-
mock_time_method.return_value = 'chronyd'
942-
mock_execute.side_effect = [
943-
('', ''),
944-
processutils.ProcessExecutionError(
945-
stderr='Source already present'),
946-
('', ''),
947-
]
948-
utils.sync_clock()
949-
mock_execute.assert_has_calls([
950-
mock.call('chronyd', check_exit_code=[0, 1]),
951-
mock.call('chronyc', 'add', 'server', '192.168.1.1'),
952-
mock.call('chronyc', 'makestep'),
932+
mock.call('chronyc', 'shutdown', check_exit_code=[0, 1]),
933+
mock.call("chronyd -q 'server 192.168.1.1 iburst'", shell=True),
953934
])
954935

955936
@mock.patch.object(utils, 'determine_time_method', autospec=True)
@@ -962,12 +943,8 @@ def test_sync_clock_chrony_failure(self, mock_time_method, mock_execute):
962943
processutils.ProcessExecutionError(stderr='time verboten'),
963944
]
964945
self.assertRaisesRegex(errors.CommandExecutionError,
965-
'Error occured adding ntp',
966-
utils.sync_clock)
967-
mock_execute.assert_has_calls([
968-
mock.call('chronyd', check_exit_code=[0, 1]),
969-
mock.call('chronyc', 'add', 'server', '192.168.1.1'),
970-
])
946+
'Failed to sync time using chrony to ntp '
947+
'server:', utils.sync_clock)
971948

972949
@mock.patch.object(utils, 'determine_time_method', autospec=True)
973950
def test_sync_clock_none(self, mock_time_method, mock_execute):

ironic_python_agent/utils.py

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -699,21 +699,11 @@ def sync_clock(ignore_errors=False):
699699
raise errors.CommandExecutionError(msg)
700700
elif method == 'chronyd':
701701
try:
702-
# 0 should be if chronyd started
703-
# 1 if already running
704-
execute('chronyd', check_exit_code=[0, 1])
705-
# NOTE(TheJulia): Once started, chronyd forks and stays in the
706-
# background as a server service, it will continue to keep the
707-
# clock in sync.
708-
try:
709-
execute('chronyc', 'add', 'server', CONF.ntp_server)
710-
except processutils.ProcessExecutionError as e:
711-
if 'Source already present' not in str(e):
712-
msg = 'Error occured adding ntp server: %s' % e
713-
LOG.error(msg)
714-
raise errors.CommandExecutionError(msg)
715-
# Force the clock to sync now.
716-
execute('chronyc', 'makestep')
702+
# stop chronyd, ignore if it ran before or not
703+
execute('chronyc', 'shutdown', check_exit_code=[0, 1])
704+
# force a time sync now
705+
query = "server " + CONF.ntp_server + " iburst"
706+
execute("chronyd -q \'%s\'" % query, shell=True)
717707
LOG.debug('Set software clock using chrony')
718708
except (processutils.ProcessExecutionError,
719709
errors.CommandExecutionError) as e:
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
fixes:
3+
- |
4+
Fixes an issue where the NTP time sync at the IPA startup via chronyd is
5+
not immediate (which can break time sensitive components such as the
6+
generation of a TLS certificate).

0 commit comments

Comments
 (0)