Cleaned init subsystem, Ipmi, SELinux, added Root option, and fixed defaults

This commit is contained in:
Gregory Kurtzer
2020-12-20 22:41:02 -08:00
parent a53a040b36
commit e5be3d8182
14 changed files with 128 additions and 55 deletions

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

@@ -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()

View File

@@ -5,10 +5,19 @@
#
# Edit at your own risk! DANGER DANGER.
WWCONTAINER={{$.Container}}
WWHOSTNAME={{$.Id}}
WWROOT={{$.Root}}
WWIPMI_IPADDR="{{$.IpmiIpaddr}}"
WWIPMI_NETMASK="{{$.IpmiNetmask}}"
WWIPMI_GATEWAY="{{$.IpmiGateway}}"
WWIPMI_USER="{{$.IpmiUserName}}"
WWIPMI_PASSWORD="{{$.IpmiPassword}}"
echo "Warewulf v4 is now booting"
export WWCONTAINER WWHOSTNAME WWROOT
chmod 755 /warewulf/wwinit
echo "Warewulf v4 is now booting: $WWHOSTNAME"
echo
echo "Mounting up kernel file systems"
mkdir /proc /dev /sys /run 2>/dev/null
@@ -17,23 +26,33 @@ mount -t devtmpfs devtmpfs /dev
mount -t sysfs sysfs /sys
mount -t tmpfs tmpfs /run
echo "Checking for 'rootfstype=ramfs'"
chmod 755 /warewulf/wwinit
echo "Checking Rootfs type"
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"
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 "We should never ever get here, but since we did, it means something went wrong so rebooting"
echo
echo "There was a problem with the provisioning process, rebooting in 1 minute..."
sleep 60
/sbin/reboot

View File

@@ -1,28 +1,20 @@
#!/bin/bash
error_exit() {
echo "ERROR: $*"
exit 1
}
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
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 +38,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,17 +1,34 @@
#!/bin/bash
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

@@ -11,6 +11,14 @@ done
/bin/bash
echo "Cleaning up"
unset WWCONTAINER
unset WWHOSTNAME
unset WWROOT
unset WWIPMI_IPADDR
unset WWIPMI_NETMASK
unset WWIPMI_GATEWAY
unset WWIPMI_USER
unset WWIPMI_PASSWORD
echo "Calling {{$.Init}}..."
echo