added profile set over API

This commit is contained in:
Christian Goll
2022-07-13 15:56:04 +02:00
parent f0eb3f8504
commit 14b86a5e8e
7 changed files with 188 additions and 440 deletions

View File

@@ -4,14 +4,14 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/hpcng/warewulf/internal/pkg/api/node" apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
"github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1" "github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/hpcng/warewulf/internal/pkg/api/util" "github.com/hpcng/warewulf/internal/pkg/api/util"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func CobraRunE(cmd *cobra.Command, args []string) (err error) { func CobraRunE(cmd *cobra.Command, args []string) (err error) {
OptionStrMap, haveNetname := node.AddNetname(OptionStrMap) OptionStrMap, haveNetname := apinode.AddNetname(OptionStrMap)
if !haveNetname { if !haveNetname {
return errors.New("a netname must be given for any network related configuration") return errors.New("a netname must be given for any network related configuration")
} }
@@ -33,7 +33,7 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) {
var nodeCount uint var nodeCount uint
// The checks run twice in the prompt case. // The checks run twice in the prompt case.
// Avoiding putting in a blocking prompt in an API. // Avoiding putting in a blocking prompt in an API.
_, nodeCount, err = node.NodeSetParameterCheck(&set, false) _, nodeCount, err = apinode.NodeSetParameterCheck(&set, false)
if err != nil { if err != nil {
return return
} }
@@ -42,5 +42,5 @@ func CobraRunE(cmd *cobra.Command, args []string) (err error) {
return return
} }
} }
return node.NodeSet(&set) return apinode.NodeSet(&set)
} }

View File

