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:
@@ -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
|
||||
);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user