porfile add has now all otions of set

This commit is contained in:
Christian Goll
2022-07-14 17:22:49 +02:00
parent 510f6a60a9
commit e6ef30ed53
4 changed files with 156 additions and 46 deletions

View File

@@ -1,28 +1,52 @@
package add
import (
"os"
"fmt"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/wwlog"
apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
apiprofile "github.com/hpcng/warewulf/internal/pkg/api/profile"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/api/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
func CobraRunE(cmd *cobra.Command, args []string) error {
nodeDB, err := node.New()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Failed opening node database: %s\n", err)
os.Exit(1)
func CobraRunE(cmd *cobra.Command, args []string) (err error) {
OptionStrMap, haveNetname := apinode.AddNetname(OptionStrMap)
if !haveNetname {
return errors.New("a netname must be given for any network related configuration")
}
realMap := make(map[string]string)
for key, val := range OptionStrMap {
realMap[key] = *val
}
for _, p := range args {
_, err := nodeDB.AddProfile(p)
set := wwapiv1.NodeSetParameter{
OptionsStrMap: realMap,
NetdevDelete: SetNetDevDel,
AllNodes: SetNodeAll,
Force: SetForce,
NodeNames: args,
}
if !SetYes {
// The checks run twice in the prompt case.
// Avoiding putting in a blocking prompt in an API.
apiprofile.AddProfile(&set, false)
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1)
return
}
_, _, err = apiprofile.ProfileSetParameterCheck(&set, false)
if err != nil {
return
}
yes := util.ConfirmationPrompt(fmt.Sprintf("Are you sure you add the profile %s", args))
if !yes {
return
}
}
return errors.Wrap(nodeDB.Persist(), "failed to persist nodedb")
return apiprofile.ProfileSet(&set)
}

View File

@@ -1,19 +1,65 @@
package add
import "github.com/spf13/cobra"
import (
"log"
"github.com/hpcng/warewulf/internal/pkg/container"
"github.com/hpcng/warewulf/internal/pkg/kernel"
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/overlay"
"github.com/spf13/cobra"
)
var (
baseCmd = &cobra.Command{
DisableFlagsInUseLine: true,
Use: "add PROFILE",
Short: "Add a new node profile",
Long: "This command adds a new named PROFILE.",
RunE: CobraRunE,
Args: cobra.MinimumNArgs(1),
Use: "add PROFILE",
Short: "Add a new node profile",
Long: "This command adds a new named PROFILE.",
RunE: CobraRunE,
Args: cobra.ExactArgs(1),
}
SetNetDevDel string
SetNodeAll bool
SetYes bool
SetForce bool
OptionStrMap map[string]*string
)
// GetRootCommand returns the root cobra.Command for the application.
func GetCommand() *cobra.Command {
// init empty helper structs, so that we know what's inside
myBase := node.CobraCommand{Command: baseCmd}
var emptyNodeConf node.NodeConf
emptyNodeConf.Kernel = new(node.KernelConf)
emptyNodeConf.Ipmi = new(node.IpmiConf)
OptionStrMap = myBase.CreateFlags(emptyNodeConf,
[]string{"ipaddr", "ipaddr6", "ipmiaddr", "profile"})
// register the command line completions
if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := container.ListSources()
return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil {
log.Println(err)
}
if err := baseCmd.RegisterFlagCompletionFunc("kerneloverride", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := kernel.ListKernels()
return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil {
log.Println(err)
}
if err := baseCmd.RegisterFlagCompletionFunc("runtime", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := overlay.FindOverlays()
return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil {
log.Println(err)
}
if err := baseCmd.RegisterFlagCompletionFunc("wwinit", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := overlay.FindOverlays()
return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil {
log.Println(err)
}
return baseCmd
}

View File

@@ -7,7 +7,9 @@ import (
apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
"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/wwlog"
"github.com/pkg/errors"
)
// NodeSet is the wwapiv1 implmentation for updating nodeinfo fields.
@@ -20,7 +22,7 @@ func ProfileSet(set *wwapiv1.NodeSetParameter) (err error) {
var nodeDB node.NodeYaml
nodeDB, _, err = ProfileSetParameterCheck(set, false)
if err != nil {
return
return errors.Wrap(err, "Could not open database")
}
return apinode.DbSave(&nodeDB)
}
@@ -61,7 +63,7 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
// Note: This does not do expansion on the nodes.
if set.AllNodes || (len(set.NodeNames) == 0 && len(profiles) > 0) {
if set.AllNodes || (len(set.NodeNames) == 0) {
if console {
fmt.Printf("\n*** WARNING: This command will modify all profiles! ***\n\n")
}
@@ -75,33 +77,58 @@ func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (node
}
for _, p := range profiles {
wwlog.Printf(wwlog.VERBOSE, "Evaluating profile: %s\n", p.Id.Get())
for key, val := range set.OptionsStrMap {
if val != "" {
wwlog.Verbose("profile:%s setting %s to %s\n", p.Id.Get(), key, val)
p.SetField(key, val)
}
}
if set.NetdevDelete != "" {
if _, ok := p.NetDevs[set.NetdevDelete]; !ok {
err = fmt.Errorf("Network device name doesn't exist: %s", set.NetdevDelete)
wwlog.Error(fmt.Sprintf("%v\n", err.Error()))
return
if util.InSlice(set.NodeNames, p.Id.Get()) {
wwlog.Printf(wwlog.VERBOSE, "Evaluating profile: %s\n", p.Id.Get())
for key, val := range set.OptionsStrMap {
if val != "" {
wwlog.Verbose("profile:%s setting %s to %s\n", p.Id.Get(), key, val)
p.SetField(key, val)
}
}
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Deleting network device: %s\n", p.Id.Get(), set.NetdevDelete)
delete(p.NetDevs, set.NetdevDelete)
}
if set.NetdevDelete != "" {
err := nodeDB.ProfileUpdate(p)
if err != nil {
wwlog.Error("%s\n", err)
os.Exit(1)
}
if _, ok := p.NetDevs[set.NetdevDelete]; !ok {
err = fmt.Errorf("Network device name doesn't exist: %s", set.NetdevDelete)
wwlog.Error(fmt.Sprintf("%v\n", err.Error()))
return
}
profileCount++
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Deleting network device: %s\n", p.Id.Get(), set.NetdevDelete)
delete(p.NetDevs, set.NetdevDelete)
}
err := nodeDB.ProfileUpdate(p)
if err != nil {
wwlog.Error("%s\n", err)
os.Exit(1)
}
profileCount++
}
}
return
}
/*
Adds a new profile with the given name
*/
func AddProfile(set *wwapiv1.NodeSetParameter, console bool) error {
nodeDB, err := node.New()
if err != nil {
return errors.Wrap(err, "Could not open database")
}
if util.InSlice(nodeDB.ListAllProfiles(), set.NodeNames[0]) {
return errors.New(fmt.Sprintf("profile with name %s allready exists", set.NodeNames[0]))
}
_, err = nodeDB.AddProfile(set.NodeNames[0])
if err != nil {
return errors.Wrap(err, "Could not create new profile")
}
err = apinode.DbSave(&nodeDB)
if err != nil {
return errors.Wrap(err, "Could not persist new profile")
}
return nil
}

View File

@@ -312,6 +312,9 @@ func (config *NodeYaml) FindAllNodes() ([]NodeInfo, error) {
return ret, nil
}
/*
Return all profiles as NodeInfo
*/
func (config *NodeYaml) FindAllProfiles() ([]NodeInfo, error) {
var ret []NodeInfo
@@ -429,7 +432,6 @@ func (config *NodeYaml) FindAllProfiles() ([]NodeInfo, error) {
ret = append(ret, p)
}
sort.Slice(ret, func(i, j int) bool {
if ret[i].ClusterName.Get() < ret[j].ClusterName.Get() {
return true
@@ -444,6 +446,17 @@ func (config *NodeYaml) FindAllProfiles() ([]NodeInfo, error) {
return ret, nil
}
/*
Return the names of all available profiles
*/
func (config *NodeYaml) ListAllProfiles() []string {
var ret []string
for name, _ := range config.NodeProfiles {
ret = append(ret, name)
}
return ret
}
func (config *NodeYaml) FindDiscoverableNode() (NodeInfo, string, error) {
var ret NodeInfo