Merge pull request #13 from gmkurtzer/init_fixes

Init fixes
This commit is contained in:
svdavidson
2020-12-21 09:31:14 -06:00
committed by GitHub
22 changed files with 172 additions and 84 deletions

View File

@@ -52,7 +52,7 @@ files: all
# cp -r tftpboot/* /var/lib/tftpboot/warewulf/ipxe/
# restorecon -r /var/lib/tftpboot/warewulf
cp -r overlays /var/warewulf/
chmod +x /var/warewulf/overlays/system/default/init.ww
chmod +x /var/warewulf/overlays/system/default/init
chmod 600 /var/warewulf/overlays/system/default/etc/ssh/ssh*
chmod 644 /var/warewulf/overlays/system/default/etc/ssh/ssh*.pub.ww
mkdir -p /var/warewulf/overlays/system/default/warewulf/bin/

View File

@@ -174,7 +174,7 @@ sudo ./wwctl overlay list -ls
sudo EDITOR=vim ./wwctl overlay edit default /etc/hello_world.ww
sudo ./wwctl overlay build -a
```
#### Start the Warewulf daemon:
Once the above provisioning images are built, you can check the provisioning "rediness"

View File

@@ -60,6 +60,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "SystemOverlay", node.SystemOverlay.Source(), node.SystemOverlay.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Ipxe", node.Ipxe.Source(), node.Ipxe.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Init", node.Init.Source(), node.Init.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Root", node.Root.Source(), node.Root.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "IpmiIpaddr", node.IpmiIpaddr.Source(), node.IpmiIpaddr.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "IpmiNetmask", node.IpmiNetmask.Source(), node.IpmiNetmask.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "IpmiGateway", node.IpmiGateway.Source(), node.IpmiGateway.Print())

View File

@@ -94,6 +94,16 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
os.Exit(1)
}
}
if SetRoot != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting root to: %s\n", n.Id.Get(), SetRoot)
n.Root.Set(SetRoot)
err := nodeDB.NodeUpdate(n)
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1)
}
}
if SetKernel != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting kernel to: %s\n", n.Id.Get(), SetKernel)

View File

@@ -35,6 +35,7 @@ var (
SetInit string
SetDiscoverable bool
SetUndiscoverable bool
SetRoot string
)
func init() {
@@ -44,6 +45,8 @@ func init() {
baseCmd.PersistentFlags().StringVarP(&SetClusterName, "cluster", "c", "", "Set the node's cluster group")
baseCmd.PersistentFlags().StringVarP(&SetIpxe, "ipxe", "P", "", "Set the node's iPXE template name")
baseCmd.PersistentFlags().StringVarP(&SetInit, "init", "i", "", "Define the init process to boot the container")
baseCmd.PersistentFlags().StringVar(&SetRoot, "root", "", "Define the rootfs")
baseCmd.PersistentFlags().StringVarP(&SetRuntimeOverlay, "runtime", "R", "", "Set the node's runtime overlay")
baseCmd.PersistentFlags().StringVarP(&SetSystemOverlay, "system", "S", "", "Set the node's system overlay")
baseCmd.PersistentFlags().StringVar(&SetIpmiIpaddr, "ipmi", "", "Set the node's IPMI IP address")

View File

@@ -17,6 +17,10 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
editor := os.Getenv("EDITOR")
var overlaySourceDir string
if editor == "" {
editor = "vi"
}
if SystemOverlay == true {
overlaySourceDir = config.SystemOverlaySource(args[0])
} else {

View File

@@ -41,6 +41,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "KernelVersion", profile.KernelVersion.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "KernelArgs", profile.KernelArgs.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Init", profile.Init.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Root", profile.Root.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "RuntimeOverlay", profile.RuntimeOverlay.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "SystemOverlay", profile.SystemOverlay.Print())

View File

@@ -108,6 +108,16 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
os.Exit(1)
}
}
if SetRoot != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting root to: %s\n", p.Id, SetRoot)
p.Root.Set(SetRoot)
err := nodeDB.ProfileUpdate(p)
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1)
}
}
if SetKernel != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Kernel version to: %s\n", p.Id, SetKernel)

View File

@@ -29,6 +29,7 @@ var (
SetHwaddr string
SetNetDevDel bool
SetInit string
SetRoot string
)
func init() {
@@ -38,6 +39,7 @@ func init() {
baseCmd.PersistentFlags().StringVarP(&SetClusterName, "cluster", "c", "", "Set the node's cluster group")
baseCmd.PersistentFlags().StringVarP(&SetIpxe, "ipxe", "P", "", "Set the node's iPXE template name")
baseCmd.PersistentFlags().StringVarP(&SetInit, "init", "i", "", "Define the init process to boot the container")
baseCmd.PersistentFlags().StringVar(&SetRoot, "root", "", "Define the rootfs")
baseCmd.PersistentFlags().StringVarP(&SetRuntimeOverlay, "runtime", "R", "", "Set the node's runtime overlay")
baseCmd.PersistentFlags().StringVarP(&SetSystemOverlay, "system", "S", "", "Set the node's system overlay")

View File

@@ -47,6 +47,8 @@ func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
n.RuntimeOverlay.SetDefault("default")
n.Ipxe.SetDefault("default")
n.Init.SetDefault("/sbin/init")
n.Root.SetDefault("tmpfs")
n.KernelArgs.SetDefault("rootfstype=ramfs crashkernel=no vga=791 quiet")
fullname := strings.SplitN(nodename, ".", 2)
if len(fullname) > 1 {
@@ -74,6 +76,7 @@ func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
n.IpmiPassword.Set(node.IpmiPassword)
n.SystemOverlay.Set(node.SystemOverlay)
n.RuntimeOverlay.Set(node.RuntimeOverlay)
n.Root.Set(node.Root)
n.Discoverable.SetB(node.Discoverable)
n.Disabled.SetB(node.Disabled)
@@ -116,6 +119,7 @@ func (self *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
n.IpmiPassword.SetAlt(self.NodeProfiles[p].IpmiPassword, pstring)
n.SystemOverlay.SetAlt(self.NodeProfiles[p].SystemOverlay, pstring)
n.RuntimeOverlay.SetAlt(self.NodeProfiles[p].RuntimeOverlay, pstring)
n.Root.SetAlt(self.NodeProfiles[p].Root, pstring)
n.Disabled.SetAltB(self.NodeProfiles[p].Disabled, pstring)
n.Discoverable.SetAltB(self.NodeProfiles[p].Discoverable, pstring)
@@ -163,6 +167,7 @@ func (self *nodeYaml) FindAllProfiles() ([]NodeInfo, error) {
p.IpmiPassword.Set(profile.IpmiPassword)
p.RuntimeOverlay.Set(profile.RuntimeOverlay)
p.SystemOverlay.Set(profile.SystemOverlay)
p.Root.Set(profile.Root)
p.Disabled.SetB(profile.Disabled)
p.Discoverable.SetB(profile.Discoverable)

View File

@@ -32,6 +32,7 @@ type NodeConf struct {
RuntimeOverlay string `yaml:"runtime overlay,omitempty"`
SystemOverlay string `yaml:"system overlay,omitempty"`
Init string `yaml:"init,omitempty"`
Root string `yaml:"root,omitempty"`
Discoverable bool `yaml:"discoverable,omitempty"`
Profiles []string `yaml:"profiles,omitempty"`
NetDevs map[string]*NetDevs `yaml:"network devices,omitempty"`
@@ -75,6 +76,7 @@ type NodeInfo struct {
IpmiPassword Entry
RuntimeOverlay Entry
SystemOverlay Entry
Root Entry
Discoverable Entry
Disabled Entry
Init Entry //TODO: Finish adding this...
@@ -104,7 +106,6 @@ func init() {
fmt.Fprintf(c, "nodeprofiles:\n")
fmt.Fprintf(c, " default:\n")
fmt.Fprintf(c, " comment: This profile is automatically included for each node\n")
fmt.Fprintf(c, " kernel args: crashkernel=no vga=791 rootfstype=ramfs quiet\n")
fmt.Fprintf(c, "nodes: {}\n")
c.Close()

View File

@@ -67,6 +67,7 @@ func (self *nodeYaml) NodeUpdate(node NodeInfo) error {
self.Nodes[nodeID].IpmiPassword = node.IpmiPassword.GetReal()
self.Nodes[nodeID].RuntimeOverlay = node.RuntimeOverlay.GetReal()
self.Nodes[nodeID].SystemOverlay = node.SystemOverlay.GetReal()
self.Nodes[nodeID].Root = node.Root.GetReal()
self.Nodes[nodeID].Disabled = node.Disabled.GetRealB()
self.Nodes[nodeID].Discoverable = node.Discoverable.GetRealB()
@@ -144,6 +145,7 @@ func (self *nodeYaml) ProfileUpdate(profile NodeInfo) error {
self.NodeProfiles[profileID].IpmiPassword = profile.IpmiPassword.GetReal()
self.NodeProfiles[profileID].RuntimeOverlay = profile.RuntimeOverlay.GetReal()
self.NodeProfiles[profileID].SystemOverlay = profile.SystemOverlay.GetReal()
self.NodeProfiles[profileID].Root = profile.Root.GetReal()
self.NodeProfiles[profileID].Disabled = profile.Disabled.GetRealB()
self.NodeProfiles[profileID].Discoverable = profile.Discoverable.GetRealB()

View File

@@ -23,6 +23,7 @@ type TemplateStruct struct {
GroupName string
Container string
Init string
Root string
IpmiIpaddr string
IpmiNetmask string
IpmiGateway string
@@ -139,6 +140,7 @@ func buildOverlay(nodeList []node.NodeInfo, overlayType string) error {
t.Hostname = n.Id.Get()
t.Container = n.ContainerName.Get()
t.Init = n.Init.Get()
t.Root = n.Root.Get()
t.IpmiIpaddr = n.IpmiIpaddr.Get()
t.IpmiNetmask = n.IpmiNetmask.Get()
t.IpmiGateway = n.IpmiGateway.Get()

56
overlays/system/default/init Executable file
View File

@@ -0,0 +1,56 @@
#!/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.
if test -f "/warewulf/config"; then
. /warewulf/config
else
echo "ERROR: Warewulf configuration file not found... rebooting in 1 minute"
sleep 60
/sbin/reboot
fi
echo "Warewulf v4 is now booting: $WWHOSTNAME"
echo
echo "Mounting up kernel file systems"
mkdir /proc /dev /sys /run 2>/dev/null
mount -t proc proc /proc
mount -t devtmpfs devtmpfs /dev
mount -t sysfs sysfs /sys
mount -t tmpfs tmpfs /run
chmod 755 /warewulf/wwinit
echo "Checking Rootfs type"
ROOTFSTYPE=`stat -f -c "%T" /`
if test "$WWROOT" == "initramfs"; then
echo "Provisioned to Rootfs type: $ROOTFSTYPE"
echo "Calling WW Init"
exec /warewulf/wwinit
elif test "$WWROOT" == "tmpfs"; then
if test "$ROOTFSTYPE" == "tmpfs"; then
echo "ERROR: Switching the root file system requires the kernel argument: 'rootfstype=ramfs'"
else
echo "Setting up tmpfs root file system"
mkdir /newroot
mount wwroot /newroot -t tmpfs
echo "Moving RAMFS to TMPFS"
tar -cf - --exclude ./proc --exclude ./sys --exclude ./dev --exclude ./newroot . | tar -xf - -C /newroot
mkdir /newroot/proc /newroot/dev /newroot/sys /newroot/run 2>/dev/null
echo "Calling switch_root and invoking WW Init"
exec /sbin/switch_root /newroot /warewulf/wwinit
fi
else
echo "ERROR: Unknown Warewulf Root file system: $WWROOT"
fi
echo
echo "There was a problem with the provisioning process, rebooting in 1 minute..."
sleep 60
/sbin/reboot

View File

@@ -1,39 +0,0 @@
#!/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 v4 is now booting"
chmod 755 /warewulf/wwinit
echo "Mounting up kernel file systems"
mkdir /proc /dev /sys /run 2>/dev/null
mount -t proc proc /proc
mount -t devtmpfs devtmpfs /dev
mount -t sysfs sysfs /sys
mount -t tmpfs tmpfs /run
echo "Checking for 'rootfstype=ramfs'"
ROOTFSTYPE=`stat -f -c "%T" /`
if test "$ROOTFSTYPE" == "ramfs"; then
echo "Running on ramfs, setting up tmpfs"
mkdir /newroot
mount wwroot /newroot -t tmpfs
echo "Moving RAMFS to TMPFS"
tar -cf - --exclude ./proc --exclude ./sys --exclude ./dev --exclude ./newroot . | tar -xf - -C /newroot
mkdir /newroot/proc /newroot/dev /newroot/sys /newroot/run 2>/dev/null
echo "Calling switch_root() and invoking WW Init"
exec /sbin/switch_root /newroot /warewulf/wwinit
else
echo "Running on tmpfs"
echo "Calling WW Init"
exec /warewulf/wwinit
fi
echo "We should never ever get here, but since we did, it means something went wrong so rebooting"
/sbin/reboot

View File

@@ -0,0 +1,9 @@
WWCONTAINER={{$.Container}}
WWHOSTNAME={{$.Id}}
WWROOT={{$.Root}}
WWINIT={{$.Init}}
WWIPMI_IPADDR="{{$.IpmiIpaddr}}"
WWIPMI_NETMASK="{{$.IpmiNetmask}}"
WWIPMI_GATEWAY="{{$.IpmiGateway}}"
WWIPMI_USER="{{$.IpmiUserName}}"
WWIPMI_PASSWORD="{{$.IpmiPassword}}"

View File

@@ -1,4 +1,6 @@
#!/bin/sh
. /warewulf/config
echo "Bringing up lo:127.0.0.1"
/sbin/ip link set dev lo up

View File

@@ -1,28 +1,26 @@
#!/bin/bash
error_exit() {
echo "ERROR: $*"
exit 1
}
. /warewulf/config
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
IP="{{$.IpmiIpaddr}}"
NETMASK="{{$.IpmiNetmask}}"
[ -z "$NETMASK" ] && NETMASK="{{$.NetDevs.eth0.Netmask}}"
GATEWAY="{{$.IpmiGateway}}"
[ -z "$GATEWAY" ] && GATEWAY="{{$.NetDevs.eth0.Gateway}}"
USER="{{$.IpmiUserName}}"
PASS="{{$.IpmiPassword}}"
if [ -z "$WWIPMI_IPADDR" ]; then
echo "No IPMI IP address supplied, skipping IPMI configuration"
exit
fi
if [ -z "$WWIPMI_NETMASK" ]; then
echo "No IPMI netmask supplied, skipping IPMI configuration"
exit
fi
echo IP is $IP
echo NETMASK is $NETMASK
echo GATEWAY is $GATEWAY
echo USER is $USER
echo PASS is $PASS
if [ -z "$IP" ]; then
error_exit "No IPMI IP address supplied, skipping IPMI configuration"
echo "IPMI IP address: $WWIPMI_IPADDR"
echo "IPMI netmask: $WWIPMI_NETMASK"
echo "IPMI gateway: $WWIPMI_GATEWAY"
echo "IPMI username: $WWIPMI_USER"
if test -n "$WWIPMI_PASSWORD"; then
echo "IPMI password is defined"
else
echo "IPMI password is undefined"
fi
modprobe ipmi_si
@@ -46,21 +44,21 @@ echo PREV_NETMASK is $PREV_NETMASK
echo PREV_GATEWAY is $PREV_GATEWAY
# Network
if [ "$PREV_IP" != "$IP" -o "$PREV_NETMASK" != "$NETMASK" -o "$PREV_GATEWAY" != "$GATEWAY" ]; then
if [ "$PREV_IP" != "$WWIPMI_IPADDR" -o "$PREV_NETMASK" != "$WWIPMI_NETMASK" -o "$PREV_GATEWAY" != "$WWIPMI_GATEWAY" ]; then
ipmitool lan set 1 access on
ipmitool lan set 1 ipsrc static
ipmitool lan set 1 ipaddr $IP
ipmitool lan set 1 netmask $NETMASK
ipmitool lan set 1 defgw ipaddr $GATEWAY
ipmitool lan set 1 ipaddr $WWIPMI_IPADDR
ipmitool lan set 1 netmask $WWIPMI_NETMASK
ipmitool lan set 1 defgw ipaddr $WWIPMI_GATEWAY
fi
# User
if [ "$USER" != "" ]; then
if [ "$WWIPMI_USER" != "" ]; then
PREV_USER=$(ipmitool user list | grep "^2 " | awk '{ print $2; }')
TEST_PASSWORD=$(ipmitool user test 2 20 $PASS)
if [ "$USER" != "$PREV_USER" -o "$TEST_PASSWORD" != "Success" ]; then
ipmitool user set name 2 $USER
ipmitool user set password 2 $PASS
TEST_PASSWORD=$(ipmitool user test 2 20 $WWIPMI_PASSWORD)
if [ "$WWIPMI_USER" != "$PREV_USER" -o "$TEST_PASSWORD" != "Success" ]; then
ipmitool user set name 2 $WWIPMI_USER
ipmitool user set password 2 $WWIPMI_PASSWORD
sleep 1
ipmitool user priv 2 4 1
ipmitool user enable 2

View File

@@ -1,6 +1,6 @@
#!/bin/sh
. /warewulf/config
# This will eventually be optional
if true; then

View File

@@ -1,4 +1,6 @@
#!/bin/sh
. /warewulf/config
echo "Starting wwclient"
nohup /warewulf/bin/wwclient >/var/log/wwclient.log 2>&1 </dev/null &

View File

@@ -1,17 +1,35 @@
#!/bin/bash
. /warewulf/config
if test -z "$WWROOT"; then
echo "Skipping SELinux configuration: Warewulf Root device not set"
exit
fi
if test -f "/etc/sysconfig/selinux"; then
. /etc/sysconfig/selinux
if test "\$SELINUX" == "disabled"; then
echo "Skipping SELinux setup per /etc/sysconfig/selinux"
elif grep -q "selinux=0" /proc/cmdline; then
echo "Skipping SELinux setup per kernel command line"
else
echo "Setting up SELinux"
/sbin/load_policy -i
/sbin/restorecon -r /
fi
else
echo "Skipping SELinux setup"
echo "Skipping SELinux configuration: Host config not found: /etc/sysconfig/selinux"
exit
fi
if test "$WWROOT" == "initramfs"; then
echo "Skipping SELinux configuration: 'Root=initramfs'"
if test "$SELINUX" != "disabled"; then
echo "WARNING: SELinux prep is being skipped, but SELinux is enabled on host! This may"
echo "WARNING: cause the system to not work properly. Try setting 'Root=tmpfs'"
sleep 5
fi
exit
fi
if test "$SELINUX" == "disabled"; then
echo "Skipping SELinux setup per /etc/sysconfig/selinux"
elif grep -q "selinux=0" /proc/cmdline; then
echo "Skipping SELinux setup per kernel command line"
else
echo "Setting up SELinux"
/sbin/load_policy -i
/sbin/restorecon -r /
fi

View File

@@ -2,6 +2,8 @@
echo "Hello from WWINIT"
. /warewulf/config
for i in /warewulf/init.d/*; do
NAME=`basename $i`
echo "Launching: $NAME"
@@ -10,10 +12,9 @@ done
/bin/bash
echo "Cleaning up"
echo "Calling {{$.Init}}..."
echo "Calling $WWINIT..."
echo
sleep 2
exec {{$.Init}}
exec $WWINIT