diff --git a/internal/app/wwctl/kernel/imprt/main.go b/internal/app/wwctl/kernel/imprt/main.go index 4158c403..f8b7f143 100644 --- a/internal/app/wwctl/kernel/imprt/main.go +++ b/internal/app/wwctl/kernel/imprt/main.go @@ -14,58 +14,57 @@ import ( ) func CobraRunE(cmd *cobra.Command, args []string) error { - for _, arg := range args { - // 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) - } - } - output, err := kernel.Build(arg, OptRoot) - if err != nil { - wwlog.Printf(wwlog.ERROR, "Failed building kernel: %s\n", err) - os.Exit(1) + + // Checking if container flag was set, then overwriting OptRoot + kernelVersion := args[0] + kernelName := kernelVersion + if len(args) > 1 { + kernelName = args[1] + } + if OptContainer != "" { + if container.ValidSource(OptContainer) { + OptRoot = container.RootFsDir(OptContainer) } else { - fmt.Printf("%s: %s\n", arg, output) + wwlog.Printf(wwlog.ERROR, " %s is not a valid container", OptContainer) + os.Exit(1) } } + 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 { - if len(args) != 1 { - wwlog.Printf(wwlog.ERROR, "Can only set default for one kernel version\n") - } else { - 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") - } + 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") - } + } + 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") } } diff --git a/internal/app/wwctl/kernel/list/main.go b/internal/app/wwctl/kernel/list/main.go index d209e786..a3a8d4ad 100644 --- a/internal/app/wwctl/kernel/list/main.go +++ b/internal/app/wwctl/kernel/list/main.go @@ -26,9 +26,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error { nodemap[n.KernelVersion.Get()]++ } - fmt.Printf("%-35s %-6s\n", "VNFS NAME", "NODES") + fmt.Printf("%-35s %-25s %-6s\n", "KERNEL NAME", "KERNEL VERSION", "NODES") for _, k := range kernels { - fmt.Printf("%-35s %6d\n", k, nodemap[k]) + fmt.Printf("%-35s %-25s %6d\n", k, kernel.GetKernelVersion(k), nodemap[k]) } return nil diff --git a/internal/pkg/kernel/kernel.go b/internal/pkg/kernel/kernel.go index 5f6ab073..7b342a2b 100644 --- a/internal/pkg/kernel/kernel.go +++ b/internal/pkg/kernel/kernel.go @@ -20,32 +20,58 @@ func ParentDir() string { return path.Join(config.LocalStateDir, "provision/kernel") } -func KernelImage(kernelVersion string) string { - if kernelVersion == "" { - wwlog.Printf(wwlog.ERROR, "Kernel Version is not defined\n") +func KernelImage(kernelName string) string { + if kernelName == "" { + wwlog.Printf(wwlog.ERROR, "Kernel Name is not defined\n") return "" } - if !util.ValidString(kernelVersion, "^[a-zA-Z0-9-._]+$") { - wwlog.Printf(wwlog.ERROR, "Runtime overlay name contains illegal characters: %s\n", kernelVersion) + 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(ParentDir(), kernelVersion, "vmlinuz") + return path.Join(ParentDir(), kernelName, "vmlinuz") } -func KmodsImage(kernelVersion string) string { - if kernelVersion == "" { - wwlog.Printf(wwlog.ERROR, "Kernel Version is not defined\n") +func GetKernelVersion(kernelName string) string { + if kernelName == "" { + wwlog.Printf(wwlog.ERROR, "Kernel Name is not defined\n") + return "" + } + kernelVersion, err := ioutil.ReadFile(path.Join(ParentDir(), kernelName, "version")) + 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(kernelVersion, "^[a-zA-Z0-9-._]+$") { - wwlog.Printf(wwlog.ERROR, "Runtime overlay name contains illegal characters: %s\n", kernelVersion) + 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(ParentDir(), kernelVersion, "kmods.img") + return path.Join(ParentDir(), kernelName, "kmods.img") +} + +func KernelVersion(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(ParentDir(), kernelName, "version") } func ListKernels() ([]string, error) { @@ -73,11 +99,12 @@ func ListKernels() ([]string, error) { return ret, nil } -func Build(kernelVersion string, root string) (string, error) { +func Build(kernelVersion string, kernelName string, root string) (string, error) { kernelImage := path.Join(root, "/boot/vmlinuz-"+kernelVersion) kernelDrivers := path.Join(root, "/lib/modules/"+kernelVersion) - kernelDestination := KernelImage(kernelVersion) - driversDestination := KmodsImage(kernelVersion) + kernelDestination := KernelImage(kernelName) + driversDestination := KmodsImage(kernelName) + versionDestination := KernelVersion(kernelName) // Create the destination paths just in case it doesn't exist err := os.MkdirAll(path.Dir(kernelDestination), 0755) @@ -90,6 +117,11 @@ func Build(kernelVersion string, root string) (string, error) { 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) + } + if !util.IsFile(kernelImage) { if !util.IsFile(kernelImage + ".gz") { return "", errors.New("Could not locate kernel image") @@ -154,6 +186,20 @@ func Build(kernelVersion string, root string) (string, error) { } } + 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 }