diff --git a/lxc/action.go b/lxc/action.go index b96b2d9919db..33961ed2c216 100644 --- a/lxc/action.go +++ b/lxc/action.go @@ -34,7 +34,7 @@ func (c *cmdStart) command() *cobra.Command { `Start instances`)) cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return c.global.cmpInstances(toComplete) + return c.global.cmpInstancesAction(toComplete, "start", c.action.flagForce) } return cmd @@ -60,7 +60,7 @@ func (c *cmdPause) command() *cobra.Command { cmd.Aliases = []string{"freeze"} cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return c.global.cmpInstances(toComplete) + return c.global.cmpInstancesAction(toComplete, "pause", c.action.flagForce) } return cmd @@ -87,7 +87,7 @@ func (c *cmdRestart) command() *cobra.Command { The opposite of "lxc pause" is "lxc start".`)) cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return c.global.cmpInstances(toComplete) + return c.global.cmpInstancesAction(toComplete, "restart", c.action.flagForce) } return cmd @@ -112,7 +112,7 @@ func (c *cmdStop) command() *cobra.Command { `Stop instances`)) cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return c.global.cmpInstances(toComplete) + return c.global.cmpInstancesAction(toComplete, "stop", c.action.flagForce) } return cmd diff --git a/lxc/completion.go b/lxc/completion.go index f18da5a99217..49b12ccf4683 100644 --- a/lxc/completion.go +++ b/lxc/completion.go @@ -9,6 +9,7 @@ import ( "github.com/canonical/lxd/lxd/instance/instancetype" "github.com/canonical/lxd/shared" + "github.com/canonical/lxd/shared/api" ) func (g *cmdGlobal) cmpClusterGroupNames(toComplete string) ([]string, cobra.ShellCompDirective) { @@ -430,6 +431,66 @@ func (g *cmdGlobal) cmpInstances(toComplete string) ([]string, cobra.ShellCompDi return results, cmpDirectives } +func (g *cmdGlobal) cmpInstancesAction(toComplete string, action string, flagForce bool) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(toComplete) + + var filteredInstanceStatuses []string + + switch action { + case "start": + filteredInstanceStatuses = append(filteredInstanceStatuses, "Stopped", "Frozen") + case "pause", "exec": + filteredInstanceStatuses = append(filteredInstanceStatuses, "Running") + case "stop": + if flagForce { + filteredInstanceStatuses = append(filteredInstanceStatuses, "Running", "Frozen") + } else { + filteredInstanceStatuses = append(filteredInstanceStatuses, "Running") + } + + case "delete": + if flagForce { + filteredInstanceStatuses = append(filteredInstanceStatuses, api.GetAllStatusCodeStrings()...) + } else { + filteredInstanceStatuses = append(filteredInstanceStatuses, "Stopped") + } + + default: + filteredInstanceStatuses = append(filteredInstanceStatuses, api.GetAllStatusCodeStrings()...) + } + + if len(resources) > 0 { + resource := resources[0] + + instances, _ := resource.server.GetInstances("") + + for _, instance := range instances { + var name string + + if shared.ValueInSlice(instance.Status, filteredInstanceStatuses) { + if resource.remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) { + name = instance.Name + } else { + name = fmt.Sprintf("%s:%s", resource.remote, instance.Name) + } + + results = append(results, name) + } + } + + if !strings.Contains(toComplete, ":") { + remotes, directives := g.cmpRemotes(false) + results = append(results, remotes...) + cmpDirectives |= directives + } + } + + return results, cmpDirectives +} + func (g *cmdGlobal) cmpInstancesAndSnapshots(toComplete string) ([]string, cobra.ShellCompDirective) { results := []string{} cmpDirectives := cobra.ShellCompDirectiveNoFileComp diff --git a/lxc/delete.go b/lxc/delete.go index a6d3bbe1808f..3ae4c64a5d62 100644 --- a/lxc/delete.go +++ b/lxc/delete.go @@ -37,7 +37,7 @@ func (c *cmdDelete) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagInteractive, "interactive", "i", false, i18n.G("Require user confirmation")) cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return c.global.cmpInstances(toComplete) + return c.global.cmpInstancesAction(toComplete, "delete", c.flagForce) } return cmd diff --git a/lxc/exec.go b/lxc/exec.go index 771920177a0a..c2f230ed0be3 100644 --- a/lxc/exec.go +++ b/lxc/exec.go @@ -62,7 +62,7 @@ Mode defaults to non-interactive, interactive mode is selected if both stdin AND 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.cmpInstancesAction(toComplete, "exec", false) } return nil, cobra.ShellCompDirectiveNoFileComp diff --git a/shared/api/status_code.go b/shared/api/status_code.go index 1f6bb73b93e9..cc9f83f57607 100644 --- a/shared/api/status_code.go +++ b/shared/api/status_code.go @@ -67,3 +67,13 @@ func StatusCodeFromString(status string) StatusCode { return -1 } + +// GetAllStatusCodeStrings returns a slice of all status code strings. +func GetAllStatusCodeStrings() []string { + var statusStrings []string + for _, code := range StatusCodeNames { + statusStrings = append(statusStrings, code) + } + + return statusStrings +}