diff --git a/internal/app/wwctl/root.go b/internal/app/wwctl/root.go index cd86b128..d225e7df 100644 --- a/internal/app/wwctl/root.go +++ b/internal/app/wwctl/root.go @@ -15,6 +15,7 @@ import ( "github.com/warewulf/warewulf/internal/app/wwctl/profile" "github.com/warewulf/warewulf/internal/app/wwctl/server" "github.com/warewulf/warewulf/internal/app/wwctl/ssh" + "github.com/warewulf/warewulf/internal/app/wwctl/upgrade" "github.com/warewulf/warewulf/internal/app/wwctl/version" warewulfconf "github.com/warewulf/warewulf/internal/pkg/config" "github.com/warewulf/warewulf/internal/pkg/help" @@ -60,6 +61,7 @@ func init() { rootCmd.AddCommand(ssh.GetCommand()) rootCmd.AddCommand(genconf.GetCommand()) rootCmd.AddCommand(clean.GetCommand()) + rootCmd.AddCommand(upgrade.Command) } // GetRootCommand returns the root cobra.Command for the application. diff --git a/internal/app/wwctl/upgrade/cobra.go b/internal/app/wwctl/upgrade/cobra.go new file mode 100644 index 00000000..22b57d6f --- /dev/null +++ b/internal/app/wwctl/upgrade/cobra.go @@ -0,0 +1,48 @@ +package upgrade + +import ( + "os" + + "github.com/spf13/cobra" + + "github.com/warewulf/warewulf/internal/pkg/node" + libupgrade "github.com/warewulf/warewulf/internal/pkg/upgrade" + "github.com/warewulf/warewulf/internal/pkg/util" +) + +var ( + Command = &cobra.Command{ + DisableFlagsInUseLine: true, + Use: "upgrade [OPTIONS]", + Short: "Upgrade an existing nodes.conf", + Long: `Upgrades nodes.conf from a previous version of Warewulf 4 to a format +supported by the current version.`, + RunE: UpgradeNodesConf, + } + + addDefaults bool + inputPath string + outputPath string +) + +func init() { + Command.Flags().BoolVar(&addDefaults, "add-defaults", false, "Configure a default profile and set default node values") + Command.Flags().StringVarP(&inputPath, "input-path", "i", node.ConfigFile, "Path to a legacy nodes.conf") + Command.Flags().StringVarP(&outputPath, "output-path", "o", node.ConfigFile, "Path to write the upgraded nodes.conf to") +} + +func UpgradeNodesConf(cmd *cobra.Command, args []string) error { + data, err := os.ReadFile(inputPath) + if err != nil { + return err + } + legacy, err := libupgrade.Parse(data) + if err != nil { + return err + } + upgraded := legacy.Upgrade(addDefaults) + if err := util.CopyFile(outputPath, outputPath+"-old"); err != nil { + return err + } + return upgraded.PersistToFile(outputPath) +} diff --git a/internal/pkg/node/constructors.go b/internal/pkg/node/constructors.go index 7e7c6b0c..7e00ed7a 100644 --- a/internal/pkg/node/constructors.go +++ b/internal/pkg/node/constructors.go @@ -18,14 +18,17 @@ var ( ConfigFile string ) -/* -Creates a new nodeDb object from the on-disk configuration -*/ -func New() (NodesYaml, error) { +func init() { conf := warewulfconf.Get() if ConfigFile == "" { ConfigFile = path.Join(conf.Paths.Sysconfdir, "warewulf/nodes.conf") } +} + +/* +Creates a new nodeDb object from the on-disk configuration +*/ +func New() (NodesYaml, error) { wwlog.Verbose("Opening node configuration file: %s", ConfigFile) data, err := os.ReadFile(ConfigFile) if err != nil { diff --git a/internal/pkg/node/modifiers.go b/internal/pkg/node/modifiers.go index be44d520..1bd5e03b 100644 --- a/internal/pkg/node/modifiers.go +++ b/internal/pkg/node/modifiers.go @@ -109,12 +109,19 @@ func (config *NodesYaml) DelProfile(nodeID string) error { Write the the NodeYaml to disk. */ func (config *NodesYaml) Persist() error { + return config.PersistToFile(ConfigFile) +} + +func (config *NodesYaml) PersistToFile(configFile string) error { + if configFile == "" { + configFile = ConfigFile + } out, dumpErr := config.Dump() if dumpErr != nil { wwlog.Error("%s", dumpErr) return dumpErr } - file, err := os.OpenFile(ConfigFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o644) + file, err := os.OpenFile(configFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o644) if err != nil { wwlog.Error("%s", err) return err @@ -124,7 +131,7 @@ func (config *NodesYaml) Persist() error { if err != nil { return err } - wwlog.Debug("persisted: %s", ConfigFile) + wwlog.Debug("persisted: %s", configFile) return nil } diff --git a/internal/pkg/upgrade/node_test.go b/internal/pkg/upgrade/node_test.go index 334199ed..4e1d99dd 100644 --- a/internal/pkg/upgrade/node_test.go +++ b/internal/pkg/upgrade/node_test.go @@ -616,7 +616,8 @@ func Test_UpgradeNodesYaml(t *testing.T) { legacy, err := Parse([]byte(tt.legacyYaml)) assert.NoError(t, err) upgraded := legacy.Upgrade(tt.addDefaults) - upgradedYaml, _ := upgraded.Dump() + upgradedYaml, err := upgraded.Dump() + assert.NoError(t, err) assert.Equal(t, strings.TrimSpace(tt.upgradedYaml), strings.TrimSpace(string(upgradedYaml))) }) }