2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-04 20:17:55 +00:00

fix(xcat-core): let site.ntpbackend reach the nodes, not just the management node

makentp picks the NTP daemon through xCAT::NTP::Backend, but then runs setupntp -- on the
management node and, through updatenode -P, on every service node -- and setupntp decided for
itself with `check_executes chronyd || USE_NTPD=yes`. A cluster with site.ntpbackend=ntpd and
chronyd present therefore configured ntpd on the MN and chrony everywhere else. The selector was
one code path only on the side that does not write the config.

setupntp now takes --backend chrony|ntpd, and makentp passes what it chose on both call sites.
The service-node dispatch passes the cluster's intent rather than this host's availability: a
service node may have a different daemon installed, and the requested backend is a preference --
a node without chronyd still falls back to ntpd and logs that it did, rather than failing.
--use-ntpd keeps working.

Two results of choose() were computed and never read. A downgrade is now reported, so an admin
who asked for one daemon and got the other is told. install=1 -- neither daemon present -- is an
error naming the daemon that is missing, instead of falling through to the ntpd branch and
reporting "Please make sure ntpd is installed" even when chrony was the preferred choice.

Six cases cover the selection: the backend honoured in both directions, the probe still used when
none is given, and the fallback when the requested daemon is absent. Removing the --backend case
fails one; ignoring the preference fails two.

