Merge branch 'main' of github.com:hpcng/warewulf into jcsiadal-loops

This commit is contained in:
Gregory Kurtzer
2022-02-27 18:06:34 -08:00
30 changed files with 333 additions and 111 deletions

View File

@@ -0,0 +1,52 @@
FROM docker.io/library/centos:8
RUN dnf install -y --allowerasing coreutils \
cpio \
dhclient \
e2fsprogs \
ethtool \
findutils \
initscripts \
ipmitool \
iproute \
kernel-core \
net-tools \
network-scripts \
nfs-utils \
openssh-clients \
openssh-server \
pciutils \
psmisc \
rsync \
rsyslog \
strace \
wget \
which \
words
RUN <<EOF
sed -i -e '/^account.*pam_unix\.so\s*$/s/\s*$/\ broken_shadow/' /etc/pam.d/system-auth
sed -i -e '/^account.*pam_unix\.so\s*$/s/\s*$/\ broken_shadow/' /etc/pam.d/password-auth
systemctl unmask console-getty.service dev-hugepages.mount \
getty.target sys-fs-fuse-connections.mount systemd-logind.service \
systemd-remount-fs.service
systemctl enable network
touch /etc/sysconfig/disable-deprecation-warnings
mkdir -p /etc/warewulf
touch /etc/warewulf/excludes
touch /etc/warewulf/container_exit.sh
chmod +x /etc/warewulf/container_exit.sh
EOF
COPY <<EOF /etc/warewulf/container_exit.sh
#!/bin/sh
set -x
dnf clean all
EOF
COPY <<EOF /etc/warewulf/excludes
/boot/
EOF

View File

