diff --git a/CHANGELOG.md b/CHANGELOG.md index 08461b73..6335b09f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -127,6 +127,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Update iPXE building script - Send Info, Recv, Send, and Out messages to stdout; and others to stderr +- default is now protected and can't be deleted +- first container imported container is added to the default profile ## [4.4.0] 2023-01-18 ### Added diff --git a/internal/app/wwctl/container/delete/main.go b/internal/app/wwctl/container/delete/main.go index 576ccef7..b30b9c69 100644 --- a/internal/app/wwctl/container/delete/main.go +++ b/internal/app/wwctl/container/delete/main.go @@ -2,10 +2,15 @@ package delete import ( "fmt" + "os" "github.com/hpcng/warewulf/internal/pkg/api/container" "github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1" - "github.com/hpcng/warewulf/internal/pkg/api/util" + apiutil "github.com/hpcng/warewulf/internal/pkg/api/util" + "github.com/hpcng/warewulf/internal/pkg/util" + + "github.com/hpcng/warewulf/internal/pkg/node" + "github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/spf13/cobra" ) @@ -13,8 +18,23 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { cdp := &wwapiv1.ContainerDeleteParameter{ ContainerNames: args, } + nodeDB, err := node.New() + if err != nil { + wwlog.Error("Failed to open node database: %s", err) + os.Exit(1) + } + + profiles, err := nodeDB.MapAllProfiles() + if err != nil { + wwlog.Error("Could not load all profiles: %s", err) + os.Exit(1) + } + + if util.InSlice(args, profiles["default"].ContainerName.Get()) { + return fmt.Errorf("can't delete container which is in the default profile") + } if !SetYes { - yes := util.ConfirmationPrompt(fmt.Sprintf("Are you sure you want to delete container %s", args)) + yes := apiutil.ConfirmationPrompt(fmt.Sprintf("Are you sure you want to delete container %s", args)) if !yes { return } diff --git a/internal/app/wwctl/container/imprt/main.go b/internal/app/wwctl/container/imprt/main.go index 1ec28322..4114b45c 100644 --- a/internal/app/wwctl/container/imprt/main.go +++ b/internal/app/wwctl/container/imprt/main.go @@ -1,7 +1,9 @@ package imprt import ( - "github.com/hpcng/warewulf/internal/pkg/api/container" + "github.com/hpcng/warewulf/internal/pkg/container" + + apicontainer "github.com/hpcng/warewulf/internal/pkg/api/container" "github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1" "github.com/spf13/cobra" ) @@ -13,6 +15,9 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { if len(args) == 2 { name = args[1] } + if list, _ := container.ListSources(); len(list) == 0 { + SetDefault = true + } cip := &wwapiv1.ContainerImportParameter{ Source: args[0], @@ -23,6 +28,7 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) { Default: SetDefault, SyncUser: SyncUser, } - _, err = container.ContainerImport(cip) + + _, err = apicontainer.ContainerImport(cip) return } diff --git a/internal/app/wwctl/profile/delete/main.go b/internal/app/wwctl/profile/delete/main.go index 71d3dabf..137ff4ae 100644 --- a/internal/app/wwctl/profile/delete/main.go +++ b/internal/app/wwctl/profile/delete/main.go @@ -5,6 +5,7 @@ import ( "os" "github.com/hpcng/warewulf/internal/pkg/node" + "github.com/hpcng/warewulf/internal/pkg/util" "github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/manifoldco/promptui" "github.com/pkg/errors" @@ -13,6 +14,9 @@ import ( func CobraRunE(cmd *cobra.Command, args []string) error { var count int + if util.InSlice(args, "default") { + return fmt.Errorf("can't delete the `default` profile ") + } nodeDB, err := node.New() if err != nil { diff --git a/internal/pkg/config/warewulf.go b/internal/pkg/config/warewulf.go index a793e074..e8f08ac5 100644 --- a/internal/pkg/config/warewulf.go +++ b/internal/pkg/config/warewulf.go @@ -10,5 +10,4 @@ type WarewulfConf struct { EnableHostOverlay bool `yaml:"host overlay" default:"true"` Syslog bool `yaml:"syslog" default:"false"` DataStore string `yaml:"datastore" default:"/var/lib/warewulf"` - DefaultBoot string `yaml:"boot method" default:"ipxe"` } diff --git a/internal/pkg/node/constructors.go b/internal/pkg/node/constructors.go index f0e59c1b..eb0baf53 100644 --- a/internal/pkg/node/constructors.go +++ b/internal/pkg/node/constructors.go @@ -307,6 +307,36 @@ func (config *NodeYaml) ListAllProfiles() []string { return ret } +/* +return a map where the key is the profile id +*/ +func (config *NodeYaml) MapAllProfiles() (retMap map[string]*NodeInfo, err error) { + retMap = make(map[string]*NodeInfo) + profileList, err := config.FindAllProfiles() + if err != nil { + return + } + for _, pr := range profileList { + retMap[pr.Id.Get()] = &pr + } + return +} + +/* +return a map where the key is the node id +*/ +func (config *NodeYaml) MapAllNodes() (retMap map[string]*NodeInfo, err error) { + retMap = make(map[string]*NodeInfo) + nodeList, err := config.FindAllNodes() + if err != nil { + return + } + for _, nd := range nodeList { + retMap[nd.Id.Get()] = &nd + } + return +} + /* FindDiscoverableNode returns the first discoverable node and an interface to associate with the discovered interface. If the node has diff --git a/internal/pkg/warewulfd/copyshim.go b/internal/pkg/warewulfd/copyshim.go new file mode 100644 index 00000000..7660fd02 --- /dev/null +++ b/internal/pkg/warewulfd/copyshim.go @@ -0,0 +1,52 @@ +package warewulfd + +import ( + "fmt" + "path" + + warewulfconf "github.com/hpcng/warewulf/internal/pkg/config" + + "github.com/hpcng/warewulf/internal/pkg/container" + "github.com/hpcng/warewulf/internal/pkg/node" + "github.com/hpcng/warewulf/internal/pkg/util" +) + +/* +Copies the default shim, which is the shim located in the default container +to the tftp directory +*/ + +func CopyShimGrub() (err error) { + nodeDB, err := node.New() + if err != nil { + return err + } + conf := warewulfconf.Get() + if err != nil { + return err + } + profiles, err := nodeDB.MapAllProfiles() + if err != nil { + return err + } + if _, ok := profiles["default"]; ok { + return fmt.Errorf("default profile doesn't exist") + } + if profiles["default"].BootMethod.Get() == "ipxe" { + return + } + shimPath := container.ShimFind("default") + if shimPath == "" { + return fmt.Errorf("no shim found in the default profile") + } + err = util.CopyFile(shimPath, path.Join(conf.TFTP.TftpRoot, "shim.efi")) + if err != nil { + return err + } + grubPath := container.GrubFind("default") + if shimPath == "" { + return fmt.Errorf("no grub found in the default profile") + } + err = util.CopyFile(grubPath, path.Join(conf.TFTP.TftpRoot, "grub.efi")) + return +} diff --git a/internal/pkg/warewulfd/warewulfd.go b/internal/pkg/warewulfd/warewulfd.go index 796054b0..ce599aad 100644 --- a/internal/pkg/warewulfd/warewulfd.go +++ b/internal/pkg/warewulfd/warewulfd.go @@ -49,6 +49,11 @@ func RunServer() error { wwlog.Error("Could not prepopulate node status DB: %s", err) } + err = CopyShimGrub() + if err != nil { + wwlog.Warn("couldn't copy default shim: %s", err) + } + http.HandleFunc("/provision/", ProvisionSend) http.HandleFunc("/ipxe/", ProvisionSend) http.HandleFunc("/kernel/", ProvisionSend) diff --git a/overlays/host/etc/dhcp/dhcpd.conf.ww b/overlays/host/etc/dhcp/dhcpd.conf.ww index 794c31e4..2582c03c 100644 --- a/overlays/host/etc/dhcp/dhcpd.conf.ww +++ b/overlays/host/etc/dhcp/dhcpd.conf.ww @@ -20,14 +20,14 @@ option architecture-type code 93 = unsigned integer 16; if exists user-class and option user-class = "iPXE" { filename "http://{{$.Ipaddr}}:{{$.Warewulf.Port}}/ipxe/${mac:hexhyp}"; } else { -{{- if .BoothMethpd == "ipxe" }} +{{- if .BoothMethod == "ipxe" }} {{range $type,$name := $.Tftp.IpxeBinaries }} if option architecture-type = {{ $type }} { filename "/warewulf/{{ basename $name }}"; } {{- end }}{{/* range IpxeBinaries */}} {{ else }} - filename {{ .DefaultShim }} + filename "warewulf/shim.efi" {{- end }}{{/* BootMethod */}} }