Restored deleted kernel components for overrides
This commit is contained in:
41
internal/app/wwctl/kernel/delete/main.go
Normal file
41
internal/app/wwctl/kernel/delete/main.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package delete
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/kernel"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
|
nodeDB, err := node.New()
|
||||||
|
if err != nil {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Could not open nodeDB: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes, _ := nodeDB.FindAllNodes()
|
||||||
|
|
||||||
|
ARG_LOOP:
|
||||||
|
for _, arg := range args {
|
||||||
|
for _, n := range nodes {
|
||||||
|
if n.KernelVersion.Get() == arg {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Kernel is configured for nodes, skipping: %s\n", arg)
|
||||||
|
continue ARG_LOOP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err := kernel.DeleteKernel(arg)
|
||||||
|
if err != nil {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Could not delete kernel: %s\n", arg)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Kernel has been deleted: %s\n", arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
33
internal/app/wwctl/kernel/delete/root.go
Normal file
33
internal/app/wwctl/kernel/delete/root.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package delete
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/kernel"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
baseCmd = &cobra.Command{
|
||||||
|
DisableFlagsInUseLine: true,
|
||||||
|
Use: "delete [OPTIONS] KERNEL [...]",
|
||||||
|
Short: "Delete imported kernels",
|
||||||
|
Long: "This command will delete KERNEL versions that have been imported into Warewulf.",
|
||||||
|
RunE: CobraRunE,
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
if len(args) != 0 {
|
||||||
|
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}
|
||||||
|
list, _ := kernel.ListKernels()
|
||||||
|
return list, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRootCommand returns the root cobra.Command for the application.
|
||||||
|
func GetCommand() *cobra.Command {
|
||||||
|
return baseCmd
|
||||||
|
}
|
||||||
92
internal/app/wwctl/kernel/imprt/main.go
Normal file
92
internal/app/wwctl/kernel/imprt/main.go
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package imprt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/container"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/kernel"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/warewulfd"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) == 0 && !OptDetect {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "the '--detect' flag is needed, if no kernel version is suppiled")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if OptDetect && (OptRoot == "" || OptContainer == "") {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "the '--detect flag needs the '--container' or '--root' flag")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
// Checking if container flag was set, then overwriting OptRoot
|
||||||
|
if OptContainer != "" {
|
||||||
|
if container.ValidSource(OptContainer) {
|
||||||
|
OptRoot = container.RootFsDir(OptContainer)
|
||||||
|
} else {
|
||||||
|
wwlog.Printf(wwlog.ERROR, " %s is not a valid container", OptContainer)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var kernelVersion string
|
||||||
|
var err error
|
||||||
|
if len(args) > 0 {
|
||||||
|
kernelVersion = args[0]
|
||||||
|
} else {
|
||||||
|
kernelVersion, err = kernel.FindKernelVersion(OptRoot)
|
||||||
|
if err != nil {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "could not detect kernel under %s\n", OptRoot)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kernelName := kernelVersion
|
||||||
|
if len(args) > 1 {
|
||||||
|
kernelName = args[1]
|
||||||
|
} else if OptDetect && (OptContainer != "") {
|
||||||
|
kernelName = OptContainer
|
||||||
|
}
|
||||||
|
output, err := kernel.Build(kernelVersion, kernelName, OptRoot)
|
||||||
|
if err != nil {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Failed building kernel: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%s: %s\n", kernelName, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
if SetDefault {
|
||||||
|
|
||||||
|
nodeDB, err := node.New()
|
||||||
|
if err != nil {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
//TODO: Don't loop through profiles, instead have a nodeDB function that goes directly to the map
|
||||||
|
profiles, _ := nodeDB.FindAllProfiles()
|
||||||
|
for _, profile := range profiles {
|
||||||
|
wwlog.Printf(wwlog.DEBUG, "Looking for profile default: %s\n", profile.Id.Get())
|
||||||
|
if profile.Id.Get() == "default" {
|
||||||
|
wwlog.Printf(wwlog.DEBUG, "Found profile default, setting kernel version to: %s\n", args[0])
|
||||||
|
profile.KernelVersion.Set(args[0])
|
||||||
|
err := nodeDB.ProfileUpdate(profile)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to update node profile")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = nodeDB.Persist()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to persist nodedb")
|
||||||
|
}
|
||||||
|
fmt.Printf("Set default kernel version to: %s\n", args[0])
|
||||||
|
err = warewulfd.DaemonReload()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to reload warewulf daemon")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
46
internal/app/wwctl/kernel/imprt/root.go
Normal file
46
internal/app/wwctl/kernel/imprt/root.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package imprt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/container"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
baseCmd = &cobra.Command{
|
||||||
|
DisableFlagsInUseLine: true,
|
||||||
|
Use: "import [OPTIONS] KERNEL",
|
||||||
|
Short: "Import Kernel version into Warewulf",
|
||||||
|
Long: "This will import a boot KERNEL version from the control node into Warewulf",
|
||||||
|
RunE: CobraRunE,
|
||||||
|
Args: cobra.MinimumNArgs(0),
|
||||||
|
}
|
||||||
|
BuildAll bool
|
||||||
|
ByNode bool
|
||||||
|
SetDefault bool
|
||||||
|
OptRoot string
|
||||||
|
OptContainer string
|
||||||
|
OptDetect bool
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
baseCmd.PersistentFlags().BoolVarP(&BuildAll, "all", "a", false, "Build all overlays (runtime and system)")
|
||||||
|
baseCmd.PersistentFlags().BoolVarP(&ByNode, "node", "n", false, "Build overlay for a particular node(s)")
|
||||||
|
baseCmd.PersistentFlags().BoolVar(&SetDefault, "setdefault", false, "Set this kernel for the default profile")
|
||||||
|
baseCmd.PersistentFlags().StringVarP(&OptRoot, "root", "r", "/", "Import kernel from root (chroot) directory")
|
||||||
|
baseCmd.PersistentFlags().StringVarP(&OptContainer, "container", "C", "", "Import kernel from container")
|
||||||
|
err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
list, _ := container.ListSources()
|
||||||
|
return list, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
baseCmd.PersistentFlags().BoolVarP(&OptDetect, "detect", "D", false, "Try to detect the kernel version in an automated way, needs the -C or -r option")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRootCommand returns the root cobra.Command for the application.
|
||||||
|
func GetCommand() *cobra.Command {
|
||||||
|
return baseCmd
|
||||||
|
}
|
||||||
35
internal/app/wwctl/kernel/list/main.go
Normal file
35
internal/app/wwctl/kernel/list/main.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package list
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/kernel"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CobraRunE(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
|
kernels, err := kernel.ListKernels()
|
||||||
|
if err != nil {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "%s\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
nconfig, _ := node.New()
|
||||||
|
nodes, _ := nconfig.FindAllNodes()
|
||||||
|
nodemap := make(map[string]int)
|
||||||
|
|
||||||
|
for _, n := range nodes {
|
||||||
|
nodemap[n.KernelVersion.Get()]++
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%-35s %-25s %-6s\n", "KERNEL NAME", "KERNEL VERSION", "NODES")
|
||||||
|
for _, k := range kernels {
|
||||||
|
fmt.Printf("%-35s %-25s %6d\n", k, kernel.GetKernelVersion(k), nodemap[k])
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
23
internal/app/wwctl/kernel/list/root.go
Normal file
23
internal/app/wwctl/kernel/list/root.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package list
|
||||||
|
|
||||||
|
import "github.com/spf13/cobra"
|
||||||
|
|
||||||
|
var (
|
||||||
|
baseCmd = &cobra.Command{
|
||||||
|
DisableFlagsInUseLine: true,
|
||||||
|
Use: "list [OPTIONS]",
|
||||||
|
Short: "List imported Kernel images",
|
||||||
|
Long: "This command will list the kernels that have been imported into Warewulf.",
|
||||||
|
RunE: CobraRunE,
|
||||||
|
Args: cobra.ExactArgs(0),
|
||||||
|
Aliases: []string{"ls"},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRootCommand returns the root cobra.Command for the application.
|
||||||
|
func GetCommand() *cobra.Command {
|
||||||
|
return baseCmd
|
||||||
|
}
|
||||||
28
internal/app/wwctl/kernel/root.go
Normal file
28
internal/app/wwctl/kernel/root.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package kernel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hpcng/warewulf/internal/app/wwctl/kernel/delete"
|
||||||
|
"github.com/hpcng/warewulf/internal/app/wwctl/kernel/imprt"
|
||||||
|
"github.com/hpcng/warewulf/internal/app/wwctl/kernel/list"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
baseCmd = &cobra.Command{
|
||||||
|
DisableFlagsInUseLine: true,
|
||||||
|
Use: "kernel COMMAND [OPTIONS]",
|
||||||
|
Short: "Kernel Image Management",
|
||||||
|
Long: "This command manages Warewulf Kernels used for bootstrapping nodes",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
baseCmd.AddCommand(imprt.GetCommand())
|
||||||
|
baseCmd.AddCommand(list.GetCommand())
|
||||||
|
baseCmd.AddCommand(delete.GetCommand())
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRootCommand returns the root cobra.Command for the application.
|
||||||
|
func GetCommand() *cobra.Command {
|
||||||
|
return baseCmd
|
||||||
|
}
|
||||||
@@ -41,6 +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(), "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())
|
||||||
@@ -96,11 +97,11 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if ShowLong {
|
} else if ShowLong {
|
||||||
fmt.Printf("%-22s %-35s %s\n", "NODE NAME", "CONTAINER", "OVERLAYS (S/R)")
|
fmt.Printf("%-22s %-26s %-35s %s\n", "NODE NAME", "KERNEL", "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 %-35s %s\n", node.Id.Get(), node.ContainerName.Print(), node.SystemOverlay.Print()+"/"+node.RuntimeOverlay.Print())
|
fmt.Printf("%-22s %-26s %-35s %s\n", node.Id.Get(), node.KernelVersion.Print(), node.ContainerName.Print(), node.SystemOverlay.Print()+"/"+node.RuntimeOverlay.Print())
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -70,6 +70,11 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
|||||||
n.AssetKey.Set(SetAssetKey)
|
n.AssetKey.Set(SetAssetKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if SetKernel != "" {
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting kernel to: %s\n", n.Id.Get(), SetKernel)
|
||||||
|
n.KernelVersion.Set(SetKernel)
|
||||||
|
}
|
||||||
|
|
||||||
if SetKernelArgs != "" {
|
if SetKernelArgs != "" {
|
||||||
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting kernel args to: %s\n", n.Id.Get(), SetKernelArgs)
|
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting kernel args to: %s\n", n.Id.Get(), SetKernelArgs)
|
||||||
n.KernelArgs.Set(SetKernelArgs)
|
n.KernelArgs.Set(SetKernelArgs)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/hpcng/warewulf/internal/pkg/container"
|
"github.com/hpcng/warewulf/internal/pkg/container"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/kernel"
|
||||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||||
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -33,6 +34,7 @@ var (
|
|||||||
}
|
}
|
||||||
SetComment string
|
SetComment string
|
||||||
SetContainer string
|
SetContainer string
|
||||||
|
SetKernel string
|
||||||
SetKernelArgs string
|
SetKernelArgs string
|
||||||
SetNetName string
|
SetNetName string
|
||||||
SetNetDev string
|
SetNetDev string
|
||||||
@@ -80,6 +82,13 @@ func init() {
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes")
|
||||||
|
if err := baseCmd.RegisterFlagCompletionFunc("kernel", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
list, _ := kernel.ListKernels()
|
||||||
|
return list, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetKernelArgs, "kernelargs", "A", "", "Set Kernel argument for nodes")
|
baseCmd.PersistentFlags().StringVarP(&SetKernelArgs, "kernelargs", "A", "", "Set Kernel argument for nodes")
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetClusterName, "cluster", "c", "", "Set the node's cluster group")
|
baseCmd.PersistentFlags().StringVarP(&SetClusterName, "cluster", "c", "", "Set the node's cluster group")
|
||||||
baseCmd.PersistentFlags().StringVar(&SetIpxe, "ipxe", "", "Set the node's iPXE template name")
|
baseCmd.PersistentFlags().StringVar(&SetIpxe, "ipxe", "", "Set the node's iPXE template name")
|
||||||
|
|||||||
@@ -33,6 +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(), "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())
|
||||||
|
|||||||
@@ -75,8 +75,13 @@ func CobraRunE(cmd *cobra.Command, args []string) error {
|
|||||||
p.AssetKey.Set(SetAssetKey)
|
p.AssetKey.Set(SetAssetKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if SetKernel != "" {
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Kernel to: %s\n", p.Id.Get(), SetKernel)
|
||||||
|
p.KernelVersion.Set(SetKernel)
|
||||||
|
}
|
||||||
|
|
||||||
if SetKernelArgs != "" {
|
if SetKernelArgs != "" {
|
||||||
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting kernel args to: %s\n", p.Id.Get(), SetKernelArgs)
|
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Kernel args to: %s\n", p.Id.Get(), SetKernelArgs)
|
||||||
p.KernelArgs.Set(SetKernelArgs)
|
p.KernelArgs.Set(SetKernelArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/hpcng/warewulf/internal/pkg/container"
|
"github.com/hpcng/warewulf/internal/pkg/container"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/kernel"
|
||||||
"github.com/hpcng/warewulf/internal/pkg/node"
|
"github.com/hpcng/warewulf/internal/pkg/node"
|
||||||
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
"github.com/hpcng/warewulf/internal/pkg/overlay"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -36,6 +37,7 @@ var (
|
|||||||
SetForce bool
|
SetForce bool
|
||||||
SetComment string
|
SetComment string
|
||||||
SetContainer string
|
SetContainer string
|
||||||
|
SetKernel string
|
||||||
SetKernelArgs string
|
SetKernelArgs string
|
||||||
SetClusterName string
|
SetClusterName string
|
||||||
SetIpxe string
|
SetIpxe string
|
||||||
@@ -77,6 +79,13 @@ func init() {
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
baseCmd.PersistentFlags().StringVarP(&SetKernel, "kernel", "K", "", "Set Kernel version for nodes")
|
||||||
|
if err := baseCmd.RegisterFlagCompletionFunc("kernel", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||||
|
list, _ := kernel.ListKernels()
|
||||||
|
return list, cobra.ShellCompDirectiveNoFileComp
|
||||||
|
}); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetKernelArgs, "kernelargs", "A", "", "Set Kernel argument for nodes")
|
baseCmd.PersistentFlags().StringVarP(&SetKernelArgs, "kernelargs", "A", "", "Set Kernel argument for nodes")
|
||||||
baseCmd.PersistentFlags().StringVarP(&SetClusterName, "cluster", "c", "", "Set the node's cluster group")
|
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(&SetIpxe, "ipxe", "P", "", "Set the node's iPXE template name")
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ package wwctl
|
|||||||
import (
|
import (
|
||||||
"github.com/hpcng/warewulf/internal/app/wwctl/configure"
|
"github.com/hpcng/warewulf/internal/app/wwctl/configure"
|
||||||
"github.com/hpcng/warewulf/internal/app/wwctl/container"
|
"github.com/hpcng/warewulf/internal/app/wwctl/container"
|
||||||
|
"github.com/hpcng/warewulf/internal/app/wwctl/kernel"
|
||||||
"github.com/hpcng/warewulf/internal/app/wwctl/node"
|
"github.com/hpcng/warewulf/internal/app/wwctl/node"
|
||||||
"github.com/hpcng/warewulf/internal/app/wwctl/overlay"
|
"github.com/hpcng/warewulf/internal/app/wwctl/overlay"
|
||||||
"github.com/hpcng/warewulf/internal/app/wwctl/power"
|
"github.com/hpcng/warewulf/internal/app/wwctl/power"
|
||||||
"github.com/hpcng/warewulf/internal/app/wwctl/profile"
|
"github.com/hpcng/warewulf/internal/app/wwctl/profile"
|
||||||
"github.com/hpcng/warewulf/internal/app/wwctl/server"
|
"github.com/hpcng/warewulf/internal/app/wwctl/server"
|
||||||
"github.com/hpcng/warewulf/internal/app/wwctl/version"
|
"github.com/hpcng/warewulf/internal/app/wwctl/version"
|
||||||
"github.com/hpcng/warewulf/internal/pkg/help"
|
|
||||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/help"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/cobra/doc"
|
"github.com/spf13/cobra/doc"
|
||||||
|
|
||||||
@@ -20,12 +21,12 @@ import (
|
|||||||
var (
|
var (
|
||||||
rootCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
Use: "wwctl COMMAND [OPTIONS]",
|
Use: "wwctl COMMAND [OPTIONS]",
|
||||||
Short: "Warewulf Control",
|
Short: "Warewulf Control",
|
||||||
Long: "Control interface to the Warewulf Cluster Provisioning System.",
|
Long: "Control interface to the Warewulf Cluster Provisioning System.",
|
||||||
PersistentPreRunE: rootPersistentPreRunE,
|
PersistentPreRunE: rootPersistentPreRunE,
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
SilenceErrors: true,
|
SilenceErrors: true,
|
||||||
}
|
}
|
||||||
verboseArg bool
|
verboseArg bool
|
||||||
DebugFlag bool
|
DebugFlag bool
|
||||||
@@ -35,12 +36,13 @@ func init() {
|
|||||||
rootCmd.PersistentFlags().BoolVarP(&verboseArg, "verbose", "v", false, "Run with increased verbosity.")
|
rootCmd.PersistentFlags().BoolVarP(&verboseArg, "verbose", "v", false, "Run with increased verbosity.")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&DebugFlag, "debug", "d", false, "Run with debugging messages enabled.")
|
rootCmd.PersistentFlags().BoolVarP(&DebugFlag, "debug", "d", false, "Run with debugging messages enabled.")
|
||||||
|
|
||||||
rootCmd.SetUsageTemplate(help.UsageTemplate)
|
rootCmd.SetUsageTemplate(help.UsageTemplate)
|
||||||
rootCmd.SetHelpTemplate(help.HelpTemplate)
|
rootCmd.SetHelpTemplate(help.HelpTemplate)
|
||||||
|
|
||||||
rootCmd.AddCommand(overlay.GetCommand())
|
rootCmd.AddCommand(overlay.GetCommand())
|
||||||
rootCmd.AddCommand(container.GetCommand())
|
rootCmd.AddCommand(container.GetCommand())
|
||||||
rootCmd.AddCommand(node.GetCommand())
|
rootCmd.AddCommand(node.GetCommand())
|
||||||
|
rootCmd.AddCommand(kernel.GetCommand())
|
||||||
rootCmd.AddCommand(power.GetCommand())
|
rootCmd.AddCommand(power.GetCommand())
|
||||||
rootCmd.AddCommand(profile.GetCommand())
|
rootCmd.AddCommand(profile.GetCommand())
|
||||||
rootCmd.AddCommand(configure.GetCommand())
|
rootCmd.AddCommand(configure.GetCommand())
|
||||||
|
|||||||
257
internal/pkg/kernel/kernel.go
Normal file
257
internal/pkg/kernel/kernel.go
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
package kernel
|
||||||
|
|
||||||
|
import (
|
||||||
|
"compress/gzip"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/buildconfig"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/util"
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
kernelSearchPaths = []string{
|
||||||
|
// This is a printf format where the %s will be the kernel version
|
||||||
|
"/boot/vmlinuz-%s",
|
||||||
|
"/boot/vmlinuz-%s.gz",
|
||||||
|
"/lib/mmodules/%s/vmlinuz",
|
||||||
|
"/lib/mmodules/%s/vmlinuz.gz",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func KernelImageTopDir() string {
|
||||||
|
return path.Join(buildconfig.WWPROVISIONDIR(), "kernel")
|
||||||
|
}
|
||||||
|
|
||||||
|
func KernelImage(kernelName string) string {
|
||||||
|
if kernelName == "" {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Kernel Name is not defined\n")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if !util.ValidString(kernelName, "^[a-zA-Z0-9-._]+$") {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Runtime overlay name contains illegal characters: %s\n", kernelName)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.Join(KernelImageTopDir(), kernelName, "vmlinuz")
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetKernelVersion(kernelName string) string {
|
||||||
|
if kernelName == "" {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Kernel Name is not defined\n")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
kernelVersion, err := ioutil.ReadFile(KernelVersionFile(kernelName))
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return string(kernelVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
func KmodsImage(kernelName string) string {
|
||||||
|
if kernelName == "" {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Kernel Name is not defined\n")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if !util.ValidString(kernelName, "^[a-zA-Z0-9-._]+$") {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Runtime overlay name contains illegal characters: %s\n", kernelName)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.Join(KernelImageTopDir(), kernelName, "kmods.img")
|
||||||
|
}
|
||||||
|
|
||||||
|
func KernelVersionFile(kernelName string) string {
|
||||||
|
if kernelName == "" {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Kernel Name is not defined\n")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if !util.ValidString(kernelName, "^[a-zA-Z0-9-._]+$") {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Runtime overlay name contains illegal characters: %s\n", kernelName)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.Join(KernelImageTopDir(), kernelName, "version")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListKernels() ([]string, error) {
|
||||||
|
var ret []string
|
||||||
|
|
||||||
|
err := os.MkdirAll(KernelImageTopDir(), 0755)
|
||||||
|
if err != nil {
|
||||||
|
return ret, errors.New("Could not create Kernel parent directory: " + KernelImageTopDir())
|
||||||
|
}
|
||||||
|
|
||||||
|
wwlog.Printf(wwlog.DEBUG, "Searching for Kernel image directories: %s\n", KernelImageTopDir())
|
||||||
|
|
||||||
|
kernels, err := ioutil.ReadDir(KernelImageTopDir())
|
||||||
|
if err != nil {
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, kernel := range kernels {
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Found Kernel: %s\n", kernel.Name())
|
||||||
|
|
||||||
|
ret = append(ret, kernel.Name())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Build(kernelVersion, kernelName, root string) (string, error) {
|
||||||
|
kernelDrivers := path.Join(root, "/lib/modules/", kernelVersion)
|
||||||
|
kernelDriversRelative := path.Join("/lib/modules/", kernelVersion)
|
||||||
|
kernelDestination := KernelImage(kernelName)
|
||||||
|
driversDestination := KmodsImage(kernelName)
|
||||||
|
versionDestination := KernelVersionFile(kernelName)
|
||||||
|
var kernelSource string
|
||||||
|
|
||||||
|
// Create the destination paths just in case it doesn't exist
|
||||||
|
err := os.MkdirAll(path.Dir(kernelDestination), 0755)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "failed to create kernel dest")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.MkdirAll(path.Dir(driversDestination), 0755)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "failed to create driver dest")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.MkdirAll(path.Dir(versionDestination), 0755)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to create version dest: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, searchPath := range kernelSearchPaths {
|
||||||
|
testPath := fmt.Sprintf(path.Join(root, searchPath), kernelVersion)
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Looking for kernel at: %s\n", testPath)
|
||||||
|
if util.IsFile(testPath) {
|
||||||
|
kernelSource = testPath
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if kernelSource == "" {
|
||||||
|
wwlog.Printf(wwlog.ERROR, "Could not locate kernel image\n")
|
||||||
|
return "", errors.New("could not locate kernel image")
|
||||||
|
} else {
|
||||||
|
wwlog.Printf(wwlog.INFO, "Found kernel at: %s\n", kernelSource)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !util.IsDir(kernelDrivers) {
|
||||||
|
return "", errors.New("Could not locate kernel drivers")
|
||||||
|
}
|
||||||
|
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Setting up Kernel\n")
|
||||||
|
if _, err := os.Stat(kernelSource); err == nil {
|
||||||
|
kernel, err := os.Open(kernelSource)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "could not open kernel")
|
||||||
|
}
|
||||||
|
defer kernel.Close()
|
||||||
|
|
||||||
|
gzipreader, err := gzip.NewReader(kernel)
|
||||||
|
if err == nil {
|
||||||
|
defer gzipreader.Close()
|
||||||
|
|
||||||
|
writer, err := os.Create(kernelDestination)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "could not decompress kernel")
|
||||||
|
}
|
||||||
|
defer writer.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(writer, gzipreader)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "could not write decompressed kernel")
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
err := util.CopyFile(kernelSource, kernelDestination)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "could not copy kernel")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Building Kernel driver image\n")
|
||||||
|
if _, err := os.Stat(kernelDrivers); err == nil {
|
||||||
|
compressor, err := exec.LookPath("pigz")
|
||||||
|
if err != nil {
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Could not locate PIGZ, using GZIP\n")
|
||||||
|
compressor = "gzip"
|
||||||
|
} else {
|
||||||
|
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)
|
||||||
|
|
||||||
|
wwlog.Printf(wwlog.DEBUG, "RUNNING: %s\n", cmd)
|
||||||
|
err = exec.Command("/bin/sh", "-c", cmd).Run()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Creating version file\n")
|
||||||
|
file, err := os.Create(versionDestination)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "Failed to create version file")
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
_, err = io.WriteString(file, kernelVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "Could not write kernel version")
|
||||||
|
}
|
||||||
|
err = file.Sync()
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "Could not sync kernel version")
|
||||||
|
}
|
||||||
|
return "Done", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteKernel(name string) error {
|
||||||
|
fullPath := path.Join(KernelImageTopDir(), name)
|
||||||
|
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Removing path: %s\n", fullPath)
|
||||||
|
return os.RemoveAll(fullPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindKernelVersion(root string) (string, error) {
|
||||||
|
for _, searchPath := range kernelSearchPaths {
|
||||||
|
testPattern := fmt.Sprintf(path.Join(root, searchPath), `*`)
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Looking for kernel version with pattern at: %s\n", testPattern)
|
||||||
|
potentialKernel, _ := filepath.Glob(testPattern)
|
||||||
|
if len(potentialKernel) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, foundKernel := range potentialKernel {
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "Parsing out kernel version for %s\n", foundKernel)
|
||||||
|
re := regexp.MustCompile(fmt.Sprintf(path.Join(root, searchPath), `([\w\d-\.]*)`))
|
||||||
|
version := re.FindAllStringSubmatch(foundKernel, -1)
|
||||||
|
if version == nil {
|
||||||
|
return "", fmt.Errorf("could not parse kernel version")
|
||||||
|
}
|
||||||
|
wwlog.Printf(wwlog.VERBOSE, "found kernel version %s\n", version)
|
||||||
|
return version[0][1], nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("could not find kernel version")
|
||||||
|
|
||||||
|
}
|
||||||
@@ -72,6 +72,7 @@ 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)
|
||||||
@@ -133,6 +134,7 @@ 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)
|
||||||
@@ -216,6 +218,7 @@ 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)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ type NodeConf struct {
|
|||||||
ClusterName string `yaml:"cluster name,omitempty"`
|
ClusterName string `yaml:"cluster name,omitempty"`
|
||||||
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"`
|
||||||
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"`
|
||||||
@@ -70,6 +71,7 @@ type NodeInfo struct {
|
|||||||
ClusterName Entry
|
ClusterName Entry
|
||||||
ContainerName Entry
|
ContainerName Entry
|
||||||
Ipxe Entry
|
Ipxe Entry
|
||||||
|
KernelVersion Entry
|
||||||
KernelArgs Entry
|
KernelArgs Entry
|
||||||
IpmiIpaddr Entry
|
IpmiIpaddr Entry
|
||||||
IpmiNetmask Entry
|
IpmiNetmask Entry
|
||||||
|
|||||||
@@ -60,6 +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].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()
|
||||||
@@ -147,6 +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].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()
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ 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.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()
|
||||||
|
|||||||
@@ -140,6 +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()
|
||||||
|
|
||||||
err = tmpl.Execute(w, replace)
|
err = tmpl.Execute(w, replace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
45
internal/pkg/warewulfd/kmods.go
Normal file
45
internal/pkg/warewulfd/kmods.go
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package warewulfd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hpcng/warewulf/internal/pkg/kernel"
|
||||||
|
)
|
||||||
|
|
||||||
|
func KmodsSend(w http.ResponseWriter, req *http.Request) {
|
||||||
|
rinfo, err := parseReq(req)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(404)
|
||||||
|
daemonLogf("ERROR: %s\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
node, err := GetNode(rinfo.hwaddr)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(403)
|
||||||
|
daemonLogf("ERROR(%s): %s\n", rinfo.hwaddr, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if node.AssetKey.Defined() && node.AssetKey.Get() != rinfo.assetkey {
|
||||||
|
w.WriteHeader(404)
|
||||||
|
daemonLogf("ERROR: Incorrect asset key for node: %s\n", node.Id.Get())
|
||||||
|
updateStatus(node.Id.Get(), "KMODS_OVERLAY", "BAD_ASSET", rinfo.ipaddr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if node.KernelVersion.Defined() {
|
||||||
|
fileName := kernel.KmodsImage(node.KernelVersion.Get())
|
||||||
|
|
||||||
|
updateStatus(node.Id.Get(), "KMODS_OVERLAY", node.KernelVersion.Get()+".img", strings.Split(req.RemoteAddr, ":")[0])
|
||||||
|
|
||||||
|
err := sendFile(w, fileName, node.Id.Get())
|
||||||
|
if err != nil {
|
||||||
|
daemonLogf("ERROR: %s\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
w.WriteHeader(503)
|
||||||
|
daemonLogf("WARNING: No 'kernel version' set for node %s\n", node.Id.Get())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,6 +48,7 @@ func RunServer() error {
|
|||||||
|
|
||||||
http.HandleFunc("/ipxe/", IpxeSend)
|
http.HandleFunc("/ipxe/", IpxeSend)
|
||||||
http.HandleFunc("/kernel/", KernelSend)
|
http.HandleFunc("/kernel/", KernelSend)
|
||||||
|
http.HandleFunc("/kmods/", KmodsSend)
|
||||||
http.HandleFunc("/container/", ContainerSend)
|
http.HandleFunc("/container/", ContainerSend)
|
||||||
http.HandleFunc("/overlay-system/", SystemOverlaySend)
|
http.HandleFunc("/overlay-system/", SystemOverlaySend)
|
||||||
http.HandleFunc("/overlay-runtime/", RuntimeOverlaySend)
|
http.HandleFunc("/overlay-runtime/", RuntimeOverlaySend)
|
||||||
|
|||||||
Reference in New Issue
Block a user