copy shim/grub on default profile container change

Signed-off-by: Christian Goll <cgoll@suse.com>
This commit is contained in:
Christian Goll
2023-07-20 12:17:46 +02:00
committed by Jonathon Anderson
parent 2fe98e5f55
commit 03ef7447e9
8 changed files with 76 additions and 49 deletions

View File

@@ -271,6 +271,10 @@ func ContainerImport(cip *wwapiv1.ContainerImportParameter) (containerName strin
err = errors.Wrap(err, "failed to update profile")
return
}
err = warewulfd.CopyShimGrub()
if err != nil {
wwlog.Warn("couldn't copy shim/grub of default container: %s", err)
}
}
}
// TODO: We need this in a function with a flock around it.

View File

@@ -8,6 +8,7 @@ import (
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/util"
"github.com/hpcng/warewulf/internal/pkg/warewulfd"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
@@ -24,7 +25,21 @@ func ProfileSet(set *wwapiv1.ProfileSetParameter) (err error) {
if err != nil {
return errors.Wrap(err, "Could not open database")
}
return apinode.DbSave(&nodeDB)
var pConf node.NodeConf
err = yaml.Unmarshal([]byte(set.NodeConfYaml), &pConf)
if err != nil {
wwlog.Error(fmt.Sprintf("%v", err.Error()))
return
}
dbError := apinode.DbSave(&nodeDB)
if util.InSlice(set.ProfileNames, "default") {
err = warewulfd.CopyShimGrub()
if err != nil {
wwlog.Warn("shim/grub couldn't be copied: %s", err)
}
}
return dbError
}
// ProfileSetParameterCheck does error checking on ProfileSetParameter.

View File

@@ -1,9 +1,9 @@
package container
import (
"os"
"path"
"path/filepath"
"sort"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
)
@@ -12,17 +12,19 @@ func grubDirs() []string {
return []string{
`/usr/share/grub2/x86_64-efi`,
`/usr/share/efi/x86_64/`,
`/boot/efi/EFI/*/`,
}
}
func grubNames() []string {
return []string{
`grub-tpm.efi`,
`grub.efi`,
`grubx64.efi`,
}
}
/*
Tries to find a grub.efi in the used container
find a grub.efi in the used container
*/
func GrubFind(container string) string {
wwlog.Debug("Finding grub")
@@ -32,26 +34,15 @@ func GrubFind(container string) string {
}
for _, grubdir := range grubDirs() {
wwlog.Debug("Checking grub directory: %s", grubdir)
for _, shimname := range shimNames() {
wwlog.Debug("Checking for shim name: %s", shimname)
grubPaths, err := filepath.Glob(path.Join(container_path, grubdir, shimname))
if err != nil {
return ""
}
if len(grubPaths) == 0 {
continue
}
sort.Slice(grubPaths, func(i, j int) bool {
return grubPaths[i] > grubPaths[j]
})
for _, grubPath := range grubPaths {
wwlog.Debug("Checking for grub path: %s", grubPath)
// Only succeeds if shimPath exists and, if a
for _, grubname := range grubNames() {
wwlog.Debug("Checking for grub name: %s", grubname)
grubPaths, _ := filepath.Glob(path.Join(container_path, grubdir, grubname))
for _, grubpath := range grubPaths {
wwlog.Debug("Checking for grub path: %s", grubpath)
// Only succeeds if grubpath exists and, if a
// symlink, links to a path that also exists
grubPath, err = filepath.EvalSymlinks(grubPath)
if err == nil {
wwlog.Debug("found grub: %s", grubPath)
return grubPath
if _, err := os.Stat(grubpath); err == nil {
return grubpath
}
}
}

View File

@@ -1,9 +1,9 @@
package container
import (
"os"
"path"
"path/filepath"
"sort"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
)
@@ -11,16 +11,22 @@ import (
func shimDirs() []string {
return []string{
`/usr/share/efi/x86_64/`,
`/usr/lib64/`,
``}
`/usr/lib64/efi`,
`/boot/efi/EFI/*/`,
}
}
func shimNames() []string {
return []string{
`shim.efi`,
`shim-sles.efi`,
`shimx64.efi`,
`shim-susesigned.efi`,
}
}
/*
find the path of the shim binary
*/
func ShimFind(container string) string {
wwlog.Debug("Finding shim")
container_path := RootFsDir(container)
@@ -31,23 +37,12 @@ func ShimFind(container string) string {
wwlog.Debug("Checking shim directory: %s", shimdir)
for _, shimname := range shimNames() {
wwlog.Debug("Checking for shim name: %s", shimname)
shimPaths, err := filepath.Glob(path.Join(container_path, shimdir, shimname))
if err != nil {
return ""
}
if len(shimPaths) == 0 {
continue
}
sort.Slice(shimPaths, func(i, j int) bool {
return shimPaths[i] > shimPaths[j]
})
shimPaths, _ := filepath.Glob(path.Join(container_path, shimdir, shimname))
for _, shimPath := range shimPaths {
wwlog.Debug("Checking for shim path: %s", shimPath)
// Only succeeds if shimPath exists and, if a
// symlink, links to a path that also exists
shimPath, err = filepath.EvalSymlinks(shimPath)
if err == nil {
wwlog.Debug("found shim: %s", shimPath)
if _, err := os.Stat(shimPath); err == nil {
return shimPath
}
}

View File

@@ -31,7 +31,6 @@ defaultnode:
init: /sbin/init
root: initramfs
ipxe template: default
grub template: grub.cfg.ww
boot method: ipxe
profiles:
- default

View File

@@ -20,7 +20,6 @@ type NodeConf struct {
ClusterName string `yaml:"cluster name,omitempty" lopt:"cluster" sopt:"c" comment:"Set cluster group"`
ContainerName string `yaml:"container name,omitempty" lopt:"container" sopt:"C" comment:"Set container name"`
Ipxe string `yaml:"ipxe template,omitempty" lopt:"ipxe" comment:"Set the iPXE template name"`
Grub string `yaml:"grub template,omitempty" lopt:"grub" comment:"Set the grub template name"`
// Deprecated start
// Kernel settings here are deprecated and here for backward compatibility
KernelVersion string `yaml:"kernel version,omitempty"`

View File

@@ -2,9 +2,11 @@ package warewulfd
import (
"fmt"
"os"
"path"
warewulfconf "github.com/hpcng/warewulf/internal/pkg/config"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
"github.com/hpcng/warewulf/internal/pkg/container"
"github.com/hpcng/warewulf/internal/pkg/node"
@@ -17,6 +19,7 @@ to the tftp directory
*/
func CopyShimGrub() (err error) {
wwlog.Debug("copy shim and grub binaries")
nodeDB, err := node.New()
if err != nil {
return err
@@ -29,24 +32,34 @@ func CopyShimGrub() (err error) {
if err != nil {
return err
}
if _, ok := profiles["default"]; ok {
if _, ok := profiles["default"]; !ok {
return fmt.Errorf("default profile doesn't exist")
}
if profiles["default"].BootMethod.Get() == "ipxe" {
// *Entry.Get doesn't work the same as it works for nodes!
if profiles["default"].BootMethod.Get() == "ipxe" || profiles["default"].BootMethod.Get() == "" {
wwlog.Verbose("default profile uses ipxe boot")
return
}
shimPath := container.ShimFind("default")
shimPath := container.ShimFind(profiles["default"].ContainerName.Get())
if shimPath == "" {
return fmt.Errorf("no shim found in the default profile")
return fmt.Errorf("no shim found in the container: %s", profiles["default"].ContainerName.Get())
}
err = util.CopyFile(shimPath, path.Join(conf.TFTP.TftpRoot, "shim.efi"))
err = util.CopyFile(shimPath, path.Join(conf.Paths.Tftpdir, "warewulf", "shim.efi"))
if err != nil {
return err
}
grubPath := container.GrubFind("default")
if shimPath == "" {
return fmt.Errorf("no grub found in the default profile")
_ = os.Chmod(path.Join(conf.Paths.Tftpdir, "warewulf", "shim.efi"), 0o755)
grubPath := container.GrubFind(profiles["default"].ContainerName.Get())
if grubPath == "" {
return fmt.Errorf("no grub found in the container: %s", profiles["default"].ContainerName.Get())
}
err = util.CopyFile(grubPath, path.Join(conf.TFTP.TftpRoot, "grub.efi"))
err = util.CopyFile(grubPath, path.Join(conf.Paths.Tftpdir, "warewulf", "grub.efi"))
if err != nil {
return err
}
_ = os.Chmod(path.Join(conf.Paths.Tftpdir, "warewulf", "grub.efi"), 0o755)
err = util.CopyFile(grubPath, path.Join(conf.Paths.Tftpdir, "warewulf", "grubx64.efi"))
_ = os.Chmod(path.Join(conf.Paths.Tftpdir, "warewulf", "grubx64.efi"), 0o755)
return
}