diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b848487..b2ce9cf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Set execute permissions for intermediate directories during `wwctl overlay import --parents`. #1655 - Fix log output formatting during overlay build. - Prevent merging of zero-value net.IP fields. #1710 +- Fixed detection of overlay files in `wwctl overlay list --long` ### Removed diff --git a/internal/app/wwctl/completions/completions.go b/internal/app/wwctl/completions/completions.go index 67d48e34..83ba8cfd 100644 --- a/internal/app/wwctl/completions/completions.go +++ b/internal/app/wwctl/completions/completions.go @@ -86,3 +86,24 @@ func Overlays(cmd *cobra.Command, args []string, toComplete string) ([]string, c list := overlay.FindOverlays() return list, cobra.ShellCompDirectiveNoFileComp } + +func OverlayFiles(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + ret, _ := overlay.OverlayGetFiles(args[0]) + return ret, cobra.ShellCompDirectiveNoFileComp +} + +func OverlayAndFiles(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return Overlays(cmd, args, toComplete) + } else { + return OverlayFiles(cmd, args, toComplete) + } +} + +func None(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return nil, cobra.ShellCompDirectiveNoFileComp +} + +func LocalFiles(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return nil, cobra.ShellCompDirectiveDefault +} diff --git a/internal/app/wwctl/overlay/build/root.go b/internal/app/wwctl/overlay/build/root.go index d6bd2098..3b82632c 100644 --- a/internal/app/wwctl/overlay/build/root.go +++ b/internal/app/wwctl/overlay/build/root.go @@ -1,12 +1,10 @@ package build import ( - "log" "runtime" "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/node" - "github.com/warewulf/warewulf/internal/pkg/overlay" + "github.com/warewulf/warewulf/internal/app/wwctl/completions" ) var ( @@ -16,19 +14,7 @@ var ( Short: "(Re)build node overlays", Long: "This command builds overlays for given nodes.", RunE: CobraRunE, - ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if len(args) != 0 { - return nil, cobra.ShellCompDirectiveNoFileComp - } - - nodeDB, _ := node.New() - nodes, _ := nodeDB.FindAllNodes() - var node_names []string - for _, node := range nodes { - node_names = append(node_names, node.Id()) - } - return node_names, cobra.ShellCompDirectiveNoFileComp - }, + ValidArgsFunction: completions.Nodes(0), // no limit } OverlayNames []string OverlayDir string @@ -38,11 +24,8 @@ var ( func init() { baseCmd.PersistentFlags().StringSliceVarP(&OverlayNames, "overlay", "O", []string{}, "Build only specific overlay(s)") - if err := baseCmd.RegisterFlagCompletionFunc("overlay", 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("overlay", completions.Overlays); err != nil { + panic(err) } baseCmd.PersistentFlags().StringVarP(&OverlayDir, "output", "o", "", `Do not create an overlay image for distribution but write to the given directory. An overlay must also be ge given to use this option.`) diff --git a/internal/app/wwctl/overlay/chmod/root.go b/internal/app/wwctl/overlay/chmod/root.go index 1ef9f3ce..2a1060b8 100644 --- a/internal/app/wwctl/overlay/chmod/root.go +++ b/internal/app/wwctl/overlay/chmod/root.go @@ -2,7 +2,7 @@ package chmod import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/overlay" + "github.com/warewulf/warewulf/internal/app/wwctl/completions" ) var ( @@ -15,16 +15,11 @@ var ( RunE: CobraRunE, Args: cobra.ExactArgs(3), ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if len(args) == 0 { - list := overlay.FindOverlays() - return list, cobra.ShellCompDirectiveNoFileComp - } else if len(args) == 1 { - ret, err := overlay.OverlayGetFiles(args[0]) - if err == nil { - return ret, cobra.ShellCompDirectiveNoFileComp - } + if len(args) < 2 { + return completions.OverlayAndFiles(cmd, args, toComplete) + } else { + return completions.None(cmd, args, toComplete) } - return []string{""}, cobra.ShellCompDirectiveNoFileComp }, } ) diff --git a/internal/app/wwctl/overlay/chown/root.go b/internal/app/wwctl/overlay/chown/root.go index 90012490..3801bc0d 100644 --- a/internal/app/wwctl/overlay/chown/root.go +++ b/internal/app/wwctl/overlay/chown/root.go @@ -2,7 +2,7 @@ package chown import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/overlay" + "github.com/warewulf/warewulf/internal/app/wwctl/completions" ) var ( @@ -14,16 +14,11 @@ var ( RunE: CobraRunE, Args: cobra.RangeArgs(3, 4), ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if len(args) == 0 { - list := overlay.FindOverlays() - return list, cobra.ShellCompDirectiveNoFileComp - } else if len(args) == 1 { - ret, err := overlay.OverlayGetFiles(args[0]) - if err == nil { - return ret, cobra.ShellCompDirectiveNoFileComp - } + if len(args) < 2 { + return completions.OverlayAndFiles(cmd, args, toComplete) + } else { + return completions.None(cmd, args, toComplete) } - return []string{""}, cobra.ShellCompDirectiveNoFileComp }, } ) diff --git a/internal/app/wwctl/overlay/create/root.go b/internal/app/wwctl/overlay/create/root.go index 750b33f8..d57b0083 100644 --- a/internal/app/wwctl/overlay/create/root.go +++ b/internal/app/wwctl/overlay/create/root.go @@ -2,6 +2,7 @@ package create import ( "github.com/spf13/cobra" + "github.com/warewulf/warewulf/internal/app/wwctl/completions" ) var ( @@ -13,6 +14,7 @@ var ( Long: "This command creates a new empty overlay with the given OVERLAY_NAME.", RunE: CobraRunE, Args: cobra.ExactArgs(1), + ValidArgsFunction: completions.None, } ) diff --git a/internal/app/wwctl/overlay/delete/root.go b/internal/app/wwctl/overlay/delete/root.go index 811b5560..ae2dbb66 100644 --- a/internal/app/wwctl/overlay/delete/root.go +++ b/internal/app/wwctl/overlay/delete/root.go @@ -2,7 +2,7 @@ package delete import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/overlay" + "github.com/warewulf/warewulf/internal/app/wwctl/completions" ) var ( @@ -15,16 +15,10 @@ var ( Args: cobra.RangeArgs(1, 2), Aliases: []string{"rm", "remove", "del"}, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if len(args) == 0 { - list := overlay.FindOverlays() - return list, cobra.ShellCompDirectiveNoFileComp - } else if len(args) == 1 { - ret, err := overlay.OverlayGetFiles(args[0]) - if err == nil { - return ret, cobra.ShellCompDirectiveNoFileComp - } + if len(args) < 2 { + return completions.OverlayAndFiles(cmd, args, toComplete) } - return []string{""}, cobra.ShellCompDirectiveNoFileComp + return completions.None(cmd, args, toComplete) }, } Force bool diff --git a/internal/app/wwctl/overlay/edit/root.go b/internal/app/wwctl/overlay/edit/root.go index 6151a4a3..ee1bc2de 100644 --- a/internal/app/wwctl/overlay/edit/root.go +++ b/internal/app/wwctl/overlay/edit/root.go @@ -2,7 +2,7 @@ package edit import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/overlay" + "github.com/warewulf/warewulf/internal/app/wwctl/completions" ) var ( @@ -14,16 +14,10 @@ var ( RunE: CobraRunE, Args: cobra.ExactArgs(2), ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if len(args) == 0 { - list := overlay.FindOverlays() - return list, cobra.ShellCompDirectiveNoFileComp - } else if len(args) == 1 { - ret, err := overlay.OverlayGetFiles(args[0]) - if err == nil { - return ret, cobra.ShellCompDirectiveNoFileComp - } + if len(args) < 2 { + return completions.OverlayAndFiles(cmd, args, toComplete) } - return []string{""}, cobra.ShellCompDirectiveNoFileComp + return completions.None(cmd, args, toComplete) }, } CreateDirs bool diff --git a/internal/app/wwctl/overlay/imprt/root.go b/internal/app/wwctl/overlay/imprt/root.go index ed49ed4f..0c1f6b49 100644 --- a/internal/app/wwctl/overlay/imprt/root.go +++ b/internal/app/wwctl/overlay/imprt/root.go @@ -4,7 +4,7 @@ import ( "runtime" "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/overlay" + "github.com/warewulf/warewulf/internal/app/wwctl/completions" ) var ( @@ -17,11 +17,13 @@ var ( Args: cobra.RangeArgs(2, 3), Aliases: []string{"cp"}, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if len(args) != 0 { - return nil, cobra.ShellCompDirectiveNoFileComp + if len(args) == 0 { + return completions.Overlays(cmd, args, toComplete) + } else if len(args) == 1 { + return completions.LocalFiles(cmd, args, toComplete) + } else { + return completions.None(cmd, args, toComplete) } - list := overlay.FindOverlays() - return list, cobra.ShellCompDirectiveNoFileComp }, } NoOverlayUpdate bool diff --git a/internal/app/wwctl/overlay/list/main.go b/internal/app/wwctl/overlay/list/main.go index 06342d87..93f16677 100644 --- a/internal/app/wwctl/overlay/list/main.go +++ b/internal/app/wwctl/overlay/list/main.go @@ -22,7 +22,7 @@ func CobraRunE(cmd *cobra.Command, args []string) error { t := table.New(cmd.OutOrStdout()) if ListLong { - t.AddHeader("PERM MODE", "UID", "GID", "SYSTEM-OVERLAY", "FILE PATH", "SITE") + t.AddHeader("PERM MODE", "UID", "GID", "OVERLAY", "FILE PATH", "SITE") } else { t.AddHeader("OVERLAY NAME", "FILES/DIRS", "SITE") } @@ -40,8 +40,9 @@ func CobraRunE(cmd *cobra.Command, args []string) error { wwlog.Debug("Iterating overlay rootfs: %s", overlay_.Rootfs()) if ListLong { for file := range files { - s, err := os.Stat(files[file]) + s, err := os.Stat(overlay_.File(files[file])) if err != nil { + wwlog.Warn("%s: %s: %s", name, files[file], err) continue } diff --git a/internal/app/wwctl/overlay/list/main_test.go b/internal/app/wwctl/overlay/list/main_test.go index 78ce6b99..3f6a1956 100644 --- a/internal/app/wwctl/overlay/list/main_test.go +++ b/internal/app/wwctl/overlay/list/main_test.go @@ -39,4 +39,15 @@ func Test_Overlay_List(t *testing.T) { assert.NoError(t, err) assert.Contains(t, buf.String(), "email.ww") }) + t.Run("overlay list long", func(t *testing.T) { + baseCmd.SetArgs([]string{"--long"}) + baseCmd := GetCommand() + buf := new(bytes.Buffer) + baseCmd.SetOut(buf) + baseCmd.SetErr(buf) + wwlog.SetLogWriter(buf) + err := baseCmd.Execute() + assert.NoError(t, err) + assert.Contains(t, buf.String(), "email.ww") + }) } diff --git a/internal/app/wwctl/overlay/list/root.go b/internal/app/wwctl/overlay/list/root.go index 8dc976e1..ff8fb903 100644 --- a/internal/app/wwctl/overlay/list/root.go +++ b/internal/app/wwctl/overlay/list/root.go @@ -2,7 +2,7 @@ package list import ( "github.com/spf13/cobra" - "github.com/warewulf/warewulf/internal/pkg/overlay" + "github.com/warewulf/warewulf/internal/app/wwctl/completions" ) var ( @@ -12,15 +12,8 @@ var ( Short: "List Warewulf Overlays and files", Long: "This command displays information about all Warewulf overlays or the specified\nOVERLAY_NAME. It also supports listing overlay content information.", RunE: CobraRunE, - Args: cobra.MinimumNArgs(0), Aliases: []string{"ls"}, - ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if len(args) != 0 { - return nil, cobra.ShellCompDirectiveNoFileComp - } - list := overlay.FindOverlays() - return list, cobra.ShellCompDirectiveNoFileComp - }, + ValidArgsFunction: completions.Overlays, } ListContents bool ListLong bool diff --git a/internal/app/wwctl/overlay/mkdir/root.go b/internal/app/wwctl/overlay/mkdir/root.go index a71723f3..e8d3af5c 100644 --- a/internal/app/wwctl/overlay/mkdir/root.go +++ b/internal/app/wwctl/overlay/mkdir/root.go @@ -2,6 +2,7 @@ package mkdir import ( "github.com/spf13/cobra" + "github.com/warewulf/warewulf/internal/app/wwctl/completions" ) var ( @@ -11,7 +12,14 @@ var ( Short: "Create a new directory within an Overlay", Long: "This command creates a new directory within the Warewulf OVERLAY_NAME.", RunE: CobraRunE, - Args: cobra.MinimumNArgs(2), + Args: cobra.ExactArgs(2), + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return completions.Overlays(cmd, args, toComplete) + } else { + return completions.None(cmd, args, toComplete) + } + }, } PermMode int32 ) diff --git a/internal/app/wwctl/overlay/root.go b/internal/app/wwctl/overlay/root.go index 2734a3c6..cbf6ca67 100644 --- a/internal/app/wwctl/overlay/root.go +++ b/internal/app/wwctl/overlay/root.go @@ -34,7 +34,6 @@ func init() { baseCmd.AddCommand(imprt.GetCommand()) baseCmd.AddCommand(chmod.GetCommand()) baseCmd.AddCommand(chown.GetCommand()) - } // GetRootCommand returns the root cobra.Command for the application. diff --git a/internal/app/wwctl/overlay/show/root.go b/internal/app/wwctl/overlay/show/root.go index b64ef281..0730be6e 100644 --- a/internal/app/wwctl/overlay/show/root.go +++ b/internal/app/wwctl/overlay/show/root.go @@ -4,8 +4,8 @@ import ( "log" "github.com/spf13/cobra" + "github.com/warewulf/warewulf/internal/app/wwctl/completions" "github.com/warewulf/warewulf/internal/pkg/node" - "github.com/warewulf/warewulf/internal/pkg/overlay" ) var ( @@ -18,16 +18,10 @@ var ( Aliases: []string{"cat"}, Args: cobra.ExactArgs(2), ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if len(args) == 0 { - list := overlay.FindOverlays() - return list, cobra.ShellCompDirectiveNoFileComp - } else if len(args) == 1 { - ret, err := overlay.OverlayGetFiles(args[0]) - if err == nil { - return ret, cobra.ShellCompDirectiveNoFileComp - } + if len(args) < 2 { + return completions.OverlayAndFiles(cmd, args, toComplete) } - return []string{""}, cobra.ShellCompDirectiveNoFileComp + return completions.None(cmd, args, toComplete) }, } NodeName string