@@ -37,17 +37,14 @@ var (
SetYes bool SetYes bool
SetForce bool SetForce bool
OptionStrMap map[string]*string OptionStrMap map[string]*string
KernelStrMap map[string]*string
) )
func init() { func init() {
//var emptyNodeConf node.NodeConf // init empty helper structs, so that we know what's inside
//var emptyKernelE node.KernelEntry
myBase := node.CobraCommand{Command: baseCmd} myBase := node.CobraCommand{Command: baseCmd}
var emptyNodeConf node.NodeConf var emptyNodeConf node.NodeConf
emptyNodeConf.Kernel = new(node.KernelConf) emptyNodeConf.Kernel = new(node.KernelConf)
emptyNodeConf.Ipmi = new(node.IpmiConf) emptyNodeConf.Ipmi = new(node.IpmiConf)
//emptyNodeConf.NetDevs = make(map[string]*node.NetDevs)
OptionStrMap = myBase.CreateFlags(emptyNodeConf) OptionStrMap = myBase.CreateFlags(emptyNodeConf)
baseCmd.PersistentFlags().StringVarP(&SetNetDevDel, "netdel", "D", "", "Delete the node's network device") baseCmd.PersistentFlags().StringVarP(&SetNetDevDel, "netdel", "D", "", "Delete the node's network device")

View File

@@ -2,352 +2,46 @@ package set
import ( import (
"fmt" "fmt"
"os"
"strings"
"github.com/hpcng/warewulf/internal/pkg/node" apinode "github.com/hpcng/warewulf/internal/pkg/api/node"
"github.com/hpcng/warewulf/internal/pkg/warewulfd" apiprofile "github.com/hpcng/warewulf/internal/pkg/api/profile"
"github.com/hpcng/warewulf/internal/pkg/wwlog" "github.com/hpcng/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/manifoldco/promptui" "github.com/hpcng/warewulf/internal/pkg/api/util"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func CobraRunE(cmd *cobra.Command, args []string) error { func CobraRunE(cmd *cobra.Command, args []string) (err error) {
var 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)
nodeDB, err := node.New() for key, val := range OptionStrMap {
if err != nil { realMap[key] = *val
wwlog.Printf(wwlog.ERROR, "Could not open node configuration: %s\n", err)
os.Exit(1)
} }
profiles, err := nodeDB.FindAllProfiles() set := wwapiv1.NodeSetParameter{
if err != nil { OptionsStrMap: realMap,
wwlog.Printf(wwlog.ERROR, "%s\n", err) NetdevDelete: SetNetDevDel,
os.Exit(1) AllNodes: SetNodeAll,
Force: SetForce,
NodeNames: args,
} }
if SetAll { if !SetYes {
fmt.Printf("\n*** WARNING: This command will modify all profiles! ***\n\n") var nodeCount uint
} else if len(args) > 0 { // The checks run twice in the prompt case.
profiles = node.FilterByName(profiles, args) // Avoiding putting in a blocking prompt in an API.
} else { _, nodeCount, err = apiprofile.ProfileSetParameterCheck(&set, false)
wwlog.Printf(wwlog.INFO, "No profile specified, selecting the 'default' profile\n")
profiles = node.FilterByName(profiles, []string{"default"})
}
if len(profiles) == 0 {
fmt.Printf("No profiles found\n")
os.Exit(1)
}
for _, p := range profiles {
wwlog.Printf(wwlog.VERBOSE, "Modifying profile: %s\n", p.Id.Get())
if SetComment != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting comment to: %s\n", p.Id.Get(), SetComment)
p.Comment.Set(SetComment)
}
if SetClusterName != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting cluster name to: %s\n", p.Id.Get(), SetClusterName)
p.ClusterName.Set(SetClusterName)
}
if SetContainer != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Container name to: %s\n", p.Id.Get(), SetContainer)
p.ContainerName.Set(SetContainer)
}
if SetInit != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting init command to: %s\n", p.Id.Get(), SetInit)
p.Init.Set(SetInit)
}
if SetRoot != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting root to: %s\n", p.Id.Get(), SetRoot)
p.Root.Set(SetRoot)
}
if SetAssetKey != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting asset key to: %s\n", p.Id.Get(), SetAssetKey)
p.AssetKey.Set(SetAssetKey)
}
if SetKernelOverride != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Kernel override version to: %s\n", p.Id.Get(), SetKernelOverride)
p.Kernel.Override.Set(SetKernelOverride)
}
if SetKernelArgs != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Kernel args to: %s\n", p.Id.Get(), SetKernelArgs)
p.Kernel.Args.Set(SetKernelArgs)
}
if SetIpxe != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting iPXE template to: %s\n", p.Id.Get(), SetIpxe)
p.Ipxe.Set(SetIpxe)
}
if len(SetRuntimeOverlay) != 0 {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting runtime overlay to: %s\n", p.Id.Get(), SetRuntimeOverlay)
p.RuntimeOverlay.SetSlice(SetRuntimeOverlay)
}
if len(SetSystemOverlay) != 0 {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting system overlay to: %s\n", p.Id.Get(), SetSystemOverlay)
p.SystemOverlay.SetSlice(SetSystemOverlay)
}
if SetIpmiNetmask != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI netmask to: %s\n", p.Id.Get(), SetIpmiNetmask)
p.Ipmi.Netmask.Set(SetIpmiNetmask)
}
if SetIpmiPort != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI port to: %s\n", p.Id.Get(), SetIpmiPort)
p.Ipmi.Port.Set(SetIpmiPort)
}
if SetIpmiGateway != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI gateway to: %s\n", p.Id.Get(), SetIpmiGateway)
p.Ipmi.Gateway.Set(SetIpmiGateway)
}
if SetIpmiUsername != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI username to: %s\n", p.Id.Get(), SetIpmiUsername)
p.Ipmi.UserName.Set(SetIpmiUsername)
}
if SetIpmiPassword != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI password to: %s\n", p.Id.Get(), SetIpmiPassword)
p.Ipmi.Password.Set(SetIpmiPassword)
}
if SetIpmiInterface != "" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting IPMI interface to: %s\n", p.Id.Get(), SetIpmiInterface)
p.Ipmi.Interface.Set(SetIpmiInterface)
}
if SetIpmiWrite == "yes" || SetNetOnBoot == "y" || SetNetOnBoot == "1" || SetNetOnBoot == "true" {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting Ipmiwrite to %s\n", p.Id.Get(), SetIpmiWrite)
p.Ipmi.Write.SetB(true)
} else {
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Setting Ipmiwrite to %s\n", p.Id.Get(), SetIpmiWrite)
p.Ipmi.Write.SetB(false)
}
if SetDiscoverable {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting all nodes to discoverable\n", p.Id.Get())
p.Discoverable.SetB(true)
}
if SetUndiscoverable {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting all nodes to undiscoverable\n", p.Id.Get())
p.Discoverable.SetB(false)
}
if SetNetName != "" {
if _, ok := p.NetDevs[SetNetName]; !ok {
var nd node.NetDevEntry
nd.Tags = make(map[string]*node.Entry)
p.NetDevs[SetNetName] = &nd
}
}
if SetNetDev != "" {
if SetNetName == "" {
wwlog.Printf(wwlog.ERROR, "You must include the '--netname' option\n")
os.Exit(1)
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s:%s, Setting net Device to: %s\n", p.Id.Get(), SetNetName, SetNetDev)
p.NetDevs[SetNetName].Device.Set(SetNetDev)
}
if SetNetmask != "" {
if SetNetName == "" {
wwlog.Printf(wwlog.ERROR, "You must include the '--netname' option\n")
os.Exit(1)
}
wwlog.Printf(wwlog.VERBOSE, "Profile '%s': Setting netmask to: %s\n", p.Id.Get(), SetNetName)
p.NetDevs[SetNetName].Netmask.Set(SetNetmask)
}
if SetGateway != "" {
if SetNetName == "" {
wwlog.Printf(wwlog.ERROR, "You must include the '--netname' option\n")
os.Exit(1)
}
wwlog.Printf(wwlog.VERBOSE, "Profile '%s': Setting gateway to: %s\n", p.Id.Get(), SetNetName)
p.NetDevs[SetNetName].Gateway.Set(SetGateway)
}
if SetType != "" {
if SetNetName == "" {
wwlog.Printf(wwlog.ERROR, "You must include the '--netname' option\n")
os.Exit(1)
}
wwlog.Printf(wwlog.VERBOSE, "Profile '%s': Setting HW address to: %s:%s\n", p.Id.Get(), SetNetName, SetType)
p.NetDevs[SetNetName].Type.Set(SetType)
}
if SetNetOnBoot != "" {
if SetNetName == "" {
wwlog.Printf(wwlog.ERROR, "You must include the '--netname' option\n")
os.Exit(1)
}
if SetNetOnBoot == "yes" || SetNetOnBoot == "y" || SetNetOnBoot == "1" || SetNetOnBoot == "true" {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s:%s, Setting ONBOOT\n", p.Id.Get(), SetNetName)
p.NetDevs[SetNetName].OnBoot.SetB(true)
} else {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s:%s, Unsetting ONBOOT\n", p.Id.Get(), SetNetName)
p.NetDevs[SetNetName].OnBoot.SetB(false)
}
}
if SetNetPrimary != "" {
if SetNetName == "" {
wwlog.Printf(wwlog.ERROR, "You must include the '--netname' option\n")
os.Exit(1)
}
if SetNetPrimary == "yes" || SetNetPrimary == "y" || SetNetPrimary == "1" || SetNetPrimary == "true" {
// Set all other networks to non-default
for _, n := range p.NetDevs {
n.Primary.SetB(false)
}
wwlog.Printf(wwlog.VERBOSE, "Profile: %s:%s, Setting PRIMARY\n", p.Id.Get(), SetNetName)
p.NetDevs[SetNetName].Primary.SetB(true)
} else {
wwlog.Printf(wwlog.VERBOSE, "Profile: %s:%s, Unsetting PRIMARY\n", p.Id.Get(), SetNetName)
p.NetDevs[SetNetName].Primary.SetB(false)
}
}
if SetNetDevDel {
if SetNetName == "" {
wwlog.Printf(wwlog.ERROR, "You must include the '--netname' option\n")
os.Exit(1)
}
if _, ok := p.NetDevs[SetNetName]; !ok {
wwlog.Printf(wwlog.ERROR, "Profile '%s': network name doesn't exist: %s\n", p.Id.Get(), SetNetName)
os.Exit(1)
}
wwlog.Printf(wwlog.VERBOSE, "Profile %s: Deleting network: %s\n", p.Id.Get(), SetNetName)
delete(p.NetDevs, SetNetName)
}
if len(SetTags) > 0 {
for _, t := range SetTags {
keyval := strings.SplitN(t, "=", 2)
key := keyval[0]
val := keyval[1]
if _, ok := p.Tags[key]; !ok {
var nd node.Entry
p.Tags[key] = &nd
}
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Setting Tag '%s'='%s'\n", p.Id.Get(), key, val)
p.Tags[key].Set(val)
}
}
if len(SetDelTags) > 0 {
for _, t := range SetDelTags {
keyval := strings.SplitN(t, "=", 1)
key := keyval[0]
if _, ok := p.Tags[key]; !ok {
wwlog.Printf(wwlog.WARN, "Key does not exist: %s\n", key)
os.Exit(1)
}
wwlog.Printf(wwlog.VERBOSE, "Profile: %s, Deleting tag: %s\n", p.Id.Get(), key)
delete(p.Tags, key)
}
}
if len(SetNetTags) > 0 {
for _, t := range SetNetTags {
keyval := strings.SplitN(t, "=", 2)
key := keyval[0]
val := keyval[1]
if _, ok := p.NetDevs[SetNetName].Tags[key]; !ok {
var nd node.Entry
p.NetDevs[SetNetName].Tags[key] = &nd
}
wwlog.Printf(wwlog.VERBOSE, "Profile: %s:%s, Setting NETTAG '%s'='%s'\n", p.Id.Get(), SetNetName, key, val)
p.NetDevs[SetNetName].Tags[key].Set(val)
}
}
if len(SetNetDelTags) > 0 {
for _, t := range SetNetDelTags {
keyval := strings.SplitN(t, "=", 1)
key := keyval[0]
if _, ok := p.NetDevs[SetNetName].Tags[key]; !ok {
wwlog.Printf(wwlog.WARN, "Profile: %s,%s, Key %s does not exist\n", p.Id.Get(), SetNetName, key)
os.Exit(1)
}
wwlog.Printf(wwlog.VERBOSE, "Profile: %s,%s Deleting NETTAG: %s\n", p.Id.Get(), SetNetName, key)
delete(p.NetDevs[SetNetName].Tags, key)
}
}
err := nodeDB.ProfileUpdate(p)
if err != nil { if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err) return
os.Exit(1) }
yes := util.ConfirmationPrompt(fmt.Sprintf("Are you sure you want to modify %d nodes(s)", nodeCount))
if !yes {
return
} }
} }
return apiprofile.ProfileSet(&set)
if len(profiles) > 0 {
if SetYes {
err := nodeDB.Persist()
if err != nil {
return errors.Wrap(err, "failed to persist nodedb")
}
err = warewulfd.DaemonReload()
if err != nil {
return errors.Wrap(err, "failed to reload warewulf daemon")
}
} else {
q := fmt.Sprintf("Are you sure you want to modify %d profile(s)", len(profiles))
prompt := promptui.Prompt{
Label: q,
IsConfirm: true,
}
result, _ := prompt.Run()
if result == "y" || result == "yes" {
err := nodeDB.Persist()
if err != nil {
return errors.Wrap(err, "failed to persist nodedb")
}
err = warewulfd.DaemonReload()
if err != nil {
return errors.Wrap(err, "failed to reload daemon")
}
}
}
} else {
fmt.Printf("No profiles found\n")
}
return nil
} }

