diff --git a/fixed-ShimFind-for-aarch64.patch b/fixed-ShimFind-for-aarch64.patch new file mode 100644 index 0000000..a62b886 --- /dev/null +++ b/fixed-ShimFind-for-aarch64.patch @@ -0,0 +1,411 @@ +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()) diff --git a/warewulf4-v4.5.0.tar.gz b/warewulf4-v4.5.0.tar.gz new file mode 100644 index 0000000..b99135e --- /dev/null +++ b/warewulf4-v4.5.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a958ad6e346bad171a806c0212c8a3e3247efedef7b17ffd4bb707fe079f9b3e +size 6461790 diff --git a/warewulf4-v4.5.0~rc2.tar.gz b/warewulf4-v4.5.0~rc2.tar.gz deleted file mode 100644 index 88ca89a..0000000 --- a/warewulf4-v4.5.0~rc2.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:49973066fcfd145019898b26f1d113cafdc7a60a422c33eb601f02181374f672 -size 6446895 diff --git a/warewulf4.changes b/warewulf4.changes index 44dc1f7..d2bc77e 100644 --- a/warewulf4.changes +++ b/warewulf4.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Mon Mar 25 11:34:23 UTC 2024 - Christian Goll + +- updated to 4.5.0 which has no functional changes to rc2 +- added fixed-ShimFind-for-aarch64.patch to fix (bsc#1221133) + ------------------------------------------------------------------- Fri Mar 22 20:23:04 UTC 2024 - Egbert Eich diff --git a/warewulf4.spec b/warewulf4.spec index 2647563..6d61ef8 100644 --- a/warewulf4.spec +++ b/warewulf4.spec @@ -17,7 +17,7 @@ %global vers 4.5.0 -%global rls_cndt rc2 +#%%global rls_cndt rc2 %if "0%{?rls_cndt}" != "0" %global rls_char ~ %endif @@ -34,12 +34,13 @@ Summary: A suite of tools for clustering License: BSD-3-Clause Group: Productivity/Clustering/Computing URL: https://warewulf.org -Source0: https://github.com/warewulf/warewulf/releases/download/v%{vers}%{?rls_cndt}/warewulf-%{vers}%{rls_cndt}.tar.gz#/warewulf4-v%{version}.tar.gz +Source0: https://github.com/warewulf/warewulf/releases/download/v%{vers}%{?rls_cndt}/warewulf-%{vers}%{?rls_cndt}.tar.gz#/warewulf4-v%{version}.tar.gz #Source1: vendor.tar.gz Source5: warewulf4-rpmlintrc Source10: config-ww4.sh Source11: adjust_overlays.sh Source20: README.dnsmasq +Patch01: fixed-ShimFind-for-aarch64.patch # no firewalld in sle12 %if 0%{?sle_version} >= 150000 || 0%{?suse_version} > 1500 @@ -116,7 +117,7 @@ This package install the necessary configuration files in order to run a slurm cluster on the configured warewulf nodes. %prep -%setup -q -n warewulf-%{vers}%{rls_cndt} +%setup -q -n warewulf-%{vers}%{?rls_cndt} %autopatch -p1 # tar xzf %{S:1}