diff --git a/cmd/incus/completion.go b/cmd/incus/completion.go index 2c9b1ade38f..bbf4bfedbc7 100644 --- a/cmd/incus/completion.go +++ b/cmd/incus/completion.go @@ -54,6 +54,23 @@ func (g *cmdGlobal) cmpInstanceAllKeys() ([]string, cobra.ShellCompDirective) { return keys, cobra.ShellCompDirectiveNoFileComp } +func (g *cmdGlobal) cmpInstanceSnapshots(instanceName string) ([]string, cobra.ShellCompDirective) { + resources, err := g.ParseServers(instanceName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + snapshots, err := client.GetInstanceSnapshotNames(instanceName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + return snapshots, cobra.ShellCompDirectiveNoFileComp +} + func (g *cmdGlobal) cmpInstances(toComplete string) ([]string, cobra.ShellCompDirective) { results := []string{} @@ -200,7 +217,29 @@ func (g *cmdGlobal) cmpNetworkProfiles(networkName string) ([]string, cobra.Shel return results, cobra.ShellCompDirectiveError } -func (g *cmdGlobal) cmpProfiles(toComplete string) ([]string, cobra.ShellCompDirective) { +func (g *cmdGlobal) cmpProfileConfigs(profileName string) ([]string, cobra.ShellCompDirective) { + resources, err := g.ParseServers(profileName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + profile, _, err := client.GetProfile(resource.name) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var configs []string + for c := range profile.Config { + configs = append(configs, c) + } + + return configs, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpProfiles(toComplete string, includeRemotes bool) ([]string, cobra.ShellCompDirective) { results := []string{} resources, _ := g.ParseServers(toComplete) @@ -223,7 +262,7 @@ func (g *cmdGlobal) cmpProfiles(toComplete string) ([]string, cobra.ShellCompDir } } - if !strings.Contains(toComplete, ":") { + if includeRemotes && !strings.Contains(toComplete, ":") { remotes, _ := g.cmpRemotes(false) results = append(results, remotes...) } diff --git a/cmd/incus/network.go b/cmd/incus/network.go index 238325ac47c..b1a2b612e05 100644 --- a/cmd/incus/network.go +++ b/cmd/incus/network.go @@ -240,7 +240,7 @@ func (c *cmdNetworkAttachProfile) Command() *cobra.Command { } if len(args) == 1 { - return c.global.cmpProfiles(args[0]) + return c.global.cmpProfiles(args[0], false) } return nil, cobra.ShellCompDirectiveNoFileComp diff --git a/cmd/incus/profile.go b/cmd/incus/profile.go index e84d3dc409f..70427c91b92 100644 --- a/cmd/incus/profile.go +++ b/cmd/incus/profile.go @@ -106,6 +106,18 @@ func (c *cmdProfileAdd) Command() *cobra.Command { cmd.RunE = c.Run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpInstances(toComplete) + } + + if len(args) == 1 { + return c.global.cmpProfiles(args[0], false) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -178,6 +190,14 @@ incus profile assign foo '' cmd.RunE = c.Run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpInstances(toComplete) + } + + return c.global.cmpProfiles(args[0], false) + } + return cmd } @@ -254,6 +274,18 @@ func (c *cmdProfileCopy) Command() *cobra.Command { cmd.RunE = c.Run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpInstances(toComplete) + } + + if len(args) == 1 { + return c.global.cmpRemotes(false) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -322,6 +354,14 @@ func (c *cmdProfileCreate) Command() *cobra.Command { cmd.RunE = c.Run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpRemotes(false) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -376,6 +416,14 @@ func (c *cmdProfileDelete) Command() *cobra.Command { cmd.RunE = c.Run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpProfiles(toComplete, true) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -429,6 +477,14 @@ func (c *cmdProfileEdit) Command() *cobra.Command { cmd.RunE = c.Run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpProfiles(toComplete, true) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -555,6 +611,19 @@ func (c *cmdProfileGet) Command() *cobra.Command { cmd.RunE = c.Run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Get the key as a profile property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpProfiles(toComplete, true) + } + + if len(args) == 1 { + return c.global.cmpProfileConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -616,6 +685,14 @@ func (c *cmdProfileList) Command() *cobra.Command { cmd.RunE = c.Run cmd.Flags().StringVarP(&c.flagFormat, "format", "f", "table", i18n.G("Format (csv|json|table|yaml|compact)")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpRemotes(false) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -676,6 +753,18 @@ func (c *cmdProfileRemove) Command() *cobra.Command { cmd.RunE = c.Run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpInstances(toComplete) + } + + if len(args) == 1 { + return c.global.cmpProfiles(args[0], false) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -752,6 +841,14 @@ func (c *cmdProfileRename) Command() *cobra.Command { cmd.RunE = c.Run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpProfiles(toComplete, true) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -807,6 +904,19 @@ For backward compatibility, a single configuration key may still be set with: cmd.RunE = c.Run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Set the key as a profile property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpProfiles(toComplete, true) + } + + if len(args) == 1 { + return c.global.cmpInstanceAllKeys() + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -880,6 +990,14 @@ func (c *cmdProfileShow) Command() *cobra.Command { cmd.RunE = c.Run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpProfiles(toComplete, true) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -937,6 +1055,18 @@ func (c *cmdProfileUnset) Command() *cobra.Command { cmd.RunE = c.Run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Unset the key as a profile property")) + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpProfiles(toComplete, true) + } + + if len(args) == 1 { + return c.global.cmpProfileConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd }