Merge pull request #2139 from anderbubble/update-config-files-and-scripts

Update clients and docs to use new warewulfd routes
This commit is contained in:
Christian Goll
2026-03-19 09:11:51 +01:00
committed by GitHub
8 changed files with 85 additions and 50 deletions

View File

@@ -68,6 +68,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
the node continues to boot and `wwclient` retries the download at runtime. the node continues to boot and `wwclient` retries the download at runtime.
- `hosts` overlay added to the default system overlay list - `hosts` overlay added to the default system overlay list
- Distinguish between OS images and overlay images in documentation - Distinguish between OS images and overlay images in documentation
- Updated iPXE, GRUB, and dracut boot scripts to use dedicated server routes
(`/kernel/`, `/image/`, `/system/`, `/runtime/`, `/initramfs/`) instead of
`/provision/{hwaddr}?stage=X`
- Updated `wwclient` to use the `/runtime/` route for runtime overlay downloads
- New `wwinit.server` kernel parameter for dracut/wwinit boot; `wwinit.uri`
remains supported for backward compatibility
- Updated troubleshooting documentation examples to reflect the new URL scheme
- Updated `MAINTAINING.md` to document golang version policy - Updated `MAINTAINING.md` to document golang version policy
- Clarified functionality of syncuser commands and overlay in documentation - Clarified functionality of syncuser commands and overlay in documentation
- Audit and correct documentation, cobra help text, and log messages for accuracy - Audit and correct documentation, cobra help text, and log messages for accuracy

View File

@@ -2,9 +2,29 @@
[ -z "${wwinit_root_device}" ] && return 0 [ -z "${wwinit_root_device}" ] && return 0
# Resolve the server base URL and hardware address from kernel parameters.
# Supports two formats:
# New: wwinit.server=http://host:port (uses wwid kernel param for hwaddr)
# Legacy: wwinit.uri=http://host:port/provision/hwaddr (extracts hwaddr from path)
# wwinit.server takes precedence over wwinit.uri when both are present.
resolve_base() {
local val="${wwinit_server:-${wwinit_uri}}"
if echo "${val}" | grep -q '/provision/'; then
# Legacy: http://host:port/provision/hwaddr
ww_base="${val%%/provision/*}"
ww_hwaddr="${val##*/provision/}"
else
# New: http://host:port
ww_base="${val}"
ww_hwaddr="$(getarg wwid)"
fi
}
resolve_base
get_stage() { get_stage() {
stage="${1}" stage="${1}"
uri="${2:-${wwinit_uri}}" base="${2:-${ww_base}}"
cacert="${3}" cacert="${3}"
info "warewulf: loading stage: ${stage}" info "warewulf: loading stage: ${stage}"
# Load runtime overlay from a static privledged port. # Load runtime overlay from a static privledged port.
@@ -17,12 +37,17 @@ get_stage() {
if [ -n "${cacert}" ]; then if [ -n "${cacert}" ]; then
cacert_opt="--cacert ${cacert}" cacert_opt="--cacert ${cacert}"
fi fi
local hwaddr="${ww_hwaddr}"
case "${stage}" in
image) uri="${base}/image/${hwaddr}" ;;
system) uri="${base}/system/${hwaddr}" ;;
runtime) uri="${base}/runtime/${hwaddr}" ;;
esac
( (
curl --location --silent --get ${localport} ${cacert_opt} \ curl --location --silent --get ${localport} ${cacert_opt} \
--retry 60 --retry-connrefused --retry-delay 1 \ --retry 60 --retry-connrefused --retry-delay 1 \
--data-urlencode "assetkey=${wwinit_assetkey}" \ --data-urlencode "assetkey=${wwinit_assetkey}" \
--data-urlencode "uuid=${wwinit_uuid}" \ --data-urlencode "uuid=${wwinit_uuid}" \
--data-urlencode "stage=${stage}" \
--data-urlencode "compress=gz" \ --data-urlencode "compress=gz" \
"${uri}" \ "${uri}" \
| gzip -d \ | gzip -d \
@@ -58,11 +83,10 @@ done
. /tmp/wwinit/warewulf/config . /tmp/wwinit/warewulf/config
cert_file="/tmp/wwinit/warewulf/tls/warewulf.crt" cert_file="/tmp/wwinit/warewulf/tls/warewulf.crt"
if [ "${WWTLS}" = "true" ] && [ -f "$cert_file" ]; then if [ "${WWTLS}" = "true" ] && [ -f "$cert_file" ]; then
# TLS enabled: build HTTPS URI using wwid from kernel cmdline # TLS enabled: build HTTPS base URL using server address from kernel cmdline
# (mirrors wwclient URL construction in internal/app/wwclient/root.go) # (mirrors wwclient URL construction in internal/app/wwclient/root.go)
wwid=$(getarg wwid) tls_base="https://${WWIPADDR}:${WWTLSPORT}"
runtime_uri="https://${WWIPADDR}:${WWTLSPORT}/provision/${wwid}" get_stage "runtime" "${tls_base}" "${cert_file}" || warn "warewulf: unable to load runtime overlay over HTTPS (ignored)"
get_stage "runtime" "${runtime_uri}" "${cert_file}" || warn "warewulf: unable to load runtime overlay over HTTPS (ignored)"
else else
# No TLS: fetch runtime over HTTP # No TLS: fetch runtime over HTTP
get_stage "runtime" || warn "warewulf: unable to load runtime overlay (ignored)" get_stage "runtime" || warn "warewulf: unable to load runtime overlay (ignored)"

View File

@@ -7,12 +7,13 @@ case "${root}" in
wwinit|wwinit:*) wwinit|wwinit:*)
info "warewulf: root=${root}" info "warewulf: root=${root}"
export wwinit_server="$(getarg wwinit.server)"
export wwinit_uri="$(getarg wwinit.uri)" export wwinit_uri="$(getarg wwinit.uri)"
if [ -n "${wwinit_uri}" ]; then if [ -n "${wwinit_server}" ] || [ -n "${wwinit_uri}" ]; then
info "warewulf: Found root=${root} and wwinit.uri=${wwinit_uri}. Will boot from Warewulf." info "warewulf: Found root=${root} and wwinit.server=${wwinit_server} wwinit.uri=${wwinit_uri}. Will boot from Warewulf."
rootok=1 rootok=1
else else
die "warewulf: Found root=${root} but no wwinit.uri. Cannot boot from Warewulf." die "warewulf: Found root=${root} but neither wwinit.server nor wwinit.uri. Cannot boot from Warewulf."
fi fi
export wwinit_uuid=$(dmidecode -s system-uuid) export wwinit_uuid=$(dmidecode -s system-uuid)

