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

fix(subiquity): three values the Ubuntu install path accepts and cannot use

The boot flip in compute.subiquity.tmpl addressed port 3002. xcatd's install
monitor listens on site.xcatiport, so a cluster that moves the port loses the
flip and every node PXE-loops back into the installer. The flip now reads
site.xcatiport and keeps 3002 as the default. TABLEBLANKOKAY, because the key is
optional and a plain TABLE lookup of an absent key fails the whole template.

The flip also counted any reply as an accepted request. It now requires the
monitor's "ready" greeting before it sends "next", and "done" afterwards, so a
different service on that port is not read as a flipped node.

subiquity_nfsroot_server in debian.pm called getipaddr without a family. A
dual-stack management node answers with its IPv6 address, and casper takes
everything after the first colon in nfsroot= as the path, so the live filesystem
never mounts. It now asks for IPv4, as dhcp.pm and mknb.pm do.

The DNS setup wrote the xcatmaster name as a nameserver when getent found no
address, which is the case the step exists to prevent. It now keeps the
resolv.conf DHCP gave the live installer.

ubuntu_subiquity_boot_flip.t, debian_subiquity_boot_params.t and
ubuntu_resolvconf_ip.t fail on the parent commit and pass here.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
Daniel Hilst
2026-09-03 14:52:49 -03:00
parent 173cbea550
commit 05fc81f7b5
2 changed files with 21 additions and 12 deletions
+4 -2
View File
@@ -521,7 +521,7 @@ sub copycd
Arguments:
$instserver the install server name, address, or the '!myipfn!' placeholder
$resolver optional coderef, for tests; defaults to NetworkUtils::getipaddr
$resolver optional coderef, for tests; defaults to NetworkUtils::getipaddr, IPv4 only
Returns:
the value to put in nfsroot, or undef when a real name does not resolve
@@ -534,7 +534,9 @@ sub subiquity_nfsroot_server {
return undef unless defined($instserver) && length($instserver);
return $instserver if $instserver eq '!myipfn!';
$resolver ||= sub { xCAT::NetworkUtils->getipaddr($_[0]) };
# A dual-stack management node also has an AAAA record. casper takes everything after the
# first colon in nfsroot= as the path, so an IPv6 address there cannot be parsed.
$resolver ||= sub { xCAT::NetworkUtils->getipaddr($_[0], OnlyV4 => 1) };
return $resolver->($instserver);
}
@@ -68,12 +68,17 @@ autoinstall:
echo "=== DNS setup ==="
# glibc's resolver discards a nameserver line naming a host, so writing the xcatmaster
# *name* leaves the installer -- and the in-target apt that inherits this file -- with no
# DNS. Resolve it here, while the live installer's DHCP resolv.conf still works.
# DNS. Resolve it here, while the live installer's DHCP resolv.conf still works, and keep
# that file when the name does not resolve. A name written back is the case this step
# exists to prevent.
xcatmaster_host="#TABLE:noderes:$NODE:xcatmaster#"
xcatmaster_ip="$(getent ahostsv4 "$xcatmaster_host" | awk '{print $1; exit}')"
[ -n "$xcatmaster_ip" ] || xcatmaster_ip="$xcatmaster_host"
rm -f /etc/resolv.conf
echo "nameserver $xcatmaster_ip" >/etc/resolv.conf
if [ -n "$xcatmaster_ip" ]; then
rm -f /etc/resolv.conf
echo "nameserver $xcatmaster_ip" >/etc/resolv.conf
else
echo "xcat: $xcatmaster_host has no IPv4 address; keeping the resolver DHCP supplied"
fi
echo "domain #TABLE:site:key=domain:value#" >>/etc/resolv.conf
echo "=== early-commands complete ==="
late-commands:
@@ -108,11 +113,13 @@ autoinstall:
curtin in-target --target /target /root/post.script;
} >>/target/var/log/xcat/xcat.log 2>&1'
# Flip the node to local-disk boot, or it PXE-loops back into the installer on reboot.
# "next" is the request xcatd's install monitor answers with "nodeset <node> next". Send it
# from the live installer, retried, and log a failure rather than silently reinstalling. A
# monitor that died and never came back is a separate problem; see #7759 -- but one that
# accepts the connection and then never answers would block a bare read forever and hang the
# install here, so both reads are bounded.
- ['bash', '-c', 'xm=#XCATVAR:XCATMASTER#; ok=0; for i in 1 2 3 4 5; do if exec 3<>/dev/tcp/$xm/3002; then read -r -t 10 r <&3 || true; printf "next\n" >&3; if read -r -t 10 r <&3; then ok=1; fi; exec 3>&- 3<&-; [ "$ok" = 1 ] && break; fi; sleep 5; done; if [ "$ok" != 1 ]; then echo "xcat: FAILED to flip $(hostname) to local-disk boot via $xm:3002; the node will PXE back into the installer" >>/target/var/log/xcat/xcat.log; fi; exit 0']
# xcatd's install monitor greets with "ready", then answers "next" with "done" and runs
# "nodeset <node> next". Require both tokens: another service on that port is not a flipped
# node. The monitor listens on site.xcatiport; TABLEBLANKOKAY because an absent key fails a
# plain TABLE lookup, and with it the whole template.
# Retry, and log a failure rather than reinstall silently. Both reads are bounded: a monitor
# that accepts and never answers would block a bare read and hang the install here. A
# monitor that died and never came back is #7759.
- ['bash', '-c', 'xm=#XCATVAR:XCATMASTER#; port="#TABLEBLANKOKAY:site:key=xcatiport:value#"; [ -n "$port" ] || port=3002; ok=0; for i in 1 2 3 4 5; do if exec 3<>/dev/tcp/$xm/$port; then if read -r -t 10 hello <&3 && [ "$hello" = "ready" ]; then printf "next\n" >&3; if read -r -t 10 ack <&3 && [ "$ack" = "done" ]; then ok=1; fi; fi; exec 3>&- 3<&-; [ "$ok" = 1 ] && break; fi; sleep 5; done; if [ "$ok" != 1 ]; then echo "xcat: FAILED to flip $(hostname) to local-disk boot via $xm:$port; the node will PXE back into the installer" >>/target/var/log/xcat/xcat.log; fi; exit 0']
error-commands:
- tar -c --ignore-failed-read --transform='s/^/#HOSTNAME#-logs\//' /var/crash /var/log/installer /tmp/pre-install.log /autoinstall.yaml 2>/dev/null |nc -l 8080