@@ -1,4 +1,4 @@
FROM warewulf/rocky:8 FROM docker.io/warewulf/rocky:8
RUN dnf -y install http://repos.openhpc.community/OpenHPC/2/CentOS_8/x86_64/ohpc-release-2-1.el8.x86_64.rpm; \ RUN dnf -y install http://repos.openhpc.community/OpenHPC/2/CentOS_8/x86_64/ohpc-release-2-1.el8.x86_64.rpm; \
sed -i -e 's/^enabled=0/enabled=1/g' /etc/yum.repos.d/*-PowerTools.repo; \ sed -i -e 's/^enabled=0/enabled=1/g' /etc/yum.repos.d/*-PowerTools.repo; \

53
containers/Docker/rocky-8 Normal file
View File

@@ -0,0 +1,53 @@
FROM docker.io/library/rockylinux:8
RUN dnf install -y --allowerasing coreutils \
cpio \
dhclient \
e2fsprogs \
ethtool \
findutils \
initscripts \
ipmitool \
iproute \
kernel-core \
net-tools \
network-scripts \
nfs-utils \
openssh-clients \
openssh-server \
pciutils \
psmisc \
rsync \
rsyslog \
strace \
wget \
which \
words
RUN <<EOF
sed -i -e '/^account.*pam_unix\.so\s*$/s/\s*$/\ broken_shadow/' /etc/pam.d/system-auth
sed -i -e '/^account.*pam_unix\.so\s*$/s/\s*$/\ broken_shadow/' /etc/pam.d/password-auth
systemctl unmask console-getty.service dev-hugepages.mount \
getty.target sys-fs-fuse-connections.mount systemd-logind.service \
systemd-remount-fs.service
systemctl enable network
touch /etc/sysconfig/disable-deprecation-warnings
mkdir -p /etc/warewulf
touch /etc/warewulf/excludes
touch /etc/warewulf/container_exit.sh
chmod +x /etc/warewulf/container_exit.sh
EOF
COPY <<EOF /etc/warewulf/container_exit.sh
#!/bin/sh
set -x
dnf clean all
EOF
COPY <<EOF /etc/warewulf/excludes
/boot/
EOF

View File

@@ -1,21 +1,40 @@
BootStrap: yum BootStrap: docker
OSVersion: 8 From: centos:8
MirrorURL: http://mirror.centos.org/centos-%{OSVERSION}/%{OSVERSION}/BaseOS/x86_64/os
Include: dnf
%post %post
dnf install -y --allowerasing coreutils \
cpio \
dhclient \
e2fsprogs \
ethtool \
findutils \
initscripts \
ipmitool \
iproute \
kernel-core \
net-tools \
network-scripts \
nfs-utils \
openssh-clients \
openssh-server \
pciutils \
psmisc \
rsync \
rsyslog \
strace \
wget \
which \
words
sed -i 's/^root:.:/root::/g' /etc/passwd # These changes make it possible for users to ssh into nodes even
# if there is no shadow entry for the user
sed -i -e '/^account.*pam_unix\.so\s*$/s/\s*$/\ broken_shadow/' /etc/pam.d/system-auth
sed -i -e '/^account.*pam_unix\.so\s*$/s/\s*$/\ broken_shadow/' /etc/pam.d/password-auth
dnf install -y basesystem bash chkconfig coreutils e2fsprogs \ systemctl unmask console-getty.service dev-hugepages.mount \
ethtool filesystem findutils gawk grep initscripts iproute \ getty.target sys-fs-fuse-connections.mount systemd-logind.service \
iputils net-tools nfs-utils pam psmisc rsync sed setup \ systemd-remount-fs.service
shadow-utils rsyslog tzdata util-linux words zlib tar less \
gzip which util-linux openssh-clients openssh-server dhclient \
pciutils vim-minimal shadow-utils strace cronie crontabs cpio \
wget centos-release ipmitool yum network-scripts
systemctl enable network systemctl enable network
touch /etc/sysconfig/disable-deprecation-warnings touch /etc/sysconfig/disable-deprecation-warnings

View File

@@ -1,21 +1,40 @@
BootStrap: yum BootStrap: docker
OSVersion: 8 From: rockylinux:8
MirrorURL: http://dl.rockylinux.org/pub/rocky/%{OSVERSION}/BaseOS/x86_64/os/
Include: dnf
%post %post
dnf install -y --allowerasing coreutils \
cpio \
dhclient \
e2fsprogs \
ethtool \
findutils \
initscripts \
ipmitool \
iproute \
kernel-core \
net-tools \
network-scripts \
nfs-utils \
openssh-clients \
openssh-server \
pciutils \
psmisc \
rsync \
rsyslog \
strace \
wget \
which \
words
sed -i 's/^root:.:/root::/g' /etc/passwd # These changes make it possible for users to ssh into nodes even
# if there is no shadow entry for the user
sed -i -e '/^account.*pam_unix\.so\s*$/s/\s*$/\ broken_shadow/' /etc/pam.d/system-auth
sed -i -e '/^account.*pam_unix\.so\s*$/s/\s*$/\ broken_shadow/' /etc/pam.d/password-auth
dnf install -y basesystem bash chkconfig coreutils e2fsprogs \ systemctl unmask console-getty.service dev-hugepages.mount \
ethtool filesystem findutils gawk grep initscripts iproute \ getty.target sys-fs-fuse-connections.mount systemd-logind.service \
iputils net-tools nfs-utils pam psmisc rsync sed setup \ systemd-remount-fs.service
shadow-utils rsyslog tzdata util-linux words zlib tar less \
gzip which util-linux openssh-clients openssh-server dhclient \
pciutils vim-minimal shadow-utils strace cronie crontabs cpio \
wget rocky-release ipmitool yum network-scripts
systemctl enable network systemctl enable network
touch /etc/sysconfig/disable-deprecation-warnings touch /etc/sysconfig/disable-deprecation-warnings

View File

@@ -11,13 +11,13 @@ echo
set base http://{{.Ipaddr}}:{{.Port}} set base http://{{.Ipaddr}}:{{.Port}}
kernel --name kernel ${base}/kernel/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot kernel --name kernel ${base}/kernel/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot
imgextract --name container ${base}/container/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot imgextract --name container ${base}/container/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot
imgextract --name kmods ${base}/kmods/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot
imgextract --name system ${base}/overlay-system/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot imgextract --name system ${base}/overlay-system/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot
imgextract --name runtime ${base}/overlay-runtime/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot imgextract --name runtime ${base}/overlay-runtime/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot
imgextract --name runtime ${base}/overlay-runtime/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot
boot kernel initrd=container initrd=kmods initrd=system initrd=runtime wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot boot kernel initrd=container initrd=system initrd=runtime wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot
:reboot :reboot
echo echo

View File

@@ -13,11 +13,10 @@ set base http://{{.Ipaddr}}:{{.Port}}
kernel --name kernel ${base}/kernel/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot kernel --name kernel ${base}/kernel/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot
initrd --name container ${base}/container/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot initrd --name container ${base}/container/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot
initrd --name kmods ${base}/kmods/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot
initrd --name system ${base}/overlay-system/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot initrd --name system ${base}/overlay-system/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot
initrd --name runtime ${base}/overlay-runtime/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot initrd --name runtime ${base}/overlay-runtime/{{.Hwaddr}}?assetkey=${asset}&uuid=${uuid} || goto reboot
boot kernel initrd=container initrd=kmods initrd=system initrd=runtime wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot boot kernel initrd=container initrd=system initrd=runtime wwid={{.Hwaddr}} {{.KernelArgs}} || goto reboot
:reboot :reboot
echo echo

View File

@@ -6,7 +6,6 @@ import (
"github.com/hpcng/warewulf/internal/pkg/container" "github.com/hpcng/warewulf/internal/pkg/container"
"github.com/hpcng/warewulf/internal/pkg/node" "github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@@ -27,14 +26,15 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
nodemap[n.ContainerName.Get()]++ nodemap[n.ContainerName.Get()]++
} }
fmt.Printf("%-35s %-6s %-6s\n", "CONTAINER NAME", "BUILT", "NODES") fmt.Printf("%-25s %-6s %-6s\n", "CONTAINER NAME", "NODES", "KERNEL VERSION")
for _, source := range sources { for _, source := range sources {
image := container.ImageFile(source)
if nodemap[source] == 0 { if nodemap[source] == 0 {
nodemap[source] = 0 nodemap[source] = 0
} }
fmt.Printf("%-35s %-6t %-6d\n", source, util.IsFile(image), nodemap[source])
wwlog.Printf(wwlog.DEBUG, "Finding kernel version for: %s\n", source)
kernelVersion := container.KernelVersion(source)
fmt.Printf("%-25s %-6d %s\n", source, nodemap[source], kernelVersion)
} }
return nil return nil

View File

@@ -23,7 +23,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
ARG_LOOP: ARG_LOOP:
for _, arg := range args { for _, arg := range args {
for _, n := range nodes { for _, n := range nodes {
if n.KernelVersion.Get() == arg { if n.KernelOverride.Get() == arg {
wwlog.Printf(wwlog.ERROR, "Kernel is configured for nodes, skipping: %s\n", arg) wwlog.Printf(wwlog.ERROR, "Kernel is configured for nodes, skipping: %s\n", arg)
continue ARG_LOOP continue ARG_LOOP
} }

View File

@@ -8,11 +8,11 @@ import (
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Use: "delete [OPTIONS] KERNEL [...]", Use: "delete [OPTIONS] KERNEL [...]",
Short: "Delete imported kernels", Short: "Delete imported kernels",
Long: "This command will delete KERNEL versions that have been imported into Warewulf.", Long: "This command will delete KERNEL versions that have been imported into Warewulf.",
RunE: CobraRunE, RunE: CobraRunE,
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 { if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp

View File

@@ -70,7 +70,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
wwlog.Printf(wwlog.DEBUG, "Looking for profile default: %s\n", profile.Id.Get()) wwlog.Printf(wwlog.DEBUG, "Looking for profile default: %s\n", profile.Id.Get())
if profile.Id.Get() == "default" { if profile.Id.Get() == "default" {
wwlog.Printf(wwlog.DEBUG, "Found profile default, setting kernel version to: %s\n", args[0]) wwlog.Printf(wwlog.DEBUG, "Found profile default, setting kernel version to: %s\n", args[0])
profile.KernelVersion.Set(args[0]) profile.KernelOverride.Set(args[0])
err := nodeDB.ProfileUpdate(profile) err := nodeDB.ProfileUpdate(profile)
if err != nil { if err != nil {
return errors.Wrap(err, "failed to update node profile") return errors.Wrap(err, "failed to update node profile")

View File

@@ -23,7 +23,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
nodemap := make(map[string]int) nodemap := make(map[string]int)
for _, n := range nodes { for _, n := range nodes {
nodemap[n.KernelVersion.Get()]++ nodemap[n.KernelOverride.Get()]++
} }
fmt.Printf("%-35s %-25s %-6s\n", "KERNEL NAME", "KERNEL VERSION", "NODES") fmt.Printf("%-35s %-25s %-6s\n", "KERNEL NAME", "KERNEL VERSION", "NODES")

View File

@@ -5,12 +5,12 @@ import "github.com/spf13/cobra"
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Use: "list [OPTIONS]", Use: "list [OPTIONS]",
Short: "List imported Kernel images", Short: "List imported Kernel images",
Long: "This command will list the kernels that have been imported into Warewulf.", Long: "This command will list the kernels that have been imported into Warewulf.",
RunE: CobraRunE, RunE: CobraRunE,
Args: cobra.ExactArgs(0), Args: cobra.ExactArgs(0),
Aliases: []string{"ls"}, Aliases: []string{"ls"},
} }
) )

View File

@@ -10,9 +10,9 @@ import (
var ( var (
baseCmd = &cobra.Command{ baseCmd = &cobra.Command{
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
Use: "kernel COMMAND [OPTIONS]", Use: "kernel COMMAND [OPTIONS]",
Short: "Kernel Image Management", Short: "Kernel Image Management",
Long: "This command manages Warewulf Kernels used for bootstrapping nodes", Long: "This command manages Warewulf Kernels used for bootstrapping nodes",
} }
) )

View File

@@ -41,7 +41,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
fmt.Printf("%-20s %-18s %-12s %t\n", node.Id.Get(), "Discoverable", node.Discoverable.Source(), node.Discoverable.PrintB()) fmt.Printf("%-20s %-18s %-12s %t\n", node.Id.Get(), "Discoverable", node.Discoverable.Source(), node.Discoverable.PrintB())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Container", node.ContainerName.Source(), node.ContainerName.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Container", node.ContainerName.Source(), node.ContainerName.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "Kernel", node.KernelVersion.Source(), node.KernelVersion.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "KernelOverride", node.KernelOverride.Source(), node.KernelOverride.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "KernelArgs", node.KernelArgs.Source(), node.KernelArgs.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "KernelArgs", node.KernelArgs.Source(), node.KernelArgs.Print())
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(), "SystemOverlay", node.SystemOverlay.Source(), node.SystemOverlay.Print())
fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "RuntimeOverlay", node.RuntimeOverlay.Source(), node.RuntimeOverlay.Print()) fmt.Printf("%-20s %-18s %-12s %s\n", node.Id.Get(), "RuntimeOverlay", node.RuntimeOverlay.Source(), node.RuntimeOverlay.Print())
@@ -97,11 +97,11 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
} }
} else if ShowLong { } else if ShowLong {
fmt.Printf("%-22s %-26s %-35s %s\n", "NODE NAME", "KERNEL", "CONTAINER", "OVERLAYS (S/R)") fmt.Printf("%-22s %-26s %-35s %s\n", "NODE NAME", "KERNEL OVERRIDE", "CONTAINER", "OVERLAYS (S/R)")
fmt.Println(strings.Repeat("=", 120)) fmt.Println(strings.Repeat("=", 120))
for _, node := range node.FilterByName(nodes, args) { for _, node := range node.FilterByName(nodes, args) {
fmt.Printf("%-22s %-26s %-35s %s\n", node.Id.Get(), node.KernelVersion.Print(), node.ContainerName.Print(), node.SystemOverlay.Print()+"/"+node.RuntimeOverlay.Print()) fmt.Printf("%-22s %-26s %-35s %s\n", node.Id.Get(), node.KernelOverride.Print(), node.ContainerName.Print(), node.SystemOverlay.Print()+"/"+node.RuntimeOverlay.Print())
} }
} else { } else {

View File

@@ -70,9 +70,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
n.AssetKey.Set(SetAssetKey) n.AssetKey.Set(SetAssetKey)
} }
if SetKernel != "" { if SetKernelOverride != "" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting kernel to: %s\n", n.Id.Get(), SetKernel) wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting kernel override to: %s\n", n.Id.Get(), SetKernelOverride)
n.KernelVersion.Set(SetKernel) n.KernelOverride.Set(SetKernelOverride)
} }
if SetKernelArgs != "" { if SetKernelArgs != "" {

View File

@@ -34,7 +34,7 @@ var (
} }
SetComment string SetComment string
SetContainer string SetContainer string
SetKernel string SetKernelOverride string
SetKernelArgs string SetKernelArgs string
SetNetName string SetNetName string
SetNetDev string SetNetDev string
@@ -82,8 +82,8 @@ func init() {
}); err != nil { }); err != nil {
log.Println(err) log.Println(err)
} }
baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes") baseCmd.PersistentFlags().StringVarP(&SetKernelOverride, "kerneloverride", "K", "", "Set kernel override version for nodes")
if err := baseCmd.RegisterFlagCompletionFunc("kernel", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if err := baseCmd.RegisterFlagCompletionFunc("kerneloverride", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := kernel.ListKernels() list, _ := kernel.ListKernels()
return list, cobra.ShellCompDirectiveNoFileComp return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil { }); err != nil {

View File

@@ -33,7 +33,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Cluster", profile.ClusterName.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Cluster", profile.ClusterName.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Container", profile.ContainerName.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Container", profile.ContainerName.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "Kernel", profile.KernelVersion.Print()) fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "KernelOverride", profile.KernelOverride.Print())
fmt.Printf("%-20s %-18s %s\n", profile.Id.Get(), "KernelArgs", profile.KernelArgs.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(), "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(), "Root", profile.Root.Print())

View File

@@ -75,9 +75,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
p.AssetKey.Set(SetAssetKey) p.AssetKey.Set(SetAssetKey)
} }
if SetKernel != "" { if SetKernelOverride != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Kernel to: %s\n", p.Id.Get(), SetKernel) wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Kernel override version to: %s\n", p.Id.Get(), SetKernelOverride)
p.KernelVersion.Set(SetKernel) p.KernelOverride.Set(SetKernelOverride)
} }
if SetKernelArgs != "" { if SetKernelArgs != "" {

View File

@@ -37,7 +37,7 @@ var (
SetForce bool SetForce bool
SetComment string SetComment string
SetContainer string SetContainer string
SetKernel string SetKernelOverride string
SetKernelArgs string SetKernelArgs string
SetClusterName string SetClusterName string
SetIpxe string SetIpxe string
@@ -77,8 +77,8 @@ func init() {
}); err != nil { }); err != nil {
log.Println(err) log.Println(err)
} }
baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes") baseCmd.PersistentFlags().StringVarP(&SetKernelOverride, "kerneloverride", "K", "", "Set kernel override version for nodes")
if err := baseCmd.RegisterFlagCompletionFunc("kernel", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if err := baseCmd.RegisterFlagCompletionFunc("kerneloverride", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := kernel.ListKernels() list, _ := kernel.ListKernels()
return list, cobra.ShellCompDirectiveNoFileComp return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil { }); err != nil {

View File

@@ -55,7 +55,7 @@ func Build(name string, buildForce bool) error {
cmd = fmt.Sprintf("cd %s; find . -xdev -xautofs | cpio --quiet -o -H newc | %s -c > \"%s\"", rootfsPath, compressor, imagePath) cmd = fmt.Sprintf("cd %s; find . -xdev -xautofs | cpio --quiet -o -H newc | %s -c > \"%s\"", rootfsPath, compressor, imagePath)
} else { } else {
wwlog.Printf(wwlog.DEBUG, "Building VNFS image with excludes: '%s' -> '%s'\n", rootfsPath, imagePath) wwlog.Printf(wwlog.DEBUG, "Building VNFS image with excludes: '%s' -> '%s'\n", rootfsPath, imagePath)
cmd = fmt.Sprintf("cd %s; find . -xdev -xautofs | grep -v -f ./etc/warewulf/exclude | cpio --quiet -o -H newc | %s -c > \"%s\"", rootfsPath, compressor, imagePath) cmd = fmt.Sprintf("cd %s; find . -xdev -xautofs | grep -v -f ./etc/warewulf/excludes | cpio --quiet -o -H newc | %s -c > \"%s\"", rootfsPath, compressor, imagePath)
} }
wwlog.Printf(wwlog.DEBUG, "RUNNING: %s\n", cmd) wwlog.Printf(wwlog.DEBUG, "RUNNING: %s\n", cmd)
err = exec.Command("/bin/sh", "-c", cmd).Run() err = exec.Command("/bin/sh", "-c", cmd).Run()

View File

@@ -0,0 +1,58 @@
package container
import (
"path"
"path/filepath"
"sort"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
)
var (
kernelNames = []string{
`vmlinux`,
`vmlinuz`,
`vmlinuz.gz`,
}
modulePath = "/lib/modules/"
)
func KernelFind(container string) string {
wwlog.Printf(wwlog.DEBUG, "Finding kernel\n")
container_path := RootFsDir(container)
if container_path == "" {
return ""
}
for _, kname := range kernelNames {
wwlog.Printf(wwlog.DEBUG, "Checking for kernel name within module path: %s\n", kname)
kernelPaths, err := filepath.Glob(path.Join(container_path, modulePath, "/*/", kname))
if err != nil {
return ""
}
sort.Slice(kernelPaths, func(i, j int) bool {
return kernelPaths[i] > kernelPaths[j]
})
for _, kernelPath := range kernelPaths {
wwlog.Printf(wwlog.DEBUG, "Checking for kernel path: %s\n", kernelPath)
if util.IsFile(kernelPath) {
return kernelPath
}
}
}
return ""
}
func KernelVersion(container string) string {
wwlog.Printf(wwlog.DEBUG, "Finding kernel version inside container: %s\n", container)
kernel := KernelFind(container)
if kernel == "" {
return ""
}
return path.Base(path.Dir(kernel))
}