View File

@@ -32,110 +32,51 @@ var (
return p_names, cobra.ShellCompDirectiveNoFileComp return p_names, cobra.ShellCompDirectiveNoFileComp
}, },
} }
SetAll bool SetNetDevDel string
SetYes bool SetNodeAll bool
SetForce bool SetYes bool
SetComment string SetForce bool
SetContainer string OptionStrMap map[string]*string
SetKernelOverride string
SetKernelArgs string
SetClusterName string
SetIpxe string
SetInitOverlay string
SetRuntimeOverlay []string
SetSystemOverlay []string
SetIpmiNetmask string
SetIpmiPort string
SetIpmiGateway string
SetIpmiUsername string
SetIpmiPassword string
SetIpmiInterface string
SetIpmiWrite string
SetNetName string
SetNetDev string
SetNetmask string
SetGateway string
SetType string
SetNetOnBoot string
SetNetPrimary string
SetNetDevDel bool
SetDiscoverable bool
SetUndiscoverable bool
SetInit string
SetRoot string
SetKey string
SetTags []string
SetDelTags []string
SetAssetKey string
SetNetTags []string
SetNetDelTags []string
) )
func init() { func init() {
baseCmd.PersistentFlags().StringVar(&SetComment, "comment", "", "Set a comment for this node") // init empty helper structs, so that we know what's inside
baseCmd.PersistentFlags().StringVarP(&SetContainer, "container", "C", "", "Set the container (VNFS) for this node") myBase := node.CobraCommand{Command: baseCmd}
var emptyNodeConf node.NodeConf
emptyNodeConf.Kernel = new(node.KernelConf)
emptyNodeConf.Ipmi = new(node.IpmiConf)
OptionStrMap = myBase.CreateFlags(emptyNodeConf)
baseCmd.PersistentFlags().StringVarP(&SetNetDevDel, "netdel", "D", "", "Delete the node's network device")
baseCmd.PersistentFlags().BoolVarP(&SetNodeAll, "all", "a", false, "Set all nodes")
baseCmd.PersistentFlags().BoolVarP(&SetYes, "yes", "y", false, "Set 'yes' to all questions asked")
baseCmd.PersistentFlags().BoolVarP(&SetForce, "force", "f", false, "Force configuration (even on error)")
// register the command line completions
if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if err := baseCmd.RegisterFlagCompletionFunc("container", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := container.ListSources() list, _ := container.ListSources()
return list, cobra.ShellCompDirectiveNoFileComp return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil { }); err != nil {
log.Println(err) log.Println(err)
} }
baseCmd.PersistentFlags().StringVarP(&SetKernelOverride, "kerneloverride", "K", "", "Set kernel override version for nodes")
if err := baseCmd.RegisterFlagCompletionFunc("kerneloverride", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if err := baseCmd.RegisterFlagCompletionFunc("kerneloverride", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := kernel.ListKernels() list, _ := kernel.ListKernels()
return list, cobra.ShellCompDirectiveNoFileComp return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil { }); err != nil {
log.Println(err) log.Println(err)
} }
baseCmd.PersistentFlags().StringVarP(&SetKernelArgs, "kernelargs", "A", "", "Set Kernel argument for nodes")
baseCmd.PersistentFlags().StringVarP(&SetClusterName, "cluster", "c", "", "Set the node's cluster group")
baseCmd.PersistentFlags().StringVarP(&SetIpxe, "ipxe", "P", "", "Set the node's iPXE template name")
baseCmd.PersistentFlags().StringVarP(&SetInit, "init", "i", "", "Define the init process to boot the container")
baseCmd.PersistentFlags().StringVar(&SetRoot, "root", "", "Define the rootfs")
baseCmd.PersistentFlags().StringVar(&SetAssetKey, "assetkey", "", "Set the node's Asset tag (key)")
baseCmd.PersistentFlags().StringSliceVarP(&SetRuntimeOverlay, "runtime", "R", []string{}, "Set the node's runtime overlay")
if err := baseCmd.RegisterFlagCompletionFunc("runtime", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if err := baseCmd.RegisterFlagCompletionFunc("runtime", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := overlay.FindOverlays() list, _ := overlay.FindOverlays()
return list, cobra.ShellCompDirectiveNoFileComp return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil { }); err != nil {
log.Println(err) log.Println(err)
} }
baseCmd.PersistentFlags().StringSliceVarP(&SetSystemOverlay, "system", "S", []string{}, "Set the node's system overlay") if err := baseCmd.RegisterFlagCompletionFunc("wwinit", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if err := baseCmd.RegisterFlagCompletionFunc("system", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
list, _ := overlay.FindOverlays() list, _ := overlay.FindOverlays()
return list, cobra.ShellCompDirectiveNoFileComp return list, cobra.ShellCompDirectiveNoFileComp
}); err != nil { }); err != nil {
log.Println(err) log.Println(err)
} }
baseCmd.PersistentFlags().StringVar(&SetIpmiNetmask, "ipminetmask", "", "Set the node's IPMI netmask")
baseCmd.PersistentFlags().StringVar(&SetIpmiPort, "ipmiport", "", "Set the node's IPMI port")
baseCmd.PersistentFlags().StringVar(&SetIpmiGateway, "ipmigateway", "", "Set the node's IPMI gateway")
baseCmd.PersistentFlags().StringVar(&SetIpmiUsername, "ipmiuser", "", "Set the node's IPMI username")
baseCmd.PersistentFlags().StringVar(&SetIpmiPassword, "ipmipass", "", "Set the node's IPMI password")
baseCmd.PersistentFlags().StringVar(&SetIpmiInterface, "ipmiinterface", "", "Set the node's IPMI interface (defaults to 'lan')")
baseCmd.PersistentFlags().StringVar(&SetIpmiWrite, "ipmiwrite", "", "Enable/disable the write of impi configuration (yes/no)")
baseCmd.PersistentFlags().StringVarP(&SetNetName, "netname", "n", "default", "Define the network name to configure")
baseCmd.PersistentFlags().StringVarP(&SetNetDev, "netdev", "N", "", "Set the node's network device")
baseCmd.PersistentFlags().StringVar(&SetNetPrimary, "primary", "", "Enable/disable device as primary (yes/no)")
baseCmd.PersistentFlags().StringVarP(&SetNetmask, "netmask", "M", "", "Set the node's network device netmask")
baseCmd.PersistentFlags().StringVarP(&SetGateway, "gateway", "G", "", "Set the node's network device gateway")
baseCmd.PersistentFlags().StringVarP(&SetType, "type", "T", "", "Set the node's network device type")
baseCmd.PersistentFlags().StringVar(&SetNetOnBoot, "onboot", "", "Enable/disable device (yes/no)")
baseCmd.PersistentFlags().BoolVar(&SetNetDevDel, "netdel", false, "Delete the node's network device")
baseCmd.PersistentFlags().StringSliceVar(&SetNetTags, "nettag", []string{}, "Define custom tag to network device (key=value)")
baseCmd.PersistentFlags().StringSliceVar(&SetNetDelTags, "netdeltag", []string{}, "Delete tag for network device")
baseCmd.PersistentFlags().StringSliceVarP(&SetTags, "tag", "t", []string{}, "Define custom tag (key=value)")
baseCmd.PersistentFlags().StringSliceVar(&SetDelTags, "tagdel", []string{}, "Delete tag")
baseCmd.PersistentFlags().BoolVarP(&SetAll, "all", "a", false, "Set all profiles")
baseCmd.PersistentFlags().BoolVarP(&SetForce, "force", "f", false, "Force configuration (even on error)")
baseCmd.PersistentFlags().BoolVarP(&SetYes, "yes", "y", false, "Set 'yes' to all questions asked")
baseCmd.PersistentFlags().BoolVar(&SetDiscoverable, "discoverable", false, "Make this node discoverable")
baseCmd.PersistentFlags().BoolVar(&SetUndiscoverable, "undiscoverable", false, "Remove the discoverable flag")
} }
// GetRootCommand returns the root cobra.Command for the application. // GetRootCommand returns the root cobra.Command for the application.

