cleanup code after review
Signed-off-by: Christian Goll <cgoll@suse.com>
This commit is contained in:
committed by
Jonathon Anderson
parent
4379c4c18d
commit
725176cfed
@@ -133,6 +133,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
the host running warewulf. If node has container it will get these binaries from the
|
||||
container image.
|
||||
|
||||
- Added support for booting nodes with grub. Enable this behavior using
|
||||
warewulf.grubboot: true in warewulf.conf. For unknown nodes, grub.efi
|
||||
and shim.efi are extracted from the Warewulf host. If the booted node
|
||||
has a container these binaries are extracted from the container image.
|
||||
## [4.4.0] 2023-01-18
|
||||
|
||||
### Added
|
||||
|
||||
@@ -24,13 +24,6 @@ func ProfileSet(set *wwapiv1.ProfileSetParameter) (err error) {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Could not open database")
|
||||
}
|
||||
|
||||
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)
|
||||
return dbError
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
)
|
||||
|
||||
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`,
|
||||
`grubia32.efi`,
|
||||
`grubaa64.efi`,
|
||||
`grubarm.efi`,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
find a grub.efi in the used container
|
||||
*/
|
||||
func GrubFind(container string) string {
|
||||
container_path := RootFsDir(container)
|
||||
wwlog.Debug("Finding grub under paths: %s", container_path)
|
||||
if container_path == "" {
|
||||
return ""
|
||||
}
|
||||
return GrubFindPath(container_path)
|
||||
}
|
||||
|
||||
func GrubFindPath(grub_path string) string {
|
||||
for _, grubdir := range grubDirs() {
|
||||
wwlog.Debug("Checking grub directory: %s", grubdir)
|
||||
for _, grubname := range grubNames() {
|
||||
wwlog.Debug("Checking for grub name: %s", grubname)
|
||||
grubPaths, _ := filepath.Glob(path.Join(grub_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
|
||||
if _, err := os.Stat(grubpath); err == nil {
|
||||
return grubpath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
)
|
||||
|
||||
func shimDirs() []string {
|
||||
return []string{
|
||||
`/usr/share/efi/x86_64/`,
|
||||
`/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 in container
|
||||
*/
|
||||
func ShimFind(container string) string {
|
||||
container_path := RootFsDir(container)
|
||||
wwlog.Debug("Finding shim under path: %s", container_path)
|
||||
if container_path == "" {
|
||||
return ""
|
||||
}
|
||||
return ShimFindPath(container_path)
|
||||
}
|
||||
|
||||
/*
|
||||
find the path of the shim binary in container
|
||||
*/
|
||||
func ShimFindPath(shimpath string) string {
|
||||
for _, shimdir := range shimDirs() {
|
||||
wwlog.Debug("Checking shim directory: %s", shimdir)
|
||||
for _, shimname := range shimNames() {
|
||||
wwlog.Debug("Checking for shim name: %s", shimname)
|
||||
shimPaths, _ := filepath.Glob(path.Join(shimpath, 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
|
||||
if _, err := os.Stat(shimPath); err == nil {
|
||||
return shimPath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
94
internal/pkg/container/shimgrub.go
Normal file
94
internal/pkg/container/shimgrub.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package container
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/hpcng/warewulf/internal/pkg/wwlog"
|
||||
)
|
||||
|
||||
func shimDirs() []string {
|
||||
return []string{
|
||||
`/usr/share/efi/x86_64/`,
|
||||
`/usr/lib64/efi/`,
|
||||
`/boot/efi/EFI/*/`,
|
||||
}
|
||||
}
|
||||
func shimNames() []string {
|
||||
return []string{
|
||||
`shim.efi`,
|
||||
`shim-sles.efi`,
|
||||
`shimx64.efi`,
|
||||
`shim-susesigned.efi`,
|
||||
}
|
||||
}
|
||||
|
||||
func grubDirs() []string {
|
||||
return []string{
|
||||
`/usr/lib64/efi/`,
|
||||
`/usr/share/grub2/*-efi/`,
|
||||
`/usr/share/efi/*/`,
|
||||
`/boot/efi/EFI/*/`,
|
||||
}
|
||||
}
|
||||
func grubNames() []string {
|
||||
return []string{
|
||||
`grub-tpm.efi`,
|
||||
`grub.efi`,
|
||||
`grubx64.efi`,
|
||||
`grubia32.efi`,
|
||||
`grubaa64.efi`,
|
||||
`grubarm.efi`,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
find the path of the shim binary in container
|
||||
*/
|
||||
func ShimFind(container string) string {
|
||||
var container_path string
|
||||
if container != "" {
|
||||
container_path = RootFsDir(container)
|
||||
} else {
|
||||
container_path = "/"
|
||||
}
|
||||
wwlog.Debug("Finding grub under paths: %s", container_path)
|
||||
return BootLoaderFindPath(container_path, shimNames, shimDirs)
|
||||
}
|
||||
|
||||
/*
|
||||
find a grub.efi in the used container
|
||||
*/
|
||||
func GrubFind(container string) string {
|
||||
var container_path string
|
||||
if container != "" {
|
||||
container_path = RootFsDir(container)
|
||||
} else {
|
||||
container_path = "/"
|
||||
}
|
||||
wwlog.Debug("Finding grub under paths: %s", container_path)
|
||||
return BootLoaderFindPath(container_path, grubNames, grubDirs)
|
||||
}
|
||||
|
||||
/*
|
||||
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)
|
||||
for _, bname := range names() {
|
||||
wwlog.Debug("Checking for bootloader name: %s", bname)
|
||||
shimPaths, _ := filepath.Glob(path.Join(cpath, bdir, bname))
|
||||
for _, shimPath := range shimPaths {
|
||||
wwlog.Debug("Checking for bootloader path: %s", shimPath)
|
||||
// Only succeeds if shimPath exists and, if a
|
||||
// symlink, links to a path that also exists
|
||||
if _, err := os.Stat(shimPath); err == nil {
|
||||
return shimPath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -34,7 +34,6 @@ type TemplateStruct struct {
|
||||
Tftp warewulfconf.TFTPConf
|
||||
Paths warewulfconf.BuildConfig
|
||||
AllNodes []node.NodeInfo
|
||||
ProfileMap map[string]*node.NodeInfo
|
||||
node.NodeConf
|
||||
// backward compatiblity
|
||||
Container string
|
||||
@@ -56,10 +55,6 @@ func InitStruct(nodeInfo *node.NodeInfo) TemplateStruct {
|
||||
if err != nil {
|
||||
wwlog.Warn("couldn't get all nodes: %s", err)
|
||||
}
|
||||
tstruct.ProfileMap, err = nodeDB.MapAllProfiles()
|
||||
if err != nil {
|
||||
wwlog.Warn("couldn't get all profiles: %s", err)
|
||||
}
|
||||
// init some convenience vars
|
||||
tstruct.Id = nodeInfo.Id.Get()
|
||||
tstruct.Hostname = nodeInfo.Id.Get()
|
||||
|
||||
@@ -20,7 +20,7 @@ to the tftp directory
|
||||
func CopyShimGrub() (err error) {
|
||||
conf := warewulfconf.Get()
|
||||
wwlog.Debug("copy shim and grub binaries from host")
|
||||
shimPath := container.ShimFindPath("/")
|
||||
shimPath := container.ShimFind("")
|
||||
if shimPath == "" {
|
||||
return fmt.Errorf("no shim found on the host os")
|
||||
}
|
||||
@@ -29,7 +29,7 @@ func CopyShimGrub() (err error) {
|
||||
return err
|
||||
}
|
||||
_ = os.Chmod(path.Join(conf.Paths.Tftpdir, "warewulf", "shim.efi"), 0o755)
|
||||
grubPath := container.GrubFindPath("/")
|
||||
grubPath := container.GrubFind("")
|
||||
if grubPath == "" {
|
||||
return fmt.Errorf("no grub found on host os")
|
||||
}
|
||||
|
||||
@@ -16,8 +16,10 @@ import (
|
||||
// TODO: https://github.com/danderson/netboot/blob/master/pixiecore/dhcp.go
|
||||
// TODO: https://github.com/pin/tftp
|
||||
/*
|
||||
wrapper type for the server mux as him requests http://efiboot//grub.efi which is filtered out by http to `301 Moved Permanently` which
|
||||
which shim.fi can't handle. So filter out `//` before they hit http
|
||||
wrapper type for the server mux as shim requests http://efiboot//grub.efi
|
||||
which is filtered out by http to `301 Moved Permanently` what
|
||||
shim.efi can't handle. So filter out `//` before they hit go/http.
|
||||
Makes go/http more to behave like apache
|
||||
*/
|
||||
type slashFix struct {
|
||||
mux http.Handler
|
||||
|
||||
@@ -27,7 +27,13 @@ option architecture-type code 93 = unsigned integer 16;
|
||||
{{- if $.Warewulf.GrubBoot }}
|
||||
if substring (option vendor-class-identifier, 0, 9) = "PXEClient" {
|
||||
next-server {{ $.Ipaddr }};
|
||||
filename "warewulf/shim.efi";
|
||||
if substring (option vendor-class-identifier, 15, 5) = "00000" {
|
||||
# pure BIOS clients will get iPXE configuration
|
||||
filename "http://{{$.Ipaddr}}:{{$.Warewulf.Port}}/ipxe/${mac:hexhyp}";
|
||||
} else {
|
||||
# EFI clients will get shim and grub instead
|
||||
filename "warewulf/shim.efi";
|
||||
}
|
||||
} elsif substring (option vendor-class-identifier, 0, 10) = "HTTPClient" {
|
||||
filename "http://{{$.Ipaddr}}:{{$.Warewulf.Port}}/efiboot/shim.efi";
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
===========
|
||||
Use of Grub
|
||||
===========
|
||||
===============
|
||||
Boot Management
|
||||
===============
|
||||
|
||||
Instead of the iPXE starter a combination of `shim and GRUB <https://www.suse.com/c/uefi-secure-boot-details/>`_
|
||||
can be used with the advantage that secure boot can be used. That means
|
||||
that only the signed kernel of a distribution can be booted. This can
|
||||
be a huge security benefit for some scenarios.
|
||||
|
||||
In order to enable the grub boot method it has to ne enabled in `warewulf.conf`.
|
||||
In order to enable the grub boot method it has to be enabled in `warewulf.conf`.
|
||||
Nodes which are not known to warewulf will then booted with the shim/grub from
|
||||
the host on which warewulf is installed.
|
||||
|
||||
@@ -55,7 +55,7 @@ when a user lands on a compute node, there is generally nothing
|
||||
stopping them from spoofing a provision request and downloading the
|
||||
provisioned raw materials for inspection.
|
||||
|
||||
In Warewulf there are ways to secure the provisioning process:
|
||||
In Warewulf there are ways multiple to secure the provisioning process:
|
||||
|
||||
#. The provisioning connections and transfers are not secure due to
|
||||
not being able to manage a secure root of trust through a PXE
|
||||
|
||||
@@ -18,7 +18,7 @@ Welcome to the Warewulf User Guide!
|
||||
Warewulf Initialization <contents/initialization>
|
||||
Container Management <contents/containers>
|
||||
Kernel Management <contents/kernel>
|
||||
Boot Management <contents/grub>
|
||||
Boot Management <contents/boot-management>
|
||||
Node Configuration <contents/nodeconfig>
|
||||
Node Profiles <contents/profiles>
|
||||
Warewulf Overlays <contents/overlays>
|
||||
|
||||
@@ -139,6 +139,7 @@ yq e '
|
||||
%config(noreplace) %{_sysconfdir}/warewulf/wwapi*.conf
|
||||
%config(noreplace) %{_sysconfdir}/warewulf/examples
|
||||
%config(noreplace) %{_sysconfdir}/warewulf/ipxe
|
||||
%config(noreplace) %{_sysconfdir}/warewulf/grub
|
||||
%config(noreplace) %attr(0640,-,-) %{_sysconfdir}/warewulf/nodes.conf
|
||||
%{_sysconfdir}/bash_completion.d/wwctl
|
||||
|
||||
|
||||
Reference in New Issue
Block a user