View File

@@ -199,7 +199,7 @@ func Build(kernelVersion, kernelName, root string) (string, error) {
wwlog.Printf(wwlog.VERBOSE, "Using PIGZ to compress the container: %s\n", compressor) wwlog.Printf(wwlog.VERBOSE, "Using PIGZ to compress the container: %s\n", compressor)
} }
cmd := fmt.Sprintf("cd %s; find .%s | cpio --quiet -o -L -H newc | %s -c > \"%s\"", root, kernelDriversRelative, compressor, driversDestination) cmd := fmt.Sprintf("cd %s; find .%s ./lib/firmware | cpio --quiet -o -L -H newc | %s -c > \"%s\"", root, kernelDriversRelative, compressor, driversDestination)
wwlog.Printf(wwlog.DEBUG, "RUNNING: %s\n", cmd) wwlog.Printf(wwlog.DEBUG, "RUNNING: %s\n", cmd)
err = exec.Command("/bin/sh", "-c", cmd).Run() err = exec.Command("/bin/sh", "-c", cmd).Run()

View File

@@ -72,7 +72,6 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
n.Id.Set(nodename) n.Id.Set(nodename)
n.Comment.Set(node.Comment) n.Comment.Set(node.Comment)
n.ContainerName.Set(node.ContainerName) n.ContainerName.Set(node.ContainerName)
n.KernelVersion.Set(node.KernelVersion)
n.KernelArgs.Set(node.KernelArgs) n.KernelArgs.Set(node.KernelArgs)
n.ClusterName.Set(node.ClusterName) n.ClusterName.Set(node.ClusterName)
n.Ipxe.Set(node.Ipxe) n.Ipxe.Set(node.Ipxe)
@@ -90,6 +89,12 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
n.AssetKey.Set(node.AssetKey) n.AssetKey.Set(node.AssetKey)
n.Discoverable.Set(node.Discoverable) n.Discoverable.Set(node.Discoverable)
if node.KernelOverride != "" {
n.KernelOverride.Set(node.KernelOverride)
} else if node.KernelVersion != "" {
n.KernelOverride.Set(node.KernelVersion)
}
for devname, netdev := range node.NetDevs { for devname, netdev := range node.NetDevs {
if _, ok := n.NetDevs[devname]; !ok { if _, ok := n.NetDevs[devname]; !ok {
var netdev NetDevEntry var netdev NetDevEntry
@@ -134,7 +139,6 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
n.Comment.SetAlt(config.NodeProfiles[p].Comment, p) n.Comment.SetAlt(config.NodeProfiles[p].Comment, p)
n.ClusterName.SetAlt(config.NodeProfiles[p].ClusterName, p) n.ClusterName.SetAlt(config.NodeProfiles[p].ClusterName, p)
n.ContainerName.SetAlt(config.NodeProfiles[p].ContainerName, p) n.ContainerName.SetAlt(config.NodeProfiles[p].ContainerName, p)
n.KernelVersion.SetAlt(config.NodeProfiles[p].KernelVersion, p)
n.KernelArgs.SetAlt(config.NodeProfiles[p].KernelArgs, p) n.KernelArgs.SetAlt(config.NodeProfiles[p].KernelArgs, p)
n.Ipxe.SetAlt(config.NodeProfiles[p].Ipxe, p) n.Ipxe.SetAlt(config.NodeProfiles[p].Ipxe, p)
n.Init.SetAlt(config.NodeProfiles[p].Init, p) n.Init.SetAlt(config.NodeProfiles[p].Init, p)
@@ -151,6 +155,12 @@ func (config *nodeYaml) FindAllNodes() ([]NodeInfo, error) {
n.AssetKey.SetAlt(config.NodeProfiles[p].AssetKey, p) n.AssetKey.SetAlt(config.NodeProfiles[p].AssetKey, p)
n.Discoverable.SetAlt(config.NodeProfiles[p].Discoverable, p) n.Discoverable.SetAlt(config.NodeProfiles[p].Discoverable, p)
if config.NodeProfiles[p].KernelOverride != "" {
n.KernelOverride.SetAlt(config.NodeProfiles[p].KernelOverride, p)
} else if config.NodeProfiles[p].KernelVersion != "" {
n.KernelOverride.SetAlt(config.NodeProfiles[p].KernelVersion, p)
}
for devname, netdev := range config.NodeProfiles[p].NetDevs { for devname, netdev := range config.NodeProfiles[p].NetDevs {
if _, ok := n.NetDevs[devname]; !ok { if _, ok := n.NetDevs[devname]; !ok {
var netdev NetDevEntry var netdev NetDevEntry
@@ -218,7 +228,6 @@ func (config *nodeYaml) FindAllProfiles() ([]NodeInfo, error) {
p.ContainerName.Set(profile.ContainerName) p.ContainerName.Set(profile.ContainerName)
p.Ipxe.Set(profile.Ipxe) p.Ipxe.Set(profile.Ipxe)
p.Init.Set(profile.Init) p.Init.Set(profile.Init)
p.KernelVersion.Set(profile.KernelVersion)
p.KernelArgs.Set(profile.KernelArgs) p.KernelArgs.Set(profile.KernelArgs)
p.IpmiNetmask.Set(profile.IpmiNetmask) p.IpmiNetmask.Set(profile.IpmiNetmask)
p.IpmiPort.Set(profile.IpmiPort) p.IpmiPort.Set(profile.IpmiPort)
@@ -232,6 +241,12 @@ func (config *nodeYaml) FindAllProfiles() ([]NodeInfo, error) {
p.AssetKey.Set(profile.AssetKey) p.AssetKey.Set(profile.AssetKey)
p.Discoverable.Set(profile.Discoverable) p.Discoverable.Set(profile.Discoverable)
if profile.KernelOverride != "" {
p.KernelOverride.Set(profile.KernelOverride)
} else if profile.KernelVersion != "" {
p.KernelOverride.Set(profile.KernelVersion)
}
for devname, netdev := range profile.NetDevs { for devname, netdev := range profile.NetDevs {
if _, ok := p.NetDevs[devname]; !ok { if _, ok := p.NetDevs[devname]; !ok {
var netdev NetDevEntry var netdev NetDevEntry

View File

@@ -20,6 +20,7 @@ type NodeConf struct {
ContainerName string `yaml:"container name,omitempty"` ContainerName string `yaml:"container name,omitempty"`
Ipxe string `yaml:"ipxe template,omitempty"` Ipxe string `yaml:"ipxe template,omitempty"`
KernelVersion string `yaml:"kernel version,omitempty"` KernelVersion string `yaml:"kernel version,omitempty"`
KernelOverride string `yaml:"kernel override,omitempty"`
KernelArgs string `yaml:"kernel args,omitempty"` KernelArgs string `yaml:"kernel args,omitempty"`
IpmiUserName string `yaml:"ipmi username,omitempty"` IpmiUserName string `yaml:"ipmi username,omitempty"`
IpmiPassword string `yaml:"ipmi password,omitempty"` IpmiPassword string `yaml:"ipmi password,omitempty"`
@@ -71,7 +72,7 @@ type NodeInfo struct {
ClusterName Entry ClusterName Entry
ContainerName Entry ContainerName Entry
Ipxe Entry Ipxe Entry
KernelVersion Entry KernelOverride Entry
KernelArgs Entry KernelArgs Entry
IpmiIpaddr Entry IpmiIpaddr Entry
IpmiNetmask Entry IpmiNetmask Entry

View File

@@ -60,7 +60,7 @@ func (config *nodeYaml) NodeUpdate(node NodeInfo) error {
config.Nodes[nodeID].ClusterName = node.ClusterName.GetReal() config.Nodes[nodeID].ClusterName = node.ClusterName.GetReal()
config.Nodes[nodeID].Ipxe = node.Ipxe.GetReal() config.Nodes[nodeID].Ipxe = node.Ipxe.GetReal()
config.Nodes[nodeID].Init = node.Init.GetReal() config.Nodes[nodeID].Init = node.Init.GetReal()
config.Nodes[nodeID].KernelVersion = node.KernelVersion.GetReal() config.Nodes[nodeID].KernelOverride = node.KernelOverride.GetReal()
config.Nodes[nodeID].KernelArgs = node.KernelArgs.GetReal() config.Nodes[nodeID].KernelArgs = node.KernelArgs.GetReal()
config.Nodes[nodeID].IpmiIpaddr = node.IpmiIpaddr.GetReal() config.Nodes[nodeID].IpmiIpaddr = node.IpmiIpaddr.GetReal()
config.Nodes[nodeID].IpmiNetmask = node.IpmiNetmask.GetReal() config.Nodes[nodeID].IpmiNetmask = node.IpmiNetmask.GetReal()
@@ -148,7 +148,7 @@ func (config *nodeYaml) ProfileUpdate(profile NodeInfo) error {
config.NodeProfiles[profileID].Ipxe = profile.Ipxe.GetReal() config.NodeProfiles[profileID].Ipxe = profile.Ipxe.GetReal()
config.NodeProfiles[profileID].Init = profile.Init.GetReal() config.NodeProfiles[profileID].Init = profile.Init.GetReal()
config.NodeProfiles[profileID].ClusterName = profile.ClusterName.GetReal() config.NodeProfiles[profileID].ClusterName = profile.ClusterName.GetReal()
config.NodeProfiles[profileID].KernelVersion = profile.KernelVersion.GetReal() config.NodeProfiles[profileID].KernelOverride = profile.KernelOverride.GetReal()
config.NodeProfiles[profileID].KernelArgs = profile.KernelArgs.GetReal() config.NodeProfiles[profileID].KernelArgs = profile.KernelArgs.GetReal()
config.NodeProfiles[profileID].IpmiIpaddr = profile.IpmiIpaddr.GetReal() config.NodeProfiles[profileID].IpmiIpaddr = profile.IpmiIpaddr.GetReal()
config.NodeProfiles[profileID].IpmiNetmask = profile.IpmiNetmask.GetReal() config.NodeProfiles[profileID].IpmiNetmask = profile.IpmiNetmask.GetReal()

View File

@@ -169,7 +169,8 @@ func BuildOverlay(nodeInfo node.NodeInfo, overlayName string) error {
tstruct.Hostname = nodeInfo.Id.Get() tstruct.Hostname = nodeInfo.Id.Get()
tstruct.ClusterName = nodeInfo.ClusterName.Get() tstruct.ClusterName = nodeInfo.ClusterName.Get()
tstruct.Container = nodeInfo.ContainerName.Get() tstruct.Container = nodeInfo.ContainerName.Get()
tstruct.KernelVersion = nodeInfo.KernelVersion.Get() tstruct.KernelVersion = nodeInfo.KernelOverride.Get()
tstruct.KernelOverride = nodeInfo.KernelOverride.Get()
tstruct.KernelArgs = nodeInfo.KernelArgs.Get() tstruct.KernelArgs = nodeInfo.KernelArgs.Get()
tstruct.Init = nodeInfo.Init.Get() tstruct.Init = nodeInfo.Init.Get()
tstruct.Root = nodeInfo.Root.Get() tstruct.Root = nodeInfo.Root.Get()

View File

@@ -15,18 +15,18 @@ import (
) )
type iPxeTemplate struct { type iPxeTemplate struct {
Message string Message string
WaitTime string WaitTime string
Hostname string Hostname string
Fqdn string Fqdn string
Id string Id string
Cluster string Cluster string
ContainerName string ContainerName string
Hwaddr string Hwaddr string
Ipaddr string Ipaddr string
Port string Port string
KernelArgs string KernelArgs string
KernelVersion string KernelOverride string
} }
func IpxeSend(w http.ResponseWriter, req *http.Request) { func IpxeSend(w http.ResponseWriter, req *http.Request) {
@@ -140,7 +140,7 @@ func IpxeSend(w http.ResponseWriter, req *http.Request) {
replace.Hwaddr = rinfo.hwaddr replace.Hwaddr = rinfo.hwaddr
replace.ContainerName = node.ContainerName.Get() replace.ContainerName = node.ContainerName.Get()
replace.KernelArgs = node.KernelArgs.Get() replace.KernelArgs = node.KernelArgs.Get()
replace.KernelVersion = node.KernelVersion.Get() replace.KernelOverride = node.KernelOverride.Get()
err = tmpl.Execute(w, replace) err = tmpl.Execute(w, replace)
if err != nil { if err != nil {

View File

@@ -2,8 +2,10 @@ package warewulfd
import ( import (
"net/http" "net/http"
"path"
"strings" "strings"
"github.com/hpcng/warewulf/internal/pkg/container"
"github.com/hpcng/warewulf/internal/pkg/kernel" "github.com/hpcng/warewulf/internal/pkg/kernel"
) )
@@ -28,18 +30,25 @@ func KernelSend(w http.ResponseWriter, req *http.Request) {
return return
} }
if node.KernelVersion.Defined() { var fileName string
fileName := kernel.KernelImage(node.KernelVersion.Get()) if node.KernelOverride.Defined() {
fileName = kernel.KernelImage(node.KernelOverride.Get())
updateStatus(node.Id.Get(), "KERNEL", node.KernelVersion.Get(), strings.Split(req.RemoteAddr, ":")[0]) } else if node.ContainerName.Defined() {
fileName = container.KernelFind(node.ContainerName.Get())
err := sendFile(w, fileName, node.Id.Get())
if err != nil {
daemonLogf("ERROR: %s\n", err)
}
} else { } else {
w.WriteHeader(503) w.WriteHeader(503)
daemonLogf("WARNING: No 'kernel version' set for node %s\n", node.Id.Get()) daemonLogf("WARNING: No 'kernel version' set for node %s\n", node.Id.Get())
return
} }
updateStatus(node.Id.Get(), "KERNEL", path.Base(fileName), strings.Split(req.RemoteAddr, ":")[0])
err = sendFile(w, fileName, node.Id.Get())
if err != nil {
daemonLogf("ERROR: %s\n", err)
}
} }

View File

@@ -28,18 +28,14 @@ func KmodsSend(w http.ResponseWriter, req *http.Request) {
return return
} }
if node.KernelVersion.Defined() { if node.KernelOverride.Defined() {
fileName := kernel.KmodsImage(node.KernelVersion.Get()) fileName := kernel.KmodsImage(node.KernelOverride.Get())
updateStatus(node.Id.Get(), "KMODS_OVERLAY", node.KernelVersion.Get()+".img", strings.Split(req.RemoteAddr, ":")[0]) updateStatus(node.Id.Get(), "KMODS_OVERLAY", node.KernelOverride.Get()+".img", strings.Split(req.RemoteAddr, ":")[0])
err := sendFile(w, fileName, node.Id.Get()) err := sendFile(w, fileName, node.Id.Get())
if err != nil { if err != nil {
daemonLogf("ERROR: %s\n", err) daemonLogf("ERROR: %s\n", err)
} }
} else {
w.WriteHeader(503)
daemonLogf("WARNING: No 'kernel version' set for node %s\n", node.Id.Get())
} }
} }