View File

@@ -29,8 +29,9 @@ reboot
echo "Reading asset key..." echo "Reading asset key..."
smbios --type 3 --get-string 8 --set assetkey smbios --type 3 --get-string 8 --set assetkey
uri="(http,{{.Authority}})/provision/${net_default_mac}?assetkey=${assetkey}" base="(http,{{.Authority}})"
kernel="${uri}&stage=kernel" params="assetkey=${assetkey}"
kernel="${base}/kernel/${net_default_mac}?${params}"
set default={{ or .Tags.GrubMenuEntry "single-stage" }} set default={{ or .Tags.GrubMenuEntry "single-stage" }}
set timeout=2 set timeout=2
@@ -64,10 +65,10 @@ menuentry "Single-stage boot" --id single-stage {
fi fi
echo "Downloading images..." echo "Downloading images..."
image="${uri}&stage=image&compress=gz" image="${base}/image/${net_default_mac}?${params}&compress=gz"
system="${uri}&stage=system&compress=gz" system="${base}/system/${net_default_mac}?${params}&compress=gz"
{{- if not (eq .TLS true) }} {{- if not (eq .TLS true) }}
runtime="${uri}&stage=runtime&compress=gz" runtime="${base}/runtime/${net_default_mac}?${params}&compress=gz"
{{- end }} {{- end }}
initrd $image $system $runtime initrd $image $system $runtime
if [ $? != 0 ] if [ $? != 0 ]
@@ -113,10 +114,10 @@ menuentry "Single-stage boot (no compression)" --id single-stage-nocompress {
fi fi
echo "Downloading images..." echo "Downloading images..."
image="${uri}&stage=image" image="${base}/image/${net_default_mac}?${params}"
system="${uri}&stage=system" system="${base}/system/${net_default_mac}?${params}"
{{- if not (eq .TLS true) }} {{- if not (eq .TLS true) }}
runtime="${uri}&stage=runtime" runtime="${base}/runtime/${net_default_mac}?${params}"
{{- end }} {{- end }}
initrd $image $system $runtime initrd $image $system $runtime
if [ $? != 0 ] if [ $? != 0 ]
@@ -149,11 +150,12 @@ menuentry "Two stage boot with dracut" --id dracut {
{{- end }} {{- end }}
echo "* KernelArgs: {{.KernelArgs}}" echo "* KernelArgs: {{.KernelArgs}}"
initramfs="${uri}&stage=initramfs" initramfs="${base}/initramfs/${net_default_mac}?${params}"
wwinit_uri="http://{{.Ipaddr}}:{{.Port}}/provision/${net_default_mac}" wwinit_uri="http://{{.Ipaddr}}:{{.Port}}/provision/${net_default_mac}"
wwinit_server="http://{{.Ipaddr}}:{{.Port}}"
net_args="rd.neednet=1 {{range $devname, $netdev := .NetDevs}}{{if and $netdev.Hwaddr $netdev.Device}} ifname={{$netdev.Device}}:{{$netdev.Hwaddr}} {{end}}{{end}}" net_args="rd.neednet=1 {{range $devname, $netdev := .NetDevs}}{{if and $netdev.Hwaddr $netdev.Device}} ifname={{$netdev.Device}}:{{$netdev.Hwaddr}} {{end}}{{end}}"
wwinit_args="root=wwinit:{{default "tmpfs" .Root}} wwinit.uri=${wwinit_uri} init=/warewulf/run-init" wwinit_args="root=wwinit:{{default "tmpfs" .Root}} wwinit.server=${wwinit_server} wwinit.uri=${wwinit_uri} init=/warewulf/run-init"
echo echo
echo "Downloading kernel image..." echo "Downloading kernel image..."

View File

@@ -15,11 +15,12 @@ sleep 30
reboot reboot
{{- end }} {{- end }}
set baseuri http://{{.Authority}}/provision/{{.Hwaddr}} set base http://{{.Authority}}
set uri ${baseuri}?assetkey=${asset}&uuid=${uuid} set hwaddr {{.Hwaddr}}
set params assetkey=${asset}&uuid=${uuid}
echo Downloading kernel image... echo Downloading kernel image...
kernel --name kernel ${uri}&stage=kernel || goto reboot kernel --name kernel ${base}/kernel/${hwaddr}?${params} || goto reboot
{{- if .Tags.IPXEMenuEntry }} {{- if .Tags.IPXEMenuEntry }}
set method {{ .Tags.IPXEMenuEntry }} set method {{ .Tags.IPXEMenuEntry }}
@@ -43,12 +44,12 @@ goto metadata
:imgextract_continue :imgextract_continue
echo echo
echo Downloading compressed image with imgextract... echo Downloading compressed image with imgextract...
imgextract --name image ${uri}&stage=image&compress=gz || goto error_use_initrd imgextract --name image ${base}/image/${hwaddr}?${params}&compress=gz || goto error_use_initrd
echo Downloading compressed system overlay image with imgextract... echo Downloading compressed system overlay image with imgextract...
imgextract --name system ${uri}&stage=system&compress=gz || goto error_reboot imgextract --name system ${base}/system/${hwaddr}?${params}&compress=gz || goto error_reboot
{{- if not (eq .TLS true) }} {{- if not (eq .TLS true) }}
echo Downloading compressed runtime overlay image with imgextract... echo Downloading compressed runtime overlay image with imgextract...
imgextract --name runtime ${uri}&stage=runtime&compress=gz && set runtime_initrd initrd=runtime || echo Unable to download runtime overlay. (ignored) imgextract --name runtime ${base}/runtime/${hwaddr}?${params}&compress=gz && set runtime_initrd initrd=runtime || echo Unable to download runtime overlay. (ignored)
{{- end }} {{- end }}
goto boot_single_stage goto boot_single_stage
@@ -62,12 +63,12 @@ goto metadata
:initrd_continue :initrd_continue
echo echo
echo Downloading compressed image with initrd... echo Downloading compressed image with initrd...
initrd --name image ${uri}&stage=image&compress=gz || goto error_reboot initrd --name image ${base}/image/${hwaddr}?${params}&compress=gz || goto error_reboot
echo Downloading compressed system overlay with initrd... echo Downloading compressed system overlay with initrd...
initrd --name system ${uri}&stage=system&compress=gz || goto error_reboot initrd --name system ${base}/system/${hwaddr}?${params}&compress=gz || goto error_reboot
{{- if not (eq .TLS true) }} {{- if not (eq .TLS true) }}
echo Downloading compressed runtime overlay with initrd... echo Downloading compressed runtime overlay with initrd...
initrd --name runtime ${uri}&stage=runtime&compress=gz && set runtime_initrd initrd=runtime || echo Unable to download runtime overlay. (ignored) initrd --name runtime ${base}/runtime/${hwaddr}?${params}&compress=gz && set runtime_initrd initrd=runtime || echo Unable to download runtime overlay. (ignored)
{{- end }} {{- end }}
goto boot_single_stage goto boot_single_stage
@@ -77,12 +78,12 @@ goto metadata
:initrd_nocompress_continue :initrd_nocompress_continue
echo echo
echo Downloading uncompressed image with initrd... echo Downloading uncompressed image with initrd...
initrd --name image ${uri}&stage=image || goto error_reboot initrd --name image ${base}/image/${hwaddr}?${params} || goto error_reboot
echo Downloading uncompressed system overlay with initrd... echo Downloading uncompressed system overlay with initrd...
initrd --name system ${uri}&stage=system || goto error_reboot initrd --name system ${base}/system/${hwaddr}?${params} || goto error_reboot
{{- if not (eq .TLS true) }} {{- if not (eq .TLS true) }}
echo Downloading uncompressed runtime overlay with initrd... echo Downloading uncompressed runtime overlay with initrd...
initrd --name runtime ${uri}&stage=runtime && set runtime_initrd initrd=runtime || echo Unable to download runtime overlay. (ignored) initrd --name runtime ${base}/runtime/${hwaddr}?${params} && set runtime_initrd initrd=runtime || echo Unable to download runtime overlay. (ignored)
{{- end }} {{- end }}
goto boot_single_stage goto boot_single_stage
@@ -92,9 +93,9 @@ goto metadata
:dracut_continue :dracut_continue
echo echo
echo Downloading dracut initramfs... echo Downloading dracut initramfs...
initrd --name initramfs ${uri}&stage=initramfs || goto error_reboot initrd --name initramfs ${base}/initramfs/${hwaddr}?${params} || goto error_reboot
set dracut_net rd.neednet=1 {{range $devname, $netdev := .NetDevs}}{{if and $netdev.Hwaddr $netdev.Device}} ifname={{$netdev.Device}}:{{$netdev.Hwaddr}} ip={{$netdev.Device}}:dhcp {{end}}{{end}} set dracut_net rd.neednet=1 {{range $devname, $netdev := .NetDevs}}{{if and $netdev.Hwaddr $netdev.Device}} ifname={{$netdev.Device}}:{{$netdev.Hwaddr}} ip={{$netdev.Device}}:dhcp {{end}}{{end}}
set dracut_wwinit root=wwinit:{{default "tmpfs" .Root}} wwinit.uri=${baseuri} init=/warewulf/run-init set dracut_wwinit root=wwinit:{{default "tmpfs" .Root}} wwinit.server=${base} wwinit.uri=${base}/provision/${hwaddr} init=/warewulf/run-init
goto boot_two_stage_dracut goto boot_two_stage_dracut
:boot_single_stage :boot_single_stage

View File

@@ -316,12 +316,11 @@ func updateSystem(target string, ipaddr string, port int, wwid string, tag strin
values := &url.Values{} values := &url.Values{}
values.Set("assetkey", tag) values.Set("assetkey", tag)
values.Set("uuid", localUUID.String()) values.Set("uuid", localUUID.String())
values.Set("stage", "runtime")
values.Set("compress", "gz") values.Set("compress", "gz")
getURL := &url.URL{ getURL := &url.URL{
Scheme: scheme, Scheme: scheme,
Host: fmt.Sprintf("%s:%d", ipaddr, port), Host: fmt.Sprintf("%s:%d", ipaddr, port),
Path: fmt.Sprintf("provision/%s", wwid), Path: fmt.Sprintf("runtime/%s", wwid),
RawQuery: values.Encode(), RawQuery: values.Encode(),
} }
wwlog.Debug("making request: %s", getURL) wwlog.Debug("making request: %s", getURL)

View File

@@ -10,11 +10,11 @@ smbios --type 3 --get-string 8 --set assetkey
set timeout=2 set timeout=2
# Must chainload in order to get kernel args for specific node # Must chainload in order to get kernel args for specific node
menuentry "Load specific configfile" { menuentry "Load specific configfile" {
conf="(http,{{.Ipaddr}}:{{.Warewulf.Port}})/efiboot/grub.cfg?assetkey=${assetkey}" conf="(http,{{.Ipaddr}}:{{.Warewulf.Port}})/grub/${net_default_mac}?assetkey=${assetkey}"
configfile $conf configfile $conf
} }
menuentry "Chainload shim from image" { menuentry "Chainload shim from image" {
shim="(http,{{.Ipaddr}}:{{.Warewulf.Port}})/efiboot/shim.efi?assetkey=${assetkey}" shim="(http,{{.Ipaddr}}:{{.Warewulf.Port}})/efiboot/shim.efi?wwid=${net_default_mac}&assetkey=${assetkey}"
chainloader ${shim} chainloader ${shim}
} }
menuentry "UEFI Firmware Settings" --id "uefi-firmware" { menuentry "UEFI Firmware Settings" --id "uefi-firmware" {

View File

@@ -52,16 +52,17 @@ cluster node's MAC address in place of 00:00:00:00:00:00.)
.. code-block:: .. code-block::
set uri http://10.0.0.1:9873/provision/00:00:00:00:00:00 set base http://10.0.0.1:9873
kernel --name kernel ${uri}?stage=kernel set hwaddr 00:00:00:00:00:00
imgextract --name image ${uri}?stage=image&compress=gz kernel --name kernel ${base}/kernel/${hwaddr}
imgextract --name system ${uri}?stage=system&compress=gz imgextract --name image ${base}/image/${hwaddr}?compress=gz
imgextract --name runtime ${uri}?stage=runtime&compress=gz imgextract --name system ${base}/system/${hwaddr}?compress=gz
imgextract --name runtime ${base}/runtime/${hwaddr}?compress=gz
boot kernel initrd=image initrd=system initrd=runtime boot kernel initrd=image initrd=system initrd=runtime
- The ``uri`` variable points to ``warewulfd`` for future reference. This - The ``base`` variable points to ``warewulfd`` for future reference. The MAC
includes the cluster node's MAC address so that Warewulf knows what image and address is appended to each resource path so that Warewulf knows what image
overlays to provide. and overlays to provide.
- The ``kernel`` command fetches a kernel for later booting. - The ``kernel`` command fetches a kernel for later booting.
@@ -110,12 +111,12 @@ the port number if you have changed it from the default of 9873.)
.. code-block:: .. code-block::
uri="(http,10.0.0.1:9873)/provision/${net_default_mac}" base="(http,10.0.0.1:9873)"
linux "${uri}?stage=kernel" wwid=${net_default_mac} linux "${base}/kernel/${net_default_mac}" wwid=${net_default_mac}
initrd "${uri}?stage=image&compress=gz" "${uri}?stage=system&compress=gz" "${uri}?stage=runtime&compress=gz" initrd "${base}/image/${net_default_mac}?compress=gz" "${base}/system/${net_default_mac}?compress=gz" "${base}/runtime/${net_default_mac}?compress=gz"
boot boot
- The ``uri`` variable points to ``warewulfd`` for future reference. - The ``base`` variable points to ``warewulfd`` for future reference.
``${net_default_mac}`` provides Warewulf with the MAC address of the booting ``${net_default_mac}`` provides Warewulf with the MAC address of the booting
node, so that Warewulf knows what image and overlays to provide it. node, so that Warewulf knows what image and overlays to provide it.
@@ -143,7 +144,7 @@ enabled. To do so, substitute the ``linux`` command above.
.. code-block:: .. code-block::
linux "${uri}?stage=kernel" wwid=${net_default_mac} debug rdinit=/bin/sh linux "${base}/kernel/${net_default_mac}" wwid=${net_default_mac} debug rdinit=/bin/sh
.. note:: .. note::