View File

@@ -1,4 +1,4 @@
package node package apinode
import ( import (
"encoding/json" "encoding/json"
@@ -477,7 +477,7 @@ func NodeSet(set *wwapiv1.NodeSetParameter) (err error) {
if err != nil { if err != nil {
return return
} }
return nodeDbSave(&nodeDB) return DbSave(&nodeDB)
} }
// NodeSetParameterCheck does error checking on NodeSetParameter. // NodeSetParameterCheck does error checking on NodeSetParameter.
@@ -658,24 +658,6 @@ func checkNetNameRequired(netname string) (err error) {
return return
} }
// nodeDbSave persists the nodeDB to disk and restarts warewulfd.
// TODO: We will likely need locking around anything changing nodeDB
// or restarting warewulfd. Determine if the reason for restart is
// just to reinitialize warewulfd with the new nodeDB or if there is
// something more to it.
func nodeDbSave(nodeDB *node.NodeYaml) (err error) {
err = nodeDB.Persist()
if err != nil {
return errors.Wrap(err, "failed to persist nodedb")
}
err = warewulfd.DaemonReload()
if err != nil {
return errors.Wrap(err, "failed to reload warewulf daemon")
}
return
}
/* /*
Add the netname to the options map, as its only known after the map Add the netname to the options map, as its only known after the map
command line options have been read out. command line options have been read out.

View File

@@ -0,0 +1,25 @@
package apinode
import (
"github.com/hpcng/warewulf/internal/pkg/node"
"github.com/hpcng/warewulf/internal/pkg/warewulfd"
"github.com/pkg/errors"
)
// nodeDbSave persists the nodeDB to disk and restarts warewulfd.
// TODO: We will likely need locking around anything changing nodeDB
// or restarting warewulfd. Determine if the reason for restart is
// just to reinitialize warewulfd with the new nodeDB or if there is
// something more to it.
func DbSave(nodeDB *node.NodeYaml) (err error) {
err = nodeDB.Persist()
if err != nil {
return errors.Wrap(err, "failed to persist nodedb")
}
err = warewulfd.DaemonReload()
if err != nil {
return errors.Wrap(err, "failed to reload warewulf daemon")
}
return
}

View File

@@ -0,0 +1,109 @@
package apiprofile
import (
"fmt"
"os"
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/wwlog"
)
// NodeSet is the wwapiv1 implmentation for updating node fields.
func ProfileSet(set *wwapiv1.NodeSetParameter) (err error) {
if set == nil {
return fmt.Errorf("NodeAddParameter is nil")
}
var nodeDB node.NodeYaml
nodeDB, _, err = ProfileSetParameterCheck(set, false)
if err != nil {
return
}
return apinode.DbSave(&nodeDB)
}
// NodeSetParameterCheck does error checking on NodeSetParameter.
// Output to the console if console is true.
// TODO: Determine if the console switch does wwlog or not.
// - console may end up being textOutput?
func ProfileSetParameterCheck(set *wwapiv1.NodeSetParameter, console bool) (nodeDB node.NodeYaml, profileCount uint, err error) {
if set == nil {
err = fmt.Errorf("Profile set parameter is nil")
if console {
fmt.Printf("%v\n", err)
return
}
}
if set.NodeNames == nil {
err = fmt.Errorf("Profile set parameter: ProfileNames is nil")
if console {
fmt.Printf("%v\n", err)
return
}
}
nodeDB, err = node.New()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not open configuration: %s\n", err)
return
}
profiles, err := nodeDB.FindAllProfiles()
if err != nil {
wwlog.Printf(wwlog.ERROR, "Could not get profile list: %s\n", err)
return
}
// Note: This does not do expansion on the nodes.
if set.AllNodes || (len(set.NodeNames) == 0 && len(profiles) > 0) {
if console {
fmt.Printf("\n*** WARNING: This command will modify all profiles! ***\n\n")
}
} else {
profiles = node.FilterByName(profiles, set.NodeNames)
}
if len(profiles) == 0 {
if console {
fmt.Printf("No profiles found\n")
}
return
}
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.Printf(wwlog.ERROR, fmt.Sprintf("%v\n", err.Error()))
return
}
wwlog.Printf(wwlog.VERBOSE, "Node: %s, Deleting network device: %s\n", p.Id.Get(), set.NetdevDelete)
delete(p.NetDevs, set.NetdevDelete)
}
err := nodeDB.NodeUpdate(p)
if err != nil {
wwlog.Printf(wwlog.ERROR, "%s\n", err)
os.Exit(1)
}
profileCount++
}
return
}