Also worth stating plainly, since the PR reads as a management-node fix: setupntp stops and
disables systemd-timesyncd wherever it runs, nodes included. It has to -- timesyncd disciplines
the clock against the daemon being configured -- but a node that was relying on it loses it.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
Daniel Hilst
2026-08-27 19:58:43 -03:00
parent ee4cd05623
commit a13a74f4c2
3 changed files with 72 additions and 5 deletions
+20 -2
View File
@@ -261,13 +261,22 @@ sub process_request {
send_msg(\%request, 1, $ntp_backend->{error});
return 1;
}
if ($ntp_backend->{downgraded}) {
send_msg(\%request, 0,
"NTP backend $ntp_backend->{downgraded} is not installed; using $ntp_backend->{name} instead.");
}
if ($ntp_backend->{install}) {
send_msg(\%request, 1,
"Neither chrony nor ntp is installed on $nodename. Install $ntp_backend->{name}, or set site.ntpbackend to the daemon you have.");
return 1;
}
my $have_systemctl = (-x "/usr/bin/systemctl" || -x "/bin/systemctl");
# Handle chronyd here,
if ($ntp_backend->{name} eq 'chrony' && $have_systemctl) {
send_msg(\%request, 0, "Will configure chronyd instead.");
my $cmd = "/install/postscripts/setupntp " .
my $cmd = "/install/postscripts/setupntp --backend $ntp_backend->{name} " .
join(' ', split(',', $ntp_servers));
send_msg(\%request, 0, "Calling ... " . $cmd);
@@ -497,12 +506,21 @@ HANDLE_MAKENTP_A:
my @servicenodes = xCAT::ServiceNodeUtils->getSNList('ntpserver');
if (@servicenodes > 0) {
send_msg(\%request, 0, "configuring service nodes: @servicenodes");
# Pass the cluster's intent, not this host's availability: a service node may have a
# different daemon installed, and setupntp falls back locally when it does.
require xCAT::NTP::Backend;
my $sn_backend = xCAT::NTP::Backend->choose();
my $sn_script = $sn_backend->{name}
? "setupntp --backend $sn_backend->{name}"
: "setupntp";
my $ret =
xCAT::Utils->runxcmd(
{
command => ['updatenode'],
node => \@servicenodes,
arg => [ "-P", "setupntp" ],
arg => [ "-P", $sn_script ],
},
$sub_req, -1, 1
);
+27
View File
@@ -25,9 +25,13 @@ my $source = join '', @lines;
# or run unprivileged. Drive its own helper functions with shell functions instead: bash resolves
# those ahead of PATH, and both `type` and `command -v` report them as present.
my ($helpers) = $source =~ /\A(.*?)^\[ "\$\{UID\}" -eq "0" \]/ms;
my ($args) = $source =~ /^(# Handle command line arguments\n.*?)^if \[ "\$\{#NTP_SERVERS\[@\]\}"/ms;
my ($select) = $source =~ /^(# The requested backend is a preference.*?)^if \[ -n "\$\{USE_NTPD\}"/ms;
my ($body) = $source =~ /^(check_exec_or_exit cp cat logger grep\n.*?)^CHRONY_CONF=/ms;
BAIL_OUT('could not take the helper functions from setupntp') unless $helpers;
BAIL_OUT('could not take the daemon setup section from setupntp') unless $body;
BAIL_OUT('could not take the argument parsing from setupntp') unless $args;
BAIL_OUT('could not take the backend selection from setupntp') unless $select;
sub run_setupntp {
my (%opt) = @_;
@@ -123,4 +127,27 @@ SKIP: {
'the xCAT rpm requires a server-capable NTP daemon');
}
# --- the backend the management node chose must reach the node ------------
# makentp selects the daemon from site.ntpbackend through xCAT::NTP::Backend and passes it here,
# so a cluster told to use ntpd does not get chrony on every node that happens to have it.
foreach my $case (
# argv chronyd present? expected daemon
[ '--backend ntpd pool.ntp.org', 'nothing', 'ntpd', 'ntpd is honoured even where chronyd is installed' ],
[ '--backend chrony pool.ntp.org','nothing', 'chrony', 'chrony is honoured' ],
[ 'pool.ntp.org', 'nothing', 'chrony', 'with no backend given the probe still picks chrony' ],
[ 'pool.ntp.org', 'chronyd', 'ntpd', 'with no backend given and no chronyd it falls back' ],
[ '--backend chrony pool.ntp.org','chronyd', 'ntpd', 'chrony requested but absent falls back rather than failing' ],
[ '--use-ntpd pool.ntp.org', 'nothing', 'ntpd', 'the legacy --use-ntpd flag still forces ntpd' ],
) {
my ($argv, $missing, $want, $name) = @$case;
my $root = File::Temp::tempdir(CLEANUP => 1);
my $prelude = "logger() { printf '%s\\n' \"\$*\" >>\"$root/log\"; return 0; }\n"
. "check_executes() { for c in \"\$@\"; do [ \"\$c\" = \"$missing\" ] && return 1; done; return 0; }\n"
. "log_label=xcat\nset -- $argv\n";
my $out = `bash -c 'exec 2>/dev/null; $prelude$args$select
printf "USE_NTPD=%s\\n" "\${USE_NTPD:-}"' 2>/dev/null`;
my $got = ($out =~ /USE_NTPD=yes/) ? 'ntpd' : 'chrony';
is($got, $want, $name);
}
done_testing();
+25 -3
View File
@@ -103,7 +103,17 @@ do
case "$1" in
"--use-ntpd")
# Use traditional ntpd
USE_NTPD="yes"
NTP_BACKEND="ntpd"
;;
"--backend")
# The daemon xCAT::NTP::Backend picked for this cluster, passed by makentp so
# site.ntpbackend reaches the nodes and not just the management node.
shift
case "$1" in
"chrony"|"chronyd") NTP_BACKEND="chrony" ;;
"ntp"|"ntpd") NTP_BACKEND="ntpd" ;;
*) logger -t $log_label -p local4.warning "setupntp: ignoring unknown --backend '$1'" ;;
esac
;;
*)
NTP_SERVERS+=($1)
@@ -129,8 +139,20 @@ then
esac
fi
check_executes chronyd >/dev/null 2>&1 || USE_NTPD="yes"
check_executes systemctl >/dev/null 2>&1 || USE_NTPD="yes"
# The requested backend is a preference, not a guarantee: a node that does not have chronyd
# still has to be configured, so fall back to ntpd and say so rather than failing.
if [ "${NTP_BACKEND}" = "ntpd" ]
then
USE_NTPD="yes"
else
check_executes chronyd >/dev/null 2>&1 || USE_NTPD="yes"
check_executes systemctl >/dev/null 2>&1 || USE_NTPD="yes"
if [ -n "${USE_NTPD}" ] && [ "${NTP_BACKEND}" = "chrony" ]
then
logger -t $log_label -p local4.warning \
"setupntp: chrony requested but chronyd/systemctl are absent; using ntpd"
fi
fi
if [ -n "${USE_NTPD}" ]
then