From 2ba9efa57ca138014bfacfb0560f77d988249a96 Mon Sep 17 00:00:00 2001 From: Christian Goll Date: Thu, 21 Mar 2024 16:21:06 +0100 Subject: [PATCH] created kernel.FindKernel reduces code complexity Signed-off-by: Christian Goll --- internal/app/wwctl/kernel/imprt/main.go | 5 +- .../pkg/api/apiconfig/container/container.go | 3 +- internal/pkg/api/container/container.go | 5 +- internal/pkg/container/kernel.go | 66 ------------------- internal/pkg/kernel/kernel.go | 64 ++++++++++-------- internal/pkg/warewulfd/provision.go | 7 +- 6 files changed, 45 insertions(+), 105 deletions(-) delete mode 100644 internal/pkg/container/kernel.go diff --git a/internal/app/wwctl/kernel/imprt/main.go b/internal/app/wwctl/kernel/imprt/main.go index 2e2cbe41..55fd57f7 100644 --- a/internal/app/wwctl/kernel/imprt/main.go +++ b/internal/app/wwctl/kernel/imprt/main.go @@ -37,10 +37,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error { if len(args) > 0 { kernelVersion = args[0] } else { - kernelVersion, err = kernel.FindKernelVersion(OptRoot) + _, kernelVersion, err = kernel.FindKernel(OptRoot) if err != nil { - wwlog.Error("could not detect kernel under %s", OptRoot) - os.Exit(1) + return err } } kernelName := kernelVersion diff --git a/internal/pkg/api/apiconfig/container/container.go b/internal/pkg/api/apiconfig/container/container.go index 9e440a08..3ca6de12 100644 --- a/internal/pkg/api/apiconfig/container/container.go +++ b/internal/pkg/api/apiconfig/container/container.go @@ -11,6 +11,7 @@ import ( "github.com/pkg/errors" "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/kernel" "github.com/warewulf/warewulf/internal/pkg/node" "github.com/warewulf/warewulf/internal/pkg/util" "github.com/warewulf/warewulf/internal/pkg/warewulfd" @@ -272,7 +273,7 @@ func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) { } wwlog.Debug("Finding kernel version for: %s", source) - kernelVersion := container.KernelVersion(source) + _, kernelVersion, _ := kernel.FindKernel(container.RootFsDir(source)) containerInfo = append(containerInfo, &wwapiv1.ContainerInfo{ Name: source, diff --git a/internal/pkg/api/container/container.go b/internal/pkg/api/container/container.go index e9336038..480bbd57 100644 --- a/internal/pkg/api/container/container.go +++ b/internal/pkg/api/container/container.go @@ -12,6 +12,7 @@ import ( "github.com/pkg/errors" "github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1" "github.com/warewulf/warewulf/internal/pkg/container" + "github.com/warewulf/warewulf/internal/pkg/kernel" "github.com/warewulf/warewulf/internal/pkg/node" "github.com/warewulf/warewulf/internal/pkg/util" "github.com/warewulf/warewulf/internal/pkg/warewulfd" @@ -324,7 +325,7 @@ func ContainerList() (containerInfo []*wwapiv1.ContainerInfo, err error) { } wwlog.Debug("Finding kernel version for: %s", source) - kernelVersion := container.KernelVersion(source) + _, kernelVersion, _ := kernel.FindKernel(container.RootFsDir(source)) var creationTime uint64 sourceStat, err := os.Stat(container.SourceDir(source)) if err != nil { @@ -376,7 +377,7 @@ func ContainerShow(csp *wwapiv1.ContainerShowParameter) (response *wwapiv1.Conta err = fmt.Errorf("%s is not a valid container", containerName) return } - kernelVersion := container.KernelVersion(containerName) + _, kernelVersion, _ := kernel.FindKernel(container.RootFsDir(containerName)) nodeDB, err := node.New() if err != nil { diff --git a/internal/pkg/container/kernel.go b/internal/pkg/container/kernel.go deleted file mode 100644 index 614d5792..00000000 --- a/internal/pkg/container/kernel.go +++ /dev/null @@ -1,66 +0,0 @@ -package container - -import ( - "fmt" - "path" - "path/filepath" - "sort" - "strings" - - "github.com/warewulf/warewulf/internal/pkg/kernel" - "github.com/warewulf/warewulf/internal/pkg/wwlog" -) - -func KernelFind(container string) string { - wwlog.Debug("Finding kernel") - container_path := RootFsDir(container) - if container_path == "" { - return "" - } - - for _, searchPath := range kernel.KernelSearchPaths { - testPath := fmt.Sprintf(path.Join(container_path, searchPath), "*") - wwlog.Debug("Checking for kernel name: %s", testPath) - - kernelPaths, err := filepath.Glob(testPath) - if err != nil { - return "" - } - - if len(kernelPaths) == 0 { - continue - } - - sort.Slice(kernelPaths, func(i, j int) bool { - return kernelPaths[i] > kernelPaths[j] - }) - - for _, kernelPath := range kernelPaths { - wwlog.Debug("Checking for kernel path: %s", kernelPath) - // Only succeeds if kernelPath exists and, if a - // symlink, links to a path that also exists - kernelPath, err = filepath.EvalSymlinks(kernelPath) - if err == nil { - wwlog.Debug("found kernel: %s", kernelPath) - return kernelPath - } - } - } - - return "" -} - -func KernelVersion(container string) string { - wwlog.Debug("Finding kernel version inside container: %s", container) - kernel := KernelFind(container) - if kernel == "" { - return "" - } - - ret := path.Base(path.Dir(kernel)) - if ret == "boot" { - ret = path.Base(kernel) - } - - return strings.TrimPrefix(ret, "vmlinuz-") -} diff --git a/internal/pkg/kernel/kernel.go b/internal/pkg/kernel/kernel.go index 0554a257..40ee7321 100644 --- a/internal/pkg/kernel/kernel.go +++ b/internal/pkg/kernel/kernel.go @@ -8,6 +8,7 @@ import ( "path" "path/filepath" "regexp" + "strings" "github.com/pkg/errors" @@ -17,7 +18,7 @@ import ( ) var ( - KernelSearchPaths = []string{ + kernelSearchPaths = []string{ // This is a printf format where the %s will be the kernel version "/boot/Image-%s", // this is the aarch64 for SUSE, vmlinux which is also present won't boot "/boot/vmlinuz-linux%.s", @@ -26,6 +27,11 @@ var ( "/lib/modules/%s/vmlinuz", "/lib/modules/%s/vmlinuz.gz", } + kernelDrivers = []string{ + "lib/modules/%s/*", + "lib/firmware/*", + "lib/modprobe.d", + "lib/modules-load.d"} ) func KernelImageTopDir() string { @@ -118,15 +124,9 @@ kernel version. A name for this kernel and were to find has also to be supplied */ func Build(kernelVersion, kernelName, root string) error { - kernelDrivers := []string{path.Join("lib/modules/", - kernelVersion, "*"), - "lib/firmware/*", - "lib/modprobe.d", - "lib/modules-load.d"} 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) @@ -144,18 +144,11 @@ func Build(kernelVersion, kernelName, root string) error { return fmt.Errorf("failed to create version dest: %s", err) } - for _, searchPath := range KernelSearchPaths { - testPath := fmt.Sprintf(path.Join(root, searchPath), kernelVersion) - wwlog.Verbose("Looking for kernel at: %s", testPath) - if util.IsFile(testPath) { - kernelSource = testPath - break - } - } - - if kernelSource == "" { - wwlog.Error("Could not locate kernel image") - return errors.New("could not locate kernel image") + kernelSource, kernelVersFound, err := FindKernel(root) + if err != nil { + return err + } else if kernelVersFound != kernelVersion { + return fmt.Errorf("requested %s and found kernel version %s differ", kernelVersion, kernelVersFound) } else { wwlog.Info("Found kernel at: %s", kernelSource) } @@ -194,13 +187,21 @@ func Build(kernelVersion, kernelName, root string) error { } name := kernelName + " drivers" + var kernelDriversSpecific []string + for _, kPath := range kernelDrivers { + if strings.Contains(kPath, "%s") { + kernelDriversSpecific = append(kernelDriversSpecific, fmt.Sprintf(kPath, kernelVersion)) + } else { + kernelDriversSpecific = append(kernelDriversSpecific, kPath) + } + } + wwlog.Debug("kernelDriversSpecific: %v", kernelDriversSpecific) wwlog.Verbose("Creating image for %s: %s", name, root) - err = util.BuildFsImage( name, root, driversDestination, - kernelDrivers, + kernelDriversSpecific, []string{}, // ignore cross-device files true, @@ -236,27 +237,32 @@ func DeleteKernel(name string) error { return os.RemoveAll(fullPath) } -func FindKernelVersion(root string) (string, error) { - for _, searchPath := range KernelSearchPaths { +/* +Searches for kernel under a given path. First return result is the +full path, second the version and an error if the kernel couldn't be found. +*/ +func FindKernel(root string) (kPath string, version string, err error) { + wwlog.Debug("root: %s", root) + for _, searchPath := range kernelSearchPaths { testPattern := fmt.Sprintf(path.Join(root, searchPath), `*`) - wwlog.Verbose("Looking for kernel version with pattern at: %s", testPattern) + wwlog.Debug("Looking for kernel version with pattern at: %s", testPattern) potentialKernel, _ := filepath.Glob(testPattern) if len(potentialKernel) == 0 { continue } for _, foundKernel := range potentialKernel { - wwlog.Verbose("Parsing out kernel version for %s", foundKernel) + wwlog.Debug("Parsing out kernel version for %s", 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") + return foundKernel, "", fmt.Errorf("could not parse kernel version") } - wwlog.Verbose("found kernel version %s", version) - return version[0][1], nil + wwlog.Verbose("found kernel version %s", strings.TrimSuffix(version[0][1], ".gz")) + return foundKernel, strings.TrimSuffix(version[0][1], ".gz"), nil } } - return "", fmt.Errorf("could not find kernel version") + return "", "", fmt.Errorf("could not find kernel version") } diff --git a/internal/pkg/warewulfd/provision.go b/internal/pkg/warewulfd/provision.go index 8fc508f7..035cd95e 100644 --- a/internal/pkg/warewulfd/provision.go +++ b/internal/pkg/warewulfd/provision.go @@ -108,10 +108,9 @@ func ProvisionSend(w http.ResponseWriter, req *http.Request) { if node.Kernel.Override.Defined() { stage_file = kernel.KernelImage(node.Kernel.Override.Get()) } else if node.ContainerName.Defined() { - stage_file = container.KernelFind(node.ContainerName.Get()) - - if stage_file == "" { - wwlog.Error("No kernel found for container %s", node.ContainerName.Get()) + stage_file, _, err = kernel.FindKernel(container.RootFsDir(node.ContainerName.Get())) + if err != nil { + wwlog.Error("No kernel found for container %s: %s", node.ContainerName.Get(), err) } } else { wwlog.Warn("No kernel version set for node %s", node.Id.Get())