File fixed-ShimFind-for-aarch64.patch of Package warewulf4.33124

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 6205991b..00000000
--- a/internal/pkg/container/kernel.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package container
-
-import (
-	"path"
-	"path/filepath"
-	"sort"
-	"strings"
-
-	"github.com/warewulf/warewulf/internal/pkg/wwlog"
-)
-
-var (
-	kernelNames = []string{
-		`vmlinux`,
-		`vmlinuz`,
-		`vmlinux-*`,
-		`vmlinuz-*`,
-		`vmlinuz.gz`}
-
-	kernelDirs = []string{
-		`/lib/modules/*/`,
-		`/boot/`}
-)
-
-func KernelFind(container string) string {
-	wwlog.Debug("Finding kernel")
-	container_path := RootFsDir(container)
-	if container_path == "" {
-		return ""
-	}
-
-	for _, kdir := range kernelDirs {
-		wwlog.Debug("Checking kernel directory: %s", kdir)
-		for _, kname := range kernelNames {
-			wwlog.Debug("Checking for kernel name: %s", kname)
-			kernelPaths, err := filepath.Glob(path.Join(container_path, kdir, kname))
-			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/container/shimgrub.go b/internal/pkg/container/shimgrub.go
index eceee4ba..95a7b590 100644
--- a/internal/pkg/container/shimgrub.go
+++ b/internal/pkg/container/shimgrub.go
@@ -10,7 +10,7 @@ import (
 
 func shimDirs() []string {
 	return []string{
-		`/usr/share/efi/x86_64/`,
+		`/usr/share/efi/*/`,
 		`/usr/lib64/efi/`,
 		`/boot/efi/EFI/*/`,
 	}
@@ -53,7 +53,7 @@ func ShimFind(container string) string {
 	} else {
 		container_path = "/"
 	}
-	wwlog.Debug("Finding grub under paths: %s", container_path)
+	wwlog.Debug("Finding shim under paths: %s", container_path)
 	return BootLoaderFindPath(container_path, shimNames, shimDirs)
 }
 
@@ -76,10 +76,13 @@ find the path of the shim binary in container
 */
 func BootLoaderFindPath(cpath string, names func() []string, paths func() []string) string {
 	for _, bdir := range paths() {
-		wwlog.Debug("Checking shim directory: %s", bdir)
+		wwlog.Debug("Checking directory: %s", bdir)
 		for _, bname := range names() {
-			wwlog.Debug("Checking for bootloader name: %s", bname)
-			shimPaths, _ := filepath.Glob(path.Join(cpath, bdir, bname))
+			wwlog.Debug("Checking for bootloader name: %s", path.Join(cpath, bdir, bname))
+			shimPaths, err := filepath.Glob(path.Join(cpath, bdir, bname))
+			if err != nil {
+				wwlog.Debug("Got error when globing %s: %s", path.Join(cpath, bdir, bname), err)
+			}
 			for _, shimPath := range shimPaths {
 				wwlog.Debug("Checking for bootloader path: %s", shimPath)
 				// Only succeeds if shimPath exists and, if a
diff --git a/internal/pkg/container/shimgrub_test.go b/internal/pkg/container/shimgrub_test.go
new file mode 100644
index 00000000..0ff207f1
--- /dev/null
+++ b/internal/pkg/container/shimgrub_test.go
@@ -0,0 +1,61 @@
+package container
+
+import (
+	"os"
+	"path"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	warewulfconf "github.com/warewulf/warewulf/internal/pkg/config"
+	"github.com/warewulf/warewulf/internal/pkg/testenv"
+	"github.com/warewulf/warewulf/internal/pkg/wwlog"
+)
+
+func Test_Find_ShimX86(t *testing.T) {
+	testenv.New(t)
+	conf := warewulfconf.Get()
+	wwlog.SetLogLevel(wwlog.DEBUG)
+	_ = os.MkdirAll(path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/lib64/efi/"), 0755)
+	shimF, err := os.Create(path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/lib64/efi/shim.efi"))
+	assert.NoError(t, err)
+	_, _ = shimF.WriteString("shim.efi")
+	assert.FileExists(t, path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/lib64/efi/shim.efi"))
+	shimPath := ShimFind("suse")
+	assert.Equal(t, path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/lib64/efi/shim.efi"), shimPath)
+}
+func Test_Find_ShimArch64(t *testing.T) {
+	testenv.New(t)
+	conf := warewulfconf.Get()
+	wwlog.SetLogLevel(wwlog.DEBUG)
+	_ = os.MkdirAll(path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/share/efi/aarch64"), 0755)
+	shimF, err := os.Create(path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/share/efi/aarch64/shim.efi"))
+	assert.NoError(t, err)
+	_, _ = shimF.WriteString("shim.efi")
+	assert.FileExists(t, path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/share/efi/aarch64/shim.efi"))
+	shimPath := ShimFind("suse")
+	assert.Equal(t, path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/share/efi/aarch64/shim.efi"), shimPath)
+}
+func Test_Find_GrubX86(t *testing.T) {
+	testenv.New(t)
+	conf := warewulfconf.Get()
+	wwlog.SetLogLevel(wwlog.DEBUG)
+	_ = os.MkdirAll(path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/share/efi/x86_64"), 0755)
+	shimF, err := os.Create(path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/share/efi/x86_64/grub.efi"))
+	assert.NoError(t, err)
+	_, _ = shimF.WriteString("grub.efi")
+	assert.FileExists(t, path.Join(conf.Paths.WWChrootdir, "suse/rootfs//usr/share/efi/x86_64/grub.efi"))
+	shimPath := GrubFind("suse")
+	assert.Equal(t, path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/share/efi/x86_64/grub.efi"), shimPath)
+}
+func Test_Find_GrubAarch64(t *testing.T) {
+	testenv.New(t)
+	conf := warewulfconf.Get()
+	wwlog.SetLogLevel(wwlog.DEBUG)
+	_ = os.MkdirAll(path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/share/efi/aarch64/"), 0755)
+	shimF, err := os.Create(path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/share/efi/aarch64/grub.efi"))
+	assert.NoError(t, err)
+	_, _ = shimF.WriteString("grub.efi")
+	assert.FileExists(t, path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/share/efi/aarch64/grub.efi"))
+	shimPath := GrubFind("suse")
+	assert.Equal(t, path.Join(conf.Paths.WWChrootdir, "suse/rootfs/usr/share/efi/aarch64/grub.efi"), shimPath)
+}
diff --git a/internal/pkg/kernel/kernel.go b/internal/pkg/kernel/kernel.go
index a40a3296..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"
 
@@ -19,12 +20,18 @@ import (
 var (
 	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",
 		"/boot/vmlinuz-%s",
 		"/boot/vmlinuz-%s.gz",
 		"/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 {
@@ -117,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)
@@ -143,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)
 	}
@@ -193,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,
@@ -235,27 +237,32 @@ func DeleteKernel(name string) error {
 	return os.RemoveAll(fullPath)
 }
 
-func FindKernelVersion(root string) (string, error) {
+/*
+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())
openSUSE Build Service is sponsored by