Merge pull request #1742 from anderbubble/wwinit-logging
Improved logging during iPXE, GRUB, and wwinit
This commit is contained in:
@@ -17,6 +17,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||||||
- Added `WW_HISTFILE` to control shell history location during `wwctl image shell`. #1732
|
- Added `WW_HISTFILE` to control shell history location during `wwctl image shell`. #1732
|
||||||
- Added target help in Makefile. #1740
|
- Added target help in Makefile. #1740
|
||||||
- Added fstab mounts for `/home` and `/opt` to initial default profile. #1744
|
- Added fstab mounts for `/home` and `/opt` to initial default profile. #1744
|
||||||
|
- Add support for an `IPXEMenuEntry` tag to select the boot method during iPXE.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
@@ -30,6 +31,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||||||
- Update syncuser documentation. #1736
|
- Update syncuser documentation. #1736
|
||||||
- Update PS1 during `wwctl image shell` to include working directory by default,
|
- Update PS1 during `wwctl image shell` to include working directory by default,
|
||||||
and to include `PS1` from the environment if present. #1245
|
and to include `PS1` from the environment if present. #1245
|
||||||
|
- DHCP template generates as much of the subnet and range definition as possible. #1469
|
||||||
|
- Updated overlay flags to `wwctl <node|profile> <add|set> [--runtime-overlays|--system-overlays]`. #1495
|
||||||
|
- Added logging and updated output during iPXE and GRUB. #1156
|
||||||
|
- Defined a menu for iPXE. #1156
|
||||||
|
- Added logging to wwinit scripts. #1156
|
||||||
|
- Renamed /warewulf/wwinit to /warewulf/prescripts. #1156
|
||||||
|
- Display auto-detected kernel version during iPXE and GRUB. #1742
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@@ -49,6 +57,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||||||
- Remove syncuser warning messages in `wwctl` that assume its use. #1321
|
- Remove syncuser warning messages in `wwctl` that assume its use. #1321
|
||||||
- Remove syncuser from the list of default runtime overlays. #1322
|
- Remove syncuser from the list of default runtime overlays. #1322
|
||||||
- Removed check for "discoverable" profiles during `wwctl upgrade nodes`.
|
- Removed check for "discoverable" profiles during `wwctl upgrade nodes`.
|
||||||
|
- Removed `dracut.ipxe` template. (Use `default.ipxe` and set tag `IPXEMenuEntry=dracut`.)
|
||||||
|
|
||||||
## v4.6.0rc2, 2025-02-07
|
## v4.6.0rc2, 2025-02-07
|
||||||
|
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -216,7 +216,7 @@ install: build docs ## Install Warewulf from source
|
|||||||
(cd overlays && find * -path '*/internal' -prune -o -type d -exec mkdir -pv $(DESTDIR)$(DATADIR)/warewulf/overlays/{} \;)
|
(cd overlays && find * -path '*/internal' -prune -o -type d -exec mkdir -pv $(DESTDIR)$(DATADIR)/warewulf/overlays/{} \;)
|
||||||
(cd overlays && find * -path '*/internal' -prune -o -type l -exec cp -av {} $(DESTDIR)$(DATADIR)/warewulf/overlays/{} \;)
|
(cd overlays && find * -path '*/internal' -prune -o -type l -exec cp -av {} $(DESTDIR)$(DATADIR)/warewulf/overlays/{} \;)
|
||||||
chmod 0755 $(DESTDIR)$(DATADIR)/warewulf/overlays/wwinit/rootfs/init
|
chmod 0755 $(DESTDIR)$(DATADIR)/warewulf/overlays/wwinit/rootfs/init
|
||||||
chmod 0755 $(DESTDIR)$(DATADIR)/warewulf/overlays/wwinit/rootfs/$(WWCLIENTDIR)/wwinit
|
chmod 0755 $(DESTDIR)$(DATADIR)/warewulf/overlays/wwinit/rootfs/$(WWCLIENTDIR)/wwprescripts
|
||||||
chmod 0600 $(DESTDIR)$(DATADIR)/warewulf/overlays/wwinit/rootfs/$(WWCLIENTDIR)/config.ww
|
chmod 0600 $(DESTDIR)$(DATADIR)/warewulf/overlays/wwinit/rootfs/$(WWCLIENTDIR)/config.ww
|
||||||
chmod 0600 $(DESTDIR)$(DATADIR)/warewulf/overlays/ssh.host_keys/rootfs/etc/ssh/ssh*
|
chmod 0600 $(DESTDIR)$(DATADIR)/warewulf/overlays/ssh.host_keys/rootfs/etc/ssh/ssh*
|
||||||
chmod 0644 $(DESTDIR)$(DATADIR)/warewulf/overlays/ssh.host_keys/rootfs/etc/ssh/ssh*.pub.ww
|
chmod 0644 $(DESTDIR)$(DATADIR)/warewulf/overlays/ssh.host_keys/rootfs/etc/ssh/ssh*.pub.ww
|
||||||
|
|||||||
@@ -1,77 +1,170 @@
|
|||||||
{{ if .ImageName }}
|
|
||||||
echo "================================================================================"
|
|
||||||
echo "Warewulf v4 now http booting grub: {{.Fqdn}} ({{.Hwaddr}})"
|
|
||||||
echo "================================================================================"
|
|
||||||
echo
|
echo
|
||||||
echo "Warewulf Controller: {{.Ipaddr}}"
|
echo "Warewulf v4 (GRUB)"
|
||||||
echo
|
echo
|
||||||
sleep 1
|
echo "Warewulf Server:"
|
||||||
|
echo "* Ipaddr: {{.Ipaddr}}"
|
||||||
|
echo "* Port: {{.Port}}"
|
||||||
|
echo
|
||||||
|
echo "This node:"
|
||||||
|
echo "* Fqdn: {{.Fqdn}}"
|
||||||
|
echo "* Hwaddr: {{.Hwaddr}}"
|
||||||
|
echo "* ImageName: {{.ImageName}}"
|
||||||
|
{{- if .KernelVersion }}
|
||||||
|
echo "* KernelVersion: {{.KernelVersion}}"
|
||||||
|
{{- else }}
|
||||||
|
echo "* KernelVersion: (image default)"
|
||||||
|
{{- end }}
|
||||||
|
echo "* KernelArgs: {{.KernelArgs}}"
|
||||||
|
|
||||||
|
{{- if not .ImageName }}
|
||||||
|
echo "!!"
|
||||||
|
echo "!! No image defined for {{.Fqdn}}."
|
||||||
|
echo "!! Rebooting in 30s...
|
||||||
|
echo "!!"
|
||||||
|
sleep 30
|
||||||
|
reboot
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
echo "Reading asset key..."
|
||||||
smbios --type 3 --get-string 8 --set assetkey
|
smbios --type 3 --get-string 8 --set assetkey
|
||||||
|
|
||||||
uri="(http,{{.Ipaddr}}:{{.Port}})/provision/${net_default_mac}?assetkey=${assetkey}"
|
uri="(http,{{.Ipaddr}}:{{.Port}})/provision/${net_default_mac}?assetkey=${assetkey}"
|
||||||
kernel="${uri}&stage=kernel"
|
kernel="${uri}&stage=kernel"
|
||||||
image="${uri}&stage=image&compress=gz"
|
|
||||||
system="${uri}&stage=system&compress=gz"
|
|
||||||
runtime="${uri}&stage=runtime&compress=gz"
|
|
||||||
|
|
||||||
set default={{ or .Tags.GrubMenuEntry "ww4" }}
|
set default={{ or .Tags.GrubMenuEntry "single-stage" }}
|
||||||
set timeout=5
|
set timeout=2
|
||||||
|
|
||||||
menuentry "Network boot node: {{.Id}}" --id ww4 {
|
menuentry "Single-stage boot" --id single-stage {
|
||||||
{{if .KernelVersion }}
|
echo "Warewulf Server:"
|
||||||
echo "Kernel: {{.KernelVersion}}"
|
echo "* Ipaddr: {{.Ipaddr}}"
|
||||||
{{else}}
|
echo "* Port: {{.Port}}"
|
||||||
echo "Kernel: {{.ImageName}} (image default)"
|
echo
|
||||||
{{end}}
|
echo "This node:"
|
||||||
echo "KernelArgs: {{.KernelArgs}}"
|
echo "* Fqdn: {{.Fqdn}}"
|
||||||
|
echo "* Hwaddr: {{.Hwaddr}}"
|
||||||
|
echo "* ImageName: {{.ImageName}}"
|
||||||
|
{{- if .KernelVersion }}
|
||||||
|
echo "* KernelVersion: {{.KernelVersion}}"
|
||||||
|
{{- else }}
|
||||||
|
echo "* KernelVersion: (image default)"
|
||||||
|
{{- end }}
|
||||||
|
echo "* KernelArgs: {{.KernelArgs}}"
|
||||||
|
echo
|
||||||
|
echo "Downloading kernel image..."
|
||||||
linux $kernel wwid=${net_default_mac} {{.KernelArgs}}
|
linux $kernel wwid=${net_default_mac} {{.KernelArgs}}
|
||||||
if [ x$? = x0 ] ; then
|
if [ $? != 0 ]
|
||||||
echo "Loading Image: {{.ImageName}}"
|
then
|
||||||
initrd $image $system $runtime
|
echo "!!"
|
||||||
boot
|
echo "!! Unable to load kernel."
|
||||||
else
|
echo "!! Rebooting in 15s..."
|
||||||
echo "MESSAGE: This node seems to be unconfigured. Please have your system administrator add a"
|
echo "!!"
|
||||||
echo " configuration for this node with HW address: ${net_default_mac}"
|
|
||||||
echo ""
|
|
||||||
echo "Rebooting in 1 minute..."
|
|
||||||
sleep 60
|
|
||||||
reboot
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "Downloading images..."
|
||||||
|
image="${uri}&stage=image&compress=gz"
|
||||||
|
system="${uri}&stage=system&compress=gz"
|
||||||
|
runtime="${uri}&stage=runtime&compress=gz"
|
||||||
|
initrd $image $system $runtime
|
||||||
|
if [ $? != 0 ]
|
||||||
|
then
|
||||||
|
echo "!!"
|
||||||
|
echo "!! Unable to load images."
|
||||||
|
echo "!! Rebooting in 15s..."
|
||||||
|
echo "!!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Booting..."
|
||||||
|
boot
|
||||||
}
|
}
|
||||||
|
|
||||||
menuentry "Network boot node with dracut: {{.Id}}" --id dracut {
|
menuentry "Single-stage boot (no compression)" --id single-stage-nocompress {
|
||||||
|
echo "Warewulf Server:"
|
||||||
|
echo "* Ipaddr: {{.Ipaddr}}"
|
||||||
|
echo "* Port: {{.Port}}"
|
||||||
|
echo
|
||||||
|
echo "This node:"
|
||||||
|
echo "* Fqdn: {{.Fqdn}}"
|
||||||
|
echo "* Hwaddr: {{.Hwaddr}}"
|
||||||
|
echo "* ImageName: {{.ImageName}}"
|
||||||
|
{{- if .KernelVersion }}
|
||||||
|
echo "* KernelVersion: {{.KernelVersion}}"
|
||||||
|
{{- else }}
|
||||||
|
echo "* KernelVersion: (image default)"
|
||||||
|
{{- end }}
|
||||||
|
echo "* KernelArgs: {{.KernelArgs}}"
|
||||||
|
echo
|
||||||
|
echo "Downloading kernel image..."
|
||||||
|
linux $kernel wwid=${net_default_mac} {{.KernelArgs}}
|
||||||
|
if [ $? != 0 ]
|
||||||
|
then
|
||||||
|
echo "!!"
|
||||||
|
echo "!! Unable to load kernel."
|
||||||
|
echo "!! Rebooting in 15s..."
|
||||||
|
echo "!!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Downloading images..."
|
||||||
|
image="${uri}&stage=image"
|
||||||
|
system="${uri}&stage=system"
|
||||||
|
runtime="${uri}&stage=runtime"
|
||||||
|
initrd $image $system $runtime
|
||||||
|
if [ $? != 0 ]
|
||||||
|
then
|
||||||
|
echo "!!"
|
||||||
|
echo "!! Unable to load images."
|
||||||
|
echo "!! Rebooting in 15s..."
|
||||||
|
echo "!!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Booting..."
|
||||||
|
boot
|
||||||
|
}
|
||||||
|
|
||||||
|
menuentry "Two stage boot with dracut" --id dracut {
|
||||||
|
echo "Warewulf Server:"
|
||||||
|
echo "* Ipaddr: {{.Ipaddr}}"
|
||||||
|
echo "* Port: {{.Port}}"
|
||||||
|
echo
|
||||||
|
echo "This node:"
|
||||||
|
echo "* Fqdn: {{.Fqdn}}"
|
||||||
|
echo "* Hwaddr: {{.Hwaddr}}"
|
||||||
|
echo "* ImageName: {{.ImageName}}"
|
||||||
|
{{- if .KernelVersion }}
|
||||||
|
echo "* KernelVersion: {{.KernelVersion}}"
|
||||||
|
{{- else }}
|
||||||
|
echo "* KernelVersion: (image default)"
|
||||||
|
{{- end }}
|
||||||
|
echo "* KernelArgs: {{.KernelArgs}}"
|
||||||
|
|
||||||
initramfs="${uri}&stage=initramfs"
|
initramfs="${uri}&stage=initramfs"
|
||||||
|
|
||||||
wwinit_uri="http://{{.Ipaddr}}:{{.Port}}/provision/${net_default_mac}"
|
wwinit_uri="http://{{.Ipaddr}}:{{.Port}}/provision/${net_default_mac}"
|
||||||
|
|
||||||
{{if .KernelVersion }}
|
|
||||||
echo "Kernel: {{.KernelVersion}}"
|
|
||||||
{{else}}
|
|
||||||
echo "Kernel: {{.ImageName}} (image default)"
|
|
||||||
{{end}}
|
|
||||||
echo "KernelArgs: {{.KernelArgs}}"
|
|
||||||
|
|
||||||
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 wwinit.uri=${wwinit_uri} init=/init"
|
wwinit_args="root=wwinit wwinit.uri=${wwinit_uri} init=/init"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Downloading kernel image..."
|
||||||
linux $kernel wwid=${net_default_mac} {{.KernelArgs}} $net_args $wwinit_args
|
linux $kernel wwid=${net_default_mac} {{.KernelArgs}} $net_args $wwinit_args
|
||||||
|
if [ $? != 0 ]
|
||||||
if [ x$? = x0 ] ; then
|
then
|
||||||
echo "Loading Image: {{.ImageName}}"
|
echo "!!"
|
||||||
initrd $initramfs
|
echo "!! Unable to load kernel."
|
||||||
boot
|
echo "!! Rebooting in 15s..."
|
||||||
else
|
echo "!!"
|
||||||
echo "MESSAGE: This node seems to be unconfigured. Please have your system administrator add a"
|
|
||||||
echo " configuration for this node with HW address: ${net_default_mac}"
|
|
||||||
echo ""
|
|
||||||
echo "Rebooting in 1 minute..."
|
|
||||||
sleep 60
|
|
||||||
reboot
|
|
||||||
fi
|
fi
|
||||||
}
|
|
||||||
|
|
||||||
menuentry "Chainload specific configfile" {
|
echo "Downloading initramfs..."
|
||||||
conf="(http,{{.Ipaddr}}:{{.Port}})/efiboot/grub.cfg?assetkey=${assetkey}"
|
initrd $initramfs
|
||||||
configfile $conf
|
if [ $? != 0 ]
|
||||||
|
then
|
||||||
|
echo "!!"
|
||||||
|
echo "!! Unable to load initramfs."
|
||||||
|
echo "!! Rebooting in 15s..."
|
||||||
|
echo "!!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Booting..."
|
||||||
|
boot
|
||||||
}
|
}
|
||||||
|
|
||||||
menuentry "UEFI Firmware Settings" --id "uefi-firmware" {
|
menuentry "UEFI Firmware Settings" --id "uefi-firmware" {
|
||||||
@@ -87,12 +180,3 @@ menuentry "System shutdown" {
|
|||||||
echo "System shutting down..."
|
echo "System shutting down..."
|
||||||
halt
|
halt
|
||||||
}
|
}
|
||||||
{{ else }}
|
|
||||||
echo "================================================================================"
|
|
||||||
echo " Warewulf v4:"
|
|
||||||
echo " No node image defined for this node ({{.Fqdn}})."
|
|
||||||
echo " Rebooting in 30s."
|
|
||||||
echo "================================================================================"
|
|
||||||
sleep 30
|
|
||||||
reboot
|
|
||||||
{{ end }}
|
|
||||||
|
|||||||
@@ -1,94 +1,129 @@
|
|||||||
#!ipxe
|
#!ipxe
|
||||||
{{ if .ImageName }}
|
|
||||||
echo
|
echo
|
||||||
echo ================================================================================
|
echo Warewulf v4 (iPXE)
|
||||||
echo Warewulf v4 now booting: {{.Fqdn}} ({{.Hwaddr}})
|
|
||||||
echo
|
|
||||||
echo Image: {{.ImageName}}
|
|
||||||
{{if .KernelVersion }}
|
|
||||||
echo Kernel: {{.KernelVersion}}
|
|
||||||
{{else}}
|
|
||||||
echo Kernel: {{.ImageName}} (image default)
|
|
||||||
{{end}}
|
|
||||||
echo KernelArgs: {{.KernelArgs}}
|
|
||||||
echo
|
echo
|
||||||
|
set next start
|
||||||
|
goto metadata
|
||||||
|
|
||||||
set uri_base http://{{.Ipaddr}}:{{.Port}}/provision/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid}
|
:start
|
||||||
echo Warewulf Controller: {{.Ipaddr}}
|
{{- if not .ImageName }}
|
||||||
|
echo !!
|
||||||
echo Downloading Kernel Image:
|
echo !! No image defined for {{.Fqdn}}.
|
||||||
kernel --name kernel ${uri_base}&stage=kernel || goto reboot
|
echo !! Rebooting in 30s...
|
||||||
|
echo !!
|
||||||
# imgextract causes RAM space problems on non-EFI systems (because of the 3GB barrier
|
|
||||||
# in 32-Bit mode).
|
|
||||||
# -> Use the old initrd method with a compressed image to save as much RAM as possible
|
|
||||||
# in this early boot stage.
|
|
||||||
# See <https://github.com/warewulf/warewulf/issues/222> for more details.
|
|
||||||
iseq ${platform} efi && goto efi || goto noefi
|
|
||||||
|
|
||||||
:efi
|
|
||||||
|
|
||||||
# try extracting compressed images first
|
|
||||||
# NOTE: system overlay tends to be the smallest, so failure here is the cheapest
|
|
||||||
echo Downloading Image:
|
|
||||||
imgextract --name image ${uri_base}&stage=image&compress=gz || goto nocompress
|
|
||||||
|
|
||||||
echo Downloading System Overlay:
|
|
||||||
imgextract --name system ${uri_base}&stage=system&compress=gz || goto reboot
|
|
||||||
|
|
||||||
echo Downloading Runtime Overlay:
|
|
||||||
imgextract --name runtime ${uri_base}&stage=runtime&compress=gz && set runtime_initrd initrd=runtime || echo Failed downloading runtime overlay.
|
|
||||||
|
|
||||||
goto imoktogo
|
|
||||||
|
|
||||||
:nocompress
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo Image extract not supported in this iPXE, using standard initrd mode
|
|
||||||
|
|
||||||
echo Downloading Image:
|
|
||||||
initrd --name image ${uri_base}&stage=image || goto reboot
|
|
||||||
|
|
||||||
echo Downloading System Overlay:
|
|
||||||
initrd --name system ${uri_base}&stage=system || goto reboot
|
|
||||||
|
|
||||||
echo Downloading Runtime Overlay:
|
|
||||||
initrd --name runtime ${uri_base}&stage=runtime && set runtime_initrd initrd=runtime || echo Failed downloading runtime overlay.
|
|
||||||
|
|
||||||
goto imoktogo
|
|
||||||
|
|
||||||
:noefi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo Use legacy initrd mode with compressed images
|
|
||||||
|
|
||||||
echo Downloading Image:
|
|
||||||
initrd --name image ${uri_base}&stage=image&compress=gz || goto reboot
|
|
||||||
|
|
||||||
echo Downloading System Overlay:
|
|
||||||
initrd --name system ${uri_base}&stage=system&compress=gz || goto reboot
|
|
||||||
|
|
||||||
echo Downloading Runtime Overlay:
|
|
||||||
initrd --name runtime ${uri_base}&stage=runtime&compress=gz && set runtime_initrd initrd=runtime || echo Failed downloading runtime overlay.
|
|
||||||
|
|
||||||
|
|
||||||
:imoktogo
|
|
||||||
|
|
||||||
echo boot kernel initrd=image initrd=system ${runtime_initrd} wwid={{.Hwaddr}} {{.KernelArgs}}
|
|
||||||
boot kernel initrd=image initrd=system ${runtime_initrd} wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot
|
|
||||||
|
|
||||||
:reboot
|
|
||||||
echo
|
|
||||||
echo There was an error, rebooting in 15s...
|
|
||||||
echo
|
|
||||||
sleep 15
|
|
||||||
reboot
|
|
||||||
{{ else }}
|
|
||||||
echo ================================================================================
|
|
||||||
echo Warewulf v4:
|
|
||||||
echo No image defined for this node ({{.Fqdn}}).
|
|
||||||
echo Rebooting in 30s.
|
|
||||||
echo ================================================================================
|
|
||||||
sleep 30
|
sleep 30
|
||||||
reboot
|
reboot
|
||||||
{{ end }}
|
{{- end }}
|
||||||
|
|
||||||
|
set baseuri http://{{.Ipaddr}}:{{.Port}}/provision/{{.Hwaddr}}
|
||||||
|
set uri ${baseuri}?assetkey=${asset}&uuid=${uuid}
|
||||||
|
|
||||||
|
echo Downloading kernel image...
|
||||||
|
kernel --name kernel ${uri}&stage=kernel || goto reboot
|
||||||
|
|
||||||
|
{{- if .Tags.IPXEMenuEntry }}
|
||||||
|
set method {{ .Tags.IPXEMenuEntry }}
|
||||||
|
{{- else }}
|
||||||
|
# https://github.com/warewulf/warewulf/issues/222
|
||||||
|
iseq ${platform} efi && set method imgextract || set method initrd
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
:menu
|
||||||
|
menu Warewulf v4 image provisioning method
|
||||||
|
item imgextract Single-stage with imgextract
|
||||||
|
item initrd Single-stage with initrd
|
||||||
|
item initrd_nocompress Single stage with initrd (no compression)
|
||||||
|
item dracut Two stage with dracut
|
||||||
|
item shell iPXE shell
|
||||||
|
choose --default ${method} --timeout 2000 method && goto ${method} || goto menu
|
||||||
|
|
||||||
|
:imgextract
|
||||||
|
set next imgextract_continue
|
||||||
|
goto metadata
|
||||||
|
:imgextract_continue
|
||||||
|
echo
|
||||||
|
echo Downloading compressed image with imgextract...
|
||||||
|
imgextract --name image ${uri}&stage=image&compress=gz || goto error_use_initrd
|
||||||
|
echo Downloading compressed system overlay image with imgextract...
|
||||||
|
imgextract --name system ${uri}&stage=system&compress=gz || goto error_reboot
|
||||||
|
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)
|
||||||
|
goto boot_single_stage
|
||||||
|
|
||||||
|
:error_use_initrd
|
||||||
|
echo Encountered an error. Now using initrd.
|
||||||
|
goto initrd_continue
|
||||||
|
|
||||||
|
:initrd
|
||||||
|
set next initrd_continue
|
||||||
|
goto metadata
|
||||||
|
:initrd_continue
|
||||||
|
echo
|
||||||
|
echo Downloading compressed image with initrd...
|
||||||
|
initrd --name image ${uri}&stage=image&compress=gz || goto error_reboot
|
||||||
|
echo Downloading compressed system overlay with initrd...
|
||||||
|
initrd --name system ${uri}&stage=system&compress=gz || goto error_reboot
|
||||||
|
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)
|
||||||
|
goto boot_single_stage
|
||||||
|
|
||||||
|
:initrd_nocompress
|
||||||
|
set next initrd_nocompress_continue
|
||||||
|
goto metadata
|
||||||
|
:initrd_nocompress_continue
|
||||||
|
echo
|
||||||
|
echo Downloading uncompressed image with initrd...
|
||||||
|
initrd --name image ${uri}&stage=image || goto error_reboot
|
||||||
|
echo Downloading uncompressed system overlay with initrd...
|
||||||
|
initrd --name system ${uri}&stage=system || goto error_reboot
|
||||||
|
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)
|
||||||
|
goto boot_single_stage
|
||||||
|
|
||||||
|
:dracut
|
||||||
|
set next dracut_continue
|
||||||
|
goto metadata
|
||||||
|
:dracut_continue
|
||||||
|
echo
|
||||||
|
echo Downloading dracut initramfs...
|
||||||
|
initrd --name initramfs ${uri}&stage=initramfs || 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_wwinit root=wwinit wwinit.uri=${baseuri} init=/init
|
||||||
|
goto boot_two_stage_dracut
|
||||||
|
|
||||||
|
:boot_single_stage
|
||||||
|
echo Booting (single stage)...
|
||||||
|
boot kernel initrd=image initrd=system ${runtime_initrd} wwid={{.Hwaddr}} {{.KernelArgs}} || goto error_reboot
|
||||||
|
|
||||||
|
:boot_two_stage_dracut
|
||||||
|
echo Booting dracut (first stage)...
|
||||||
|
boot kernel initrd=initramfs ${dracut_net} ${dracut_wwinit} wwid={{.Hwaddr}} {{.KernelArgs}} || error_reboot
|
||||||
|
|
||||||
|
:error_reboot
|
||||||
|
echo !!
|
||||||
|
echo !! Encountered an error.
|
||||||
|
echo !! rebooting in 15s...
|
||||||
|
echo !!
|
||||||
|
sleep 15
|
||||||
|
reboot
|
||||||
|
|
||||||
|
:shell
|
||||||
|
shell
|
||||||
|
goto menu
|
||||||
|
|
||||||
|
:metadata
|
||||||
|
echo Warewulf Server:
|
||||||
|
echo * Ipaddr: {{.Ipaddr}}
|
||||||
|
echo * Port: {{.Port}}
|
||||||
|
echo
|
||||||
|
echo This node:
|
||||||
|
echo * Fqdn: {{.Fqdn}}
|
||||||
|
echo * Hwaddr: {{.Hwaddr}}
|
||||||
|
echo * ImageName: {{.ImageName}}
|
||||||
|
{{- if .KernelVersion }}
|
||||||
|
echo * KernelVersion: {{.KernelVersion}}
|
||||||
|
{{- else }}
|
||||||
|
echo * KernelVersion: (image default)
|
||||||
|
{{- end }}
|
||||||
|
echo * KernelArgs: {{.KernelArgs}}
|
||||||
|
goto ${next}
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
#!ipxe
|
|
||||||
{{ if .ImageName }}
|
|
||||||
echo
|
|
||||||
echo ================================================================================
|
|
||||||
echo Warewulf v4 now booting via dracut: {{.Fqdn}} ({{.Hwaddr}})
|
|
||||||
echo
|
|
||||||
echo Image: {{.ImageName}}
|
|
||||||
{{if .KernelVersion }}
|
|
||||||
echo Kernel: {{.KernelVersion}}
|
|
||||||
{{else}}
|
|
||||||
echo Kernel: {{.ImageName}} (image default)
|
|
||||||
{{end}}
|
|
||||||
echo KernelArgs: {{.KernelArgs}}
|
|
||||||
echo
|
|
||||||
|
|
||||||
set baseuri http://{{.Ipaddr}}:{{.Port}}/provision/{{.Hwaddr}}
|
|
||||||
set uri ${baseuri}?assetkey=${asset}&uuid=${uuid}
|
|
||||||
echo Warewulf Controller: {{.Ipaddr}}
|
|
||||||
|
|
||||||
echo Downloading Kernel Image:
|
|
||||||
kernel --name kernel ${uri}&stage=kernel || goto reboot
|
|
||||||
|
|
||||||
echo Downloading initramfs
|
|
||||||
initrd --name initramfs ${uri}&stage=initramfs || goto 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_wwinit root=wwinit wwinit.uri=${baseuri} init=/init
|
|
||||||
|
|
||||||
echo Booting initramfs
|
|
||||||
boot kernel initrd=initramfs ${dracut_net} ${dracut_wwinit} wwid={{.Hwaddr}} {{.KernelArgs}}
|
|
||||||
|
|
||||||
|
|
||||||
:reboot
|
|
||||||
echo
|
|
||||||
echo There was an error, rebooting in 15s...
|
|
||||||
echo
|
|
||||||
sleep 15
|
|
||||||
reboot
|
|
||||||
{{ else }}
|
|
||||||
echo ================================================================================
|
|
||||||
echo Warewulf v4:
|
|
||||||
echo No image defined for this node ({{.Fqdn}}).
|
|
||||||
echo Rebooting in 30s.
|
|
||||||
echo ================================================================================
|
|
||||||
sleep 30
|
|
||||||
reboot
|
|
||||||
{{ end }}
|
|
||||||
48
init.bak
Executable file
48
init.bak
Executable file
@@ -0,0 +1,48 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
echo "Warewulf pre-init (/init)"
|
||||||
|
echo
|
||||||
|
echo "Mounting kernel file systems..."
|
||||||
|
mountpoint -q /proc || (mkdir -p /proc && mount -t proc proc /proc && echo "Mounted /proc")
|
||||||
|
mountpoint -q /dev || (mkdir -p /dev && mount -t devtmpfs devtmpfs /dev && echo "Mounted /dev")
|
||||||
|
mountpoint -q /sys || (mkdir -p /sys && mount -t sysfs sysfs /sys && echo "Mounted /sys")
|
||||||
|
echo
|
||||||
|
echo "Loading /warewulf/config..."
|
||||||
|
if [ -f "/warewulf/config" ]; then
|
||||||
|
. /warewulf/config
|
||||||
|
else
|
||||||
|
echo "ERROR: Warewulf configuration file not found."
|
||||||
|
echo "Rebooting in 1 minute..."
|
||||||
|
sleep 60
|
||||||
|
echo b > /proc/sysrq-trigger || /sbin/reboot -f
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo "Configuring root file system..."
|
||||||
|
|
||||||
|
WWPRESCRIPTS=/warewulf/wwprescripts
|
||||||
|
chmod +rx "${WWPRESCRIPTS}"
|
||||||
|
|
||||||
|
WWROOT="${WWROOT:-initramfs}"
|
||||||
|
if [ "${WWROOT}" = "initramfs" ]; then
|
||||||
|
echo "WWROOT=${WWROOT}: using initial rootfs and invoking ${WWPRESCRIPTS}..."
|
||||||
|
exec "${WWPRESCRIPTS}"
|
||||||
|
elif [ "${WWROOT}" = "ramfs" -o "${WWROOT}" = "tmpfs" ]; then
|
||||||
|
echo "WWROOT=${WWROOT}: setting up new ${WWROOT} rootfs (/newroot)..."
|
||||||
|
mkdir /newroot
|
||||||
|
mount wwroot /newroot -t ${WWROOT} -o mpol=interleave # mpol ignored for ramfs
|
||||||
|
tar -cf - --exclude ./proc --exclude ./sys --exclude ./dev --exclude --exclude ./newroot . | tar -xf - -C /newroot
|
||||||
|
mkdir /newroot/proc /newroot/dev /newroot/sys 2>/dev/null
|
||||||
|
echo "Switching to new rootfs (/newroot) and invoking ${WWPRESCRIPTS}..."
|
||||||
|
exec /sbin/switch_root /newroot "${WWPRESCRIPTS}"
|
||||||
|
else
|
||||||
|
echo "ERROR: Unrecognized rootfs type requested: ${WWROOT}"
|
||||||
|
echo "Rebooting in 1 minute..."
|
||||||
|
sleep 60
|
||||||
|
echo b > /proc/sysrq-trigger || /sbin/reboot -f
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "ERROR: wwinit encountered a problem."
|
||||||
|
echo "Rebooting in 1 minute..."
|
||||||
|
sleep 60
|
||||||
|
echo b > /proc/sysrq-trigger || /sbin/reboot -f
|
||||||
@@ -165,6 +165,7 @@ type Node struct {
|
|||||||
func (legacy *Node) Upgrade(addDefaults bool, replaceOverlays bool) (upgraded *node.Node) {
|
func (legacy *Node) Upgrade(addDefaults bool, replaceOverlays bool) (upgraded *node.Node) {
|
||||||
upgraded = new(node.Node)
|
upgraded = new(node.Node)
|
||||||
upgraded.Tags = make(map[string]string)
|
upgraded.Tags = make(map[string]string)
|
||||||
|
upgraded.Resources = make(map[string]node.Resource)
|
||||||
upgraded.Disks = make(map[string]*node.Disk)
|
upgraded.Disks = make(map[string]*node.Disk)
|
||||||
upgraded.FileSystems = make(map[string]*node.FileSystem)
|
upgraded.FileSystems = make(map[string]*node.FileSystem)
|
||||||
upgraded.Ipmi = new(node.IpmiConf)
|
upgraded.Ipmi = new(node.IpmiConf)
|
||||||
@@ -226,7 +227,31 @@ func (legacy *Node) Upgrade(addDefaults bool, replaceOverlays bool) (upgraded *n
|
|||||||
if upgraded.Ipmi.Write == "" && legacy.IpmiWrite != "" {
|
if upgraded.Ipmi.Write == "" && legacy.IpmiWrite != "" {
|
||||||
warnError(upgraded.Ipmi.Write.Set(legacy.IpmiWrite))
|
warnError(upgraded.Ipmi.Write.Set(legacy.IpmiWrite))
|
||||||
}
|
}
|
||||||
upgraded.Ipxe = legacy.Ipxe
|
if legacy.Keys != nil {
|
||||||
|
for key, value := range legacy.Keys {
|
||||||
|
upgraded.Tags[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if legacy.Tags != nil {
|
||||||
|
for key, value := range legacy.Tags {
|
||||||
|
upgraded.Tags[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, tag := range legacy.TagsDel {
|
||||||
|
delete(upgraded.Tags, tag)
|
||||||
|
}
|
||||||
|
if legacy.Ipxe == "dracut" {
|
||||||
|
if _, ok := upgraded.Tags["IPXEMenuEntry"]; !ok {
|
||||||
|
wwlog.Info("Replacing ipxe template 'dracut' with 'default' and setting tag 'IPXEMenuEntry=dracut'")
|
||||||
|
upgraded.Ipxe = "default"
|
||||||
|
upgraded.Tags["IPXEMenuEntry"] = "dracut"
|
||||||
|
} else {
|
||||||
|
wwlog.Warn("Found ipxe template 'dracut' but tag 'IPXEMenuEntry' is already set; ignoring")
|
||||||
|
upgraded.Ipxe = legacy.Ipxe
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
upgraded.Ipxe = legacy.Ipxe
|
||||||
|
}
|
||||||
if legacy.Kernel != nil {
|
if legacy.Kernel != nil {
|
||||||
upgraded.Kernel = legacy.Kernel.Upgrade(upgraded.ImageName)
|
upgraded.Kernel = legacy.Kernel.Upgrade(upgraded.ImageName)
|
||||||
} else {
|
} else {
|
||||||
@@ -237,11 +262,6 @@ func (legacy *Node) Upgrade(addDefaults bool, replaceOverlays bool) (upgraded *n
|
|||||||
}
|
}
|
||||||
upgraded.Kernel = inlineKernel.Upgrade(upgraded.ImageName)
|
upgraded.Kernel = inlineKernel.Upgrade(upgraded.ImageName)
|
||||||
}
|
}
|
||||||
if legacy.Keys != nil {
|
|
||||||
for key, value := range legacy.Keys {
|
|
||||||
upgraded.Tags[key] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if legacy.NetDevs != nil {
|
if legacy.NetDevs != nil {
|
||||||
for name, netDev := range legacy.NetDevs {
|
for name, netDev := range legacy.NetDevs {
|
||||||
upgraded.NetDevs[name] = netDev.Upgrade(false)
|
upgraded.NetDevs[name] = netDev.Upgrade(false)
|
||||||
@@ -313,14 +333,11 @@ func (legacy *Node) Upgrade(addDefaults bool, replaceOverlays bool) (upgraded *n
|
|||||||
genericSplitOverlays)
|
genericSplitOverlays)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if legacy.Tags != nil {
|
if legacy.Resources != nil {
|
||||||
for key, value := range legacy.Tags {
|
for key, value := range legacy.Resources {
|
||||||
upgraded.Tags[key] = value
|
upgraded.Resources[key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, tag := range legacy.TagsDel {
|
|
||||||
delete(upgraded.Tags, tag)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +444,31 @@ func (legacy *Profile) Upgrade(addDefaults bool, replaceOverlays bool) (upgraded
|
|||||||
if upgraded.Ipmi.Write == "" && legacy.IpmiWrite != "" {
|
if upgraded.Ipmi.Write == "" && legacy.IpmiWrite != "" {
|
||||||
warnError(upgraded.Ipmi.Write.Set(legacy.IpmiWrite))
|
warnError(upgraded.Ipmi.Write.Set(legacy.IpmiWrite))
|
||||||
}
|
}
|
||||||
upgraded.Ipxe = legacy.Ipxe
|
if legacy.Keys != nil {
|
||||||
|
for key, value := range legacy.Keys {
|
||||||
|
upgraded.Tags[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if legacy.Tags != nil {
|
||||||
|
for key, value := range legacy.Tags {
|
||||||
|
upgraded.Tags[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, tag := range legacy.TagsDel {
|
||||||
|
delete(upgraded.Tags, tag)
|
||||||
|
}
|
||||||
|
if legacy.Ipxe == "dracut" {
|
||||||
|
if _, ok := upgraded.Tags["IPXEMenuEntry"]; !ok {
|
||||||
|
wwlog.Info("Replacing ipxe template 'dracut' with 'default' and setting tag 'IPXEMenuEntry=dracut'")
|
||||||
|
upgraded.Ipxe = "default"
|
||||||
|
upgraded.Tags["IPXEMenuEntry"] = "dracut"
|
||||||
|
} else {
|
||||||
|
wwlog.Warn("Found ipxe template 'dracut' but tag 'IPXEMenuEntry' is already set; ignoring")
|
||||||
|
upgraded.Ipxe = legacy.Ipxe
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
upgraded.Ipxe = legacy.Ipxe
|
||||||
|
}
|
||||||
if legacy.Kernel != nil {
|
if legacy.Kernel != nil {
|
||||||
upgraded.Kernel = legacy.Kernel.Upgrade(upgraded.ImageName)
|
upgraded.Kernel = legacy.Kernel.Upgrade(upgraded.ImageName)
|
||||||
} else {
|
} else {
|
||||||
@@ -438,11 +479,6 @@ func (legacy *Profile) Upgrade(addDefaults bool, replaceOverlays bool) (upgraded
|
|||||||
}
|
}
|
||||||
upgraded.Kernel = inlineKernel.Upgrade(upgraded.ImageName)
|
upgraded.Kernel = inlineKernel.Upgrade(upgraded.ImageName)
|
||||||
}
|
}
|
||||||
if legacy.Keys != nil {
|
|
||||||
for key, value := range legacy.Keys {
|
|
||||||
upgraded.Tags[key] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if legacy.NetDevs != nil {
|
if legacy.NetDevs != nil {
|
||||||
for name, netDev := range legacy.NetDevs {
|
for name, netDev := range legacy.NetDevs {
|
||||||
upgraded.NetDevs[name] = netDev.Upgrade(addDefaults)
|
upgraded.NetDevs[name] = netDev.Upgrade(addDefaults)
|
||||||
@@ -503,14 +539,6 @@ func (legacy *Profile) Upgrade(addDefaults bool, replaceOverlays bool) (upgraded
|
|||||||
genericSplitOverlays)
|
genericSplitOverlays)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if legacy.Tags != nil {
|
|
||||||
for key, value := range legacy.Tags {
|
|
||||||
upgraded.Tags[key] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, tag := range legacy.TagsDel {
|
|
||||||
delete(upgraded.Tags, tag)
|
|
||||||
}
|
|
||||||
if legacy.Resources != nil {
|
if legacy.Resources != nil {
|
||||||
for key, value := range legacy.Resources {
|
for key, value := range legacy.Resources {
|
||||||
upgraded.Resources[key] = value
|
upgraded.Resources[key] = value
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ nodes:
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "keys and tags",
|
name: "keys, tags, and resources",
|
||||||
addDefaults: false,
|
addDefaults: false,
|
||||||
replaceOverlays: false,
|
replaceOverlays: false,
|
||||||
legacyYaml: `
|
legacyYaml: `
|
||||||
@@ -269,6 +269,13 @@ nodeprofiles:
|
|||||||
key4: valD
|
key4: valD
|
||||||
tagsdel:
|
tagsdel:
|
||||||
- key4
|
- key4
|
||||||
|
resources:
|
||||||
|
res1:
|
||||||
|
- val1a
|
||||||
|
- val1b
|
||||||
|
res2:
|
||||||
|
- val2a
|
||||||
|
- val2b
|
||||||
network devices:
|
network devices:
|
||||||
default:
|
default:
|
||||||
tags:
|
tags:
|
||||||
@@ -295,6 +302,13 @@ nodes:
|
|||||||
key4: valD
|
key4: valD
|
||||||
tagsdel:
|
tagsdel:
|
||||||
- key4
|
- key4
|
||||||
|
resources:
|
||||||
|
resn1:
|
||||||
|
- valn1a
|
||||||
|
- valn1b
|
||||||
|
resn2:
|
||||||
|
- valn2a
|
||||||
|
- valn2b
|
||||||
network devices:
|
network devices:
|
||||||
default:
|
default:
|
||||||
tags:
|
tags:
|
||||||
@@ -327,6 +341,13 @@ nodeprofiles:
|
|||||||
key1: val1
|
key1: val1
|
||||||
key2: valB
|
key2: valB
|
||||||
key3: valC
|
key3: valC
|
||||||
|
resources:
|
||||||
|
res1:
|
||||||
|
- val1a
|
||||||
|
- val1b
|
||||||
|
res2:
|
||||||
|
- val2a
|
||||||
|
- val2b
|
||||||
nodes:
|
nodes:
|
||||||
n1:
|
n1:
|
||||||
ipmi:
|
ipmi:
|
||||||
@@ -342,6 +363,13 @@ nodes:
|
|||||||
key1: val1
|
key1: val1
|
||||||
key2: valB
|
key2: valB
|
||||||
key3: valC
|
key3: valC
|
||||||
|
resources:
|
||||||
|
resn1:
|
||||||
|
- valn1a
|
||||||
|
- valn1b
|
||||||
|
resn2:
|
||||||
|
- valn2a
|
||||||
|
- valn2b
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -852,6 +880,29 @@ nfs:
|
|||||||
mount: true
|
mount: true
|
||||||
- path: /var
|
- path: /var
|
||||||
mount: false
|
mount: false
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Replace dracut template with IPXEMenuEntry",
|
||||||
|
legacyYaml: `
|
||||||
|
nodeprofiles:
|
||||||
|
default:
|
||||||
|
ipxe template: dracut
|
||||||
|
nodes:
|
||||||
|
n1:
|
||||||
|
ipxe template: dracut
|
||||||
|
`,
|
||||||
|
upgradedYaml: `
|
||||||
|
nodeprofiles:
|
||||||
|
default:
|
||||||
|
ipxe template: default
|
||||||
|
tags:
|
||||||
|
IPXEMenuEntry: dracut
|
||||||
|
nodes:
|
||||||
|
n1:
|
||||||
|
ipxe template: default
|
||||||
|
tags:
|
||||||
|
IPXEMenuEntry: dracut
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,6 +104,11 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) {
|
|||||||
kernelArgs = strings.Join(remoteNode.Kernel.Args, " ")
|
kernelArgs = strings.Join(remoteNode.Kernel.Args, " ")
|
||||||
kernelVersion = remoteNode.Kernel.Version
|
kernelVersion = remoteNode.Kernel.Version
|
||||||
}
|
}
|
||||||
|
if kernelVersion == "" {
|
||||||
|
if kernel_ := kernel.FromNode(&remoteNode); kernel_ != nil {
|
||||||
|
kernelVersion = kernel_.Version()
|
||||||
|
}
|
||||||
|
}
|
||||||
tmpl_data = &templateVars{
|
tmpl_data = &templateVars{
|
||||||
Id: remoteNode.Id(),
|
Id: remoteNode.Id(),
|
||||||
Cluster: remoteNode.ClusterName,
|
Cluster: remoteNode.ClusterName,
|
||||||
@@ -186,6 +191,11 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) {
|
|||||||
kernelArgs = strings.Join(remoteNode.Kernel.Args, " ")
|
kernelArgs = strings.Join(remoteNode.Kernel.Args, " ")
|
||||||
kernelVersion = remoteNode.Kernel.Version
|
kernelVersion = remoteNode.Kernel.Version
|
||||||
}
|
}
|
||||||
|
if kernelVersion == "" {
|
||||||
|
if kernel_ := kernel.FromNode(&remoteNode); kernel_ != nil {
|
||||||
|
kernelVersion = kernel_.Version()
|
||||||
|
}
|
||||||
|
}
|
||||||
tmpl_data = &templateVars{
|
tmpl_data = &templateVars{
|
||||||
Id: remoteNode.Id(),
|
Id: remoteNode.Id(),
|
||||||
Cluster: remoteNode.ClusterName,
|
Cluster: remoteNode.ClusterName,
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
|
||||||
# This is one of those types of files that you shouldn't edit unless you really
|
|
||||||
# know what you are doing and even then you should make a backup.
|
|
||||||
#
|
|
||||||
# Edit at your own risk! DANGER DANGER.
|
|
||||||
|
|
||||||
|
echo "Warewulf pre-init (/init)"
|
||||||
|
echo
|
||||||
|
echo "Mounting kernel file systems..."
|
||||||
mountpoint -q /proc || (mkdir -p /proc && mount -t proc proc /proc && echo "Mounted /proc")
|
mountpoint -q /proc || (mkdir -p /proc && mount -t proc proc /proc && echo "Mounted /proc")
|
||||||
mountpoint -q /dev || (mkdir -p /dev && mount -t devtmpfs devtmpfs /dev && echo "Mounted /dev")
|
mountpoint -q /dev || (mkdir -p /dev && mount -t devtmpfs devtmpfs /dev && echo "Mounted /dev")
|
||||||
mountpoint -q /sys || (mkdir -p /sys && mount -t sysfs sysfs /sys && echo "Mounted /sys")
|
mountpoint -q /sys || (mkdir -p /sys && mount -t sysfs sysfs /sys && echo "Mounted /sys")
|
||||||
|
echo
|
||||||
|
echo "Loading /warewulf/config..."
|
||||||
if [ -f "/warewulf/config" ]; then
|
if [ -f "/warewulf/config" ]; then
|
||||||
. /warewulf/config
|
. /warewulf/config
|
||||||
else
|
else
|
||||||
@@ -17,24 +16,24 @@ else
|
|||||||
sleep 60
|
sleep 60
|
||||||
echo b > /proc/sysrq-trigger || /sbin/reboot -f
|
echo b > /proc/sysrq-trigger || /sbin/reboot -f
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo
|
|
||||||
echo "Warewulf v4 is now booting: ${WWHOSTNAME}"
|
|
||||||
echo
|
echo
|
||||||
|
echo "Configuring root file system..."
|
||||||
|
|
||||||
chmod 755 /warewulf/wwinit
|
WWPRESCRIPTS=/warewulf/wwprescripts
|
||||||
|
chmod +rx "${WWPRESCRIPTS}"
|
||||||
|
|
||||||
if [ -z "${WWROOT}" -o "${WWROOT}" = "initramfs" ]; then
|
WWROOT="${WWROOT:-initramfs}"
|
||||||
echo "Retaining initramfs and invoking /warewulf/wwinit..."
|
if [ "${WWROOT}" = "initramfs" ]; then
|
||||||
exec /warewulf/wwinit
|
echo "WWROOT=${WWROOT}: using initial rootfs and invoking ${WWPRESCRIPTS}..."
|
||||||
|
exec "${WWPRESCRIPTS}"
|
||||||
elif [ "${WWROOT}" = "ramfs" -o "${WWROOT}" = "tmpfs" ]; then
|
elif [ "${WWROOT}" = "ramfs" -o "${WWROOT}" = "tmpfs" ]; then
|
||||||
echo "Setting up new ${WWROOT} rootfs..."
|
echo "WWROOT=${WWROOT}: setting up new ${WWROOT} rootfs (/newroot)..."
|
||||||
mkdir /newroot
|
mkdir /newroot
|
||||||
mount wwroot /newroot -t ${WWROOT} -o mpol=interleave # mpol ignored for ramfs
|
mount wwroot /newroot -t ${WWROOT} -o mpol=interleave # mpol ignored for ramfs
|
||||||
tar -cf - --exclude ./proc --exclude ./sys --exclude ./dev --exclude --exclude ./newroot . | tar -xf - -C /newroot
|
tar -cf - --exclude ./proc --exclude ./sys --exclude ./dev --exclude --exclude ./newroot . | tar -xf - -C /newroot
|
||||||
mkdir /newroot/proc /newroot/dev /newroot/sys 2>/dev/null
|
mkdir /newroot/proc /newroot/dev /newroot/sys 2>/dev/null
|
||||||
echo "Switching to new rootfs and invoking /warewulf/wwinit..."
|
echo "Switching to new rootfs (/newroot) and invoking ${WWPRESCRIPTS}..."
|
||||||
exec /sbin/switch_root /newroot /warewulf/wwinit
|
exec /sbin/switch_root /newroot "${WWPRESCRIPTS}"
|
||||||
else
|
else
|
||||||
echo "ERROR: Unrecognized rootfs type requested: ${WWROOT}"
|
echo "ERROR: Unrecognized rootfs type requested: ${WWROOT}"
|
||||||
echo "Rebooting in 1 minute..."
|
echo "Rebooting in 1 minute..."
|
||||||
@@ -43,7 +42,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "ERROR: There was a problem with the initial provisioning process."
|
echo "ERROR: wwinit encountered a problem."
|
||||||
echo "Rebooting in 1 minute..."
|
echo "Rebooting in 1 minute..."
|
||||||
sleep 60
|
sleep 60
|
||||||
echo b > /proc/sysrq-trigger || /sbin/reboot -f
|
echo b > /proc/sysrq-trigger || /sbin/reboot -f
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
. /warewulf/config
|
echo "Warewulf prescript: localhost"
|
||||||
|
echo
|
||||||
echo "Bringing up lo:127.0.0.1"
|
echo "Bringing up lo..."
|
||||||
/sbin/ip link set dev lo up
|
/sbin/ip link set dev lo up
|
||||||
|
|||||||
@@ -4,17 +4,22 @@
|
|||||||
|
|
||||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||||
|
|
||||||
|
echo "Warewulf prescript: IPMI"
|
||||||
|
echo
|
||||||
|
|
||||||
if [ "$WWIPMI_WRITE" != "true" ]; then
|
if [ "$WWIPMI_WRITE" != "true" ]; then
|
||||||
echo "IPMI write not configured: skipping"
|
echo "IPMI write not configured: skipping"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "Loading IPMI kernel modules..."
|
||||||
modprobe ipmi_si ipmi_ssif ipmi_devintf ipmi_msghandler || (
|
modprobe ipmi_si ipmi_ssif ipmi_devintf ipmi_msghandler || (
|
||||||
echo "unable to load IPMI kernel modules: skipping IPMI configuration"
|
echo "Unable to load IPMI kernel modules: skipping IPMI configuration"
|
||||||
exit
|
exit
|
||||||
)
|
)
|
||||||
|
|
||||||
if [ ! -e /dev/ipmi0 ]; then
|
if [ ! -e /dev/ipmi0 ]; then
|
||||||
|
echo "/dev/ipmi0 does not exist; creating..."
|
||||||
sleep 1
|
sleep 1
|
||||||
ipmi_dev=$(grep ipmidev /proc/devices | awk '{ print $1 }')
|
ipmi_dev=$(grep ipmidev /proc/devices | awk '{ print $1 }')
|
||||||
mknod -m 0666 /dev/ipmi0 c "$ipmi_dev" 0
|
mknod -m 0666 /dev/ipmi0 c "$ipmi_dev" 0
|
||||||
@@ -83,7 +88,7 @@ if [ -n "$WWIPMI_PASSWORD" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Serial Over LAN
|
echo "Configuring Serial over LAN..."
|
||||||
ipmitool channel setaccess 1 2 link=on ipmi=on callin=on privilege=4
|
ipmitool channel setaccess 1 2 link=on ipmi=on callin=on privilege=4
|
||||||
ipmitool sol set force-encryption true 1
|
ipmitool sol set force-encryption true 1
|
||||||
ipmitool sol set force-authentication true 1
|
ipmitool sol set force-authentication true 1
|
||||||
|
|||||||
@@ -2,23 +2,19 @@
|
|||||||
|
|
||||||
. /warewulf/config
|
. /warewulf/config
|
||||||
|
|
||||||
# This will eventually be optional
|
echo "Warewulf prescript: VNFS fixes"
|
||||||
if true; then
|
echo
|
||||||
if [ -f "/etc/pam.d/system-auth" ]; then
|
|
||||||
echo "FIXING: system-auth"
|
add_broken_shadow() {
|
||||||
sed -i -e '/^account.*pam_unix\.so\s*$/s/\s*$/\ broken_shadow/' /etc/pam.d/system-auth
|
if [ -f "${1}" ]; then
|
||||||
|
echo "Adding broken_shadow to ${1}..."
|
||||||
|
sed -i -e '/^account.*pam_unix\.so\s*$/s/\s*$/\ broken_shadow/' "${1}"
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
if [ -f "/etc/pam.d/password-auth" ]; then
|
add_broken_shadow /etc/pam.d/system-auth
|
||||||
echo "FIXING: password-auth"
|
add_broken_shadow /etc/pam.d/password-auth
|
||||||
sed -i -e '/^account.*pam_unix\.so\s*$/s/\s*$/\ broken_shadow/' /etc/pam.d/password-auth
|
add_broken_shadow /etc/pam.d/common-account
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "/etc/pam.d/common-account" ]; then
|
|
||||||
echo "FIXING: common-account"
|
|
||||||
sed -i -e '/^account.*pam_unix\.so\s*$/s/\s*$/\ broken_shadow/' /etc/pam.d/common-account
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
|
echo "Adjusting root directory permissions..."
|
||||||
chmod 755 /
|
chmod 755 /
|
||||||
|
|||||||
@@ -2,32 +2,42 @@
|
|||||||
|
|
||||||
. /warewulf/config
|
. /warewulf/config
|
||||||
|
|
||||||
|
echo "Warewulf prescript: SELinux"
|
||||||
|
|
||||||
if test -f "/etc/sysconfig/selinux"; then
|
if test -f "/etc/sysconfig/selinux"; then
|
||||||
. /etc/sysconfig/selinux
|
. /etc/sysconfig/selinux
|
||||||
else
|
else
|
||||||
echo "Skipping SELinux configuration: Host config not found: /etc/sysconfig/selinux"
|
echo "File not found: /etc/sysconfig/selinux"
|
||||||
|
echo "Skipping SELinux configuration."
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$SELINUX" == "disabled"; then
|
if [ "$SELINUX" = "disabled" ]; then
|
||||||
echo "Skipping SELinux setup per /etc/sysconfig/selinux"
|
echo "/etc/sysconfig/selinux:SELINUX=${SELINUX}: skipping SELinux configuration."
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if grep -q "selinux=0" /proc/cmdline; then
|
if grep -q "selinux=0" /proc/cmdline; then
|
||||||
echo "Skipping SELinux setup per kernel command line"
|
echo "/proc/cmdline:selinux=0: skipping SELinux configuration."
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $(findmnt / --noheadings --output SOURCE) == 'rootfs' ]; then
|
if [ $(findmnt / --noheadings --output SOURCE) = 'rootfs' ]; then
|
||||||
echo "Skipping SELinux configuration: rootfs does not support SELinux contexts"
|
echo "/ is a 'rootfs' file system, which does not support SELinux contexts."
|
||||||
|
echo "Skipping SELinux configuration."
|
||||||
echo
|
echo
|
||||||
echo "WARNING: SELinux prep is being skipped, but SELinux is enabled on host! This may"
|
echo "WARNING: SELinux configuration is being skipped, but SELinux is"
|
||||||
echo "WARNING: cause the system to not work properly. Try setting 'Root=tmpfs'"
|
echo "WARNING: enabled in the image! The node will probably not boot"
|
||||||
sleep 5
|
echo "WARNING: properly."
|
||||||
|
echo "WARNING:"
|
||||||
|
echo "WARNING: Try setting 'Root=tmpfs'"
|
||||||
|
echo
|
||||||
|
echo "Continuing in 60s..."
|
||||||
|
sleep 60
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Setting up SELinux"
|
echo "Loading SELinux policy..."
|
||||||
/sbin/load_policy -i
|
/sbin/load_policy -i
|
||||||
|
echo "Restoring filesystem labels..."
|
||||||
/sbin/restorecon -e /sys -r /
|
/sbin/restorecon -e /sys -r /
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
echo "Hello from WWINIT"
|
|
||||||
|
|
||||||
. /warewulf/config
|
|
||||||
|
|
||||||
myPATH=/warewulf/init.d
|
|
||||||
ls -1 $myPATH/ | while read -r NAME; do
|
|
||||||
echo "Launching: $NAME"
|
|
||||||
sh "$myPATH/$NAME"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Calling $WWINIT..."
|
|
||||||
echo
|
|
||||||
|
|
||||||
sleep 2
|
|
||||||
exec $WWINIT
|
|
||||||
14
overlays/wwinit/rootfs/warewulf/wwprescripts
Executable file
14
overlays/wwinit/rootfs/warewulf/wwprescripts
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/sh
|
||||||
|
|
||||||
|
. /warewulf/config
|
||||||
|
|
||||||
|
echo "Warewulf prescript runner (/warewulf/wwprescripts)"
|
||||||
|
scriptdir=/warewulf/init.d
|
||||||
|
echo "Looking for prescripts in /warewulf/init.d/..."
|
||||||
|
ls -1 "${scriptdir}/" | while read -r name; do
|
||||||
|
echo "Running prescript: ${name}..."
|
||||||
|
sh "${scriptdir}/${name}"
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
echo "Running ${WWINIT}..."
|
||||||
|
exec $WWINIT
|
||||||
@@ -332,24 +332,22 @@ initramfs inside the image.
|
|||||||
necessary to remove ``/etc/machine-id`` for dracut to properly generate
|
necessary to remove ``/etc/machine-id`` for dracut to properly generate
|
||||||
the initramfs in the location that Warewulf is expecting.
|
the initramfs in the location that Warewulf is expecting.
|
||||||
|
|
||||||
Set the node's iPXE template to ``dracut`` to direct iPXE to fetch the
|
To direct iPXE to fetch the node's initramfs image and boot with dracut
|
||||||
node's initramfs image and boot with dracut semantics, rather than
|
semantics, set an ``IPXEMenuEntry`` tag for the node.
|
||||||
booting the node image directly.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Warewulf iPXE templates are located at ``/etc/warewulf/ipxe/`` when
|
Warewulf configures iPXE with a template located at
|
||||||
Warewulf is installed via official packages. You can learn more
|
``/etc/warewulf/ipxe/default.ipxe``. Inspect the template to learn more about
|
||||||
about how dracut booting works by inspecting its iPXE template at
|
the dracut booting process.
|
||||||
``/etc/warewulf/ipxe/dracut.ipxe``.
|
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
wwctl node set wwnode1 --ipxe dracut
|
wwctl node set wwnode1 --tagadd IPXEMenuEntry=dracut
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The iPXE template may be set at the node or profile level.
|
The IPXEMenuEntry variable may be set at the node or profile level.
|
||||||
|
|
||||||
Alternatively, to direct GRUB to fetch the node's initramfs image and boot with
|
Alternatively, to direct GRUB to fetch the node's initramfs image and boot with
|
||||||
dracut semantics, set a ``GrubMenuEntry`` tag for the node.
|
dracut semantics, set a ``GrubMenuEntry`` tag for the node.
|
||||||
@@ -379,8 +377,3 @@ to use up to 50% of physical memory. This size limit may be adjustd
|
|||||||
using the kernel argument `wwinit.tmpfs.size`. (This parameter is
|
using the kernel argument `wwinit.tmpfs.size`. (This parameter is
|
||||||
passed to the `size` option during tmpfs mount. See ``tmpfs(5)`` for
|
passed to the `size` option during tmpfs mount. See ``tmpfs(5)`` for
|
||||||
more details.)
|
more details.)
|
||||||
|
|
||||||
.. warning::
|
|
||||||
|
|
||||||
Kernel overrides are not currently fully supported during dracut initramfs boot.
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,10 @@ iPXE
|
|||||||
|
|
||||||
If you're using iPXE to boot (the default), you can get a command prompt by pressing with C-b during boot.
|
If you're using iPXE to boot (the default), you can get a command prompt by pressing with C-b during boot.
|
||||||
|
|
||||||
From the iPXE command prompt, you can run the same commands from `default.ipxe`_ (or `dracut.ipxe`_) to troubleshoot potential boot problems.
|
From the iPXE command prompt, you can run the same commands from `default.ipxe`_ to troubleshoot potential boot problems.
|
||||||
|
|
||||||
.. _default.ipxe: https://github.com/warewulf/warewulf/blob/main/etc/ipxe/default.ipxe
|
.. _default.ipxe: https://github.com/warewulf/warewulf/blob/main/etc/ipxe/default.ipxe
|
||||||
|
|
||||||
.. _dracut.ipxe: https://github.com/warewulf/warewulf/blob/main/etc/ipxe/dracut.ipxe
|
|
||||||
|
|
||||||
For example, the following commands perform a (relatively) normal Warewulf boot.
|
For example, the following commands perform a (relatively) normal Warewulf boot.
|
||||||
(Substitute your Warewulf server's IP address in place of 10.0.0.1,
|
(Substitute your Warewulf server's IP address in place of 10.0.0.1,
|
||||||
update the port number if you have changed it from the default of 9873,
|
update the port number if you have changed it from the default of 9873,
|
||||||
|
|||||||
Reference in New Issue
Block a user