diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c37c9904bf50..26f1b4deee79 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,7 +39,6 @@ Separate commits should be used for: - API structure (`shared/api: Add XYZ` for changes to `shared/api/`) - Go client package (`client: Add XYZ` for changes to `client/`) - CLI (`lxc/: Change XYZ` for changes to `lxc/`) -- Scripts (`scripts: Update bash completion for XYZ` for changes to `scripts/`) - LXD daemon (`lxd/: Add support for XYZ` for changes to `lxd/`) - Tests (`tests: Add test for XYZ` for changes to `tests/`) diff --git a/lxc/action.go b/lxc/action.go index 61eb450f4ba7..b96b2d9919db 100644 --- a/lxc/action.go +++ b/lxc/action.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "os" "strings" @@ -32,6 +33,10 @@ func (c *cmdStart) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G( `Start instances`)) + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return c.global.cmpInstances(toComplete) + } + return cmd } @@ -54,6 +59,10 @@ func (c *cmdPause) command() *cobra.Command { `Pause instances`)) cmd.Aliases = []string{"freeze"} + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return c.global.cmpInstances(toComplete) + } + return cmd } @@ -77,6 +86,10 @@ 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 cmd } @@ -98,6 +111,10 @@ func (c *cmdStop) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G( `Stop instances`)) + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return c.global.cmpInstances(toComplete) + } + return cmd } @@ -144,7 +161,7 @@ func (c *cmdAction) Command(action string) *cobra.Command { func (c *cmdAction) doActionAll(action string, resource remoteResource) error { if resource.name != "" { // both --all and instance name given. - return fmt.Errorf(i18n.G("Both --all and instance name given")) + return errors.New(i18n.G("Both --all and instance name given")) } remote := resource.remote @@ -216,7 +233,7 @@ func (c *cmdAction) doAction(action string, conf *config.Config, nameArg string) } if action == "stop" && c.flagForce && c.flagConsole != "" { - return fmt.Errorf(i18n.G("--console can't be used while forcing instance shutdown")) + return errors.New(i18n.G("--console can't be used while forcing instance shutdown")) } remote, name, err := conf.ParseRemote(nameArg) @@ -321,7 +338,7 @@ func (c *cmdAction) run(cmd *cobra.Command, args []string) error { for _, resource := range resources { // We don't allow instance names with --all. if resource.name != "" { - return fmt.Errorf(i18n.G("Both --all and instance name given")) + return errors.New(i18n.G("Both --all and instance name given")) } // See if we can use the bulk API. @@ -365,11 +382,11 @@ func (c *cmdAction) run(cmd *cobra.Command, args []string) error { if c.flagConsole != "" { if c.flagAll { - return fmt.Errorf(i18n.G("--console can't be used with --all")) + return errors.New(i18n.G("--console can't be used with --all")) } if len(names) != 1 { - return fmt.Errorf(i18n.G("--console only works with a single instance")) + return errors.New(i18n.G("--console only works with a single instance")) } } diff --git a/lxc/cluster.go b/lxc/cluster.go index bd9bd5b8e575..82fb0e280ab7 100644 --- a/lxc/cluster.go +++ b/lxc/cluster.go @@ -126,6 +126,14 @@ func (c *cmdClusterList) 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 } @@ -209,6 +217,14 @@ func (c *cmdClusterShow) 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.cmpClusterMembers(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -258,6 +274,14 @@ func (c *cmdClusterInfo) 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.cmpClusterMembers(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -309,6 +333,18 @@ func (c *cmdClusterGet) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Get the key as a cluster property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpClusterMembers(toComplete) + } + + if len(args) == 1 { + return c.global.cmpClusterMemberConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -370,6 +406,14 @@ func (c *cmdClusterSet) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Set the key as a cluster property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpClusterMembers(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -442,6 +486,18 @@ func (c *cmdClusterUnset) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Unset the key as a cluster property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpClusterMembers(toComplete) + } + + if len(args) == 1 { + return c.global.cmpClusterMemberConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -474,6 +530,14 @@ func (c *cmdClusterRename) 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.cmpClusterMembers(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -526,6 +590,14 @@ func (c *cmdClusterRemove) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagForce, "force", "f", false, i18n.G("Force removing a member, even if degraded")) cmd.Flags().BoolVar(&c.flagNonInteractive, "yes", false, i18n.G("Don't require user confirmation for using --force")) + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpClusterMembers(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -614,6 +686,14 @@ func (c *cmdClusterEnable) 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 } @@ -685,7 +765,7 @@ type cmdClusterEdit struct { func (c *cmdClusterEdit) command() *cobra.Command { cmd := &cobra.Command{} - cmd.Use = usage("edit", i18n.G("[:]")) + cmd.Use = usage("edit", i18n.G("[:]")) cmd.Short = i18n.G("Edit cluster member configurations as YAML") cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G( `Edit cluster member configurations as YAML`)) @@ -695,6 +775,14 @@ func (c *cmdClusterEdit) 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.cmpClusterMembers(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -800,13 +888,21 @@ type cmdClusterAdd struct { func (c *cmdClusterAdd) command() *cobra.Command { cmd := &cobra.Command{} - cmd.Use = usage("add", i18n.G("[[:]]")) + cmd.Use = usage("add", i18n.G("[[:]]")) cmd.Short = i18n.G("Request a join token for adding a cluster member") cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(`Request a join token for adding a cluster member`)) cmd.Flags().StringVar(&c.flagName, "name", "", i18n.G("Cluster member name (alternative to passing it as an argument)")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpClusterMembers(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -883,6 +979,14 @@ func (c *cmdClusterListTokens) 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 } @@ -983,6 +1087,15 @@ func (c *cmdClusterRevokeToken) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), cmd.Short) cmd.RunE = c.run + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpClusterMembers(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1063,6 +1176,23 @@ func (c *cmdClusterUpdateCertificate) command() *cobra.Command { i18n.G("Update cluster certificate with PEM certificate and key read from input files.")) cmd.RunE = c.run + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpClusterMembers(toComplete) + } + + if len(args) == 1 { + return nil, cobra.ShellCompDirectiveDefault + } + + if len(args) == 2 { + return nil, cobra.ShellCompDirectiveDefault + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1171,6 +1301,14 @@ func (c *cmdClusterEvacuate) command() *cobra.Command { cmd.Flags().BoolVar(&c.action.flagForce, "force", false, i18n.G(`Force evacuation without user confirmation`)+"``") cmd.Flags().StringVar(&c.action.flagAction, "action", "", i18n.G(`Force a particular evacuation action`)+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpClusterMembers(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1192,6 +1330,14 @@ func (c *cmdClusterRestore) command() *cobra.Command { cmd.Flags().BoolVar(&c.action.flagForce, "force", false, i18n.G(`Force restoration without user confirmation`)+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpClusterMembers(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } diff --git a/lxc/cluster_group.go b/lxc/cluster_group.go index 5446eec88d91..291a73c7128b 100644 --- a/lxc/cluster_group.go +++ b/lxc/cluster_group.go @@ -93,6 +93,18 @@ lxc cluster group assign foo default cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpClusterMembers(toComplete) + } + + if len(args) == 1 { + return c.global.cmpClusterGroupNames(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -165,6 +177,14 @@ lxc cluster group create g1 < config.yaml 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 } @@ -238,6 +258,14 @@ func (c *cmdClusterGroupDelete) 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.cmpClusterGroups(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -290,6 +318,14 @@ func (c *cmdClusterGroupEdit) 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.cmpClusterGroups(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -407,6 +443,14 @@ func (c *cmdClusterGroupList) 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 } @@ -480,6 +524,18 @@ func (c *cmdClusterGroupRemove) 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.cmpClusterMembers(toComplete) + } + + if len(args) == 1 { + return c.global.cmpClusterGroupNames(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -553,6 +609,14 @@ func (c *cmdClusterGroupRename) 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.cmpClusterGroups(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -601,6 +665,14 @@ func (c *cmdClusterGroupShow) 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.cmpClusterGroups(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -655,6 +727,18 @@ func (c *cmdClusterGroupAdd) 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.cmpClusterMembers(toComplete) + } + + if len(args) == 1 { + return c.global.cmpClusterGroupNames(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } diff --git a/lxc/cluster_role.go b/lxc/cluster_role.go index 499f96a0dc87..911bd9a4e716 100644 --- a/lxc/cluster_role.go +++ b/lxc/cluster_role.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "github.com/spf13/cobra" @@ -52,6 +53,14 @@ func (c *cmdClusterRoleAdd) 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.cmpClusterMembers(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -70,7 +79,7 @@ func (c *cmdClusterRoleAdd) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Missing cluster member name")) + return errors.New(i18n.G("Missing cluster member name")) } // Extract the current value @@ -108,6 +117,18 @@ func (c *cmdClusterRoleRemove) 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.cmpClusterMembers(toComplete) + } + + if len(args) == 1 { + return c.global.cmpClusterMemberRoles(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -126,7 +147,7 @@ func (c *cmdClusterRoleRemove) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Missing cluster member name")) + return errors.New(i18n.G("Missing cluster member name")) } // Extract the current value diff --git a/lxc/completion.go b/lxc/completion.go new file mode 100644 index 000000000000..631a031654dc --- /dev/null +++ b/lxc/completion.go @@ -0,0 +1,1168 @@ +package main + +import ( + "fmt" + "regexp" + "strings" + + "github.com/spf13/cobra" + + "github.com/canonical/lxd/lxd/instance/instancetype" + "github.com/canonical/lxd/shared" +) + +func (g *cmdGlobal) cmpClusterGroupNames(toComplete string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(toComplete) + + if len(resources) <= 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + + cluster, _, err := resource.server.GetCluster() + if err != nil || !cluster.Enabled { + return nil, cobra.ShellCompDirectiveError + } + + results, err = resource.server.GetClusterGroupNames() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + return results, cmpDirectives +} + +func (g *cmdGlobal) cmpClusterGroups(toComplete string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(toComplete) + + if len(resources) <= 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + + cluster, _, err := resource.server.GetCluster() + if err != nil || !cluster.Enabled { + return nil, cobra.ShellCompDirectiveError + } + + groups, err := resource.server.GetClusterGroupNames() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for _, group := range groups { + var name string + + if resource.remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) { + name = group + } else { + name = fmt.Sprintf("%s:%s", resource.remote, group) + } + + 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) cmpClusterMemberConfigs(memberName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(memberName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + cluster, _, err := client.GetCluster() + if err != nil || !cluster.Enabled { + return nil, cobra.ShellCompDirectiveError + } + + member, _, err := client.GetClusterMember(memberName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var results []string + for k := range member.Config { + results = append(results, k) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpClusterMemberRoles(memberName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(memberName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + cluster, _, err := client.GetCluster() + if err != nil || !cluster.Enabled { + return nil, cobra.ShellCompDirectiveError + } + + member, _, err := client.GetClusterMember(memberName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + return member.Roles, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpClusterMembers(toComplete string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(toComplete) + + if len(resources) > 0 { + resource := resources[0] + + cluster, _, err := resource.server.GetCluster() + if err != nil || !cluster.Enabled { + return nil, cobra.ShellCompDirectiveError + } + + // Get the cluster members + members, err := resource.server.GetClusterMembers() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for _, member := range members { + var name string + + if resource.remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) { + name = member.ServerName + } else { + name = fmt.Sprintf("%s:%s", resource.remote, member.ServerName) + } + + 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) cmpImages(toComplete string) ([]string, cobra.ShellCompDirective) { + var results []string + var remote string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + if strings.Contains(toComplete, ":") { + remote = strings.Split(toComplete, ":")[0] + } else { + remote = g.conf.DefaultRemote + } + + remoteServer, _ := g.conf.GetImageServer(remote) + + images, _ := remoteServer.GetImages() + + for _, image := range images { + for _, alias := range image.Aliases { + var name string + + if remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) { + name = alias.Name + } else { + name = fmt.Sprintf("%s:%s", remote, alias.Name) + } + + results = append(results, name) + } + } + + if !strings.Contains(toComplete, ":") { + remotes, directives := g.cmpRemotes(true) + results = append(results, remotes...) + cmpDirectives |= directives + } + + return results, cmpDirectives +} + +func (g *cmdGlobal) cmpInstanceAllKeys() ([]string, cobra.ShellCompDirective) { + keys := []string{} + for k := range instancetype.InstanceConfigKeysAny { + keys = append(keys, k) + } + + return keys, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpInstanceConfigTemplates(instanceName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(instanceName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + var instanceNameOnly = instanceName + if strings.Contains(instanceName, ":") { + instanceNameOnly = strings.Split(instanceName, ":")[1] + } + + results, err := client.GetInstanceTemplateFiles(instanceNameOnly) + if err != nil { + cobra.CompDebug(fmt.Sprintf("%v", err), true) + return nil, cobra.ShellCompDirectiveError + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpInstanceDeviceNames(instanceName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(instanceName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + instanceNameOnly, _, err := client.GetInstance(instanceName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var results []string + for k := range instanceNameOnly.Devices { + results = append(results, k) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpInstances(toComplete string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(toComplete) + + if len(resources) > 0 { + resource := resources[0] + + instances, _ := resource.server.GetInstanceNames("") + + for _, instance := range instances { + var name string + + if resource.remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) { + name = instance + } else { + name = fmt.Sprintf("%s:%s", resource.remote, instance) + } + + 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 + + resources, _ := g.ParseServers(toComplete) + + if len(resources) > 0 { + resource := resources[0] + + if strings.Contains(resource.name, shared.SnapshotDelimiter) { + instName := strings.SplitN(resource.name, shared.SnapshotDelimiter, 2)[0] + snapshots, _ := resource.server.GetInstanceSnapshotNames(instName) + for _, snapshot := range snapshots { + results = append(results, fmt.Sprintf("%s/%s", instName, snapshot)) + } + } else { + instances, _ := resource.server.GetInstanceNames("") + for _, instance := range instances { + var name string + + if resource.remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) { + name = instance + } else { + name = fmt.Sprintf("%s:%s", resource.remote, instance) + } + + 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) cmpInstanceNamesFromRemote(toComplete string) ([]string, cobra.ShellCompDirective) { + var results []string + + resources, _ := g.ParseServers(toComplete) + + if len(resources) > 0 { + resource := resources[0] + + containers, _ := resource.server.GetInstanceNames("container") + results = append(results, containers...) + vms, _ := resource.server.GetInstanceNames("virtual-machine") + results = append(results, vms...) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpNetworkACLConfigs(aclName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(aclName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + acl, _, err := client.GetNetworkACL(resource.name) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var results []string + for k := range acl.Config { + results = append(results, k) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpNetworkACLs(toComplete string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(toComplete) + + if len(resources) <= 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + + acls, err := resource.server.GetNetworkACLNames() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for _, acl := range acls { + var name string + + if resource.remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) { + name = acl + } else { + name = fmt.Sprintf("%s:%s", resource.remote, acl) + } + + 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) cmpNetworkACLRuleProperties() ([]string, cobra.ShellCompDirective) { + var results []string + + allowedKeys := networkACLRuleJSONStructFieldMap() + for key := range allowedKeys { + results = append(results, fmt.Sprintf("%s=", key)) + } + + return results, cobra.ShellCompDirectiveNoSpace +} + +func (g *cmdGlobal) cmpNetworkForwardConfigs(networkName string, listenAddress string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(networkName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + forward, _, err := client.GetNetworkForward(networkName, listenAddress) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var results []string + for k := range forward.Config { + results = append(results, k) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpNetworkForwards(networkName string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(networkName) + + if len(resources) <= 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + + results, err := resource.server.GetNetworkForwardAddresses(networkName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + return results, cmpDirectives +} + +func (g *cmdGlobal) cmpNetworkLoadBalancers(networkName string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(networkName) + + if len(resources) <= 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + + results, err := resource.server.GetNetworkForwardAddresses(networkName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + return results, cmpDirectives +} + +func (g *cmdGlobal) cmpNetworkPeerConfigs(networkName string, peerName string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(networkName) + + if len(resources) <= 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + + peer, _, err := resource.server.GetNetworkPeer(resource.name, peerName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for k := range peer.Config { + results = append(results, k) + } + + return results, cmpDirectives +} + +func (g *cmdGlobal) cmpNetworkPeers(networkName string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(networkName) + + if len(resources) <= 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + + results, err := resource.server.GetNetworkPeerNames(networkName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + return results, cmpDirectives +} + +func (g *cmdGlobal) cmpNetworks(toComplete string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(toComplete) + + if len(resources) > 0 { + resource := resources[0] + + networks, err := resource.server.GetNetworkNames() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for _, network := range networks { + var name string + + if resource.remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) { + name = network + } else { + name = fmt.Sprintf("%s:%s", resource.remote, network) + } + + 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) cmpNetworkConfigs(networkName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(networkName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + network, _, err := client.GetNetwork(networkName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var results []string + for k := range network.Config { + results = append(results, k) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpNetworkInstances(networkName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(networkName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + network, _, err := client.GetNetwork(networkName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var results []string + for _, i := range network.UsedBy { + r := regexp.MustCompile(`/1.0/instances/(.*)`) + match := r.FindStringSubmatch(i) + + if len(match) == 2 { + results = append(results, match[1]) + } + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpNetworkProfiles(networkName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(networkName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + network, _, err := client.GetNetwork(networkName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var results []string + for _, i := range network.UsedBy { + r := regexp.MustCompile(`/1.0/profiles/(.*)`) + match := r.FindStringSubmatch(i) + + if len(match) == 2 { + results = append(results, match[1]) + } + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpNetworkZoneConfigs(zoneName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(zoneName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + zone, _, err := client.GetNetworkZone(zoneName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var results []string + for k := range zone.Config { + results = append(results, k) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpNetworkZoneRecordConfigs(zoneName string, recordName string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(zoneName) + + if len(resources) <= 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + + peer, _, err := resource.server.GetNetworkZoneRecord(resource.name, recordName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for k := range peer.Config { + results = append(results, k) + } + + return results, cmpDirectives +} + +func (g *cmdGlobal) cmpNetworkZoneRecords(zoneName string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(zoneName) + + if len(resources) <= 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + + results, err := resource.server.GetNetworkZoneRecordNames(zoneName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + return results, cmpDirectives +} + +func (g *cmdGlobal) cmpNetworkZones(toComplete string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(toComplete) + + if len(resources) > 0 { + resource := resources[0] + + zones, err := resource.server.GetNetworkZoneNames() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for _, project := range zones { + var name string + + if resource.remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) { + name = project + } else { + name = fmt.Sprintf("%s:%s", resource.remote, project) + } + + 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) 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) cmpProfileDeviceNames(instanceName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(instanceName) + 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 results []string + for k := range profile.Devices { + results = append(results, k) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpProfileNamesFromRemote(toComplete string) ([]string, cobra.ShellCompDirective) { + var results []string + + resources, _ := g.ParseServers(toComplete) + + if len(resources) > 0 { + resource := resources[0] + + profiles, _ := resource.server.GetProfileNames() + results = append(results, profiles...) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpProfiles(toComplete string, includeRemotes bool) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(toComplete) + + if len(resources) > 0 { + resource := resources[0] + + profiles, _ := resource.server.GetProfileNames() + + for _, profile := range profiles { + var name string + + if resource.remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) { + name = profile + } else { + name = fmt.Sprintf("%s:%s", resource.remote, profile) + } + + results = append(results, name) + } + } + + if includeRemotes && !strings.Contains(toComplete, ":") { + remotes, directives := g.cmpRemotes(false) + results = append(results, remotes...) + cmpDirectives |= directives + } + + return results, cmpDirectives +} + +func (g *cmdGlobal) cmpProjectConfigs(projectName string) ([]string, cobra.ShellCompDirective) { + resources, err := g.ParseServers(projectName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + project, _, err := client.GetProject(resource.name) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var configs []string + for c := range project.Config { + configs = append(configs, c) + } + + return configs, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpProjects(toComplete string) ([]string, cobra.ShellCompDirective) { + var results []string + cmpDirectives := cobra.ShellCompDirectiveNoFileComp + + resources, _ := g.ParseServers(toComplete) + + if len(resources) > 0 { + resource := resources[0] + + projects, err := resource.server.GetProjectNames() + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + for _, project := range projects { + var name string + + if resource.remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) { + name = project + } else { + name = fmt.Sprintf("%s:%s", resource.remote, project) + } + + 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) cmpRemotes(includeAll bool) ([]string, cobra.ShellCompDirective) { + var results []string + + for remoteName, rc := range g.conf.Remotes { + if !includeAll && rc.Protocol != "lxd" && rc.Protocol != "" { + continue + } + + results = append(results, fmt.Sprintf("%s:", remoteName)) + } + + return results, cobra.ShellCompDirectiveNoSpace +} + +func (g *cmdGlobal) cmpRemoteNames() ([]string, cobra.ShellCompDirective) { + var results []string + + for remoteName := range g.conf.Remotes { + results = append(results, remoteName) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpStoragePoolConfigs(poolName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(poolName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + if strings.Contains(poolName, ":") { + poolName = strings.Split(poolName, ":")[1] + } + + pool, _, err := client.GetStoragePool(poolName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var results []string + for k := range pool.Config { + results = append(results, k) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpStoragePoolWithVolume(toComplete string) ([]string, cobra.ShellCompDirective) { + if !strings.Contains(toComplete, "/") { + pools, compdir := g.cmpStoragePools(toComplete) + if compdir == cobra.ShellCompDirectiveError { + return nil, compdir + } + + var results []string + for _, pool := range pools { + if strings.HasSuffix(pool, ":") { + results = append(results, pool) + } else { + results = append(results, fmt.Sprintf("%s/", pool)) + } + } + + return results, cobra.ShellCompDirectiveNoSpace + } + + pool := strings.Split(toComplete, "/")[0] + volumes, compdir := g.cmpStoragePoolVolumes(pool) + if compdir == cobra.ShellCompDirectiveError { + return nil, compdir + } + + var results []string + for _, volume := range volumes { + results = append(results, fmt.Sprintf("%s/%s", pool, volume)) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpStoragePools(toComplete string) ([]string, cobra.ShellCompDirective) { + var results []string + + resources, _ := g.ParseServers(toComplete) + + if len(resources) > 0 { + resource := resources[0] + + storagePools, _ := resource.server.GetStoragePoolNames() + + for _, storage := range storagePools { + var name string + + if resource.remote == g.conf.DefaultRemote && !strings.Contains(toComplete, g.conf.DefaultRemote) { + name = storage + } else { + name = fmt.Sprintf("%s:%s", resource.remote, storage) + } + + results = append(results, name) + } + } + + if !strings.Contains(toComplete, ":") { + remotes, _ := g.cmpRemotes(false) + results = append(results, remotes...) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpStoragePoolVolumeConfigs(poolName string, volumeName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(poolName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + var pool = poolName + if strings.Contains(poolName, ":") { + pool = strings.Split(poolName, ":")[1] + } + + volName, volType := parseVolume("custom", volumeName) + + volume, _, err := client.GetStoragePoolVolume(pool, volType, volName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var results []string + for k := range volume.Config { + results = append(results, k) + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpStoragePoolVolumeInstances(poolName string, volumeName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(poolName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + var pool = poolName + if strings.Contains(poolName, ":") { + pool = strings.Split(poolName, ":")[1] + } + + volName, volType := parseVolume("custom", volumeName) + + volume, _, err := client.GetStoragePoolVolume(pool, volType, volName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var results []string + for _, i := range volume.UsedBy { + r := regexp.MustCompile(`/1.0/instances/(.*)`) + match := r.FindStringSubmatch(i) + + if len(match) == 2 { + results = append(results, match[1]) + } + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpStoragePoolVolumeProfiles(poolName string, volumeName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(poolName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + var pool = poolName + if strings.Contains(poolName, ":") { + pool = strings.Split(poolName, ":")[1] + } + + volName, volType := parseVolume("custom", volumeName) + + volume, _, err := client.GetStoragePoolVolume(pool, volType, volName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var results []string + for _, i := range volume.UsedBy { + r := regexp.MustCompile(`/1.0/profiles/(.*)`) + match := r.FindStringSubmatch(i) + + if len(match) == 2 { + results = append(results, match[1]) + } + } + + return results, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpStoragePoolVolumeSnapshots(poolName string, volumeName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(poolName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + var pool = poolName + if strings.Contains(poolName, ":") { + pool = strings.Split(poolName, ":")[1] + } + + volName, volType := parseVolume("custom", volumeName) + + snapshots, err := client.GetStoragePoolVolumeSnapshotNames(pool, volType, volName) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + return snapshots, cobra.ShellCompDirectiveNoFileComp +} + +func (g *cmdGlobal) cmpStoragePoolVolumes(poolName string) ([]string, cobra.ShellCompDirective) { + // Parse remote + resources, err := g.ParseServers(poolName) + if err != nil || len(resources) == 0 { + return nil, cobra.ShellCompDirectiveError + } + + resource := resources[0] + client := resource.server + + var pool = poolName + if strings.Contains(poolName, ":") { + pool = strings.Split(poolName, ":")[1] + } + + volumes, err := client.GetStoragePoolVolumeNames(pool) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + return volumes, cobra.ShellCompDirectiveNoFileComp +} diff --git a/lxc/config.go b/lxc/config.go index 4638355be494..161418e3d910 100644 --- a/lxc/config.go +++ b/lxc/config.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "io" "os" @@ -105,6 +106,14 @@ func (c *cmdConfigEdit) command() *cobra.Command { cmd.Flags().StringVar(&c.config.flagTarget, "target", "", i18n.G("Cluster member name")+"``") 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 nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -158,7 +167,7 @@ func (c *cmdConfigEdit) run(cmd *cobra.Command, args []string) error { if resource.name != "" { // Quick checks. if c.config.flagTarget != "" { - return fmt.Errorf(i18n.G("--target cannot be used with instances")) + return errors.New(i18n.G("--target cannot be used with instances")) } // If stdin isn't a terminal, read text from it @@ -294,7 +303,7 @@ func (c *cmdConfigEdit) run(cmd *cobra.Command, args []string) error { // Targeting if c.config.flagTarget != "" { if !resource.server.IsClustered() { - return fmt.Errorf(i18n.G("To use --target, the destination remote must be a cluster")) + return errors.New(i18n.G("To use --target, the destination remote must be a cluster")) } resource.server = resource.server.UseTarget(c.config.flagTarget) @@ -389,6 +398,18 @@ func (c *cmdConfigGet) command() *cobra.Command { cmd.Flags().StringVar(&c.config.flagTarget, "target", "", i18n.G("Cluster member name")+"``") 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.cmpInstanceAllKeys() + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -419,7 +440,7 @@ func (c *cmdConfigGet) run(cmd *cobra.Command, args []string) error { if resource.name != "" { // Quick checks. if c.config.flagTarget != "" { - return fmt.Errorf(i18n.G("--target cannot be used with instances")) + return errors.New(i18n.G("--target cannot be used with instances")) } if isSnapshot { @@ -469,13 +490,13 @@ func (c *cmdConfigGet) run(cmd *cobra.Command, args []string) error { } else { // Quick check. if c.flagExpanded { - return fmt.Errorf(i18n.G("--expanded cannot be used with a server")) + return errors.New(i18n.G("--expanded cannot be used with a server")) } // Targeting if c.config.flagTarget != "" { if !resource.server.IsClustered() { - return fmt.Errorf(i18n.G("To use --target, the destination remote must be a cluster")) + return errors.New(i18n.G("To use --target, the destination remote must be a cluster")) } resource.server = resource.server.UseTarget(c.config.flagTarget) @@ -530,6 +551,18 @@ lxc config set core.https_address=[::]:8443 cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Set the key as an instance property")) 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.cmpInstanceAllKeys() + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -592,7 +625,7 @@ func (c *cmdConfigSet) run(cmd *cobra.Command, args []string) error { if resource.name != "" { // Quick checks. if c.config.flagTarget != "" { - return fmt.Errorf(i18n.G("--target cannot be used with instances")) + return errors.New(i18n.G("--target cannot be used with instances")) } keys, err := getConfig(args[1:]...) @@ -630,7 +663,7 @@ func (c *cmdConfigSet) run(cmd *cobra.Command, args []string) error { return op.Wait() } - return fmt.Errorf(i18n.G("There is no config key to set on an instance snapshot.")) + return errors.New(i18n.G("There is no config key to set on an instance snapshot.")) } inst, etag, err := resource.server.GetInstance(resource.name) @@ -679,7 +712,7 @@ func (c *cmdConfigSet) run(cmd *cobra.Command, args []string) error { // Targeting if c.config.flagTarget != "" { if !resource.server.IsClustered() { - return fmt.Errorf(i18n.G("To use --target, the destination remote must be a cluster")) + return errors.New(i18n.G("To use --target, the destination remote must be a cluster")) } resource.server = resource.server.UseTarget(c.config.flagTarget) @@ -735,6 +768,14 @@ func (c *cmdConfigShow) command() *cobra.Command { cmd.Flags().StringVar(&c.config.flagTarget, "target", "", i18n.G("Cluster member name")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpInstances(toComplete) + } + return cmd } @@ -765,13 +806,13 @@ func (c *cmdConfigShow) run(cmd *cobra.Command, args []string) error { if resource.name == "" { // Quick check. if c.flagExpanded { - return fmt.Errorf(i18n.G("--expanded cannot be used with a server")) + return errors.New(i18n.G("--expanded cannot be used with a server")) } // Targeting if c.config.flagTarget != "" { if !resource.server.IsClustered() { - return fmt.Errorf(i18n.G("To use --target, the destination remote must be a cluster")) + return errors.New(i18n.G("To use --target, the destination remote must be a cluster")) } resource.server = resource.server.UseTarget(c.config.flagTarget) @@ -791,7 +832,7 @@ func (c *cmdConfigShow) run(cmd *cobra.Command, args []string) error { } else { // Quick checks. if c.config.flagTarget != "" { - return fmt.Errorf(i18n.G("--target cannot be used with instances")) + return errors.New(i18n.G("--target cannot be used with instances")) } // Instance or snapshot config @@ -859,6 +900,18 @@ func (c *cmdConfigUnset) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Unset the key as an instance property")) 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.cmpInstanceAllKeys() + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -952,7 +1005,7 @@ func (c *cmdConfigUefiGet) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Instance name must be specified")) + return errors.New(i18n.G("Instance name must be specified")) } // Get the UEFI variable @@ -963,7 +1016,7 @@ func (c *cmdConfigUefiGet) run(cmd *cobra.Command, args []string) error { efiVariable, ok := resp.Variables[args[len(args)-1]] if !ok { - return fmt.Errorf(i18n.G("Requested UEFI variable does not exist")) + return errors.New(i18n.G("Requested UEFI variable does not exist")) } fmt.Println(efiVariable.Data) @@ -1010,7 +1063,7 @@ func (c *cmdConfigUefiSet) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Instance name must be specified")) + return errors.New(i18n.G("Instance name must be specified")) } // Set the config keys @@ -1129,7 +1182,7 @@ func (c *cmdConfigUefiShow) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Instance name must be specified")) + return errors.New(i18n.G("Instance name must be specified")) } instEFI, _, err := resource.server.GetInstanceUEFIVars(resource.name) @@ -1221,7 +1274,7 @@ func (c *cmdConfigUefiEdit) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Instance name must be specified")) + return errors.New(i18n.G("Instance name must be specified")) } // If stdin isn't a terminal, read text from it diff --git a/lxc/config_device.go b/lxc/config_device.go index e31f7772c770..c0ead2681a71 100644 --- a/lxc/config_device.go +++ b/lxc/config_device.go @@ -98,6 +98,18 @@ lxc profile device add [:]profile1 disk pool=some-pool sou cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + if c.config != nil { + return c.global.cmpInstances(toComplete) + } else if c.profile != nil { + return c.global.cmpProfiles(toComplete, true) + } + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -211,6 +223,26 @@ func (c *cmdConfigDeviceGet) command() *cobra.Command { cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + if c.config != nil { + return c.global.cmpInstances(toComplete) + } else if c.profile != nil { + return c.global.cmpProfiles(toComplete, true) + } + } + + if len(args) == 1 { + if c.config != nil { + return c.global.cmpInstanceDeviceNames(args[0]) + } else if c.profile != nil { + return c.global.cmpProfileDeviceNames(args[0]) + } + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -293,6 +325,18 @@ func (c *cmdConfigDeviceList) command() *cobra.Command { cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + if c.config != nil { + return c.global.cmpInstances(toComplete) + } else if c.profile != nil { + return c.global.cmpProfiles(toComplete, true) + } + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -359,6 +403,14 @@ func (c *cmdConfigDeviceOverride) 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) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -453,6 +505,24 @@ func (c *cmdConfigDeviceRemove) command() *cobra.Command { cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + if c.config != nil { + return c.global.cmpInstances(toComplete) + } else if c.profile != nil { + return c.global.cmpProfiles(toComplete, true) + } + } + + if c.config != nil { + return c.global.cmpInstanceDeviceNames(args[0]) + } else if c.profile != nil { + return c.global.cmpProfileDeviceNames(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -562,6 +632,26 @@ For backward compatibility, a single configuration key may still be set with: cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + if c.config != nil { + return c.global.cmpInstances(toComplete) + } else if c.profile != nil { + return c.global.cmpProfiles(toComplete, true) + } + } + + if len(args) == 1 { + if c.config != nil { + return c.global.cmpInstanceDeviceNames(args[0]) + } else if c.profile != nil { + return c.global.cmpProfileDeviceNames(args[0]) + } + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -671,6 +761,18 @@ func (c *cmdConfigDeviceShow) command() *cobra.Command { cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + if c.config != nil { + return c.global.cmpInstances(toComplete) + } else if c.profile != nil { + return c.global.cmpProfiles(toComplete, true) + } + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -744,6 +846,26 @@ func (c *cmdConfigDeviceUnset) command() *cobra.Command { cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + if c.config != nil { + return c.global.cmpInstances(toComplete) + } else if c.profile != nil { + return c.global.cmpProfiles(toComplete, true) + } + } + + if len(args) == 1 { + if c.config != nil { + return c.global.cmpInstanceDeviceNames(args[0]) + } else if c.profile != nil { + return c.global.cmpProfileDeviceNames(args[0]) + } + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } diff --git a/lxc/config_metadata.go b/lxc/config_metadata.go index 17b3de585d7e..119ccf9a5ded 100644 --- a/lxc/config_metadata.go +++ b/lxc/config_metadata.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "io" "os" @@ -57,6 +58,14 @@ func (c *cmdConfigMetadataEdit) 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) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -100,7 +109,7 @@ func (c *cmdConfigMetadataEdit) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Missing instance name")) + return errors.New(i18n.G("Missing instance name")) } // Edit the metadata @@ -182,6 +191,14 @@ func (c *cmdConfigMetadataShow) 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) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -201,7 +218,7 @@ func (c *cmdConfigMetadataShow) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Missing instance name")) + return errors.New(i18n.G("Missing instance name")) } // Show the instance metadata diff --git a/lxc/config_template.go b/lxc/config_template.go index f3bbf80a7fed..7b78ed6ddea7 100644 --- a/lxc/config_template.go +++ b/lxc/config_template.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "errors" "fmt" "io" "os" @@ -69,6 +70,14 @@ func (c *cmdConfigTemplateCreate) 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) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -88,7 +97,7 @@ func (c *cmdConfigTemplateCreate) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Missing instance name")) + return errors.New(i18n.G("Missing instance name")) } // Create instance file template @@ -112,6 +121,18 @@ func (c *cmdConfigTemplateDelete) 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.cmpInstanceConfigTemplates(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -131,7 +152,7 @@ func (c *cmdConfigTemplateDelete) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Missing instance name")) + return errors.New(i18n.G("Missing instance name")) } // Delete instance file template @@ -154,6 +175,18 @@ func (c *cmdConfigTemplateEdit) 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.cmpInstanceConfigTemplates(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -173,7 +206,7 @@ func (c *cmdConfigTemplateEdit) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Missing instance name")) + return errors.New(i18n.G("Missing instance name")) } // Edit instance file template @@ -243,6 +276,14 @@ func (c *cmdConfigTemplateList) 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) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -262,7 +303,7 @@ func (c *cmdConfigTemplateList) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Missing instance name")) + return errors.New(i18n.G("Missing instance name")) } // List the templates @@ -302,6 +343,18 @@ func (c *cmdConfigTemplateShow) 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.cmpInstanceConfigTemplates(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -321,7 +374,7 @@ func (c *cmdConfigTemplateShow) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return fmt.Errorf(i18n.G("Missing instance name")) + return errors.New(i18n.G("Missing instance name")) } // Show the template diff --git a/lxc/copy.go b/lxc/copy.go index f04036f72f67..7c012a68e618 100644 --- a/lxc/copy.go +++ b/lxc/copy.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "strings" @@ -64,6 +65,18 @@ The pull transfer mode is the default as it is compatible with all LXD versions. cmd.Flags().BoolVar(&c.flagRefresh, "refresh", false, i18n.G("Perform an incremental copy")) cmd.Flags().BoolVar(&c.flagAllowInconsistent, "allow-inconsistent", false, i18n.G("Ignore copy errors for volatile files")) + 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 } @@ -82,12 +95,12 @@ func (c *cmdCopy) copyInstance(conf *config.Config, sourceResource string, destR // Make sure we have an instance or snapshot name if sourceName == "" { - return fmt.Errorf(i18n.G("You must specify a source instance name")) + return errors.New(i18n.G("You must specify a source instance name")) } // Don't allow refreshing without profiles. if c.flagRefresh && c.flagNoProfiles { - return fmt.Errorf(i18n.G("--no-profiles cannot be used with --refresh")) + return errors.New(i18n.G("--no-profiles cannot be used with --refresh")) } // If the instance is being copied to a different remote and no destination name is @@ -99,7 +112,7 @@ func (c *cmdCopy) copyInstance(conf *config.Config, sourceResource string, destR // Ensure that a destination name is provided. if destName == "" { - return fmt.Errorf(i18n.G("You must specify a destination instance name")) + return errors.New(i18n.G("You must specify a destination instance name")) } // Connect to the source host @@ -128,7 +141,7 @@ func (c *cmdCopy) copyInstance(conf *config.Config, sourceResource string, destR // Confirm that --target is only used with a cluster if c.flagTarget != "" && !dest.IsClustered() { - return fmt.Errorf(i18n.G("To use --target, the destination remote must be a cluster")) + return errors.New(i18n.G("To use --target, the destination remote must be a cluster")) } // Parse the config overrides @@ -153,7 +166,7 @@ func (c *cmdCopy) copyInstance(conf *config.Config, sourceResource string, destR if shared.IsSnapshot(sourceName) { if instanceOnly { - return fmt.Errorf(i18n.G("--instance-only can't be passed when the source is a snapshot")) + return errors.New(i18n.G("--instance-only can't be passed when the source is a snapshot")) } // Prepare the instance creation request @@ -164,7 +177,7 @@ func (c *cmdCopy) copyInstance(conf *config.Config, sourceResource string, destR } if c.flagRefresh { - return fmt.Errorf(i18n.G("--refresh can only be used with instances")) + return errors.New(i18n.G("--refresh can only be used with instances")) } // Copy of a snapshot into a new instance diff --git a/lxc/delete.go b/lxc/delete.go index b067e527e8b9..a6d3bbe1808f 100644 --- a/lxc/delete.go +++ b/lxc/delete.go @@ -2,6 +2,7 @@ package main import ( "bufio" + "errors" "fmt" "os" "strings" @@ -35,6 +36,10 @@ func (c *cmdDelete) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagForce, "force", "f", false, i18n.G("Force the removal of running instances")) 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 cmd } @@ -45,7 +50,7 @@ func (c *cmdDelete) promptDelete(name string) error { input = strings.TrimSuffix(input, "\n") if !shared.ValueInSlice(strings.ToLower(input), []string{i18n.G("yes")}) { - return fmt.Errorf(i18n.G("User aborted delete operation")) + return errors.New(i18n.G("User aborted delete operation")) } return nil @@ -120,7 +125,7 @@ func (c *cmdDelete) run(cmd *cobra.Command, args []string) error { if ct.StatusCode != 0 && ct.StatusCode != api.Stopped { if !c.flagForce { - return fmt.Errorf(i18n.G("The instance is currently running, stop it first or pass --force")) + return errors.New(i18n.G("The instance is currently running, stop it first or pass --force")) } req := api.InstanceStatePut{ diff --git a/lxc/exec.go b/lxc/exec.go index 5f22df43171b..15658ea0f13b 100644 --- a/lxc/exec.go +++ b/lxc/exec.go @@ -2,7 +2,7 @@ package main import ( "bytes" - "fmt" + "errors" "io" "os" "strconv" @@ -60,6 +60,14 @@ Mode defaults to non-interactive, interactive mode is selected if both stdin AND cmd.Flags().Uint32Var(&c.flagGroup, "group", 0, i18n.G("Group ID to run the command as (default 0)")+"``") cmd.Flags().StringVar(&c.flagCwd, "cwd", "", i18n.G("Directory to run the command in (default /root)")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpInstances(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -90,11 +98,11 @@ func (c *cmdExec) run(cmd *cobra.Command, args []string) error { } if c.flagForceInteractive && c.flagForceNonInteractive { - return fmt.Errorf(i18n.G("You can't pass -t and -T at the same time")) + return errors.New(i18n.G("You can't pass -t and -T at the same time")) } if c.flagMode != "auto" && (c.flagForceInteractive || c.flagForceNonInteractive) { - return fmt.Errorf(i18n.G("You can't pass -t or -T at the same time as --mode")) + return errors.New(i18n.G("You can't pass -t or -T at the same time as --mode")) } // Connect to the daemon diff --git a/lxc/image.go b/lxc/image.go index 4e4264ee14fd..ac4b7b11f150 100644 --- a/lxc/image.go +++ b/lxc/image.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "errors" "fmt" "io" "os" @@ -171,6 +172,18 @@ It requires the source to be an alias and for it to be public.`)) cmd.Flags().StringArrayVarP(&c.flagProfile, "profile", "p", nil, i18n.G("Profile to apply to the new image")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpImages(toComplete) + } + + if len(args) == 1 { + return c.global.cmpRemotes(false) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -184,7 +197,7 @@ func (c *cmdImageCopy) run(cmd *cobra.Command, args []string) error { } if c.flagMode != "pull" && c.flagAutoUpdate { - return fmt.Errorf(i18n.G("Auto update is only available in pull mode")) + return errors.New(i18n.G("Auto update is only available in pull mode")) } // Parse source remote @@ -217,7 +230,7 @@ func (c *cmdImageCopy) run(cmd *cobra.Command, args []string) error { destinationServer := resources[0].server if resources[0].name != "" { - return fmt.Errorf(i18n.G("Can't provide a name for the target image")) + return errors.New(i18n.G("Can't provide a name for the target image")) } // Resolve image type @@ -326,6 +339,10 @@ func (c *cmdImageDelete) command() *cobra.Command { cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return c.global.cmpImages(toComplete) + } + return cmd } @@ -344,7 +361,7 @@ func (c *cmdImageDelete) run(cmd *cobra.Command, args []string) error { for _, resource := range resources { if resource.name == "" { - return fmt.Errorf(i18n.G("Image identifier missing")) + return errors.New(i18n.G("Image identifier missing")) } image, _, err := c.image.dereferenceAlias(resource.server, "", resource.name) @@ -387,6 +404,14 @@ lxc image edit < image.yaml cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpImages(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -505,6 +530,14 @@ The output target is optional and defaults to the working directory.`)) cmd.Flags().BoolVar(&c.flagVM, "vm", false, i18n.G("Query virtual machine images")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpImages(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -670,15 +703,27 @@ Directory import is only available on Linux and must be performed as root.`)) cmd.Flags().StringArrayVar(&c.flagAliases, "alias", nil, i18n.G("New aliases to add to the image")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return nil, cobra.ShellCompDirectiveDefault + } + + if len(args) == 1 { + return c.global.cmpRemotes(false) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } func (c *cmdImageImport) packImageDir(path string) (string, error) { // Quick checks. if os.Geteuid() == -1 { - return "", fmt.Errorf(i18n.G("Directory import is not available on this platform")) + return "", errors.New(i18n.G("Directory import is not available on this platform")) } else if os.Geteuid() != 0 { - return "", fmt.Errorf(i18n.G("Must run as root to import from directory")) + return "", errors.New(i18n.G("Must run as root to import from directory")) } outFile, err := os.CreateTemp("", "lxd_image_") @@ -755,7 +800,7 @@ func (c *cmdImageImport) run(cmd *cobra.Command, args []string) error { } if strings.HasPrefix(imageFile, "http://") { - return fmt.Errorf(i18n.G("Only https:// is supported for remote image import")) + return errors.New(i18n.G("Only https:// is supported for remote image import")) } var createArgs *lxd.ImageCreateArgs @@ -904,6 +949,14 @@ func (c *cmdImageInfo) command() *cobra.Command { cmd.Flags().BoolVar(&c.flagVM, "vm", false, i18n.G("Query virtual machine images")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpImages(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -961,7 +1014,7 @@ func (c *cmdImageInfo) run(cmd *cobra.Command, args []string) error { fmt.Printf(i18n.G("Architecture: %s")+"\n", info.Architecture) fmt.Printf(i18n.G("Type: %s")+"\n", imgType) fmt.Printf(i18n.G("Public: %s")+"\n", public) - fmt.Printf(i18n.G("Timestamps:") + "\n") + fmt.Print(i18n.G("Timestamps:") + "\n") const layout = "2006/01/02 15:04 UTC" if shared.TimeIsSet(info.CreatedAt) { @@ -973,13 +1026,13 @@ func (c *cmdImageInfo) run(cmd *cobra.Command, args []string) error { if shared.TimeIsSet(info.ExpiresAt) { fmt.Printf(" "+i18n.G("Expires: %s")+"\n", info.ExpiresAt.UTC().Format(layout)) } else { - fmt.Printf(" " + i18n.G("Expires: never") + "\n") + fmt.Print(" " + i18n.G("Expires: never") + "\n") } if shared.TimeIsSet(info.LastUsedAt) { fmt.Printf(" "+i18n.G("Last used: %s")+"\n", info.LastUsedAt.UTC().Format(layout)) } else { - fmt.Printf(" " + i18n.G("Last used: never") + "\n") + fmt.Print(" " + i18n.G("Last used: never") + "\n") } fmt.Println(i18n.G("Properties:")) @@ -1007,7 +1060,7 @@ func (c *cmdImageInfo) run(cmd *cobra.Command, args []string) error { } if len(info.Profiles) == 0 { - fmt.Printf(i18n.G("Profiles: ") + "[]\n") + fmt.Print(i18n.G("Profiles: ") + "[]\n") } else { fmt.Println(i18n.G("Profiles:")) for _, name := range info.Profiles { @@ -1061,6 +1114,14 @@ Column shorthand chars: cmd.Flags().StringVarP(&c.flagFormat, "format", "f", "table", i18n.G("Format (csv|json|table|yaml|compact)")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpImages(toComplete) + } + return cmd } @@ -1356,6 +1417,10 @@ func (c *cmdImageRefresh) command() *cobra.Command { cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return c.global.cmpImages(toComplete) + } + return cmd } @@ -1374,7 +1439,7 @@ func (c *cmdImageRefresh) run(cmd *cobra.Command, args []string) error { for _, resource := range resources { if resource.name == "" { - return fmt.Errorf(i18n.G("Image identifier missing")) + return errors.New(i18n.G("Image identifier missing")) } image, _, err := c.image.dereferenceAlias(resource.server, "", resource.name) @@ -1444,6 +1509,14 @@ func (c *cmdImageShow) command() *cobra.Command { cmd.Flags().BoolVar(&c.flagVM, "vm", false, i18n.G("Query virtual machine images")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpImages(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1501,6 +1574,19 @@ func (c *cmdImageGetProp) 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.cmpImages(toComplete) + } + + if len(args) == 1 { + // individual image prop could complete here + return nil, cobra.ShellCompDirectiveNoFileComp + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1530,7 +1616,7 @@ func (c *cmdImageGetProp) run(cmd *cobra.Command, args []string) error { prop, propFound := image.Properties[args[1]] if !propFound { - return fmt.Errorf(i18n.G("Property not found")) + return errors.New(i18n.G("Property not found")) } fmt.Println(prop) @@ -1552,6 +1638,14 @@ func (c *cmdImageSetProp) 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.cmpImages(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1607,6 +1701,14 @@ func (c *cmdImageUnsetProp) 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.cmpImages(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } diff --git a/lxc/info.go b/lxc/info.go index 015a7621617a..02a84bfe4447 100644 --- a/lxc/info.go +++ b/lxc/info.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "io" "sort" @@ -43,6 +44,14 @@ lxc info [:] [--resources] cmd.Flags().BoolVar(&c.flagResources, "resources", false, i18n.G("Show the resources available to the server")) cmd.Flags().StringVar(&c.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpInstances(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -105,7 +114,7 @@ func (c *cmdInfo) renderGPU(gpu api.ResourcesGPUCard, prefix string, initial boo } if gpu.DRM != nil { - fmt.Printf(prefix + i18n.G("DRM:") + "\n") + fmt.Print(prefix + i18n.G("DRM:") + "\n") fmt.Printf(prefix+" "+i18n.G("ID: %d")+"\n", gpu.DRM.ID) if gpu.DRM.CardName != "" { @@ -122,7 +131,7 @@ func (c *cmdInfo) renderGPU(gpu api.ResourcesGPUCard, prefix string, initial boo } if gpu.Nvidia != nil { - fmt.Printf(prefix + i18n.G("NVIDIA information:") + "\n") + fmt.Print(prefix + i18n.G("NVIDIA information:") + "\n") fmt.Printf(prefix+" "+i18n.G("Architecture: %v")+"\n", gpu.Nvidia.Architecture) fmt.Printf(prefix+" "+i18n.G("Brand: %v")+"\n", gpu.Nvidia.Brand) fmt.Printf(prefix+" "+i18n.G("Model: %v")+"\n", gpu.Nvidia.Model) @@ -132,7 +141,7 @@ func (c *cmdInfo) renderGPU(gpu api.ResourcesGPUCard, prefix string, initial boo } if gpu.SRIOV != nil { - fmt.Printf(prefix + i18n.G("SR-IOV information:") + "\n") + fmt.Print(prefix + i18n.G("SR-IOV information:") + "\n") fmt.Printf(prefix+" "+i18n.G("Current number of VFs: %d")+"\n", gpu.SRIOV.CurrentVFs) fmt.Printf(prefix+" "+i18n.G("Maximum number of VFs: %d")+"\n", gpu.SRIOV.MaximumVFs) if len(gpu.SRIOV.VFs) > 0 { @@ -145,7 +154,7 @@ func (c *cmdInfo) renderGPU(gpu api.ResourcesGPUCard, prefix string, initial boo } if gpu.Mdev != nil { - fmt.Printf(prefix + i18n.G("Mdev profiles:") + "\n") + fmt.Print(prefix + i18n.G("Mdev profiles:") + "\n") keys := make([]string, 0, len(gpu.Mdev)) for k := range gpu.Mdev { @@ -191,7 +200,7 @@ func (c *cmdInfo) renderNIC(nic api.ResourcesNetworkCard, prefix string, initial } if len(nic.Ports) > 0 { - fmt.Printf(prefix + i18n.G("Ports:") + "\n") + fmt.Print(prefix + i18n.G("Ports:") + "\n") for _, port := range nic.Ports { fmt.Printf(prefix+" "+i18n.G("- Port %d (%s)")+"\n", port.Port, port.Protocol) fmt.Printf(prefix+" "+i18n.G("ID: %s")+"\n", port.ID) @@ -223,7 +232,7 @@ func (c *cmdInfo) renderNIC(nic api.ResourcesNetworkCard, prefix string, initial } if port.Infiniband != nil { - fmt.Printf(prefix + " " + i18n.G("Infiniband:") + "\n") + fmt.Print(prefix + " " + i18n.G("Infiniband:") + "\n") if port.Infiniband.IsSMName != "" { fmt.Printf(prefix+" "+i18n.G("IsSM: %s (%s)")+"\n", port.Infiniband.IsSMName, port.Infiniband.IsSMDevice) @@ -241,7 +250,7 @@ func (c *cmdInfo) renderNIC(nic api.ResourcesNetworkCard, prefix string, initial } if nic.SRIOV != nil { - fmt.Printf(prefix + i18n.G("SR-IOV information:") + "\n") + fmt.Print(prefix + i18n.G("SR-IOV information:") + "\n") fmt.Printf(prefix+" "+i18n.G("Current number of VFs: %d")+"\n", nic.SRIOV.CurrentVFs) fmt.Printf(prefix+" "+i18n.G("Maximum number of VFs: %d")+"\n", nic.SRIOV.MaximumVFs) if len(nic.SRIOV.VFs) > 0 { @@ -283,7 +292,7 @@ func (c *cmdInfo) renderDisk(disk api.ResourcesStorageDisk, prefix string, initi fmt.Printf(prefix+i18n.G("Removable: %v")+"\n", disk.Removable) if len(disk.Partitions) != 0 { - fmt.Printf(prefix + i18n.G("Partitions:") + "\n") + fmt.Print(prefix + i18n.G("Partitions:") + "\n") for _, partition := range disk.Partitions { fmt.Printf(prefix+" "+i18n.G("- Partition %d")+"\n", partition.Partition) fmt.Printf(prefix+" "+i18n.G("ID: %s")+"\n", partition.ID) @@ -305,17 +314,17 @@ func (c *cmdInfo) renderCPU(cpu api.ResourcesCPUSocket, prefix string) { } if cpu.Cache != nil { - fmt.Printf(prefix + i18n.G("Caches:") + "\n") + fmt.Print(prefix + i18n.G("Caches:") + "\n") for _, cache := range cpu.Cache { fmt.Printf(prefix+" "+i18n.G("- Level %d (type: %s): %s")+"\n", cache.Level, cache.Type, units.GetByteSizeStringIEC(int64(cache.Size), 0)) } } - fmt.Printf(prefix + i18n.G("Cores:") + "\n") + fmt.Print(prefix + i18n.G("Cores:") + "\n") for _, core := range cpu.Cores { fmt.Printf(prefix+" - "+i18n.G("Core %d")+"\n", core.Core) fmt.Printf(prefix+" "+i18n.G("Frequency: %vMhz")+"\n", core.Frequency) - fmt.Printf(prefix + " " + i18n.G("Threads:") + "\n") + fmt.Print(prefix + " " + i18n.G("Threads:") + "\n") for _, thread := range core.Threads { fmt.Printf(prefix+" - "+i18n.G("%d (id: %d, online: %v, NUMA node: %v)")+"\n", thread.Thread, thread.ID, thread.Online, thread.NUMANode) } @@ -334,7 +343,7 @@ func (c *cmdInfo) remoteInfo(d lxd.InstanceServer) error { // Targeting if c.flagTarget != "" { if !d.IsClustered() { - return fmt.Errorf(i18n.G("To use --target, the destination remote must be a cluster")) + return errors.New(i18n.G("To use --target, the destination remote must be a cluster")) } d = d.UseTarget(c.flagTarget) @@ -342,7 +351,7 @@ func (c *cmdInfo) remoteInfo(d lxd.InstanceServer) error { if c.flagResources { if !d.HasExtension("resources_v2") { - return fmt.Errorf(i18n.G("The server doesn't implement the newer v2 resources API")) + return errors.New(i18n.G("The server doesn't implement the newer v2 resources API")) } resources, err := d.GetServerResources() @@ -363,20 +372,20 @@ func (c *cmdInfo) remoteInfo(d lxd.InstanceServer) error { } // Memory - fmt.Printf("\n" + i18n.G("Memory:") + "\n") + fmt.Print("\n" + i18n.G("Memory:") + "\n") if resources.Memory.HugepagesTotal > 0 { - fmt.Printf(" " + i18n.G("Hugepages:"+"\n")) + fmt.Print(" " + i18n.G("Hugepages:"+"\n")) fmt.Printf(" "+i18n.G("Free: %v")+"\n", units.GetByteSizeStringIEC(int64(resources.Memory.HugepagesTotal-resources.Memory.HugepagesUsed), 2)) fmt.Printf(" "+i18n.G("Used: %v")+"\n", units.GetByteSizeStringIEC(int64(resources.Memory.HugepagesUsed), 2)) fmt.Printf(" "+i18n.G("Total: %v")+"\n", units.GetByteSizeStringIEC(int64(resources.Memory.HugepagesTotal), 2)) } if len(resources.Memory.Nodes) > 1 { - fmt.Printf(" " + i18n.G("NUMA nodes:"+"\n")) + fmt.Print(" " + i18n.G("NUMA nodes:"+"\n")) for _, node := range resources.Memory.Nodes { fmt.Printf(" "+i18n.G("Node %d:"+"\n"), node.NUMANode) if node.HugepagesTotal > 0 { - fmt.Printf(" " + i18n.G("Hugepages:"+"\n")) + fmt.Print(" " + i18n.G("Hugepages:"+"\n")) fmt.Printf(" "+i18n.G("Free: %v")+"\n", units.GetByteSizeStringIEC(int64(node.HugepagesTotal-node.HugepagesUsed), 2)) fmt.Printf(" "+i18n.G("Used: %v")+"\n", units.GetByteSizeStringIEC(int64(node.HugepagesUsed), 2)) fmt.Printf(" "+i18n.G("Total: %v")+"\n", units.GetByteSizeStringIEC(int64(node.HugepagesTotal), 2)) @@ -394,10 +403,10 @@ func (c *cmdInfo) remoteInfo(d lxd.InstanceServer) error { // GPUs if len(resources.GPU.Cards) == 1 { - fmt.Printf("\n" + i18n.G("GPU:") + "\n") + fmt.Print("\n" + i18n.G("GPU:") + "\n") c.renderGPU(resources.GPU.Cards[0], " ", true) } else if len(resources.GPU.Cards) > 1 { - fmt.Printf("\n" + i18n.G("GPUs:") + "\n") + fmt.Print("\n" + i18n.G("GPUs:") + "\n") for id, gpu := range resources.GPU.Cards { fmt.Printf(" "+i18n.G("Card %d:")+"\n", id) c.renderGPU(gpu, " ", true) @@ -406,10 +415,10 @@ func (c *cmdInfo) remoteInfo(d lxd.InstanceServer) error { // Network interfaces if len(resources.Network.Cards) == 1 { - fmt.Printf("\n" + i18n.G("NIC:") + "\n") + fmt.Print("\n" + i18n.G("NIC:") + "\n") c.renderNIC(resources.Network.Cards[0], " ", true) } else if len(resources.Network.Cards) > 1 { - fmt.Printf("\n" + i18n.G("NICs:") + "\n") + fmt.Print("\n" + i18n.G("NICs:") + "\n") for id, nic := range resources.Network.Cards { fmt.Printf(" "+i18n.G("Card %d:")+"\n", id) c.renderNIC(nic, " ", true) @@ -418,10 +427,10 @@ func (c *cmdInfo) remoteInfo(d lxd.InstanceServer) error { // Storage if len(resources.Storage.Disks) == 1 { - fmt.Printf("\n" + i18n.G("Disk:") + "\n") + fmt.Print("\n" + i18n.G("Disk:") + "\n") c.renderDisk(resources.Storage.Disks[0], " ", true) } else if len(resources.Storage.Disks) > 1 { - fmt.Printf("\n" + i18n.G("Disks:") + "\n") + fmt.Print("\n" + i18n.G("Disks:") + "\n") for id, nic := range resources.Storage.Disks { fmt.Printf(" "+i18n.G("Disk %d:")+"\n", id) c.renderDisk(nic, " ", true) @@ -449,7 +458,7 @@ func (c *cmdInfo) remoteInfo(d lxd.InstanceServer) error { func (c *cmdInfo) instanceInfo(d lxd.InstanceServer, name string, showLog bool) error { // Quick checks. if c.flagTarget != "" { - return fmt.Errorf(i18n.G("--target cannot be used with instances")) + return errors.New(i18n.G("--target cannot be used with instances")) } // Get the full instance data. diff --git a/lxc/init.go b/lxc/init.go index 18f34277603c..9522c8b45179 100644 --- a/lxc/init.go +++ b/lxc/init.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "io" "net/url" @@ -66,6 +67,14 @@ lxc init ubuntu:24.04 v1 --vm -c limits.cpu=2 -c limits.memory=8GiB -d root,size cmd.Flags().BoolVar(&c.flagEmpty, "empty", false, i18n.G("Create an empty instance")) cmd.Flags().BoolVar(&c.flagVM, "vm", false, i18n.G("Create a virtual machine")) + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpImages(toComplete) + } + return cmd } @@ -130,7 +139,7 @@ func (c *cmdInit) create(conf *config.Config, args []string, launch bool) (lxd.I if c.flagEmpty { if len(args) > 1 { - return nil, "", fmt.Errorf(i18n.G("--empty cannot be combined with an image name")) + return nil, "", errors.New(i18n.G("--empty cannot be combined with an image name")) } if len(args) == 0 { @@ -166,13 +175,13 @@ func (c *cmdInit) create(conf *config.Config, args []string, launch bool) (lxd.I if !c.global.flagQuiet { if d.HasExtension("instance_create_start") && launch { if name == "" { - fmt.Printf(i18n.G("Launching the instance") + "\n") + fmt.Print(i18n.G("Launching the instance") + "\n") } else { fmt.Printf(i18n.G("Launching %s")+"\n", name) } } else { if name == "" { - fmt.Printf(i18n.G("Creating the instance") + "\n") + fmt.Print(i18n.G("Creating the instance") + "\n") } else { fmt.Printf(i18n.G("Creating %s")+"\n", name) } @@ -330,7 +339,7 @@ func (c *cmdInit) create(conf *config.Config, args []string, launch bool) (lxd.I if conf.Remotes[iremote].Protocol != "simplestreams" { if imgInfo.Type != "virtual-machine" && c.flagVM { - return nil, "", fmt.Errorf(i18n.G("Asked for a VM but image is of type container")) + return nil, "", errors.New(i18n.G("Asked for a VM but image is of type container")) } req.Type = api.InstanceType(imgInfo.Type) @@ -390,7 +399,7 @@ func (c *cmdInit) create(conf *config.Config, args []string, launch bool) (lxd.I // Try using the older "containers" field instances, ok = opInfo.Resources["containers"] if !ok || len(instances) == 0 { - return nil, "", fmt.Errorf(i18n.G("Didn't get any affected image, instance or snapshot from server")) + return nil, "", errors.New(i18n.G("Didn't get any affected image, instance or snapshot from server")) } } @@ -422,7 +431,7 @@ func (c *cmdInit) checkNetwork(d lxd.InstanceServer, name string) { } } - fmt.Fprintf(os.Stderr, "\n"+i18n.G("The instance you are starting doesn't have any network attached to it.")+"\n") - fmt.Fprintf(os.Stderr, " "+i18n.G("To create a new network, use: lxc network create")+"\n") - fmt.Fprintf(os.Stderr, " "+i18n.G("To attach a network to an instance, use: lxc network attach")+"\n\n") + fmt.Fprint(os.Stderr, "\n"+i18n.G("The instance you are starting doesn't have any network attached to it.")+"\n") + fmt.Fprint(os.Stderr, " "+i18n.G("To create a new network, use: lxc network create")+"\n") + fmt.Fprint(os.Stderr, " "+i18n.G("To attach a network to an instance, use: lxc network attach")+"\n\n") } diff --git a/lxc/launch.go b/lxc/launch.go index 50cc5ec4e337..236e13f94e33 100644 --- a/lxc/launch.go +++ b/lxc/launch.go @@ -45,6 +45,14 @@ lxc launch ubuntu:24.04 v1 --vm -c limits.cpu=2 -c limits.memory=8GiB -d root,si cmd.Flags().StringVar(&c.flagConsole, "console", "", i18n.G("Immediately attach to the console")+"``") cmd.Flags().Lookup("console").NoOptDefVal = "console" + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpImages(toComplete) + } + return cmd } diff --git a/lxc/list.go b/lxc/list.go index 9cbbe986b647..3035a9d38bc0 100644 --- a/lxc/list.go +++ b/lxc/list.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "net" "regexp" @@ -133,6 +134,14 @@ lxc list -c ns,user.comment:comment cmd.Flags().BoolVar(&c.flagFast, "fast", false, i18n.G("Fast mode (same as --columns=nsacPt)")) cmd.Flags().BoolVar(&c.flagAllProjects, "all-projects", false, i18n.G("Display instances from all projects")) + 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 } @@ -455,7 +464,7 @@ func (c *cmdList) run(cmd *cobra.Command, args []string) error { } if c.global.flagProject != "" && c.flagAllProjects { - return fmt.Errorf(i18n.G("Can't specify --project with --all-projects")) + return errors.New(i18n.G("Can't specify --project with --all-projects")) } // Parse the remote @@ -582,7 +591,7 @@ func (c *cmdList) parseColumns(clustered bool) ([]column, bool, error) { if c.flagFast { if c.flagColumns != defaultColumns && c.flagColumns != defaultColumnsAllProjects { // --columns was specified too - return nil, false, fmt.Errorf(i18n.G("Can't specify --fast with --columns")) + return nil, false, errors.New(i18n.G("Can't specify --fast with --columns")) } if c.flagColumns == defaultColumnsAllProjects { @@ -598,7 +607,7 @@ func (c *cmdList) parseColumns(clustered bool) ([]column, bool, error) { } else { if c.flagColumns != defaultColumns && c.flagColumns != defaultColumnsAllProjects { if strings.ContainsAny(c.flagColumns, "L") { - return nil, false, fmt.Errorf(i18n.G("Can't specify column L when not clustered")) + return nil, false, errors.New(i18n.G("Can't specify column L when not clustered")) } } c.flagColumns = strings.Replace(c.flagColumns, "L", "", -1) diff --git a/lxc/main.go b/lxc/main.go index f95e710350f6..ee7e1a6350b8 100644 --- a/lxc/main.go +++ b/lxc/main.go @@ -87,7 +87,7 @@ All of LXD's features can be driven through the various commands below. For help with any of those, simply call them with --help.`)) app.SilenceUsage = true app.SilenceErrors = true - app.CompletionOptions = cobra.CompletionOptions{DisableDefaultCmd: true} + app.CompletionOptions = cobra.CompletionOptions{HiddenDefaultCmd: true} // Global flags globalCmd := cmdGlobal{cmd: app, asker: cli.NewAsker(bufio.NewReader(os.Stdin), nil)} @@ -278,9 +278,14 @@ For help with any of those, simply call them with --help.`)) if globalCmd.flagHelpAll { // Show all commands for _, cmd := range app.Commands() { + if cmd.Name() == "completion" { + continue + } + cmd.Hidden = false } } + if globalCmd.flagSubCmds { app.SetUsageTemplate(usageTemplateSubCmds()) } diff --git a/lxc/main_aliases.go b/lxc/main_aliases.go index ece07ba1c1ae..5324d2f52524 100644 --- a/lxc/main_aliases.go +++ b/lxc/main_aliases.go @@ -49,6 +49,8 @@ func findAlias(aliases map[string]string, origArgs []string) ([]string, []string } func expandAlias(conf *config.Config, args []string) ([]string, bool, error) { + var completion = false + var completionFragment string var newArgs []string var origArgs []string @@ -62,6 +64,13 @@ func expandAlias(conf *config.Config, args []string) ([]string, bool, error) { origArgs = append([]string{args[0]}, args[len(newArgs)+1:]...) + // strip out completion subcommand and fragment from end + if len(origArgs) >= 3 && origArgs[1] == "__complete" { + completion = true + completionFragment = origArgs[len(origArgs)-1] + origArgs = append(origArgs[:1], origArgs[2:len(origArgs)-1]...) + } + aliasKey, aliasValue, foundAlias := findAlias(conf.Aliases, origArgs) if !foundAlias { aliasKey, aliasValue, foundAlias = findAlias(defaultAliases, origArgs) @@ -116,7 +125,13 @@ func expandAlias(conf *config.Config, args []string) ([]string, bool, error) { for _, aliasArg := range aliasValue { // Only replace all @ARGS@ when it is not part of another string if aliasArg == "@ARGS@" { - newArgs = append(newArgs, atArgs...) + // if completing we want to stop on @ARGS@ and append the completion below + if completion { + break + } else { + newArgs = append(newArgs, atArgs...) + } + hasReplacedArgsVar = true continue } @@ -143,6 +158,12 @@ func expandAlias(conf *config.Config, args []string) ([]string, bool, error) { newArgs = append(newArgs, aliasArg) } + // add back in completion if it was stripped before + if completion { + newArgs = append([]string{newArgs[0], "__complete"}, newArgs[1:]...) + newArgs = append(newArgs, completionFragment) + } + // Add the rest of the arguments only if @ARGS@ wasn't used. if !hasReplacedArgsVar { newArgs = append(newArgs, atArgs...) diff --git a/lxc/manpage.go b/lxc/manpage.go index 360d531ca451..246be52d966b 100644 --- a/lxc/manpage.go +++ b/lxc/manpage.go @@ -36,6 +36,15 @@ func (c *cmdManpage) run(cmd *cobra.Command, args []string) error { return err } + // If asked to do all commands, mark them all visible. + for _, c := range c.global.cmd.Commands() { + if c.Name() == "completion" { + continue + } + + c.Hidden = false + } + // Generate the documentation. switch c.flagFormat { case "man": diff --git a/lxc/move.go b/lxc/move.go index a8f2ab8c6317..700b5d1d9922 100644 --- a/lxc/move.go +++ b/lxc/move.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "strings" @@ -67,6 +68,18 @@ lxc move / / cmd.Flags().StringVar(&c.flagTargetProject, "target-project", "", i18n.G("Copy to a project different from the source")+"``") cmd.Flags().BoolVar(&c.flagAllowInconsistent, "allow-inconsistent", false, i18n.G("Ignore copy errors for volatile files")) + 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 } @@ -114,7 +127,7 @@ func (c *cmdMove) run(cmd *cobra.Command, args []string) error { // simply won't work). if sourceRemote == destRemote && c.flagTarget == "" && c.flagStorage == "" && c.flagTargetProject == "" { if c.flagConfig != nil || c.flagDevice != nil || c.flagProfile != nil || c.flagNoProfiles { - return fmt.Errorf(i18n.G("Can't override configuration or profiles in local rename")) + return errors.New(i18n.G("Can't override configuration or profiles in local rename")) } source, err := conf.GetInstanceServer(sourceRemote) @@ -128,11 +141,11 @@ func (c *cmdMove) run(cmd *cobra.Command, args []string) error { dstParent, dstSnap, dstIsSnap := api.GetParentAndSnapshotName(destName) if srcParent != dstParent { - return fmt.Errorf(i18n.G("Invalid new snapshot name, parent must be the same as source")) + return errors.New(i18n.G("Invalid new snapshot name, parent must be the same as source")) } if !dstIsSnap { - return fmt.Errorf(i18n.G("Invalid new snapshot name")) + return errors.New(i18n.G("Invalid new snapshot name")) } op, err := source.RenameInstanceSnapshot(srcParent, srcSnap, api.InstanceSnapshotPost{Name: dstSnap}) @@ -165,19 +178,19 @@ func (c *cmdMove) run(cmd *cobra.Command, args []string) error { // cluster member to another, let's use the dedicated API. if sourceRemote == destRemote { if c.flagInstanceOnly { - return fmt.Errorf(i18n.G("The --instance-only flag can't be used with --target")) + return errors.New(i18n.G("The --instance-only flag can't be used with --target")) } if c.flagStorage != "" { - return fmt.Errorf(i18n.G("The --storage flag can't be used with --target")) + return errors.New(i18n.G("The --storage flag can't be used with --target")) } if c.flagTargetProject != "" { - return fmt.Errorf(i18n.G("The --target-project flag can't be used with --target")) + return errors.New(i18n.G("The --target-project flag can't be used with --target")) } if c.flagMode != moveDefaultMode { - return fmt.Errorf(i18n.G("The --mode flag can't be used with --target")) + return errors.New(i18n.G("The --mode flag can't be used with --target")) } return moveClusterInstance(conf, sourceResource, destResource, c.flagTarget, c.global.flagQuiet, stateful) @@ -189,7 +202,7 @@ func (c *cmdMove) run(cmd *cobra.Command, args []string) error { } if !dest.IsClustered() { - return fmt.Errorf(i18n.G("The destination LXD server is not clustered")) + return errors.New(i18n.G("The destination LXD server is not clustered")) } } @@ -203,7 +216,7 @@ func (c *cmdMove) run(cmd *cobra.Command, args []string) error { if source.HasExtension("instance_move_config") { if c.flagMode != moveDefaultMode { - return fmt.Errorf(i18n.G("The --mode flag can't be used with --storage or --target-project")) + return errors.New(i18n.G("The --mode flag can't be used with --storage or --target-project")) } // Evaluate provided profiles. If no profiles were provided and flag noProfiles is false, @@ -224,7 +237,7 @@ func (c *cmdMove) run(cmd *cobra.Command, args []string) error { } if c.flagMode != moveDefaultMode { - return fmt.Errorf(i18n.G("The --mode flag can't be used with --storage or --target-project")) + return errors.New(i18n.G("The --mode flag can't be used with --storage or --target-project")) } return moveInstance(conf, sourceResource, destResource, c.flagStorage, c.flagTargetProject, []string{}, []string{}, nil, c.flagInstanceOnly, stateful) @@ -277,7 +290,7 @@ func moveClusterInstance(conf *config.Config, sourceResource string, destResourc // Make sure we have an instance or snapshot name. if sourceName == "" { - return fmt.Errorf(i18n.G("You must specify a source instance name")) + return errors.New(i18n.G("You must specify a source instance name")) } // The destination name is optional. @@ -293,7 +306,7 @@ func moveClusterInstance(conf *config.Config, sourceResource string, destResourc // Check that it's a cluster if !source.IsClustered() { - return fmt.Errorf(i18n.G("The source LXD server is not clustered")) + return errors.New(i18n.G("The source LXD server is not clustered")) } // The migrate API will do the right thing when passed a target. @@ -353,7 +366,7 @@ func moveInstance(conf *config.Config, sourceResource string, destResource strin // Make sure we have an instance or snapshot name. if sourceName == "" { - return fmt.Errorf(i18n.G("You must specify a source instance name")) + return errors.New(i18n.G("You must specify a source instance name")) } // The destination name is optional. diff --git a/lxc/network.go b/lxc/network.go index 2347a65418db..dfaf2fc71752 100644 --- a/lxc/network.go +++ b/lxc/network.go @@ -138,6 +138,18 @@ func (c *cmdNetworkAttach) 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.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpInstances(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -223,6 +235,18 @@ func (c *cmdNetworkAttachProfile) 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.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpProfiles(args[0], false) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -303,6 +327,14 @@ lxc network create bar network=baz --type ovn cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpRemotes(false) + } + return cmd } @@ -375,6 +407,14 @@ func (c *cmdNetworkDelete) 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 nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpNetworks(toComplete) + } + return cmd } @@ -425,6 +465,18 @@ func (c *cmdNetworkDetach) 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.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkInstances(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -510,6 +562,18 @@ func (c *cmdNetworkDetachProfile) 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.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkProfiles(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -595,6 +659,14 @@ func (c *cmdNetworkEdit) 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 nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpNetworks(toComplete) + } + return cmd } @@ -725,6 +797,18 @@ func (c *cmdNetworkGet) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Get the key as a network property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -793,6 +877,14 @@ func (c *cmdNetworkInfo) command() *cobra.Command { cmd.Flags().StringVar(&c.network.flagTarget, "target", "", i18n.G("Cluster member name")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpNetworks(toComplete) + } + return cmd } @@ -916,6 +1008,14 @@ func (c *cmdNetworkList) 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 nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpRemotes(false) + } + return cmd } @@ -1009,6 +1109,14 @@ func (c *cmdNetworkListLeases) 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 nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpNetworks(toComplete) + } + return cmd } @@ -1079,6 +1187,14 @@ func (c *cmdNetworkRename) 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 nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpNetworks(toComplete) + } + return cmd } @@ -1136,6 +1252,14 @@ For backward compatibility, a single configuration key may still be set with: cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Set the key as a network property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpNetworks(toComplete) + } + return cmd } @@ -1220,6 +1344,14 @@ func (c *cmdNetworkShow) command() *cobra.Command { cmd.Flags().StringVar(&c.network.flagTarget, "target", "", i18n.G("Cluster member name")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + return c.global.cmpNetworks(toComplete) + } + return cmd } @@ -1285,6 +1417,18 @@ func (c *cmdNetworkUnset) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Unset the key as a network property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } diff --git a/lxc/network_acl.go b/lxc/network_acl.go index 1a207119d388..d1cd571a8f0e 100644 --- a/lxc/network_acl.go +++ b/lxc/network_acl.go @@ -97,6 +97,14 @@ func (c *cmdNetworkACLList) 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 } @@ -166,6 +174,14 @@ func (c *cmdNetworkACLShow) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Show network ACL configurations")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkACLs(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -219,6 +235,14 @@ func (c *cmdNetworkACLShowLog) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Show network ACL log")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkACLs(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -269,6 +293,18 @@ func (c *cmdNetworkACLGet) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Get the key as a network ACL property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkACLs(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkACLConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -333,6 +369,14 @@ lxc network acl create a1 < config.yaml cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkACLs(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -423,6 +467,14 @@ For backward compatibility, a single configuration key may still be set with: cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Set the key as a network ACL property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkACLs(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -498,6 +550,19 @@ func (c *cmdNetworkACLUnset) command() *cobra.Command { cmd.RunE = c.run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Unset the key as a network ACL property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkACLs(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkACLConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -528,6 +593,14 @@ func (c *cmdNetworkACLEdit) 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.cmpNetworkACLs(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -658,6 +731,14 @@ func (c *cmdNetworkACLRename) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Rename network ACLs")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkACLs(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -707,6 +788,14 @@ func (c *cmdNetworkACLDelete) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Delete network ACLs")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkACLs(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -771,11 +860,27 @@ func (c *cmdNetworkACLRule) commandAdd() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Add rules to an ACL")) cmd.RunE = c.runAdd + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkACLs(toComplete) + } + + if len(args) == 1 { + return []string{"ingress", "egress"}, cobra.ShellCompDirectiveNoFileComp + } + + if len(args) == 2 { + return c.global.cmpNetworkACLRuleProperties() + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } -// ruleJSONStructFieldMap returns a map of JSON tag names to struct field indices for api.NetworkACLRule. -func (c *cmdNetworkACLRule) ruleJSONStructFieldMap() map[string]int { +// networkACLRuleJSONStructFieldMap returns a map of JSON tag names to struct field indices for api.NetworkACLRule. +func networkACLRuleJSONStructFieldMap() map[string]int { // Use reflect to get field names in rule from json tags. ruleType := reflect.TypeOf(api.NetworkACLRule{}) allowedKeys := make(map[string]int, ruleType.NumField()) @@ -807,7 +912,7 @@ func (c *cmdNetworkACLRule) ruleJSONStructFieldMap() map[string]int { // parseConfigKeysToRule converts a map of key/value pairs into an api.NetworkACLRule using reflection. func (c *cmdNetworkACLRule) parseConfigToRule(config map[string]string) (*api.NetworkACLRule, error) { // Use reflect to get struct field indices in NetworkACLRule for json tags. - allowedKeys := c.ruleJSONStructFieldMap() + allowedKeys := networkACLRuleJSONStructFieldMap() // Initialise new rule. rule := api.NetworkACLRule{} @@ -894,6 +999,22 @@ func (c *cmdNetworkACLRule) commandRemove() *cobra.Command { cmd.RunE = c.runRemove + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkACLs(toComplete) + } + + if len(args) == 1 { + return []string{"ingress", "egress"}, cobra.ShellCompDirectiveNoFileComp + } + + if len(args) == 2 { + return c.global.cmpNetworkACLRuleProperties() + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -929,7 +1050,7 @@ func (c *cmdNetworkACLRule) runRemove(cmd *cobra.Command, args []string) error { } // Use reflect to get struct field indices in NetworkACLRule for json tags. - allowedKeys := c.ruleJSONStructFieldMap() + allowedKeys := networkACLRuleJSONStructFieldMap() // Check the supplied filters match possible fields. for k := range filters { diff --git a/lxc/network_forward.go b/lxc/network_forward.go index 94ba4de736b4..5241a6fbf0f1 100644 --- a/lxc/network_forward.go +++ b/lxc/network_forward.go @@ -92,6 +92,14 @@ func (c *cmdNetworkForwardList) 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.cmpNetworks(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -173,6 +181,18 @@ func (c *cmdNetworkForwardShow) command() *cobra.Command { cmd.Flags().StringVar(&c.networkForward.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkForwards(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -386,6 +406,22 @@ func (c *cmdNetworkForwardGet) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Get the key as a network forward property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkForwards(args[0]) + } + + if len(args) == 2 { + return c.global.cmpNetworkForwardConfigs(args[0], args[1]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -460,6 +496,18 @@ For backward compatibility, a single configuration key may still be set with: cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Set the key as a network forward property")) cmd.Flags().StringVar(&c.networkForward.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkForwards(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -552,6 +600,23 @@ func (c *cmdNetworkForwardUnset) command() *cobra.Command { cmd.RunE = c.run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Unset the key as a network forward property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkForwards(args[0]) + } + + if len(args) == 2 { + return c.global.cmpNetworkForwardConfigs(args[0], args[1]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -583,6 +648,18 @@ func (c *cmdNetworkForwardEdit) command() *cobra.Command { cmd.Flags().StringVar(&c.networkForward.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkForwards(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -725,6 +802,18 @@ func (c *cmdNetworkForwardDelete) command() *cobra.Command { cmd.Flags().StringVar(&c.networkForward.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkForwards(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -802,6 +891,22 @@ func (c *cmdNetworkForwardPort) commandAdd() *cobra.Command { cmd.Flags().StringVar(&c.networkForward.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkForwards(args[0]) + } + + if len(args) == 2 { + return []string{"tcp", "udp"}, cobra.ShellCompDirectiveNoFileComp + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -868,6 +973,22 @@ func (c *cmdNetworkForwardPort) commandRemove() *cobra.Command { cmd.Flags().StringVar(&c.networkForward.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkForwards(args[0]) + } + + if len(args) == 2 { + return []string{"tcp", "udp"}, cobra.ShellCompDirectiveNoFileComp + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } diff --git a/lxc/network_load_balancer.go b/lxc/network_load_balancer.go index 98f3cf420581..a97fc5f42e05 100644 --- a/lxc/network_load_balancer.go +++ b/lxc/network_load_balancer.go @@ -96,6 +96,14 @@ func (c *cmdNetworkLoadBalancerList) 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.cmpNetworks(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -175,6 +183,18 @@ func (c *cmdNetworkLoadBalancerShow) command() *cobra.Command { cmd.Flags().StringVar(&c.networkLoadBalancer.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkLoadBalancers(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -463,6 +483,18 @@ For backward compatibility, a single configuration key may still be set with: cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Set the key as a network load balancer property")) cmd.Flags().StringVar(&c.networkLoadBalancer.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkLoadBalancers(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -586,6 +618,18 @@ func (c *cmdNetworkLoadBalancerEdit) command() *cobra.Command { cmd.Flags().StringVar(&c.networkLoadBalancer.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkLoadBalancers(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -729,6 +773,18 @@ func (c *cmdNetworkLoadBalancerDelete) command() *cobra.Command { cmd.Flags().StringVar(&c.networkLoadBalancer.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkLoadBalancers(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -805,6 +861,18 @@ func (c *cmdNetworkLoadBalancerBackend) commandAdd() *cobra.Command { cmd.Flags().StringVar(&c.networkLoadBalancer.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkLoadBalancers(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -869,6 +937,18 @@ func (c *cmdNetworkLoadBalancerBackend) commandRemove() *cobra.Command { cmd.Flags().StringVar(&c.networkLoadBalancer.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkLoadBalancers(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -970,6 +1050,18 @@ func (c *cmdNetworkLoadBalancerPort) commandAdd() *cobra.Command { cmd.Flags().StringVar(&c.networkLoadBalancer.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkLoadBalancers(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1032,6 +1124,18 @@ func (c *cmdNetworkLoadBalancerPort) commandRemove() *cobra.Command { cmd.Flags().StringVar(&c.networkLoadBalancer.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkLoadBalancers(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } diff --git a/lxc/network_peer.go b/lxc/network_peer.go index 832a8f5def0f..6c4c816bd61d 100644 --- a/lxc/network_peer.go +++ b/lxc/network_peer.go @@ -84,6 +84,14 @@ func (c *cmdNetworkPeerList) 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.cmpNetworks(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -159,6 +167,18 @@ func (c *cmdNetworkPeerShow) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Show network peer configurations")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkPeers(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -216,6 +236,14 @@ func (c *cmdNetworkPeerCreate) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Create new network peering")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -333,6 +361,23 @@ func (c *cmdNetworkPeerGet) command() *cobra.Command { cmd.RunE = c.run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Get the key as a network peer property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkPeers(args[0]) + } + + if len(args) == 2 { + return c.global.cmpNetworkPeerConfigs(args[0], args[1]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -405,6 +450,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 network peer property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkPeers(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -490,6 +548,23 @@ func (c *cmdNetworkPeerUnset) command() *cobra.Command { cmd.RunE = c.run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Unset the key as a network peer property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkPeers(args[0]) + } + + if len(args) == 2 { + return c.global.cmpNetworkPeerConfigs(args[0], args[1]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -519,6 +594,18 @@ func (c *cmdNetworkPeerEdit) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Edit network peer configurations as YAML")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkPeers(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -644,6 +731,18 @@ func (c *cmdNetworkPeerDelete) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Delete network peerings")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworks(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkPeers(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } diff --git a/lxc/network_zone.go b/lxc/network_zone.go index edd2de12c0f6..0b3fcf628500 100644 --- a/lxc/network_zone.go +++ b/lxc/network_zone.go @@ -88,6 +88,14 @@ func (c *cmdNetworkZoneList) 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 } @@ -157,6 +165,14 @@ func (c *cmdNetworkZoneShow) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Show network zone configurations")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -213,6 +229,19 @@ func (c *cmdNetworkZoneGet) command() *cobra.Command { cmd.RunE = c.run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Get the key as a network zone property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkZoneConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -277,6 +306,14 @@ lxc network zone create z1 < config.yaml cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -365,6 +402,14 @@ 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 network zone property")) + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -441,6 +486,18 @@ func (c *cmdNetworkZoneUnset) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Unset the key as a network zone property")) + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkZoneConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -471,6 +528,14 @@ func (c *cmdNetworkZoneEdit) 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.cmpNetworkZones(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -589,6 +654,14 @@ func (c *cmdNetworkZoneDelete) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Delete network zones")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -696,6 +769,14 @@ func (c *cmdNetworkZoneRecordList) 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.cmpNetworkZones(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -764,6 +845,18 @@ func (c *cmdNetworkZoneRecordShow) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Show network zone record configurations")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkZoneRecords(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -817,6 +910,23 @@ func (c *cmdNetworkZoneRecordGet) command() *cobra.Command { cmd.RunE = c.run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Get the key as a network zone record property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkZoneRecords(args[0]) + } + + if len(args) == 2 { + return c.global.cmpNetworkZoneRecordConfigs(args[0], args[1]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -880,6 +990,18 @@ lxc network zone record create z1 r1 < config.yaml cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkZoneRecords(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -964,6 +1086,19 @@ func (c *cmdNetworkZoneRecordSet) command() *cobra.Command { cmd.RunE = c.run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Set the key as a network zone record property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkZoneRecords(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1038,6 +1173,23 @@ func (c *cmdNetworkZoneRecordUnset) command() *cobra.Command { cmd.RunE = c.run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Unset the key as a network zone record property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkZoneRecords(args[0]) + } + + if len(args) == 2 { + return c.global.cmpNetworkZoneRecordConfigs(args[0], args[1]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1068,6 +1220,18 @@ func (c *cmdNetworkZoneRecordEdit) 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.cmpNetworkZones(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkZoneRecords(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1185,6 +1349,18 @@ func (c *cmdNetworkZoneRecordDelete) command() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Delete network zone record")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkZoneRecords(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1250,6 +1426,18 @@ func (c *cmdNetworkZoneRecordEntry) commandAdd() *cobra.Command { cmd.RunE = c.runAdd cmd.Flags().Uint64Var(&c.flagTTL, "ttl", 0, i18n.G("Entry TTL")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkZoneRecords(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1295,6 +1483,18 @@ func (c *cmdNetworkZoneRecordEntry) commandRemove() *cobra.Command { cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G("Remove entries from a network zone record")) cmd.RunE = c.runRemove + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpNetworkZones(toComplete) + } + + if len(args) == 1 { + return c.global.cmpNetworkZoneRecords(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } diff --git a/lxc/profile.go b/lxc/profile.go index fc65de8df7cd..58c321136793 100644 --- a/lxc/profile.go +++ b/lxc/profile.go @@ -107,6 +107,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 } @@ -179,6 +191,14 @@ lxc 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 } @@ -255,6 +275,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 } @@ -327,6 +359,14 @@ lxc profile create p1 < config.yaml 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 } @@ -361,7 +401,7 @@ func (c *cmdProfileCreate) run(cmd *cobra.Command, args []string) error { resource := resources[0] if resource.name == "" { - return errors.New(i18n.G("Missing profile name")) + return fmt.Errorf("%s", i18n.G("Missing project name")) } // Create the profile @@ -397,6 +437,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 } @@ -450,6 +498,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 } @@ -576,6 +632,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 } @@ -637,6 +706,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 } @@ -697,6 +774,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 } @@ -773,6 +862,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 } @@ -828,6 +925,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 } @@ -901,6 +1011,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 } @@ -958,6 +1076,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 } diff --git a/lxc/project.go b/lxc/project.go index 3fad70eef138..ecc68a2b8ed6 100644 --- a/lxc/project.go +++ b/lxc/project.go @@ -102,6 +102,14 @@ lxc project create p1 < config.yaml 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 } @@ -184,6 +192,14 @@ func (c *cmdProjectDelete) 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.cmpProjects(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -250,6 +266,14 @@ func (c *cmdProjectEdit) 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.cmpProjects(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -375,6 +399,19 @@ func (c *cmdProjectGet) command() *cobra.Command { cmd.RunE = c.run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Get the key as a project property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpProjects(toComplete) + } + + if len(args) == 1 { + return c.global.cmpProjectConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -437,6 +474,14 @@ func (c *cmdProjectList) 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 } @@ -455,8 +500,6 @@ func (c *cmdProjectList) run(cmd *cobra.Command, args []string) error { remote = args[0] } - remoteName := strings.TrimSuffix(remote, ":") - resources, err := c.global.ParseServers(remote) if err != nil { return err @@ -470,9 +513,10 @@ func (c *cmdProjectList) run(cmd *cobra.Command, args []string) error { return err } - currentProject := conf.Remotes[remoteName].Project - if currentProject == "" { - currentProject = "default" + // Get the current project. + info, err := resource.server.GetConnectionInfo() + if err != nil { + return err } data := [][]string{} @@ -508,7 +552,7 @@ func (c *cmdProjectList) run(cmd *cobra.Command, args []string) error { } name := project.Name - if name == currentProject { + if name == info.Project { name = fmt.Sprintf("%s (%s)", name, i18n.G("current")) } @@ -549,6 +593,14 @@ func (c *cmdProjectRename) 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.cmpProjects(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -609,6 +661,15 @@ 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 project property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpProjects(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -685,6 +746,19 @@ func (c *cmdProjectUnset) command() *cobra.Command { cmd.RunE = c.run cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Unset the key as a project property")) + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpProjects(toComplete) + } + + if len(args) == 1 { + return c.global.cmpProjectConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -716,6 +790,14 @@ func (c *cmdProjectShow) 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.cmpProjects(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -769,6 +851,14 @@ func (c *cmdProjectSwitch) 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.cmpProjects(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -821,7 +911,7 @@ type cmdProjectInfo struct { func (c *cmdProjectInfo) command() *cobra.Command { cmd := &cobra.Command{} - cmd.Use = usage("info", i18n.G("[:] ")) + cmd.Use = usage("info", i18n.G("[:]")) cmd.Short = i18n.G("Get a summary of resource allocations") cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G( `Get a summary of resource allocations`)) @@ -829,6 +919,14 @@ func (c *cmdProjectInfo) 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.cmpProjects(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } diff --git a/lxc/publish.go b/lxc/publish.go index 191777fb34c7..512ece940a1a 100644 --- a/lxc/publish.go +++ b/lxc/publish.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "strings" "time" @@ -41,6 +42,18 @@ func (c *cmdPublish) command() *cobra.Command { cmd.Flags().StringVar(&c.flagExpiresAt, "expire", "", i18n.G("Image expiration date (format: rfc3339)")+"``") cmd.Flags().BoolVar(&c.flagReuse, "reuse", false, i18n.G("If the image alias already exists, delete and create a new one")) + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpInstancesAndSnapshots(toComplete) + } + + if len(args) == 1 { + return c.global.cmpRemotes(false) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -77,11 +90,11 @@ func (c *cmdPublish) run(cmd *cobra.Command, args []string) error { } if cName == "" { - return fmt.Errorf(i18n.G("Instance name is mandatory")) + return errors.New(i18n.G("Instance name is mandatory")) } if iName != "" { - return fmt.Errorf(i18n.G("There is no \"image name\". Did you want an alias?")) + return errors.New(i18n.G("There is no \"image name\". Did you want an alias?")) } d, err := conf.GetInstanceServer(iRemote) @@ -108,7 +121,7 @@ func (c *cmdPublish) run(cmd *cobra.Command, args []string) error { if wasRunning { if !c.flagForce { - return fmt.Errorf(i18n.G("The instance is currently running. Use --force to have it stopped and restarted")) + return errors.New(i18n.G("The instance is currently running. Use --force to have it stopped and restarted")) } if ct.Ephemeral { @@ -139,7 +152,7 @@ func (c *cmdPublish) run(cmd *cobra.Command, args []string) error { err = op.Wait() if err != nil { - return fmt.Errorf(i18n.G("Stopping instance failed!")) + return errors.New(i18n.G("Stopping instance failed!")) } // Start the instance back up on exit. diff --git a/lxc/remote.go b/lxc/remote.go index 550d7eeca030..22a478962c9f 100644 --- a/lxc/remote.go +++ b/lxc/remote.go @@ -774,6 +774,14 @@ func (c *cmdRemoteRename) 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.cmpRemoteNames() + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -847,6 +855,14 @@ func (c *cmdRemoteRemove) 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.cmpRemoteNames() + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -903,6 +919,14 @@ func (c *cmdRemoteSwitch) 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.cmpRemoteNames() + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -943,6 +967,14 @@ func (c *cmdRemoteSetURL) 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.cmpRemoteNames() + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } diff --git a/lxc/rename.go b/lxc/rename.go index 4f196f6aa572..201d2d1168ac 100644 --- a/lxc/rename.go +++ b/lxc/rename.go @@ -1,6 +1,7 @@ package main import ( + "errors" "fmt" "strings" @@ -22,6 +23,14 @@ func (c *cmdRename) command() *cobra.Command { `Rename instances and snapshots`)) 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 nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -48,7 +57,7 @@ func (c *cmdRename) run(cmd *cobra.Command, args []string) error { if sourceRemote != destRemote { // We just do renames if strings.Contains(args[1], ":") { - return fmt.Errorf(i18n.G("Can't specify a different remote for rename")) + return errors.New(i18n.G("Can't specify a different remote for rename")) } // Don't require the remote to be passed as both source and target diff --git a/lxc/storage.go b/lxc/storage.go index dac15ae65b70..67b70d7bff88 100644 --- a/lxc/storage.go +++ b/lxc/storage.go @@ -105,6 +105,14 @@ lxc storage create s1 dir < config.yaml cmd.Flags().StringVar(&c.storage.flagTarget, "target", "", i18n.G("Cluster member name")+"``") 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 } @@ -197,6 +205,14 @@ func (c *cmdStorageDelete) 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.cmpStoragePools(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -250,6 +266,14 @@ func (c *cmdStorageEdit) 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.cmpStoragePools(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -373,6 +397,18 @@ func (c *cmdStorageGet) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Get the key as a storage property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -443,6 +479,14 @@ func (c *cmdStorageInfo) command() *cobra.Command { cmd.Flags().StringVar(&c.storage.flagTarget, "target", "", i18n.G("Cluster member name")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -614,6 +658,14 @@ func (c *cmdStorageList) 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 } @@ -697,6 +749,14 @@ For backward compatibility, a single configuration key may still be set with: cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Set the key as a storage property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -790,6 +850,14 @@ func (c *cmdStorageShow) command() *cobra.Command { cmd.Flags().StringVar(&c.storage.flagTarget, "target", "", i18n.G("Cluster member name")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -876,6 +944,18 @@ func (c *cmdStorageUnset) command() *cobra.Command { cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Unset the key as a storage property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolConfigs(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } diff --git a/lxc/storage_volume.go b/lxc/storage_volume.go index 4f0a38326db4..308b876f56af 100644 --- a/lxc/storage_volume.go +++ b/lxc/storage_volume.go @@ -7,6 +7,7 @@ import ( "net/url" "os" "path" + "slices" "sort" "strconv" "strings" @@ -37,6 +38,19 @@ type cmdStorageVolume struct { flagDestinationTarget string } +func parseVolume(defaultType string, name string) (volName string, volType string) { + fields := strings.SplitN(name, "/", 2) + if len(fields) == 1 { + volName, volType = fields[0], defaultType + } else if len(fields) == 2 && !slices.Contains([]string{"custom", "image", "container", "virtual-machine"}, fields[0]) { + volName, volType = name, defaultType + } else { + volName, volType = fields[1], fields[0] + } + + return volName, volType +} + func (c *cmdStorageVolume) command() *cobra.Command { cmd := &cobra.Command{} cmd.Use = usage("volume") @@ -132,17 +146,6 @@ Unless specified through a prefix, all volume operations affect "custom" (user c return cmd } -func (c *cmdStorageVolume) parseVolume(defaultType string, name string) (volumeName string, volumeType string) { - fields := strings.SplitN(name, "/", 2) - if len(fields) == 1 { - return fields[0], defaultType - } else if len(fields) == 2 && !shared.ValueInSlice(fields[0], []string{"custom", "image", "container", "virtual-machine"}) { - return name, defaultType - } - - return fields[1], fields[0] -} - func (c *cmdStorageVolume) parseVolumeWithPool(name string) (volumeName string, poolName string) { fields := strings.SplitN(name, "/", 2) if len(fields) == 1 { @@ -168,6 +171,22 @@ func (c *cmdStorageVolumeAttach) 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.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + if len(args) == 2 { + return c.global.cmpInstanceNamesFromRemote(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -190,7 +209,7 @@ func (c *cmdStorageVolumeAttach) run(cmd *cobra.Command, args []string) error { return errors.New(i18n.G("Missing pool name")) } - volName, volType := c.storageVolume.parseVolume("custom", args[1]) + volName, volType := parseVolume("custom", args[1]) if volType != "custom" { return errors.New(i18n.G("Only \"custom\" volumes can be attached to instances")) } @@ -266,6 +285,22 @@ func (c *cmdStorageVolumeAttachProfile) 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.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + if len(args) == 2 { + return c.global.cmpProfileNamesFromRemote(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -303,7 +338,7 @@ func (c *cmdStorageVolumeAttachProfile) run(cmd *cobra.Command, args []string) e devPath = args[4] } - volName, volType := c.storageVolume.parseVolume("custom", args[1]) + volName, volType := parseVolume("custom", args[1]) if volType != "custom" { return errors.New(i18n.G("Only \"custom\" volumes can be attached to instances")) } @@ -363,6 +398,18 @@ func (c *cmdStorageVolumeCopy) command() *cobra.Command { cmd.Flags().BoolVar(&c.flagRefresh, "refresh", false, i18n.G("Refresh and update the existing storage volume copies")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePoolWithVolume(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePools(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -566,6 +613,14 @@ lxc storage volume create p1 v1 < config.yaml cmd.Flags().StringVar(&c.flagContentType, "type", "filesystem", i18n.G("Content type, block or filesystem")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -604,7 +659,7 @@ func (c *cmdStorageVolumeCreate) run(cmd *cobra.Command, args []string) error { } // Parse the input - volName, volType := c.storageVolume.parseVolume("custom", args[1]) + volName, volType := parseVolume("custom", args[1]) // Create the storage volume entry vol := api.StorageVolumesPost{ @@ -662,6 +717,18 @@ func (c *cmdStorageVolumeDelete) command() *cobra.Command { cmd.Flags().StringVar(&c.storage.flagTarget, "target", "", i18n.G("Cluster member name")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -686,7 +753,7 @@ func (c *cmdStorageVolumeDelete) run(cmd *cobra.Command, args []string) error { client := resource.server // Parse the input - volName, volType := c.storageVolume.parseVolume("custom", args[1]) + volName, volType := parseVolume("custom", args[1]) // If a target was specified, delete the volume on the given member. if c.storage.flagTarget != "" { @@ -736,6 +803,22 @@ func (c *cmdStorageVolumeDetach) 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.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + if len(args) == 2 { + return c.global.cmpStoragePoolVolumeInstances(args[0], args[1]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -818,6 +901,22 @@ func (c *cmdStorageVolumeDetachProfile) 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.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + if len(args) == 2 { + return c.global.cmpStoragePoolVolumeProfiles(args[0], args[1]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -906,6 +1005,18 @@ lxc storage volume edit [:] [/] < volume.yaml cmd.Flags().StringVar(&c.storage.flagTarget, "target", "", i18n.G("Cluster member name")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -945,7 +1056,7 @@ func (c *cmdStorageVolumeEdit) run(cmd *cobra.Command, args []string) error { client := resource.server // Parse the input - volName, volType := c.storageVolume.parseVolume("custom", args[1]) + volName, volType := parseVolume("custom", args[1]) isSnapshot := false fields := strings.Split(volName, "/") @@ -1121,6 +1232,22 @@ lxc storage volume get default virtual-machine/data snapshots.expiry cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Get the key as a storage volume property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + if len(args) == 2 { + return c.global.cmpStoragePoolVolumeConfigs(args[0], args[1]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1146,7 +1273,7 @@ func (c *cmdStorageVolumeGet) run(cmd *cobra.Command, args []string) error { client := resource.server // Parse input - volName, volType := c.storageVolume.parseVolume("custom", args[1]) + volName, volType := parseVolume("custom", args[1]) isSnapshot := false fields := strings.Split(volName, "/") @@ -1233,6 +1360,18 @@ lxc storage volume info default virtual-machine/data cmd.Flags().StringVar(&c.storage.flagTarget, "target", "", i18n.G("Cluster member name")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1258,7 +1397,7 @@ func (c *cmdStorageVolumeInfo) run(cmd *cobra.Command, args []string) error { client := resource.server // Parse the input - volName, volType := c.storageVolume.parseVolume("custom", args[1]) + volName, volType := parseVolume("custom", args[1]) isSnapshot := false fields := strings.Split(volName, "/") @@ -1470,6 +1609,14 @@ Column shorthand chars: cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1703,6 +1850,18 @@ func (c *cmdStorageVolumeMove) command() *cobra.Command { cmd.Flags().StringVar(&c.storageVolumeCopy.flagTargetProject, "target-project", "", i18n.G("Move to a project different from the source")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePoolWithVolume(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePools(toComplete) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1781,6 +1940,18 @@ func (c *cmdStorageVolumeRename) command() *cobra.Command { cmd.Flags().StringVar(&c.storage.flagTarget, "target", "", i18n.G("Cluster member name")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1806,7 +1977,7 @@ func (c *cmdStorageVolumeRename) run(cmd *cobra.Command, args []string) error { client := resource.server // Parse the input - volName, volType := c.storageVolume.parseVolume("custom", args[1]) + volName, volType := parseVolume("custom", args[1]) isSnapshot := false fields := strings.Split(volName, "/") @@ -1909,6 +2080,20 @@ lxc storage volume set default virtual-machine/data snapshots.expiry=7d cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Set the key as a storage volume property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + // TODO all volume config keys + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -1939,7 +2124,7 @@ func (c *cmdStorageVolumeSet) run(cmd *cobra.Command, args []string) error { } // Parse the input. - volName, volType := c.storageVolume.parseVolume("custom", args[1]) + volName, volType := parseVolume("custom", args[1]) isSnapshot := false fields := strings.Split(volName, "/") @@ -2054,6 +2239,18 @@ lxc storage volume show default virtual-machine/data/snap0 cmd.Flags().StringVar(&c.storage.flagTarget, "target", "", i18n.G("Cluster member name")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -2079,7 +2276,7 @@ func (c *cmdStorageVolumeShow) run(cmd *cobra.Command, args []string) error { client := resource.server // Parse the input - volName, volType := c.storageVolume.parseVolume("custom", args[1]) + volName, volType := parseVolume("custom", args[1]) isSnapshot := false fields := strings.Split(volName, "/") @@ -2159,6 +2356,22 @@ lxc storage volume unset default virtual-machine/data snapshots.expiry cmd.Flags().BoolVarP(&c.flagIsProperty, "property", "p", false, i18n.G("Unset the key as a storage volume property")) cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + if len(args) == 2 { + return c.global.cmpStoragePoolVolumeConfigs(args[0], args[1]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -2201,6 +2414,19 @@ lxc storage volume snapshot create default v1 snap0 < config.yaml cmd.Flags().BoolVar(&c.flagNoExpiry, "no-expiry", false, i18n.G("Ignore any configured auto-expiry for the storage volume")) cmd.Flags().BoolVar(&c.flagReuse, "reuse", false, i18n.G("If the snapshot name already exists, delete and create a new one")) cmd.Flags().StringVar(&c.storage.flagTarget, "target", "", i18n.G("Cluster member name")+"``") + cmd.RunE = c.run + + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } return cmd } @@ -2246,7 +2472,7 @@ func (c *cmdStorageVolumeSnapshot) run(cmd *cobra.Command, args []string) error } // Parse the input - volName, volType := c.storageVolume.parseVolume("custom", args[1]) + volName, volType := parseVolume("custom", args[1]) if volType != "custom" { return errors.New(i18n.G("Only \"custom\" volumes can be snapshotted")) } @@ -2318,6 +2544,22 @@ func (c *cmdStorageVolumeRestore) 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.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + if len(args) == 2 { + return c.global.cmpStoragePoolVolumeSnapshots(args[0], args[1]) + } + + return nil, cobra.ShellCompDirectiveNoFileComp + } + return cmd } @@ -2389,6 +2631,18 @@ func (c *cmdStorageVolumeExport) command() *cobra.Command { cmd.Flags().StringVar(&c.storage.flagTarget, "target", "", i18n.G("Cluster member name")+"``") cmd.RunE = c.run + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + if len(args) == 1 { + return c.global.cmpStoragePoolVolumes(args[0]) + } + + return nil, cobra.ShellCompDirectiveDefault + } + return cmd } @@ -2419,7 +2673,7 @@ func (c *cmdStorageVolumeExport) run(cmd *cobra.Command, args []string) error { volumeOnly := c.flagVolumeOnly - volName, volType := c.storageVolume.parseVolume("custom", args[1]) + volName, volType := parseVolume("custom", args[1]) if volType != "custom" { return errors.New(i18n.G("Only \"custom\" volumes can be exported")) } @@ -2542,6 +2796,14 @@ func (c *cmdStorageVolumeImport) command() *cobra.Command { cmd.RunE = c.run cmd.Flags().StringVar(&c.flagType, "type", "", i18n.G("Import type, backup or iso (default \"backup\")")+"``") + cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) == 0 { + return c.global.cmpStoragePools(toComplete) + } + + return nil, cobra.ShellCompDirectiveDefault + } + return cmd } diff --git a/po/ar.po b/po/ar.po index 4db639186503..cf5e5406eb82 100644 --- a/po/ar.po +++ b/po/ar.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: lxd\n" "Report-Msgid-Bugs-To: lxd@lists.canonical.com\n" -"POT-Creation-Date: 2024-08-30 14:10+0200\n" +"POT-Creation-Date: 2024-09-04 08:52-0600\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -29,7 +29,7 @@ msgid "" "### size: \"61203283968\"" msgstr "" -#: lxc/storage.go:261 +#: lxc/storage.go:281 msgid "" "### This is a YAML representation of a storage pool.\n" "### Any line starting with a '#' will be ignored.\n" @@ -46,7 +46,7 @@ msgid "" "### zfs.pool_name: default" msgstr "" -#: lxc/storage_volume.go:913 +#: lxc/storage_volume.go:1024 msgid "" "### This is a YAML representation of a storage volume.\n" "### Any line starting with a '# will be ignored.\n" @@ -60,7 +60,7 @@ msgid "" "### size: \"61203283968\"" msgstr "" -#: lxc/config.go:1174 +#: lxc/config.go:1227 msgid "" "### This is a YAML representation of the UEFI variables configuration.\n" "### Any line starting with a '# will be ignored.\n" @@ -103,13 +103,13 @@ msgid "" "### Note that the fingerprint is shown but cannot be changed" msgstr "" -#: lxc/cluster_group.go:385 +#: lxc/cluster_group.go:421 msgid "" "### This is a YAML representation of the cluster group.\n" "### Any line starting with a '# will be ignored." msgstr "" -#: lxc/config.go:113 +#: lxc/config.go:122 msgid "" "### This is a YAML representation of the configuration.\n" "### Any line starting with a '# will be ignored.\n" @@ -192,7 +192,7 @@ msgid "" "### Note that the name is shown but cannot be modified" msgstr "" -#: lxc/image.go:394 +#: lxc/image.go:419 msgid "" "### This is a YAML representation of the image properties.\n" "### Any line starting with a '# will be ignored.\n" @@ -202,7 +202,7 @@ msgid "" "### description: My custom image" msgstr "" -#: lxc/config_metadata.go:64 +#: lxc/config_metadata.go:73 msgid "" "### This is a YAML representation of the instance metadata.\n" "### Any line starting with a '# will be ignored.\n" @@ -226,7 +226,7 @@ msgid "" "### properties: {}" msgstr "" -#: lxc/network_acl.go:535 +#: lxc/network_acl.go:608 msgid "" "### This is a YAML representation of the network ACL.\n" "### Any line starting with a '# will be ignored.\n" @@ -254,7 +254,7 @@ msgid "" "configuration keys can be changed." msgstr "" -#: lxc/network_forward.go:590 +#: lxc/network_forward.go:667 msgid "" "### This is a YAML representation of the network forward.\n" "### Any line starting with a '# will be ignored.\n" @@ -278,7 +278,7 @@ msgid "" "### Note that the listen_address and location cannot be changed." msgstr "" -#: lxc/network_load_balancer.go:593 +#: lxc/network_load_balancer.go:637 msgid "" "### This is a YAML representation of the network load balancer.\n" "### Any line starting with a '# will be ignored.\n" @@ -302,7 +302,7 @@ msgid "" "### Note that the listen_address and location cannot be changed." msgstr "" -#: lxc/network_peer.go:525 +#: lxc/network_peer.go:613 msgid "" "### This is a YAML representation of the network peer.\n" "### Any line starting with a '# will be ignored.\n" @@ -319,7 +319,7 @@ msgid "" "cannot be changed." msgstr "" -#: lxc/network_zone.go:1075 +#: lxc/network_zone.go:1239 msgid "" "### This is a YAML representation of the network zone record.\n" "### Any line starting with a '# will be ignored.\n" @@ -333,7 +333,7 @@ msgid "" "### user.foo: bah\n" msgstr "" -#: lxc/network_zone.go:478 +#: lxc/network_zone.go:543 msgid "" "### This is a YAML representation of the network zone.\n" "### Any line starting with a '# will be ignored.\n" @@ -347,7 +347,7 @@ msgid "" "### user.foo: bah\n" msgstr "" -#: lxc/network.go:601 +#: lxc/network.go:674 msgid "" "### This is a YAML representation of the network.\n" "### Any line starting with a '# will be ignored.\n" @@ -367,7 +367,7 @@ msgid "" "### Note that only the configuration can be changed." msgstr "" -#: lxc/profile.go:456 +#: lxc/profile.go:513 msgid "" "### This is a YAML representation of the profile.\n" "### Any line starting with a '# will be ignored.\n" @@ -388,7 +388,7 @@ msgid "" "### Note that the name is shown but cannot be changed" msgstr "" -#: lxc/project.go:256 +#: lxc/project.go:280 msgid "" "### This is a YAML representation of the project.\n" "### Any line starting with a '# will be ignored.\n" @@ -409,23 +409,23 @@ msgid "" "### Note that the name is shown but cannot be changed" msgstr "" -#: lxc/cluster.go:701 +#: lxc/cluster.go:790 msgid "" "### This is a yaml representation of the cluster member.\n" "### Any line starting with a '# will be ignored." msgstr "" -#: lxc/info.go:320 +#: lxc/info.go:329 #, c-format msgid "%d (id: %d, online: %v, NUMA node: %v)" msgstr "" -#: lxc/image.go:1105 +#: lxc/image.go:1166 #, c-format msgid "%s (%d more)" msgstr "" -#: lxc/info.go:160 +#: lxc/info.go:169 #, c-format msgid "%s (%s) (%d available)" msgstr "" @@ -440,50 +440,50 @@ msgstr "" msgid "'%s' isn't a supported file type" msgstr "" -#: lxc/cluster_group.go:137 lxc/profile.go:226 +#: lxc/cluster_group.go:149 lxc/profile.go:247 msgid "(none)" msgstr "" -#: lxc/info.go:310 +#: lxc/info.go:319 #, c-format msgid "- Level %d (type: %s): %s" msgstr "" -#: lxc/info.go:288 +#: lxc/info.go:297 #, c-format msgid "- Partition %d" msgstr "" -#: lxc/info.go:196 +#: lxc/info.go:205 #, c-format msgid "- Port %d (%s)" msgstr "" -#: lxc/action.go:219 +#: lxc/action.go:236 msgid "--console can't be used while forcing instance shutdown" msgstr "" -#: lxc/action.go:368 +#: lxc/action.go:385 msgid "--console can't be used with --all" msgstr "" -#: lxc/action.go:372 +#: lxc/action.go:389 msgid "--console only works with a single instance" msgstr "" -#: lxc/init.go:133 lxc/rebuild.go:64 +#: lxc/init.go:142 lxc/rebuild.go:64 msgid "--empty cannot be combined with an image name" msgstr "" -#: lxc/config.go:472 lxc/config.go:768 +#: lxc/config.go:493 lxc/config.go:809 msgid "--expanded cannot be used with a server" msgstr "" -#: lxc/copy.go:156 +#: lxc/copy.go:169 msgid "--instance-only can't be passed when the source is a snapshot" msgstr "" -#: lxc/copy.go:90 +#: lxc/copy.go:103 msgid "--no-profiles cannot be used with --refresh" msgstr "" @@ -491,12 +491,12 @@ msgstr "" msgid "--project cannot be used with the query command" msgstr "" -#: lxc/copy.go:167 +#: lxc/copy.go:180 msgid "--refresh can only be used with instances" msgstr "" -#: lxc/config.go:161 lxc/config.go:422 lxc/config.go:595 lxc/config.go:794 -#: lxc/info.go:452 +#: lxc/config.go:170 lxc/config.go:443 lxc/config.go:628 lxc/config.go:835 +#: lxc/info.go:461 msgid "--target cannot be used with instances" msgstr "" @@ -512,11 +512,11 @@ msgstr "" msgid " " msgstr "" -#: lxc/remote.go:842 lxc/remote.go:899 +#: lxc/remote.go:850 lxc/remote.go:915 msgid "" msgstr "" -#: lxc/remote.go:939 +#: lxc/remote.go:963 msgid " " msgstr "" @@ -528,7 +528,7 @@ msgstr "" msgid "... [:]/" msgstr "" -#: lxc/image.go:662 +#: lxc/image.go:695 msgid "" "|| [] [:] [key=value...]" msgstr "" @@ -541,15 +541,15 @@ msgstr "" msgid "ADDRESS" msgstr "" -#: lxc/alias.go:139 lxc/image.go:1069 lxc/image_alias.go:234 +#: lxc/alias.go:139 lxc/image.go:1130 lxc/image_alias.go:234 msgid "ALIAS" msgstr "" -#: lxc/image.go:1070 +#: lxc/image.go:1131 msgid "ALIASES" msgstr "" -#: lxc/cluster.go:186 lxc/image.go:1075 lxc/list.go:553 +#: lxc/cluster.go:195 lxc/image.go:1136 lxc/list.go:562 msgid "ARCHITECTURE" msgstr "" @@ -574,7 +574,7 @@ msgstr "" msgid "Access key: %s" msgstr "" -#: lxc/config.go:387 +#: lxc/config.go:396 msgid "Access the expanded configuration" msgstr "" @@ -591,7 +591,7 @@ msgstr "" msgid "Action (defaults to GET)" msgstr "" -#: lxc/cluster_group.go:653 +#: lxc/cluster_group.go:725 msgid "Add a cluster member to a cluster group" msgstr "" @@ -603,27 +603,27 @@ msgstr "" msgid "Add a group to an identity provider group" msgstr "" -#: lxc/network_zone.go:1248 +#: lxc/network_zone.go:1424 msgid "Add a network zone record entry" msgstr "" -#: lxc/network_load_balancer.go:803 +#: lxc/network_load_balancer.go:859 msgid "Add backend to a load balancer" msgstr "" -#: lxc/network_load_balancer.go:802 +#: lxc/network_load_balancer.go:858 msgid "Add backends to a load balancer" msgstr "" -#: lxc/network_zone.go:1249 +#: lxc/network_zone.go:1425 msgid "Add entries to a network zone record" msgstr "" -#: lxc/config_device.go:77 lxc/config_device.go:78 +#: lxc/config_device.go:78 lxc/config_device.go:79 msgid "Add instance devices" msgstr "" -#: lxc/cluster_group.go:652 +#: lxc/cluster_group.go:724 msgid "Add member to group" msgstr "" @@ -672,27 +672,27 @@ msgstr "" msgid "Add permissions to groups" msgstr "" -#: lxc/network_forward.go:799 lxc/network_forward.go:800 +#: lxc/network_forward.go:888 lxc/network_forward.go:889 msgid "Add ports to a forward" msgstr "" -#: lxc/network_load_balancer.go:967 lxc/network_load_balancer.go:968 +#: lxc/network_load_balancer.go:1047 lxc/network_load_balancer.go:1048 msgid "Add ports to a load balancer" msgstr "" -#: lxc/profile.go:103 lxc/profile.go:104 +#: lxc/profile.go:104 lxc/profile.go:105 msgid "Add profiles to instances" msgstr "" -#: lxc/cluster_role.go:49 lxc/cluster_role.go:50 +#: lxc/cluster_role.go:50 lxc/cluster_role.go:51 msgid "Add roles to a cluster member" msgstr "" -#: lxc/network_acl.go:770 lxc/network_acl.go:771 +#: lxc/network_acl.go:859 lxc/network_acl.go:860 msgid "Add rules to an ACL" msgstr "" -#: lxc/info.go:200 +#: lxc/info.go:209 #, c-format msgid "Address: %s" msgstr "" @@ -726,16 +726,16 @@ msgstr "" msgid "Alias name missing" msgstr "" -#: lxc/publish.go:243 +#: lxc/publish.go:256 #, c-format msgid "Aliases already exists: %s" msgstr "" -#: lxc/image.go:990 +#: lxc/image.go:1043 msgid "Aliases:" msgstr "" -#: lxc/storage_volume.go:1451 +#: lxc/storage_volume.go:1590 msgid "All projects" msgstr "" @@ -747,17 +747,17 @@ msgstr "" msgid "Alternative certificate name" msgstr "" -#: lxc/image.go:961 lxc/info.go:477 +#: lxc/image.go:1014 lxc/info.go:486 #, c-format msgid "Architecture: %s" msgstr "" -#: lxc/info.go:126 +#: lxc/info.go:135 #, c-format msgid "Architecture: %v" msgstr "" -#: lxc/cluster.go:1224 +#: lxc/cluster.go:1371 #, c-format msgid "Are you sure you want to %s cluster member %q? (yes/no) [default=no]: " msgstr "" @@ -766,7 +766,7 @@ msgstr "" msgid "As neither could be found, the raw SPICE socket can be found at:" msgstr "" -#: lxc/init.go:333 lxc/rebuild.go:130 +#: lxc/init.go:342 lxc/rebuild.go:130 msgid "Asked for a VM but image is of type container" msgstr "" @@ -774,27 +774,27 @@ msgstr "" msgid "Assign sets of groups to cluster members" msgstr "" -#: lxc/profile.go:166 lxc/profile.go:167 +#: lxc/profile.go:179 lxc/profile.go:180 msgid "Assign sets of profiles to instances" msgstr "" -#: lxc/network.go:134 +#: lxc/network.go:135 msgid "Attach network interfaces to instances" msgstr "" -#: lxc/network.go:219 lxc/network.go:220 +#: lxc/network.go:232 lxc/network.go:233 msgid "Attach network interfaces to profiles" msgstr "" -#: lxc/network.go:135 +#: lxc/network.go:136 msgid "Attach new network interfaces to instances" msgstr "" -#: lxc/storage_volume.go:165 lxc/storage_volume.go:166 +#: lxc/storage_volume.go:168 lxc/storage_volume.go:169 msgid "Attach new storage volumes to instances" msgstr "" -#: lxc/storage_volume.go:263 lxc/storage_volume.go:264 +#: lxc/storage_volume.go:282 lxc/storage_volume.go:283 msgid "Attach new storage volumes to profiles" msgstr "" @@ -815,21 +815,21 @@ msgstr "" msgid "Authentication type '%s' not supported by server" msgstr "" -#: lxc/info.go:219 +#: lxc/info.go:228 #, c-format msgid "Auto negotiation: %v" msgstr "" -#: lxc/image.go:187 +#: lxc/image.go:200 msgid "Auto update is only available in pull mode" msgstr "" -#: lxc/image.go:1000 +#: lxc/image.go:1053 #, c-format msgid "Auto update: %s" msgstr "" -#: lxc/network_forward.go:245 lxc/network_load_balancer.go:247 +#: lxc/network_forward.go:265 lxc/network_load_balancer.go:267 msgid "Auto-allocate an IPv4 or IPv6 listen address. One of 'ipv4', 'ipv6'." msgstr "" @@ -837,7 +837,7 @@ msgstr "" msgid "Available projects:" msgstr "" -#: lxc/list.go:559 lxc/list.go:560 +#: lxc/list.go:568 lxc/list.go:569 msgid "BASE IMAGE" msgstr "" @@ -846,16 +846,16 @@ msgstr "" msgid "Backing up instance: %s" msgstr "" -#: lxc/storage_volume.go:2442 +#: lxc/storage_volume.go:2696 #, c-format msgid "Backing up storage volume: %s" msgstr "" -#: lxc/export.go:192 lxc/storage_volume.go:2519 +#: lxc/export.go:192 lxc/storage_volume.go:2773 msgid "Backup exported successfully!" msgstr "" -#: lxc/info.go:645 lxc/storage_volume.go:1382 +#: lxc/info.go:654 lxc/storage_volume.go:1521 msgid "Backups:" msgstr "" @@ -864,50 +864,50 @@ msgstr "" msgid "Bad device override syntax, expecting ,=: %s" msgstr "" -#: lxc/network.go:333 lxc/network_acl.go:387 lxc/network_forward.go:298 -#: lxc/network_load_balancer.go:301 lxc/network_peer.go:280 -#: lxc/network_zone.go:329 lxc/network_zone.go:931 lxc/storage_bucket.go:141 +#: lxc/network.go:366 lxc/network_acl.go:431 lxc/network_forward.go:318 +#: lxc/network_load_balancer.go:321 lxc/network_peer.go:309 +#: lxc/network_zone.go:366 lxc/network_zone.go:1053 lxc/storage_bucket.go:141 #, c-format msgid "Bad key/value pair: %s" msgstr "" -#: lxc/copy.go:139 lxc/init.go:232 lxc/move.go:380 lxc/project.go:151 +#: lxc/copy.go:152 lxc/init.go:241 lxc/move.go:393 lxc/project.go:159 #, c-format msgid "Bad key=value pair: %q" msgstr "" -#: lxc/publish.go:180 lxc/storage.go:152 lxc/storage_volume.go:624 +#: lxc/publish.go:193 lxc/storage.go:162 lxc/storage_volume.go:679 #, c-format msgid "Bad key=value pair: %s" msgstr "" -#: lxc/image.go:769 +#: lxc/image.go:814 #, c-format msgid "Bad property: %s" msgstr "" -#: lxc/network.go:859 +#: lxc/network.go:952 msgid "Bond:" msgstr "" -#: lxc/action.go:147 lxc/action.go:324 +#: lxc/action.go:164 lxc/action.go:341 msgid "Both --all and instance name given" msgstr "" -#: lxc/info.go:127 +#: lxc/info.go:136 #, c-format msgid "Brand: %v" msgstr "" -#: lxc/network.go:872 +#: lxc/network.go:965 msgid "Bridge:" msgstr "" -#: lxc/info.go:568 lxc/network.go:851 +#: lxc/info.go:577 lxc/network.go:944 msgid "Bytes received" msgstr "" -#: lxc/info.go:569 lxc/network.go:852 +#: lxc/info.go:578 lxc/network.go:945 msgid "Bytes sent" msgstr "" @@ -919,7 +919,7 @@ msgstr "" msgid "COMMON NAME" msgstr "" -#: lxc/storage_volume.go:1586 +#: lxc/storage_volume.go:1733 msgid "CONTENT-TYPE" msgstr "" @@ -927,24 +927,24 @@ msgstr "" msgid "COUNT" msgstr "" -#: lxc/info.go:355 +#: lxc/info.go:364 #, c-format msgid "CPU (%s):" msgstr "" -#: lxc/list.go:571 +#: lxc/list.go:580 msgid "CPU USAGE" msgstr "" -#: lxc/info.go:518 +#: lxc/info.go:527 msgid "CPU usage (in seconds)" msgstr "" -#: lxc/info.go:522 +#: lxc/info.go:531 msgid "CPU usage:" msgstr "" -#: lxc/info.go:358 +#: lxc/info.go:367 #, c-format msgid "CPUs (%s):" msgstr "" @@ -953,29 +953,29 @@ msgstr "" msgid "CREATED" msgstr "" -#: lxc/list.go:555 +#: lxc/list.go:564 msgid "CREATED AT" msgstr "" -#: lxc/info.go:129 +#: lxc/info.go:138 #, c-format msgid "CUDA Version: %v" msgstr "" -#: lxc/image.go:999 +#: lxc/image.go:1052 #, c-format msgid "Cached: %s" msgstr "" -#: lxc/info.go:308 +#: lxc/info.go:317 msgid "Caches:" msgstr "" -#: lxc/move.go:117 +#: lxc/move.go:130 msgid "Can't override configuration or profiles in local rename" msgstr "" -#: lxc/image.go:220 +#: lxc/image.go:233 msgid "Can't provide a name for the target image" msgstr "" @@ -988,23 +988,23 @@ msgstr "" msgid "Can't read from stdin: %w" msgstr "" -#: lxc/remote.go:878 +#: lxc/remote.go:894 msgid "Can't remove the default remote" msgstr "" -#: lxc/list.go:585 +#: lxc/list.go:594 msgid "Can't specify --fast with --columns" msgstr "" -#: lxc/list.go:458 +#: lxc/list.go:467 msgid "Can't specify --project with --all-projects" msgstr "" -#: lxc/rename.go:51 +#: lxc/rename.go:60 msgid "Can't specify a different remote for rename" msgstr "" -#: lxc/list.go:601 lxc/storage_volume.go:1596 lxc/warning.go:224 +#: lxc/list.go:610 lxc/storage_volume.go:1743 lxc/warning.go:224 msgid "Can't specify column L when not clustered" msgstr "" @@ -1012,7 +1012,7 @@ msgstr "" msgid "Can't supply uid/gid/mode in recursive mode" msgstr "" -#: lxc/config.go:661 lxc/config.go:1031 +#: lxc/config.go:694 lxc/config.go:1084 #, c-format msgid "Can't unset key '%s', it's not currently set" msgstr "" @@ -1021,16 +1021,16 @@ msgstr "" msgid "Can't use an image with --empty" msgstr "" -#: lxc/storage_volume.go:439 +#: lxc/storage_volume.go:486 msgid "" "Cannot set --destination-target when destination server is not clustered" msgstr "" -#: lxc/storage_volume.go:393 +#: lxc/storage_volume.go:440 msgid "Cannot set --target when source server is not clustered" msgstr "" -#: lxc/network_acl.go:824 +#: lxc/network_acl.go:929 #, c-format msgid "Cannot set key: %s" msgstr "" @@ -1039,12 +1039,12 @@ msgstr "" msgid "Cannot use metrics type certificate when using a token" msgstr "" -#: lxc/info.go:402 lxc/info.go:414 +#: lxc/info.go:411 lxc/info.go:423 #, c-format msgid "Card %d:" msgstr "" -#: lxc/info.go:112 +#: lxc/info.go:121 #, c-format msgid "Card: %s (%s)" msgstr "" @@ -1064,7 +1064,7 @@ msgid "" "Certificate fingerprint mismatch between certificate token and server %q" msgstr "" -#: lxc/network.go:893 +#: lxc/network.go:986 msgid "Chassis" msgstr "" @@ -1082,94 +1082,94 @@ msgstr "" msgid "Client version: %s\n" msgstr "" -#: lxc/cluster_group.go:218 +#: lxc/cluster_group.go:238 #, c-format msgid "Cluster group %s created" msgstr "" -#: lxc/cluster_group.go:271 +#: lxc/cluster_group.go:299 #, c-format msgid "Cluster group %s deleted" msgstr "" -#: lxc/cluster_group.go:513 +#: lxc/cluster_group.go:569 #, c-format msgid "Cluster group %s isn't currently applied to %s" msgstr "" -#: lxc/cluster_group.go:582 +#: lxc/cluster_group.go:646 #, c-format msgid "Cluster group %s renamed to %s" msgstr "" -#: lxc/cluster.go:1040 +#: lxc/cluster.go:1154 #, c-format msgid "Cluster join token for %s:%s deleted" msgstr "" -#: lxc/cluster_group.go:141 +#: lxc/cluster_group.go:153 #, c-format msgid "Cluster member %s added to cluster groups %s" msgstr "" -#: lxc/cluster_group.go:698 +#: lxc/cluster_group.go:782 #, c-format msgid "Cluster member %s added to group %s" msgstr "" -#: lxc/cluster_group.go:687 +#: lxc/cluster_group.go:771 #, c-format msgid "Cluster member %s is already in group %s" msgstr "" -#: lxc/cluster_group.go:533 +#: lxc/cluster_group.go:589 #, c-format msgid "Cluster member %s removed from group %s" msgstr "" -#: lxc/config.go:105 lxc/config.go:389 lxc/config.go:529 lxc/config.go:735 -#: lxc/config.go:858 lxc/copy.go:61 lxc/info.go:44 lxc/init.go:64 -#: lxc/move.go:66 lxc/network.go:300 lxc/network.go:723 lxc/network.go:792 -#: lxc/network.go:1134 lxc/network.go:1219 lxc/network.go:1283 -#: lxc/network_forward.go:174 lxc/network_forward.go:244 -#: lxc/network_forward.go:461 lxc/network_forward.go:584 -#: lxc/network_forward.go:726 lxc/network_forward.go:803 -#: lxc/network_forward.go:869 lxc/network_load_balancer.go:176 -#: lxc/network_load_balancer.go:246 lxc/network_load_balancer.go:464 -#: lxc/network_load_balancer.go:587 lxc/network_load_balancer.go:730 -#: lxc/network_load_balancer.go:806 lxc/network_load_balancer.go:870 -#: lxc/network_load_balancer.go:971 lxc/network_load_balancer.go:1033 -#: lxc/storage.go:105 lxc/storage.go:376 lxc/storage.go:447 lxc/storage.go:700 -#: lxc/storage.go:794 lxc/storage.go:879 lxc/storage_bucket.go:90 +#: lxc/config.go:106 lxc/config.go:398 lxc/config.go:550 lxc/config.go:768 +#: lxc/config.go:899 lxc/copy.go:62 lxc/info.go:45 lxc/init.go:65 +#: lxc/move.go:67 lxc/network.go:325 lxc/network.go:796 lxc/network.go:877 +#: lxc/network.go:1251 lxc/network.go:1344 lxc/network.go:1416 +#: lxc/network_forward.go:182 lxc/network_forward.go:264 +#: lxc/network_forward.go:497 lxc/network_forward.go:649 +#: lxc/network_forward.go:803 lxc/network_forward.go:892 +#: lxc/network_forward.go:974 lxc/network_load_balancer.go:184 +#: lxc/network_load_balancer.go:266 lxc/network_load_balancer.go:484 +#: lxc/network_load_balancer.go:619 lxc/network_load_balancer.go:774 +#: lxc/network_load_balancer.go:862 lxc/network_load_balancer.go:938 +#: lxc/network_load_balancer.go:1051 lxc/network_load_balancer.go:1125 +#: lxc/storage.go:105 lxc/storage.go:396 lxc/storage.go:479 lxc/storage.go:748 +#: lxc/storage.go:850 lxc/storage.go:943 lxc/storage_bucket.go:90 #: lxc/storage_bucket.go:190 lxc/storage_bucket.go:253 #: lxc/storage_bucket.go:384 lxc/storage_bucket.go:541 #: lxc/storage_bucket.go:634 lxc/storage_bucket.go:700 #: lxc/storage_bucket.go:775 lxc/storage_bucket.go:861 #: lxc/storage_bucket.go:961 lxc/storage_bucket.go:1026 -#: lxc/storage_bucket.go:1162 lxc/storage_volume.go:359 -#: lxc/storage_volume.go:565 lxc/storage_volume.go:662 -#: lxc/storage_volume.go:906 lxc/storage_volume.go:1120 -#: lxc/storage_volume.go:1233 lxc/storage_volume.go:1701 -#: lxc/storage_volume.go:1781 lxc/storage_volume.go:1908 -#: lxc/storage_volume.go:2054 lxc/storage_volume.go:2158 -#: lxc/storage_volume.go:2203 lxc/storage_volume.go:2317 -#: lxc/storage_volume.go:2389 lxc/storage_volume.go:2541 +#: lxc/storage_bucket.go:1162 lxc/storage_volume.go:394 +#: lxc/storage_volume.go:612 lxc/storage_volume.go:717 +#: lxc/storage_volume.go:1005 lxc/storage_volume.go:1231 +#: lxc/storage_volume.go:1360 lxc/storage_volume.go:1848 +#: lxc/storage_volume.go:1940 lxc/storage_volume.go:2079 +#: lxc/storage_volume.go:2239 lxc/storage_volume.go:2355 +#: lxc/storage_volume.go:2416 lxc/storage_volume.go:2543 +#: lxc/storage_volume.go:2631 lxc/storage_volume.go:2795 msgid "Cluster member name" msgstr "" -#: lxc/cluster.go:805 +#: lxc/cluster.go:894 msgid "Cluster member name (alternative to passing it as an argument)" msgstr "" -#: lxc/cluster.go:829 +#: lxc/cluster.go:926 msgid "Cluster member name was provided as both a flag and as an argument" msgstr "" -#: lxc/cluster.go:675 +#: lxc/cluster.go:756 msgid "Clustering enabled" msgstr "" -#: lxc/image.go:1060 lxc/list.go:131 lxc/storage_volume.go:1450 +#: lxc/image.go:1113 lxc/list.go:132 lxc/storage_volume.go:1589 #: lxc/warning.go:92 msgid "Columns" msgstr "" @@ -1186,7 +1186,7 @@ msgid "" "For help with any of those, simply call them with --help." msgstr "" -#: lxc/publish.go:40 +#: lxc/publish.go:41 msgid "Compression algorithm to use (`none` for uncompressed)" msgstr "" @@ -1194,7 +1194,7 @@ msgstr "" msgid "Compression algorithm to use (none for uncompressed)" msgstr "" -#: lxc/copy.go:53 lxc/init.go:57 +#: lxc/copy.go:54 lxc/init.go:58 msgid "Config key/value to apply to the new instance" msgstr "" @@ -1202,50 +1202,50 @@ msgstr "" msgid "Config key/value to apply to the new project" msgstr "" -#: lxc/move.go:58 +#: lxc/move.go:59 msgid "Config key/value to apply to the target instance" msgstr "" -#: lxc/cluster.go:770 lxc/cluster_group.go:361 lxc/config.go:272 -#: lxc/config.go:347 lxc/config.go:1274 lxc/config_metadata.go:147 -#: lxc/config_trust.go:314 lxc/image.go:466 lxc/network.go:686 -#: lxc/network_acl.go:625 lxc/network_forward.go:690 -#: lxc/network_load_balancer.go:694 lxc/network_peer.go:610 -#: lxc/network_zone.go:556 lxc/network_zone.go:1152 lxc/profile.go:538 -#: lxc/project.go:338 lxc/storage.go:339 lxc/storage_bucket.go:348 -#: lxc/storage_bucket.go:1125 lxc/storage_volume.go:1039 -#: lxc/storage_volume.go:1071 +#: lxc/cluster.go:859 lxc/cluster_group.go:397 lxc/config.go:281 +#: lxc/config.go:356 lxc/config.go:1327 lxc/config_metadata.go:156 +#: lxc/config_trust.go:314 lxc/image.go:491 lxc/network.go:759 +#: lxc/network_acl.go:698 lxc/network_forward.go:767 +#: lxc/network_load_balancer.go:738 lxc/network_peer.go:698 +#: lxc/network_zone.go:621 lxc/network_zone.go:1316 lxc/profile.go:595 +#: lxc/project.go:362 lxc/storage.go:359 lxc/storage_bucket.go:348 +#: lxc/storage_bucket.go:1125 lxc/storage_volume.go:1150 +#: lxc/storage_volume.go:1182 #, c-format msgid "Config parsing error: %s" msgstr "" -#: lxc/storage_volume.go:566 +#: lxc/storage_volume.go:613 msgid "Content type, block or filesystem" msgstr "" -#: lxc/storage_volume.go:1322 +#: lxc/storage_volume.go:1461 #, c-format msgid "Content type: %s" msgstr "" -#: lxc/info.go:116 +#: lxc/info.go:125 #, c-format msgid "Control: %s (%s)" msgstr "" -#: lxc/copy.go:59 lxc/move.go:64 +#: lxc/copy.go:60 lxc/move.go:65 msgid "Copy a stateful instance stateless" msgstr "" -#: lxc/image.go:165 +#: lxc/image.go:166 msgid "Copy aliases from source" msgstr "" -#: lxc/image.go:157 +#: lxc/image.go:158 msgid "Copy images between servers" msgstr "" -#: lxc/image.go:158 +#: lxc/image.go:159 msgid "" "Copy images between servers\n" "\n" @@ -1253,11 +1253,11 @@ msgid "" "It requires the source to be an alias and for it to be public." msgstr "" -#: lxc/copy.go:40 +#: lxc/copy.go:41 msgid "Copy instances within or in between LXD servers" msgstr "" -#: lxc/copy.go:41 +#: lxc/copy.go:42 msgid "" "Copy instances within or in between LXD servers\n" "\n" @@ -1273,51 +1273,51 @@ msgid "" "versions.\n" msgstr "" -#: lxc/config_device.go:355 lxc/config_device.go:356 +#: lxc/config_device.go:400 lxc/config_device.go:401 msgid "Copy profile inherited devices and override configuration keys" msgstr "" -#: lxc/profile.go:249 lxc/profile.go:250 +#: lxc/profile.go:270 lxc/profile.go:271 msgid "Copy profiles" msgstr "" -#: lxc/storage_volume.go:354 lxc/storage_volume.go:355 +#: lxc/storage_volume.go:389 lxc/storage_volume.go:390 msgid "Copy storage volumes" msgstr "" -#: lxc/copy.go:58 +#: lxc/copy.go:59 msgid "Copy the instance without its snapshots" msgstr "" -#: lxc/storage_volume.go:361 +#: lxc/storage_volume.go:396 msgid "Copy the volume without its snapshots" msgstr "" -#: lxc/copy.go:62 lxc/image.go:170 lxc/move.go:67 lxc/profile.go:252 -#: lxc/storage_volume.go:362 +#: lxc/copy.go:63 lxc/image.go:171 lxc/move.go:68 lxc/profile.go:273 +#: lxc/storage_volume.go:397 msgid "Copy to a project different from the source" msgstr "" -#: lxc/image.go:168 +#: lxc/image.go:169 msgid "Copy virtual machine images" msgstr "" -#: lxc/image.go:275 +#: lxc/image.go:288 #, c-format msgid "Copying the image: %s" msgstr "" -#: lxc/storage_volume.go:461 +#: lxc/storage_volume.go:508 #, c-format msgid "Copying the storage volume: %s" msgstr "" -#: lxc/info.go:316 +#: lxc/info.go:325 #, c-format msgid "Core %d" msgstr "" -#: lxc/info.go:314 +#: lxc/info.go:323 msgid "Cores:" msgstr "" @@ -1330,12 +1330,12 @@ msgstr "" msgid "Could not create server cert dir" msgstr "" -#: lxc/cluster.go:1104 +#: lxc/cluster.go:1235 #, c-format msgid "Could not find certificate file path: %s" msgstr "" -#: lxc/cluster.go:1108 +#: lxc/cluster.go:1239 #, c-format msgid "Could not find certificate key file path: %s" msgstr "" @@ -1350,17 +1350,17 @@ msgstr "" msgid "Could not parse identity: %s" msgstr "" -#: lxc/cluster.go:1113 +#: lxc/cluster.go:1244 #, c-format msgid "Could not read certificate file: %s with error: %v" msgstr "" -#: lxc/cluster.go:1118 +#: lxc/cluster.go:1249 #, c-format msgid "Could not read certificate key file: %s with error: %v" msgstr "" -#: lxc/cluster.go:1135 +#: lxc/cluster.go:1266 #, c-format msgid "Could not write new remote certificate for remote '%s' with error: %v" msgstr "" @@ -1370,15 +1370,15 @@ msgstr "" msgid "Could not write server cert file %q: %w" msgstr "" -#: lxc/network_zone.go:1336 +#: lxc/network_zone.go:1536 msgid "Couldn't find a matching entry" msgstr "" -#: lxc/cluster_group.go:157 lxc/cluster_group.go:158 +#: lxc/cluster_group.go:169 lxc/cluster_group.go:170 msgid "Create a cluster group" msgstr "" -#: lxc/init.go:67 +#: lxc/init.go:68 msgid "Create a virtual machine" msgstr "" @@ -1386,7 +1386,7 @@ msgstr "" msgid "Create aliases for existing images" msgstr "" -#: lxc/init.go:66 +#: lxc/init.go:67 msgid "Create an empty instance" msgstr "" @@ -1418,7 +1418,7 @@ msgid "" "running state, including process memory state, TCP connections, ..." msgstr "" -#: lxc/init.go:42 lxc/init.go:43 +#: lxc/init.go:43 lxc/init.go:44 msgid "Create instances from images" msgstr "" @@ -1430,43 +1430,43 @@ msgstr "" msgid "Create new custom storage buckets" msgstr "" -#: lxc/storage_volume.go:557 lxc/storage_volume.go:558 +#: lxc/storage_volume.go:604 lxc/storage_volume.go:605 msgid "Create new custom storage volumes" msgstr "" -#: lxc/config_template.go:66 lxc/config_template.go:67 +#: lxc/config_template.go:67 lxc/config_template.go:68 msgid "Create new instance file templates" msgstr "" -#: lxc/network_acl.go:327 lxc/network_acl.go:328 +#: lxc/network_acl.go:363 lxc/network_acl.go:364 msgid "Create new network ACLs" msgstr "" -#: lxc/network_forward.go:235 lxc/network_forward.go:236 +#: lxc/network_forward.go:255 lxc/network_forward.go:256 msgid "Create new network forwards" msgstr "" -#: lxc/network_load_balancer.go:237 lxc/network_load_balancer.go:238 +#: lxc/network_load_balancer.go:257 lxc/network_load_balancer.go:258 msgid "Create new network load balancers" msgstr "" -#: lxc/network_peer.go:214 lxc/network_peer.go:215 +#: lxc/network_peer.go:235 lxc/network_peer.go:236 msgid "Create new network peering" msgstr "" -#: lxc/network_zone.go:874 lxc/network_zone.go:875 +#: lxc/network_zone.go:984 lxc/network_zone.go:985 msgid "Create new network zone record" msgstr "" -#: lxc/network_zone.go:271 lxc/network_zone.go:272 +#: lxc/network_zone.go:300 lxc/network_zone.go:301 msgid "Create new network zones" msgstr "" -#: lxc/network.go:292 lxc/network.go:293 +#: lxc/network.go:317 lxc/network.go:318 msgid "Create new networks" msgstr "" -#: lxc/profile.go:319 lxc/profile.go:320 +#: lxc/profile.go:352 lxc/profile.go:353 msgid "Create profiles" msgstr "" @@ -1478,61 +1478,61 @@ msgstr "" msgid "Create storage pools" msgstr "" -#: lxc/copy.go:63 lxc/init.go:65 +#: lxc/copy.go:64 lxc/init.go:66 msgid "Create the instance with no profiles applied" msgstr "" -#: lxc/image.go:968 lxc/info.go:488 lxc/storage_volume.go:1336 +#: lxc/image.go:1021 lxc/info.go:497 lxc/storage_volume.go:1475 #, c-format msgid "Created: %s" msgstr "" -#: lxc/init.go:177 +#: lxc/init.go:186 #, c-format msgid "Creating %s" msgstr "" -#: lxc/init.go:175 +#: lxc/init.go:184 msgid "Creating the instance" msgstr "" -#: lxc/info.go:136 lxc/info.go:245 +#: lxc/info.go:145 lxc/info.go:254 #, c-format msgid "Current number of VFs: %d" msgstr "" -#: lxc/network_forward.go:150 +#: lxc/network_forward.go:158 msgid "DEFAULT TARGET ADDRESS" msgstr "" -#: lxc/auth.go:376 lxc/cluster.go:188 lxc/cluster_group.go:460 -#: lxc/image.go:1074 lxc/image_alias.go:237 lxc/list.go:556 lxc/network.go:985 -#: lxc/network_acl.go:149 lxc/network_forward.go:149 -#: lxc/network_load_balancer.go:152 lxc/network_peer.go:140 -#: lxc/network_zone.go:140 lxc/network_zone.go:747 lxc/operation.go:172 -#: lxc/profile.go:678 lxc/project.go:528 lxc/storage.go:675 +#: lxc/auth.go:376 lxc/cluster.go:197 lxc/cluster_group.go:504 +#: lxc/image.go:1135 lxc/image_alias.go:237 lxc/list.go:565 lxc/network.go:1086 +#: lxc/network_acl.go:157 lxc/network_forward.go:157 +#: lxc/network_load_balancer.go:160 lxc/network_peer.go:149 +#: lxc/network_zone.go:148 lxc/network_zone.go:828 lxc/operation.go:172 +#: lxc/profile.go:756 lxc/project.go:572 lxc/storage.go:723 #: lxc/storage_bucket.go:512 lxc/storage_bucket.go:832 -#: lxc/storage_volume.go:1585 +#: lxc/storage_volume.go:1732 msgid "DESCRIPTION" msgstr "" -#: lxc/list.go:557 +#: lxc/list.go:566 msgid "DISK USAGE" msgstr "" -#: lxc/storage.go:668 +#: lxc/storage.go:716 msgid "DRIVER" msgstr "" -#: lxc/info.go:108 +#: lxc/info.go:117 msgid "DRM:" msgstr "" -#: lxc/network.go:876 +#: lxc/network.go:969 msgid "Default VLAN ID" msgstr "" -#: lxc/storage_volume.go:2388 +#: lxc/storage_volume.go:2630 msgid "Define a compression algorithm: for backup or none" msgstr "" @@ -1540,7 +1540,7 @@ msgstr "" msgid "Delete a background operation (will attempt to cancel)" msgstr "" -#: lxc/cluster_group.go:235 lxc/cluster_group.go:236 +#: lxc/cluster_group.go:255 lxc/cluster_group.go:256 msgid "Delete a cluster group" msgstr "" @@ -1564,15 +1564,15 @@ msgstr "" msgid "Delete image aliases" msgstr "" -#: lxc/image.go:323 lxc/image.go:324 +#: lxc/image.go:336 lxc/image.go:337 msgid "Delete images" msgstr "" -#: lxc/config_template.go:109 lxc/config_template.go:110 +#: lxc/config_template.go:118 lxc/config_template.go:119 msgid "Delete instance file templates" msgstr "" -#: lxc/delete.go:30 lxc/delete.go:31 +#: lxc/delete.go:31 lxc/delete.go:32 msgid "Delete instances and snapshots" msgstr "" @@ -1580,39 +1580,39 @@ msgstr "" msgid "Delete key from a storage bucket" msgstr "" -#: lxc/network_acl.go:706 lxc/network_acl.go:707 +#: lxc/network_acl.go:787 lxc/network_acl.go:788 msgid "Delete network ACLs" msgstr "" -#: lxc/network_forward.go:722 lxc/network_forward.go:723 +#: lxc/network_forward.go:799 lxc/network_forward.go:800 msgid "Delete network forwards" msgstr "" -#: lxc/network_load_balancer.go:726 lxc/network_load_balancer.go:727 +#: lxc/network_load_balancer.go:770 lxc/network_load_balancer.go:771 msgid "Delete network load balancers" msgstr "" -#: lxc/network_peer.go:642 lxc/network_peer.go:643 +#: lxc/network_peer.go:730 lxc/network_peer.go:731 msgid "Delete network peerings" msgstr "" -#: lxc/network_zone.go:1184 lxc/network_zone.go:1185 +#: lxc/network_zone.go:1348 lxc/network_zone.go:1349 msgid "Delete network zone record" msgstr "" -#: lxc/network_zone.go:588 lxc/network_zone.go:589 +#: lxc/network_zone.go:653 lxc/network_zone.go:654 msgid "Delete network zones" msgstr "" -#: lxc/network.go:371 lxc/network.go:372 +#: lxc/network.go:404 lxc/network.go:405 msgid "Delete networks" msgstr "" -#: lxc/profile.go:393 lxc/profile.go:394 +#: lxc/profile.go:434 lxc/profile.go:435 msgid "Delete profiles" msgstr "" -#: lxc/project.go:180 lxc/project.go:181 +#: lxc/project.go:188 lxc/project.go:189 msgid "Delete projects" msgstr "" @@ -1620,11 +1620,11 @@ msgstr "" msgid "Delete storage buckets" msgstr "" -#: lxc/storage.go:198 lxc/storage.go:199 +#: lxc/storage.go:202 lxc/storage.go:203 msgid "Delete storage pools" msgstr "" -#: lxc/storage_volume.go:658 lxc/storage_volume.go:659 +#: lxc/storage_volume.go:713 lxc/storage_volume.go:714 msgid "Delete storage volumes" msgstr "" @@ -1632,7 +1632,7 @@ msgstr "" msgid "Delete warning" msgstr "" -#: lxc/action.go:32 lxc/action.go:53 lxc/action.go:75 lxc/action.go:98 +#: lxc/action.go:33 lxc/action.go:58 lxc/action.go:84 lxc/action.go:111 #: lxc/alias.go:23 lxc/alias.go:60 lxc/alias.go:110 lxc/alias.go:159 #: lxc/alias.go:214 lxc/auth.go:30 lxc/auth.go:59 lxc/auth.go:98 #: lxc/auth.go:152 lxc/auth.go:201 lxc/auth.go:332 lxc/auth.go:392 @@ -1642,85 +1642,85 @@ msgstr "" #: lxc/auth.go:1234 lxc/auth.go:1256 lxc/auth.go:1434 lxc/auth.go:1472 #: lxc/auth.go:1524 lxc/auth.go:1573 lxc/auth.go:1692 lxc/auth.go:1752 #: lxc/auth.go:1801 lxc/auth.go:1852 lxc/auth.go:1875 lxc/auth.go:1928 -#: lxc/cluster.go:29 lxc/cluster.go:122 lxc/cluster.go:206 lxc/cluster.go:255 -#: lxc/cluster.go:306 lxc/cluster.go:367 lxc/cluster.go:439 lxc/cluster.go:471 -#: lxc/cluster.go:521 lxc/cluster.go:604 lxc/cluster.go:689 lxc/cluster.go:804 -#: lxc/cluster.go:880 lxc/cluster.go:982 lxc/cluster.go:1061 -#: lxc/cluster.go:1168 lxc/cluster.go:1190 lxc/cluster_group.go:31 -#: lxc/cluster_group.go:85 lxc/cluster_group.go:158 lxc/cluster_group.go:236 -#: lxc/cluster_group.go:288 lxc/cluster_group.go:404 lxc/cluster_group.go:478 -#: lxc/cluster_group.go:551 lxc/cluster_group.go:599 lxc/cluster_group.go:653 -#: lxc/cluster_role.go:23 lxc/cluster_role.go:50 lxc/cluster_role.go:106 -#: lxc/config.go:32 lxc/config.go:99 lxc/config.go:384 lxc/config.go:517 -#: lxc/config.go:731 lxc/config.go:855 lxc/config.go:890 lxc/config.go:930 -#: lxc/config.go:985 lxc/config.go:1076 lxc/config.go:1107 lxc/config.go:1161 -#: lxc/config_device.go:24 lxc/config_device.go:78 lxc/config_device.go:208 -#: lxc/config_device.go:285 lxc/config_device.go:356 lxc/config_device.go:450 -#: lxc/config_device.go:548 lxc/config_device.go:555 lxc/config_device.go:668 -#: lxc/config_device.go:741 lxc/config_metadata.go:27 lxc/config_metadata.go:55 -#: lxc/config_metadata.go:180 lxc/config_template.go:27 -#: lxc/config_template.go:67 lxc/config_template.go:110 -#: lxc/config_template.go:152 lxc/config_template.go:240 -#: lxc/config_template.go:300 lxc/config_trust.go:34 lxc/config_trust.go:87 +#: lxc/cluster.go:30 lxc/cluster.go:123 lxc/cluster.go:215 lxc/cluster.go:272 +#: lxc/cluster.go:331 lxc/cluster.go:404 lxc/cluster.go:484 lxc/cluster.go:528 +#: lxc/cluster.go:586 lxc/cluster.go:677 lxc/cluster.go:770 lxc/cluster.go:893 +#: lxc/cluster.go:977 lxc/cluster.go:1087 lxc/cluster.go:1175 +#: lxc/cluster.go:1299 lxc/cluster.go:1329 lxc/cluster_group.go:31 +#: lxc/cluster_group.go:85 lxc/cluster_group.go:170 lxc/cluster_group.go:256 +#: lxc/cluster_group.go:316 lxc/cluster_group.go:440 lxc/cluster_group.go:522 +#: lxc/cluster_group.go:607 lxc/cluster_group.go:663 lxc/cluster_group.go:725 +#: lxc/cluster_role.go:24 lxc/cluster_role.go:51 lxc/cluster_role.go:115 +#: lxc/config.go:33 lxc/config.go:100 lxc/config.go:393 lxc/config.go:538 +#: lxc/config.go:764 lxc/config.go:896 lxc/config.go:943 lxc/config.go:983 +#: lxc/config.go:1038 lxc/config.go:1129 lxc/config.go:1160 lxc/config.go:1214 +#: lxc/config_device.go:25 lxc/config_device.go:79 lxc/config_device.go:221 +#: lxc/config_device.go:318 lxc/config_device.go:401 lxc/config_device.go:503 +#: lxc/config_device.go:619 lxc/config_device.go:626 lxc/config_device.go:759 +#: lxc/config_device.go:844 lxc/config_metadata.go:28 lxc/config_metadata.go:56 +#: lxc/config_metadata.go:189 lxc/config_template.go:28 +#: lxc/config_template.go:68 lxc/config_template.go:119 +#: lxc/config_template.go:173 lxc/config_template.go:273 +#: lxc/config_template.go:341 lxc/config_trust.go:34 lxc/config_trust.go:87 #: lxc/config_trust.go:236 lxc/config_trust.go:350 lxc/config_trust.go:432 #: lxc/config_trust.go:534 lxc/config_trust.go:580 lxc/config_trust.go:651 -#: lxc/console.go:37 lxc/copy.go:41 lxc/delete.go:31 lxc/exec.go:41 +#: lxc/console.go:37 lxc/copy.go:42 lxc/delete.go:32 lxc/exec.go:41 #: lxc/export.go:32 lxc/file.go:83 lxc/file.go:123 lxc/file.go:172 -#: lxc/file.go:242 lxc/file.go:467 lxc/file.go:986 lxc/image.go:37 -#: lxc/image.go:158 lxc/image.go:324 lxc/image.go:379 lxc/image.go:500 -#: lxc/image.go:664 lxc/image.go:901 lxc/image.go:1035 lxc/image.go:1354 -#: lxc/image.go:1441 lxc/image.go:1499 lxc/image.go:1550 lxc/image.go:1605 +#: lxc/file.go:242 lxc/file.go:467 lxc/file.go:986 lxc/image.go:38 +#: lxc/image.go:159 lxc/image.go:337 lxc/image.go:396 lxc/image.go:525 +#: lxc/image.go:697 lxc/image.go:946 lxc/image.go:1088 lxc/image.go:1415 +#: lxc/image.go:1506 lxc/image.go:1572 lxc/image.go:1636 lxc/image.go:1699 #: lxc/image_alias.go:24 lxc/image_alias.go:60 lxc/image_alias.go:107 #: lxc/image_alias.go:152 lxc/image_alias.go:255 lxc/import.go:29 -#: lxc/info.go:32 lxc/init.go:43 lxc/launch.go:24 lxc/list.go:48 lxc/main.go:83 -#: lxc/manpage.go:22 lxc/monitor.go:33 lxc/move.go:37 lxc/network.go:32 -#: lxc/network.go:135 lxc/network.go:220 lxc/network.go:293 lxc/network.go:372 -#: lxc/network.go:422 lxc/network.go:507 lxc/network.go:592 lxc/network.go:720 -#: lxc/network.go:789 lxc/network.go:912 lxc/network.go:1005 -#: lxc/network.go:1076 lxc/network.go:1128 lxc/network.go:1216 -#: lxc/network.go:1280 lxc/network_acl.go:30 lxc/network_acl.go:95 -#: lxc/network_acl.go:166 lxc/network_acl.go:219 lxc/network_acl.go:267 -#: lxc/network_acl.go:328 lxc/network_acl.go:417 lxc/network_acl.go:497 -#: lxc/network_acl.go:527 lxc/network_acl.go:658 lxc/network_acl.go:707 -#: lxc/network_acl.go:756 lxc/network_acl.go:771 lxc/network_acl.go:892 +#: lxc/info.go:33 lxc/init.go:44 lxc/launch.go:24 lxc/list.go:49 lxc/main.go:83 +#: lxc/manpage.go:22 lxc/monitor.go:33 lxc/move.go:38 lxc/network.go:33 +#: lxc/network.go:136 lxc/network.go:233 lxc/network.go:318 lxc/network.go:405 +#: lxc/network.go:463 lxc/network.go:560 lxc/network.go:657 lxc/network.go:793 +#: lxc/network.go:874 lxc/network.go:1005 lxc/network.go:1106 +#: lxc/network.go:1185 lxc/network.go:1245 lxc/network.go:1341 +#: lxc/network.go:1413 lxc/network_acl.go:30 lxc/network_acl.go:95 +#: lxc/network_acl.go:174 lxc/network_acl.go:235 lxc/network_acl.go:291 +#: lxc/network_acl.go:364 lxc/network_acl.go:461 lxc/network_acl.go:549 +#: lxc/network_acl.go:592 lxc/network_acl.go:731 lxc/network_acl.go:788 +#: lxc/network_acl.go:845 lxc/network_acl.go:860 lxc/network_acl.go:997 #: lxc/network_allocations.go:51 lxc/network_forward.go:33 -#: lxc/network_forward.go:90 lxc/network_forward.go:171 -#: lxc/network_forward.go:236 lxc/network_forward.go:384 -#: lxc/network_forward.go:453 lxc/network_forward.go:551 -#: lxc/network_forward.go:581 lxc/network_forward.go:723 -#: lxc/network_forward.go:785 lxc/network_forward.go:800 -#: lxc/network_forward.go:865 lxc/network_load_balancer.go:33 -#: lxc/network_load_balancer.go:94 lxc/network_load_balancer.go:173 -#: lxc/network_load_balancer.go:238 lxc/network_load_balancer.go:388 -#: lxc/network_load_balancer.go:456 lxc/network_load_balancer.go:554 -#: lxc/network_load_balancer.go:584 lxc/network_load_balancer.go:727 -#: lxc/network_load_balancer.go:788 lxc/network_load_balancer.go:803 -#: lxc/network_load_balancer.go:867 lxc/network_load_balancer.go:953 -#: lxc/network_load_balancer.go:968 lxc/network_load_balancer.go:1029 -#: lxc/network_peer.go:28 lxc/network_peer.go:81 lxc/network_peer.go:158 -#: lxc/network_peer.go:215 lxc/network_peer.go:331 lxc/network_peer.go:399 -#: lxc/network_peer.go:488 lxc/network_peer.go:518 lxc/network_peer.go:643 -#: lxc/network_zone.go:29 lxc/network_zone.go:86 lxc/network_zone.go:157 -#: lxc/network_zone.go:212 lxc/network_zone.go:272 lxc/network_zone.go:359 -#: lxc/network_zone.go:439 lxc/network_zone.go:470 lxc/network_zone.go:589 -#: lxc/network_zone.go:637 lxc/network_zone.go:694 lxc/network_zone.go:764 -#: lxc/network_zone.go:816 lxc/network_zone.go:875 lxc/network_zone.go:961 -#: lxc/network_zone.go:1037 lxc/network_zone.go:1067 lxc/network_zone.go:1185 -#: lxc/network_zone.go:1234 lxc/network_zone.go:1249 lxc/network_zone.go:1295 +#: lxc/network_forward.go:90 lxc/network_forward.go:179 +#: lxc/network_forward.go:256 lxc/network_forward.go:404 +#: lxc/network_forward.go:489 lxc/network_forward.go:599 +#: lxc/network_forward.go:646 lxc/network_forward.go:800 +#: lxc/network_forward.go:874 lxc/network_forward.go:889 +#: lxc/network_forward.go:970 lxc/network_load_balancer.go:33 +#: lxc/network_load_balancer.go:94 lxc/network_load_balancer.go:181 +#: lxc/network_load_balancer.go:258 lxc/network_load_balancer.go:408 +#: lxc/network_load_balancer.go:476 lxc/network_load_balancer.go:586 +#: lxc/network_load_balancer.go:616 lxc/network_load_balancer.go:771 +#: lxc/network_load_balancer.go:844 lxc/network_load_balancer.go:859 +#: lxc/network_load_balancer.go:935 lxc/network_load_balancer.go:1033 +#: lxc/network_load_balancer.go:1048 lxc/network_load_balancer.go:1121 +#: lxc/network_peer.go:29 lxc/network_peer.go:82 lxc/network_peer.go:167 +#: lxc/network_peer.go:236 lxc/network_peer.go:360 lxc/network_peer.go:445 +#: lxc/network_peer.go:547 lxc/network_peer.go:594 lxc/network_peer.go:731 +#: lxc/network_zone.go:29 lxc/network_zone.go:86 lxc/network_zone.go:165 +#: lxc/network_zone.go:228 lxc/network_zone.go:301 lxc/network_zone.go:396 +#: lxc/network_zone.go:484 lxc/network_zone.go:527 lxc/network_zone.go:654 +#: lxc/network_zone.go:710 lxc/network_zone.go:767 lxc/network_zone.go:845 +#: lxc/network_zone.go:909 lxc/network_zone.go:985 lxc/network_zone.go:1083 +#: lxc/network_zone.go:1172 lxc/network_zone.go:1219 lxc/network_zone.go:1349 +#: lxc/network_zone.go:1410 lxc/network_zone.go:1425 lxc/network_zone.go:1483 #: lxc/operation.go:24 lxc/operation.go:56 lxc/operation.go:106 -#: lxc/operation.go:193 lxc/profile.go:29 lxc/profile.go:104 lxc/profile.go:167 -#: lxc/profile.go:250 lxc/profile.go:320 lxc/profile.go:394 lxc/profile.go:444 -#: lxc/profile.go:572 lxc/profile.go:633 lxc/profile.go:694 lxc/profile.go:770 -#: lxc/profile.go:822 lxc/profile.go:898 lxc/profile.go:954 lxc/project.go:29 -#: lxc/project.go:93 lxc/project.go:181 lxc/project.go:244 lxc/project.go:372 -#: lxc/project.go:433 lxc/project.go:546 lxc/project.go:603 lxc/project.go:682 -#: lxc/project.go:713 lxc/project.go:766 lxc/project.go:825 lxc/publish.go:33 +#: lxc/operation.go:193 lxc/profile.go:30 lxc/profile.go:105 lxc/profile.go:180 +#: lxc/profile.go:271 lxc/profile.go:353 lxc/profile.go:435 lxc/profile.go:493 +#: lxc/profile.go:629 lxc/profile.go:703 lxc/profile.go:772 lxc/profile.go:860 +#: lxc/profile.go:920 lxc/profile.go:1009 lxc/profile.go:1073 lxc/project.go:29 +#: lxc/project.go:93 lxc/project.go:189 lxc/project.go:260 lxc/project.go:396 +#: lxc/project.go:470 lxc/project.go:590 lxc/project.go:655 lxc/project.go:743 +#: lxc/project.go:787 lxc/project.go:848 lxc/project.go:915 lxc/publish.go:34 #: lxc/query.go:34 lxc/rebuild.go:27 lxc/remote.go:35 lxc/remote.go:91 -#: lxc/remote.go:648 lxc/remote.go:686 lxc/remote.go:772 lxc/remote.go:845 -#: lxc/remote.go:901 lxc/remote.go:941 lxc/rename.go:21 lxc/restore.go:24 -#: lxc/snapshot.go:32 lxc/storage.go:34 lxc/storage.go:97 lxc/storage.go:199 -#: lxc/storage.go:249 lxc/storage.go:373 lxc/storage.go:443 lxc/storage.go:615 -#: lxc/storage.go:694 lxc/storage.go:790 lxc/storage.go:876 +#: lxc/remote.go:648 lxc/remote.go:686 lxc/remote.go:772 lxc/remote.go:853 +#: lxc/remote.go:917 lxc/remote.go:965 lxc/rename.go:22 lxc/restore.go:24 +#: lxc/snapshot.go:32 lxc/storage.go:34 lxc/storage.go:97 lxc/storage.go:203 +#: lxc/storage.go:261 lxc/storage.go:393 lxc/storage.go:475 lxc/storage.go:655 +#: lxc/storage.go:742 lxc/storage.go:846 lxc/storage.go:940 #: lxc/storage_bucket.go:29 lxc/storage_bucket.go:83 lxc/storage_bucket.go:188 #: lxc/storage_bucket.go:249 lxc/storage_bucket.go:382 #: lxc/storage_bucket.go:458 lxc/storage_bucket.go:535 @@ -1728,57 +1728,57 @@ msgstr "" #: lxc/storage_bucket.go:732 lxc/storage_bucket.go:773 #: lxc/storage_bucket.go:852 lxc/storage_bucket.go:958 #: lxc/storage_bucket.go:1022 lxc/storage_bucket.go:1157 -#: lxc/storage_volume.go:44 lxc/storage_volume.go:166 lxc/storage_volume.go:264 -#: lxc/storage_volume.go:355 lxc/storage_volume.go:558 -#: lxc/storage_volume.go:659 lxc/storage_volume.go:734 -#: lxc/storage_volume.go:816 lxc/storage_volume.go:897 -#: lxc/storage_volume.go:1106 lxc/storage_volume.go:1221 -#: lxc/storage_volume.go:1368 lxc/storage_volume.go:1452 -#: lxc/storage_volume.go:1697 lxc/storage_volume.go:1778 -#: lxc/storage_volume.go:1893 lxc/storage_volume.go:2037 -#: lxc/storage_volume.go:2146 lxc/storage_volume.go:2192 -#: lxc/storage_volume.go:2315 lxc/storage_volume.go:2382 -#: lxc/storage_volume.go:2536 lxc/version.go:22 lxc/warning.go:29 +#: lxc/storage_volume.go:58 lxc/storage_volume.go:169 lxc/storage_volume.go:283 +#: lxc/storage_volume.go:390 lxc/storage_volume.go:605 +#: lxc/storage_volume.go:714 lxc/storage_volume.go:801 +#: lxc/storage_volume.go:899 lxc/storage_volume.go:996 +#: lxc/storage_volume.go:1217 lxc/storage_volume.go:1348 +#: lxc/storage_volume.go:1507 lxc/storage_volume.go:1591 +#: lxc/storage_volume.go:1844 lxc/storage_volume.go:1937 +#: lxc/storage_volume.go:2064 lxc/storage_volume.go:2222 +#: lxc/storage_volume.go:2343 lxc/storage_volume.go:2405 +#: lxc/storage_volume.go:2541 lxc/storage_volume.go:2624 +#: lxc/storage_volume.go:2790 lxc/version.go:22 lxc/warning.go:29 #: lxc/warning.go:71 lxc/warning.go:262 lxc/warning.go:303 lxc/warning.go:357 msgid "Description" msgstr "" -#: lxc/storage_volume.go:1309 +#: lxc/storage_volume.go:1448 #, c-format msgid "Description: %s" msgstr "" -#: lxc/storage_volume.go:360 lxc/storage_volume.go:1702 +#: lxc/storage_volume.go:395 lxc/storage_volume.go:1849 msgid "Destination cluster member name" msgstr "" -#: lxc/network.go:421 lxc/network.go:422 +#: lxc/network.go:462 lxc/network.go:463 msgid "Detach network interfaces from instances" msgstr "" -#: lxc/network.go:506 lxc/network.go:507 +#: lxc/network.go:559 lxc/network.go:560 msgid "Detach network interfaces from profiles" msgstr "" -#: lxc/storage_volume.go:733 lxc/storage_volume.go:734 +#: lxc/storage_volume.go:800 lxc/storage_volume.go:801 msgid "Detach storage volumes from instances" msgstr "" -#: lxc/storage_volume.go:815 lxc/storage_volume.go:816 +#: lxc/storage_volume.go:898 lxc/storage_volume.go:899 msgid "Detach storage volumes from profiles" msgstr "" -#: lxc/config_device.go:185 +#: lxc/config_device.go:198 #, c-format msgid "Device %s added to %s" msgstr "" -#: lxc/config_device.go:426 +#: lxc/config_device.go:479 #, c-format msgid "Device %s overridden for %s" msgstr "" -#: lxc/config_device.go:529 +#: lxc/config_device.go:600 #, c-format msgid "Device %s removed from %s" msgstr "" @@ -1788,37 +1788,37 @@ msgstr "" msgid "Device already exists: %s" msgstr "" -#: lxc/config_device.go:247 lxc/config_device.go:261 lxc/config_device.go:487 -#: lxc/config_device.go:508 lxc/config_device.go:602 lxc/config_device.go:625 +#: lxc/config_device.go:280 lxc/config_device.go:294 lxc/config_device.go:558 +#: lxc/config_device.go:579 lxc/config_device.go:693 lxc/config_device.go:716 msgid "Device doesn't exist" msgstr "" -#: lxc/config_device.go:628 +#: lxc/config_device.go:719 msgid "" "Device from profile(s) cannot be modified for individual instance. Override " "device or modify profile instead" msgstr "" -#: lxc/config_device.go:511 +#: lxc/config_device.go:582 msgid "" "Device from profile(s) cannot be removed from individual instance. Override " "device or modify profile instead" msgstr "" -#: lxc/config_device.go:264 +#: lxc/config_device.go:297 msgid "Device from profile(s) cannot be retrieved for individual instance" msgstr "" -#: lxc/info.go:265 lxc/info.go:290 +#: lxc/info.go:274 lxc/info.go:299 #, c-format msgid "Device: %s" msgstr "" -#: lxc/init.go:393 +#: lxc/init.go:402 msgid "Didn't get any affected image, instance or snapshot from server" msgstr "" -#: lxc/image.go:679 +#: lxc/image.go:724 msgid "Directory import is not available on this platform" msgstr "" @@ -1838,28 +1838,28 @@ msgstr "" msgid "Disable stdin (reads from /dev/null)" msgstr "" -#: lxc/info.go:426 +#: lxc/info.go:435 #, c-format msgid "Disk %d:" msgstr "" -#: lxc/info.go:511 +#: lxc/info.go:520 msgid "Disk usage:" msgstr "" -#: lxc/info.go:421 +#: lxc/info.go:430 msgid "Disk:" msgstr "" -#: lxc/info.go:424 +#: lxc/info.go:433 msgid "Disks:" msgstr "" -#: lxc/list.go:134 +#: lxc/list.go:135 msgid "Display instances from all projects" msgstr "" -#: lxc/cluster.go:526 +#: lxc/cluster.go:591 msgid "Don't require user confirmation for using --force" msgstr "" @@ -1867,24 +1867,24 @@ msgstr "" msgid "Don't show progress information" msgstr "" -#: lxc/network.go:863 +#: lxc/network.go:956 msgid "Down delay" msgstr "" -#: lxc/info.go:104 lxc/info.go:190 +#: lxc/info.go:113 lxc/info.go:199 #, c-format msgid "Driver: %v (%v)" msgstr "" -#: lxc/network_zone.go:748 +#: lxc/network_zone.go:829 msgid "ENTRIES" msgstr "" -#: lxc/list.go:865 +#: lxc/list.go:874 msgid "EPHEMERAL" msgstr "" -#: lxc/cluster.go:966 lxc/config_trust.go:516 +#: lxc/cluster.go:1071 lxc/config_trust.go:516 msgid "EXPIRES AT" msgstr "" @@ -1898,7 +1898,7 @@ msgid "" "(interrupt two more times to force)" msgstr "" -#: lxc/cluster_group.go:287 lxc/cluster_group.go:288 +#: lxc/cluster_group.go:315 lxc/cluster_group.go:316 msgid "Edit a cluster group" msgstr "" @@ -1906,7 +1906,7 @@ msgstr "" msgid "Edit an identity as YAML" msgstr "" -#: lxc/cluster.go:688 lxc/cluster.go:689 +#: lxc/cluster.go:769 lxc/cluster.go:770 msgid "Edit cluster member configurations as YAML" msgstr "" @@ -1922,59 +1922,59 @@ msgstr "" msgid "Edit identity provider groups as YAML" msgstr "" -#: lxc/image.go:378 lxc/image.go:379 +#: lxc/image.go:395 lxc/image.go:396 msgid "Edit image properties" msgstr "" -#: lxc/config.go:1160 lxc/config.go:1161 +#: lxc/config.go:1213 lxc/config.go:1214 msgid "Edit instance UEFI variables" msgstr "" -#: lxc/config_template.go:151 lxc/config_template.go:152 +#: lxc/config_template.go:172 lxc/config_template.go:173 msgid "Edit instance file templates" msgstr "" -#: lxc/config_metadata.go:54 lxc/config_metadata.go:55 +#: lxc/config_metadata.go:55 lxc/config_metadata.go:56 msgid "Edit instance metadata files" msgstr "" -#: lxc/config.go:98 lxc/config.go:99 +#: lxc/config.go:99 lxc/config.go:100 msgid "Edit instance or server configurations as YAML" msgstr "" -#: lxc/network_acl.go:526 lxc/network_acl.go:527 +#: lxc/network_acl.go:591 lxc/network_acl.go:592 msgid "Edit network ACL configurations as YAML" msgstr "" -#: lxc/network.go:591 lxc/network.go:592 +#: lxc/network.go:656 lxc/network.go:657 msgid "Edit network configurations as YAML" msgstr "" -#: lxc/network_forward.go:580 lxc/network_forward.go:581 +#: lxc/network_forward.go:645 lxc/network_forward.go:646 msgid "Edit network forward configurations as YAML" msgstr "" -#: lxc/network_load_balancer.go:583 lxc/network_load_balancer.go:584 +#: lxc/network_load_balancer.go:615 lxc/network_load_balancer.go:616 msgid "Edit network load balancer configurations as YAML" msgstr "" -#: lxc/network_peer.go:517 lxc/network_peer.go:518 +#: lxc/network_peer.go:593 lxc/network_peer.go:594 msgid "Edit network peer configurations as YAML" msgstr "" -#: lxc/network_zone.go:469 lxc/network_zone.go:470 +#: lxc/network_zone.go:526 lxc/network_zone.go:527 msgid "Edit network zone configurations as YAML" msgstr "" -#: lxc/network_zone.go:1066 lxc/network_zone.go:1067 +#: lxc/network_zone.go:1218 lxc/network_zone.go:1219 msgid "Edit network zone record configurations as YAML" msgstr "" -#: lxc/profile.go:443 lxc/profile.go:444 +#: lxc/profile.go:492 lxc/profile.go:493 msgid "Edit profile configurations as YAML" msgstr "" -#: lxc/project.go:243 lxc/project.go:244 +#: lxc/project.go:259 lxc/project.go:260 msgid "Edit project configurations as YAML" msgstr "" @@ -1986,11 +1986,11 @@ msgstr "" msgid "Edit storage bucket key as YAML" msgstr "" -#: lxc/storage.go:248 lxc/storage.go:249 +#: lxc/storage.go:260 lxc/storage.go:261 msgid "Edit storage pool configurations as YAML" msgstr "" -#: lxc/storage_volume.go:896 lxc/storage_volume.go:897 +#: lxc/storage_volume.go:995 lxc/storage_volume.go:996 msgid "Edit storage volume configurations as YAML" msgstr "" @@ -1998,17 +1998,17 @@ msgstr "" msgid "Edit trust configurations as YAML" msgstr "" -#: lxc/image.go:1086 lxc/list.go:613 lxc/storage_volume.go:1619 +#: lxc/image.go:1147 lxc/list.go:622 lxc/storage_volume.go:1766 #: lxc/warning.go:235 #, c-format msgid "Empty column entry (redundant, leading or trailing command) in '%s'" msgstr "" -#: lxc/cluster.go:603 +#: lxc/cluster.go:676 msgid "Enable clustering on a single non-clustered LXD server" msgstr "" -#: lxc/cluster.go:604 +#: lxc/cluster.go:677 msgid "" "Enable clustering on a single non-clustered LXD server\n" "\n" @@ -2023,7 +2023,7 @@ msgid "" " for the address if not yet set." msgstr "" -#: lxc/network_zone.go:1251 +#: lxc/network_zone.go:1427 msgid "Entry TTL" msgstr "" @@ -2031,7 +2031,7 @@ msgstr "" msgid "Environment variable to set (e.g. HOME=/home/foo)" msgstr "" -#: lxc/copy.go:56 lxc/init.go:60 +#: lxc/copy.go:57 lxc/init.go:61 msgid "Ephemeral instance" msgstr "" @@ -2045,46 +2045,46 @@ msgstr "" msgid "Error decoding data: %v" msgstr "" -#: lxc/publish.go:234 +#: lxc/publish.go:247 #, c-format msgid "Error retrieving aliases: %w" msgstr "" -#: lxc/cluster.go:414 lxc/config.go:621 lxc/config.go:653 lxc/network.go:1194 -#: lxc/network_acl.go:472 lxc/network_forward.go:524 -#: lxc/network_load_balancer.go:527 lxc/network_peer.go:463 -#: lxc/network_zone.go:414 lxc/network_zone.go:1012 lxc/profile.go:876 -#: lxc/project.go:657 lxc/storage.go:756 lxc/storage_bucket.go:602 -#: lxc/storage_volume.go:1970 lxc/storage_volume.go:2008 +#: lxc/cluster.go:459 lxc/config.go:654 lxc/config.go:686 lxc/network.go:1319 +#: lxc/network_acl.go:524 lxc/network_forward.go:572 +#: lxc/network_load_balancer.go:559 lxc/network_peer.go:522 +#: lxc/network_zone.go:459 lxc/network_zone.go:1147 lxc/profile.go:987 +#: lxc/project.go:718 lxc/storage.go:812 lxc/storage_bucket.go:602 +#: lxc/storage_volume.go:2155 lxc/storage_volume.go:2193 #, c-format msgid "Error setting properties: %v" msgstr "" -#: lxc/config.go:615 lxc/config.go:647 +#: lxc/config.go:648 lxc/config.go:680 #, c-format msgid "Error unsetting properties: %v" msgstr "" -#: lxc/cluster.go:408 lxc/network.go:1188 lxc/network_acl.go:466 -#: lxc/network_forward.go:518 lxc/network_load_balancer.go:521 -#: lxc/network_peer.go:457 lxc/network_zone.go:408 lxc/network_zone.go:1006 -#: lxc/profile.go:870 lxc/project.go:651 lxc/storage.go:750 -#: lxc/storage_bucket.go:596 lxc/storage_volume.go:1964 -#: lxc/storage_volume.go:2002 +#: lxc/cluster.go:453 lxc/network.go:1313 lxc/network_acl.go:518 +#: lxc/network_forward.go:566 lxc/network_load_balancer.go:553 +#: lxc/network_peer.go:516 lxc/network_zone.go:453 lxc/network_zone.go:1141 +#: lxc/profile.go:981 lxc/project.go:712 lxc/storage.go:806 +#: lxc/storage_bucket.go:596 lxc/storage_volume.go:2149 +#: lxc/storage_volume.go:2187 #, c-format msgid "Error unsetting property: %v" msgstr "" -#: lxc/config_template.go:205 +#: lxc/config_template.go:238 #, c-format msgid "Error updating template file: %s" msgstr "" -#: lxc/cluster.go:1167 lxc/cluster.go:1168 +#: lxc/cluster.go:1298 lxc/cluster.go:1299 msgid "Evacuate cluster member" msgstr "" -#: lxc/cluster.go:1249 +#: lxc/cluster.go:1396 #, c-format msgid "Evacuating cluster member: %s" msgstr "" @@ -2112,32 +2112,32 @@ msgid "" "AND stdout are terminals (stderr is ignored)." msgstr "" -#: lxc/info.go:631 lxc/info.go:682 lxc/storage_volume.go:1369 -#: lxc/storage_volume.go:1419 +#: lxc/info.go:640 lxc/info.go:691 lxc/storage_volume.go:1508 +#: lxc/storage_volume.go:1558 msgid "Expires at" msgstr "" -#: lxc/image.go:974 +#: lxc/image.go:1027 #, c-format msgid "Expires: %s" msgstr "" -#: lxc/image.go:976 +#: lxc/image.go:1029 msgid "Expires: never" msgstr "" -#: lxc/image.go:499 +#: lxc/image.go:524 msgid "Export and download images" msgstr "" -#: lxc/image.go:500 +#: lxc/image.go:525 msgid "" "Export and download images\n" "\n" "The output target is optional and defaults to the working directory." msgstr "" -#: lxc/storage_volume.go:2381 lxc/storage_volume.go:2382 +#: lxc/storage_volume.go:2623 lxc/storage_volume.go:2624 msgid "Export custom storage volume" msgstr "" @@ -2149,29 +2149,29 @@ msgstr "" msgid "Export instances as backup tarballs." msgstr "" -#: lxc/storage_volume.go:2385 +#: lxc/storage_volume.go:2627 msgid "Export the volume without its snapshots" msgstr "" -#: lxc/export.go:152 lxc/storage_volume.go:2502 +#: lxc/export.go:152 lxc/storage_volume.go:2756 #, c-format msgid "Exporting the backup: %s" msgstr "" -#: lxc/image.go:571 +#: lxc/image.go:604 #, c-format msgid "Exporting the image: %s" msgstr "" -#: lxc/cluster.go:187 +#: lxc/cluster.go:196 msgid "FAILURE DOMAIN" msgstr "" -#: lxc/config_template.go:283 +#: lxc/config_template.go:324 msgid "FILENAME" msgstr "" -#: lxc/config_trust.go:411 lxc/image.go:1071 lxc/image.go:1072 +#: lxc/config_trust.go:411 lxc/image.go:1132 lxc/image.go:1133 #: lxc/image_alias.go:235 msgid "FINGERPRINT" msgstr "" @@ -2215,22 +2215,22 @@ msgstr "" msgid "Failed converting token operation to certificate add token: %w" msgstr "" -#: lxc/delete.go:168 +#: lxc/delete.go:173 #, c-format msgid "Failed deleting instance %q in project %q: %w" msgstr "" -#: lxc/delete.go:110 +#: lxc/delete.go:115 #, c-format msgid "Failed deleting instance snapshot %q in project %q: %w" msgstr "" -#: lxc/image.go:132 +#: lxc/image.go:133 #, c-format msgid "Failed fetching fingerprint %q for alias %q: %w" msgstr "" -#: lxc/image.go:123 +#: lxc/image.go:124 #, c-format msgid "Failed fetching fingerprint %q: %w" msgstr "" @@ -2240,7 +2240,7 @@ msgstr "" msgid "Failed generating SSH host key: %w" msgstr "" -#: lxc/network_peer.go:304 +#: lxc/network_peer.go:333 #, c-format msgid "Failed getting peer's status: %w" msgstr "" @@ -2279,7 +2279,7 @@ msgstr "" msgid "Failed to close server cert file %q: %w" msgstr "" -#: lxc/move.go:291 lxc/move.go:367 +#: lxc/move.go:304 lxc/move.go:380 #, c-format msgid "Failed to connect to cluster member: %w" msgstr "" @@ -2309,7 +2309,7 @@ msgstr "" msgid "Failed to listen for connection: %w" msgstr "" -#: lxc/copy.go:391 +#: lxc/copy.go:404 #, c-format msgid "Failed to refresh target instance '%s': %v" msgstr "" @@ -2329,25 +2329,25 @@ msgstr "" msgid "Failed to write server cert file %q: %w" msgstr "" -#: lxc/list.go:133 +#: lxc/list.go:134 msgid "Fast mode (same as --columns=nsacPt)" msgstr "" -#: lxc/network.go:943 lxc/network_acl.go:125 lxc/network_zone.go:116 +#: lxc/network.go:1044 lxc/network_acl.go:133 lxc/network_zone.go:124 #: lxc/operation.go:136 msgid "Filtering isn't supported yet" msgstr "" -#: lxc/image.go:959 +#: lxc/image.go:1012 #, c-format msgid "Fingerprint: %s" msgstr "" -#: lxc/cluster.go:1171 +#: lxc/cluster.go:1302 msgid "Force a particular evacuation action" msgstr "" -#: lxc/cluster.go:1170 +#: lxc/cluster.go:1301 msgid "Force evacuation without user confirmation" msgstr "" @@ -2355,19 +2355,19 @@ msgstr "" msgid "Force pseudo-terminal allocation" msgstr "" -#: lxc/cluster.go:525 +#: lxc/cluster.go:590 msgid "Force removing a member, even if degraded" msgstr "" -#: lxc/cluster.go:1192 +#: lxc/cluster.go:1331 msgid "Force restoration without user confirmation" msgstr "" -#: lxc/action.go:135 +#: lxc/action.go:152 msgid "Force the instance to stop" msgstr "" -#: lxc/delete.go:35 +#: lxc/delete.go:36 msgid "Force the removal of running instances" msgstr "" @@ -2375,7 +2375,7 @@ msgstr "" msgid "Force using the local unix socket" msgstr "" -#: lxc/cluster.go:533 +#: lxc/cluster.go:606 #, c-format msgid "" "Forcefully removing a server from the cluster should only be done as a last\n" @@ -2400,16 +2400,16 @@ msgid "" msgstr "" #: lxc/alias.go:112 lxc/auth.go:336 lxc/auth.go:769 lxc/auth.go:1696 -#: lxc/cluster.go:124 lxc/cluster.go:881 lxc/cluster_group.go:406 -#: lxc/config_template.go:242 lxc/config_trust.go:352 lxc/config_trust.go:434 -#: lxc/image.go:1061 lxc/image_alias.go:157 lxc/list.go:132 lxc/network.go:916 -#: lxc/network.go:1007 lxc/network_acl.go:98 lxc/network_allocations.go:57 +#: lxc/cluster.go:125 lxc/cluster.go:978 lxc/cluster_group.go:442 +#: lxc/config_template.go:275 lxc/config_trust.go:352 lxc/config_trust.go:434 +#: lxc/image.go:1114 lxc/image_alias.go:157 lxc/list.go:133 lxc/network.go:1009 +#: lxc/network.go:1108 lxc/network_acl.go:98 lxc/network_allocations.go:57 #: lxc/network_forward.go:93 lxc/network_load_balancer.go:97 -#: lxc/network_peer.go:84 lxc/network_zone.go:89 lxc/network_zone.go:697 -#: lxc/operation.go:108 lxc/profile.go:637 lxc/project.go:435 -#: lxc/project.go:827 lxc/remote.go:690 lxc/storage.go:617 +#: lxc/network_peer.go:85 lxc/network_zone.go:89 lxc/network_zone.go:770 +#: lxc/operation.go:108 lxc/profile.go:707 lxc/project.go:472 +#: lxc/project.go:917 lxc/remote.go:690 lxc/storage.go:657 #: lxc/storage_bucket.go:459 lxc/storage_bucket.go:774 -#: lxc/storage_volume.go:1469 lxc/warning.go:93 +#: lxc/storage_volume.go:1608 lxc/warning.go:93 msgid "Format (csv|json|table|yaml|compact)" msgstr "" @@ -2421,26 +2421,26 @@ msgstr "" msgid "Format (man|md|rest|yaml)" msgstr "" -#: lxc/network.go:875 +#: lxc/network.go:968 msgid "Forward delay" msgstr "" -#: lxc/main_aliases.go:99 +#: lxc/main_aliases.go:108 #, c-format msgid "Found alias %q references an argument outside the given number" msgstr "" -#: lxc/info.go:369 lxc/info.go:380 lxc/info.go:385 lxc/info.go:391 +#: lxc/info.go:378 lxc/info.go:389 lxc/info.go:394 lxc/info.go:400 #, c-format msgid "Free: %v" msgstr "" -#: lxc/info.go:317 lxc/info.go:328 +#: lxc/info.go:326 lxc/info.go:337 #, c-format msgid "Frequency: %vMhz" msgstr "" -#: lxc/info.go:326 +#: lxc/info.go:335 #, c-format msgid "Frequency: %vMhz (min: %vMhz, max: %vMhz)" msgstr "" @@ -2449,11 +2449,11 @@ msgstr "" msgid "GLOBAL" msgstr "" -#: lxc/info.go:397 +#: lxc/info.go:406 msgid "GPU:" msgstr "" -#: lxc/info.go:400 +#: lxc/info.go:409 msgid "GPUs:" msgstr "" @@ -2469,59 +2469,59 @@ msgstr "" msgid "Generating a client certificate. This may take a minute..." msgstr "" -#: lxc/config.go:929 lxc/config.go:930 +#: lxc/config.go:982 lxc/config.go:983 msgid "Get UEFI variables for instance" msgstr "" -#: lxc/project.go:824 lxc/project.go:825 +#: lxc/project.go:914 lxc/project.go:915 msgid "Get a summary of resource allocations" msgstr "" -#: lxc/image.go:1498 lxc/image.go:1499 +#: lxc/image.go:1571 lxc/image.go:1572 msgid "Get image properties" msgstr "" -#: lxc/network.go:788 lxc/network.go:789 +#: lxc/network.go:873 lxc/network.go:874 msgid "Get runtime information on networks" msgstr "" -#: lxc/cluster.go:308 +#: lxc/cluster.go:333 msgid "Get the key as a cluster property" msgstr "" -#: lxc/network_acl.go:269 +#: lxc/network_acl.go:293 msgid "Get the key as a network ACL property" msgstr "" -#: lxc/network_forward.go:386 +#: lxc/network_forward.go:406 msgid "Get the key as a network forward property" msgstr "" -#: lxc/network_load_balancer.go:391 +#: lxc/network_load_balancer.go:411 msgid "Get the key as a network load balancer property" msgstr "" -#: lxc/network_peer.go:334 +#: lxc/network_peer.go:363 msgid "Get the key as a network peer property" msgstr "" -#: lxc/network.go:724 +#: lxc/network.go:797 msgid "Get the key as a network property" msgstr "" -#: lxc/network_zone.go:215 +#: lxc/network_zone.go:231 msgid "Get the key as a network zone property" msgstr "" -#: lxc/network_zone.go:819 +#: lxc/network_zone.go:912 msgid "Get the key as a network zone record property" msgstr "" -#: lxc/profile.go:577 +#: lxc/profile.go:634 msgid "Get the key as a profile property" msgstr "" -#: lxc/project.go:376 +#: lxc/project.go:400 msgid "Get the key as a project property" msgstr "" @@ -2529,63 +2529,63 @@ msgstr "" msgid "Get the key as a storage bucket property" msgstr "" -#: lxc/storage.go:377 +#: lxc/storage.go:397 msgid "Get the key as a storage property" msgstr "" -#: lxc/storage_volume.go:1121 +#: lxc/storage_volume.go:1232 msgid "Get the key as a storage volume property" msgstr "" -#: lxc/config.go:388 +#: lxc/config.go:397 msgid "Get the key as an instance property" msgstr "" -#: lxc/cluster.go:305 +#: lxc/cluster.go:330 msgid "Get values for cluster member configuration keys" msgstr "" -#: lxc/config_device.go:207 lxc/config_device.go:208 +#: lxc/config_device.go:220 lxc/config_device.go:221 msgid "Get values for device configuration keys" msgstr "" -#: lxc/config.go:383 lxc/config.go:384 +#: lxc/config.go:392 lxc/config.go:393 msgid "Get values for instance or server configuration keys" msgstr "" -#: lxc/network_acl.go:266 lxc/network_acl.go:267 +#: lxc/network_acl.go:290 lxc/network_acl.go:291 msgid "Get values for network ACL configuration keys" msgstr "" -#: lxc/network.go:719 lxc/network.go:720 +#: lxc/network.go:792 lxc/network.go:793 msgid "Get values for network configuration keys" msgstr "" -#: lxc/network_forward.go:383 lxc/network_forward.go:384 +#: lxc/network_forward.go:403 lxc/network_forward.go:404 msgid "Get values for network forward configuration keys" msgstr "" -#: lxc/network_load_balancer.go:387 lxc/network_load_balancer.go:388 +#: lxc/network_load_balancer.go:407 lxc/network_load_balancer.go:408 msgid "Get values for network load balancer configuration keys" msgstr "" -#: lxc/network_peer.go:330 lxc/network_peer.go:331 +#: lxc/network_peer.go:359 lxc/network_peer.go:360 msgid "Get values for network peer configuration keys" msgstr "" -#: lxc/network_zone.go:211 lxc/network_zone.go:212 +#: lxc/network_zone.go:227 lxc/network_zone.go:228 msgid "Get values for network zone configuration keys" msgstr "" -#: lxc/network_zone.go:815 lxc/network_zone.go:816 +#: lxc/network_zone.go:908 lxc/network_zone.go:909 msgid "Get values for network zone record configuration keys" msgstr "" -#: lxc/profile.go:571 lxc/profile.go:572 +#: lxc/profile.go:628 lxc/profile.go:629 msgid "Get values for profile configuration keys" msgstr "" -#: lxc/project.go:371 lxc/project.go:372 +#: lxc/project.go:395 lxc/project.go:396 msgid "Get values for project configuration keys" msgstr "" @@ -2593,15 +2593,15 @@ msgstr "" msgid "Get values for storage bucket configuration keys" msgstr "" -#: lxc/storage.go:372 lxc/storage.go:373 +#: lxc/storage.go:392 lxc/storage.go:393 msgid "Get values for storage pool configuration keys" msgstr "" -#: lxc/storage_volume.go:1105 lxc/storage_volume.go:1106 +#: lxc/storage_volume.go:1216 lxc/storage_volume.go:1217 msgid "Get values for storage volume configuration keys" msgstr "" -#: lxc/storage_volume.go:422 +#: lxc/storage_volume.go:469 #, c-format msgid "Given target %q does not match source volume location %q" msgstr "" @@ -2629,15 +2629,15 @@ msgstr "" msgid "HARDWARE ADDRESS" msgstr "" -#: lxc/network.go:1052 +#: lxc/network.go:1161 msgid "HOSTNAME" msgstr "" -#: lxc/info.go:557 +#: lxc/info.go:566 msgid "Host interface" msgstr "" -#: lxc/info.go:368 lxc/info.go:379 +#: lxc/info.go:377 lxc/info.go:388 msgid "Hugepages:\n" msgstr "" @@ -2661,16 +2661,16 @@ msgstr "" msgid "I/O copy from sshfs to instance failed: %v" msgstr "" -#: lxc/network.go:873 lxc/operation.go:170 +#: lxc/network.go:966 lxc/operation.go:170 msgid "ID" msgstr "" -#: lxc/info.go:109 +#: lxc/info.go:118 #, c-format msgid "ID: %d" msgstr "" -#: lxc/info.go:197 lxc/info.go:264 lxc/info.go:289 +#: lxc/info.go:206 lxc/info.go:273 lxc/info.go:298 #, c-format msgid "ID: %s" msgstr "" @@ -2679,27 +2679,27 @@ msgstr "" msgid "IDENTIFIER" msgstr "" -#: lxc/project.go:522 +#: lxc/project.go:566 msgid "IMAGES" msgstr "" -#: lxc/network.go:1054 +#: lxc/network.go:1163 msgid "IP ADDRESS" msgstr "" -#: lxc/info.go:573 +#: lxc/info.go:582 msgid "IP addresses" msgstr "" -#: lxc/network.go:842 +#: lxc/network.go:935 msgid "IP addresses:" msgstr "" -#: lxc/list.go:551 lxc/network.go:983 +#: lxc/list.go:560 lxc/network.go:1084 msgid "IPV4" msgstr "" -#: lxc/list.go:552 lxc/network.go:984 +#: lxc/list.go:561 lxc/network.go:1085 msgid "IPV6" msgstr "" @@ -2721,15 +2721,15 @@ msgstr "" msgid "If an instance is running, stop it and then rebuild it" msgstr "" -#: lxc/publish.go:42 +#: lxc/publish.go:43 msgid "If the image alias already exists, delete and create a new one" msgstr "" -#: lxc/snapshot.go:46 lxc/storage_volume.go:2202 +#: lxc/snapshot.go:46 lxc/storage_volume.go:2415 msgid "If the snapshot name already exists, delete and create a new one" msgstr "" -#: lxc/main.go:400 +#: lxc/main.go:405 msgid "" "If this is your first time running LXD on this machine, you should also run: " "lxd init" @@ -2739,57 +2739,57 @@ msgstr "" msgid "Ignore any configured auto-expiry for the instance" msgstr "" -#: lxc/storage_volume.go:2201 +#: lxc/storage_volume.go:2414 msgid "Ignore any configured auto-expiry for the storage volume" msgstr "" -#: lxc/copy.go:65 lxc/move.go:68 +#: lxc/copy.go:66 lxc/move.go:69 msgid "Ignore copy errors for volatile files" msgstr "" -#: lxc/action.go:126 +#: lxc/action.go:143 msgid "Ignore the instance state" msgstr "" -#: lxc/image.go:1422 +#: lxc/image.go:1487 msgid "Image already up to date." msgstr "" -#: lxc/image.go:292 +#: lxc/image.go:305 msgid "Image copied successfully!" msgstr "" -#: lxc/publish.go:41 +#: lxc/publish.go:42 msgid "Image expiration date (format: rfc3339)" msgstr "" -#: lxc/image.go:647 +#: lxc/image.go:680 msgid "Image exported successfully!" msgstr "" -#: lxc/image.go:347 lxc/image.go:1377 +#: lxc/image.go:364 lxc/image.go:1442 msgid "Image identifier missing" msgstr "" -#: lxc/image.go:419 lxc/image.go:1574 +#: lxc/image.go:444 lxc/image.go:1668 #, c-format msgid "Image identifier missing: %s" msgstr "" -#: lxc/image.go:871 +#: lxc/image.go:916 #, c-format msgid "Image imported with fingerprint: %s" msgstr "" -#: lxc/image.go:1420 +#: lxc/image.go:1485 msgid "Image refreshed successfully!" msgstr "" -#: lxc/action.go:130 lxc/launch.go:45 +#: lxc/action.go:147 lxc/launch.go:45 msgid "Immediately attach to the console" msgstr "" -#: lxc/storage_volume.go:2536 +#: lxc/storage_volume.go:2790 msgid "Import backups of custom volumes including their snapshots." msgstr "" @@ -2797,18 +2797,18 @@ msgstr "" msgid "Import backups of instances including their snapshots." msgstr "" -#: lxc/storage_volume.go:2535 +#: lxc/storage_volume.go:2789 msgid "Import custom storage volumes" msgstr "" -#: lxc/image.go:664 +#: lxc/image.go:697 msgid "" "Import image into the image store\n" "\n" "Directory import is only available on Linux and must be performed as root." msgstr "" -#: lxc/image.go:663 +#: lxc/image.go:696 msgid "Import images into the image store" msgstr "" @@ -2816,11 +2816,11 @@ msgstr "" msgid "Import instance backups" msgstr "" -#: lxc/storage_volume.go:2543 +#: lxc/storage_volume.go:2797 msgid "Import type, backup or iso (default \"backup\")" msgstr "" -#: lxc/storage_volume.go:2609 +#: lxc/storage_volume.go:2871 #, c-format msgid "Importing custom volume: %s" msgstr "" @@ -2830,7 +2830,7 @@ msgstr "" msgid "Importing instance: %s" msgstr "" -#: lxc/info.go:226 +#: lxc/info.go:235 msgid "Infiniband:" msgstr "" @@ -2842,7 +2842,7 @@ msgstr "" msgid "Inspect permissions" msgstr "" -#: lxc/info.go:683 +#: lxc/info.go:692 msgid "Instance Only" msgstr "" @@ -2855,16 +2855,16 @@ msgstr "" msgid "Instance disconnected for client %q" msgstr "" -#: lxc/publish.go:80 +#: lxc/publish.go:93 msgid "Instance name is mandatory" msgstr "" -#: lxc/init.go:404 +#: lxc/init.go:413 #, c-format msgid "Instance name is: %s" msgstr "" -#: lxc/config.go:955 lxc/config.go:1013 lxc/config.go:1132 lxc/config.go:1224 +#: lxc/config.go:1008 lxc/config.go:1066 lxc/config.go:1185 lxc/config.go:1277 msgid "Instance name must be specified" msgstr "" @@ -2872,7 +2872,7 @@ msgstr "" msgid "Instance path cannot be used in SSH SFTP listener mode" msgstr "" -#: lxc/publish.go:350 +#: lxc/publish.go:363 #, c-format msgid "Instance published with fingerprint: %s" msgstr "" @@ -2882,7 +2882,7 @@ msgstr "" msgid "Instance snapshots cannot be rebuilt: %s" msgstr "" -#: lxc/init.go:63 +#: lxc/init.go:64 msgid "Instance type" msgstr "" @@ -2891,7 +2891,7 @@ msgstr "" msgid "Invalid URL scheme \"%s\" in \"%s\"" msgstr "" -#: lxc/main_aliases.go:95 lxc/main_aliases.go:132 +#: lxc/main_aliases.go:104 lxc/main_aliases.go:147 #, c-format msgid "Invalid argument %q" msgstr "" @@ -2900,12 +2900,12 @@ msgstr "" msgid "Invalid certificate" msgstr "" -#: lxc/list.go:647 +#: lxc/list.go:656 #, c-format msgid "Invalid config key '%s' in '%s'" msgstr "" -#: lxc/list.go:640 +#: lxc/list.go:649 #, c-format msgid "Invalid config key column format (too many fields): '%s'" msgstr "" @@ -2930,35 +2930,35 @@ msgstr "" msgid "Invalid key=value configuration: %s" msgstr "" -#: lxc/list.go:668 +#: lxc/list.go:677 #, c-format msgid "Invalid max width (must -1, 0 or a positive integer) '%s' in '%s'" msgstr "" -#: lxc/list.go:664 +#: lxc/list.go:673 #, c-format msgid "Invalid max width (must be an integer) '%s' in '%s'" msgstr "" -#: lxc/list.go:654 +#: lxc/list.go:663 #, c-format msgid "" "Invalid name in '%s', empty string is only allowed when defining maxWidth" msgstr "" -#: lxc/move.go:135 lxc/storage_volume.go:1829 +#: lxc/move.go:148 lxc/storage_volume.go:2000 msgid "Invalid new snapshot name" msgstr "" -#: lxc/move.go:131 +#: lxc/move.go:144 msgid "Invalid new snapshot name, parent must be the same as source" msgstr "" -#: lxc/storage_volume.go:1825 +#: lxc/storage_volume.go:1996 msgid "Invalid new snapshot name, parent volume must be the same as source" msgstr "" -#: lxc/main.go:502 +#: lxc/main.go:507 msgid "Invalid number of arguments" msgstr "" @@ -2972,9 +2972,9 @@ msgstr "" msgid "Invalid protocol: %s" msgstr "" -#: lxc/storage_volume.go:953 lxc/storage_volume.go:1154 -#: lxc/storage_volume.go:1266 lxc/storage_volume.go:1814 -#: lxc/storage_volume.go:1947 lxc/storage_volume.go:2087 +#: lxc/storage_volume.go:1064 lxc/storage_volume.go:1281 +#: lxc/storage_volume.go:1405 lxc/storage_volume.go:1985 +#: lxc/storage_volume.go:2132 lxc/storage_volume.go:2284 msgid "Invalid snapshot name" msgstr "" @@ -2988,12 +2988,12 @@ msgstr "" msgid "Invalid target %s" msgstr "" -#: lxc/info.go:229 +#: lxc/info.go:238 #, c-format msgid "IsSM: %s (%s)" msgstr "" -#: lxc/image.go:166 +#: lxc/image.go:167 msgid "Keep the image up to date after initial copy" msgstr "" @@ -3001,25 +3001,25 @@ msgstr "" msgid "LAST SEEN" msgstr "" -#: lxc/list.go:561 +#: lxc/list.go:570 msgid "LAST USED AT" msgstr "" -#: lxc/project.go:886 +#: lxc/project.go:984 msgid "LIMIT" msgstr "" -#: lxc/network_forward.go:148 lxc/network_load_balancer.go:151 +#: lxc/network_forward.go:156 lxc/network_load_balancer.go:159 msgid "LISTEN ADDRESS" msgstr "" -#: lxc/list.go:597 lxc/network.go:1059 lxc/network_forward.go:155 -#: lxc/network_load_balancer.go:157 lxc/operation.go:177 -#: lxc/storage_bucket.go:516 lxc/storage_volume.go:1592 lxc/warning.go:220 +#: lxc/list.go:606 lxc/network.go:1168 lxc/network_forward.go:163 +#: lxc/network_load_balancer.go:165 lxc/operation.go:177 +#: lxc/storage_bucket.go:516 lxc/storage_volume.go:1739 lxc/warning.go:220 msgid "LOCATION" msgstr "" -#: lxc/manpage.go:43 +#: lxc/manpage.go:52 msgid "LXD - Command line client" msgstr "" @@ -3027,45 +3027,45 @@ msgstr "" msgid "LXD automatically uses either spicy or remote-viewer when present." msgstr "" -#: lxc/cluster.go:158 lxc/cluster.go:915 lxc/cluster.go:1009 -#: lxc/cluster.go:1100 lxc/cluster_group.go:441 +#: lxc/cluster.go:167 lxc/cluster.go:1020 lxc/cluster.go:1123 +#: lxc/cluster.go:1231 lxc/cluster_group.go:485 msgid "LXD server isn't part of a cluster" msgstr "" -#: lxc/info.go:492 +#: lxc/info.go:501 #, c-format msgid "Last Used: %s" msgstr "" -#: lxc/image.go:980 +#: lxc/image.go:1033 #, c-format msgid "Last used: %s" msgstr "" -#: lxc/image.go:982 +#: lxc/image.go:1035 msgid "Last used: never" msgstr "" -#: lxc/init.go:171 +#: lxc/init.go:180 #, c-format msgid "Launching %s" msgstr "" -#: lxc/init.go:169 +#: lxc/init.go:178 msgid "Launching the instance" msgstr "" -#: lxc/info.go:220 +#: lxc/info.go:229 #, c-format msgid "Link detected: %v" msgstr "" -#: lxc/info.go:222 +#: lxc/info.go:231 #, c-format msgid "Link speed: %dMbit/s (%s duplex)" msgstr "" -#: lxc/network.go:1004 lxc/network.go:1005 +#: lxc/network.go:1105 lxc/network.go:1106 msgid "List DHCP leases" msgstr "" @@ -3077,15 +3077,15 @@ msgstr "" msgid "List all active certificate add tokens" msgstr "" -#: lxc/cluster.go:879 lxc/cluster.go:880 +#: lxc/cluster.go:976 lxc/cluster.go:977 msgid "List all active cluster member join tokens" msgstr "" -#: lxc/cluster_group.go:403 lxc/cluster_group.go:404 +#: lxc/cluster_group.go:439 lxc/cluster_group.go:440 msgid "List all the cluster groups" msgstr "" -#: lxc/cluster.go:121 lxc/cluster.go:122 +#: lxc/cluster.go:122 lxc/cluster.go:123 msgid "List all the cluster members" msgstr "" @@ -3109,7 +3109,7 @@ msgstr "" msgid "List available network load balancers" msgstr "" -#: lxc/network_peer.go:80 lxc/network_peer.go:81 +#: lxc/network_peer.go:81 lxc/network_peer.go:82 msgid "List available network peers" msgstr "" @@ -3117,7 +3117,7 @@ msgstr "" msgid "List available network zone" msgstr "" -#: lxc/network_zone.go:693 lxc/network_zone.go:694 +#: lxc/network_zone.go:766 lxc/network_zone.go:767 msgid "List available network zone records" msgstr "" @@ -3125,11 +3125,11 @@ msgstr "" msgid "List available network zoneS" msgstr "" -#: lxc/network.go:911 lxc/network.go:912 +#: lxc/network.go:1004 lxc/network.go:1005 msgid "List available networks" msgstr "" -#: lxc/storage.go:614 lxc/storage.go:615 +#: lxc/storage.go:654 lxc/storage.go:655 msgid "List available storage pools" msgstr "" @@ -3160,11 +3160,11 @@ msgid "" "Filters may be part of the image hash or part of the image alias name.\n" msgstr "" -#: lxc/image.go:1034 +#: lxc/image.go:1087 msgid "List images" msgstr "" -#: lxc/image.go:1035 +#: lxc/image.go:1088 msgid "" "List images\n" "\n" @@ -3191,19 +3191,19 @@ msgid "" " t - Type" msgstr "" -#: lxc/config_device.go:284 lxc/config_device.go:285 +#: lxc/config_device.go:317 lxc/config_device.go:318 msgid "List instance devices" msgstr "" -#: lxc/config_template.go:239 lxc/config_template.go:240 +#: lxc/config_template.go:272 lxc/config_template.go:273 msgid "List instance file templates" msgstr "" -#: lxc/list.go:47 +#: lxc/list.go:48 msgid "List instances" msgstr "" -#: lxc/list.go:48 +#: lxc/list.go:49 #, c-format msgid "" "List instances\n" @@ -3302,11 +3302,11 @@ msgstr "" msgid "List permissions" msgstr "" -#: lxc/profile.go:632 lxc/profile.go:633 +#: lxc/profile.go:702 lxc/profile.go:703 msgid "List profiles" msgstr "" -#: lxc/project.go:432 lxc/project.go:433 +#: lxc/project.go:469 lxc/project.go:470 msgid "List projects" msgstr "" @@ -3318,11 +3318,11 @@ msgstr "" msgid "List storage buckets" msgstr "" -#: lxc/storage_volume.go:1447 +#: lxc/storage_volume.go:1586 msgid "List storage volumes" msgstr "" -#: lxc/storage_volume.go:1452 +#: lxc/storage_volume.go:1591 msgid "" "List storage volumes\n" "\n" @@ -3381,7 +3381,7 @@ msgstr "" msgid "List, show and delete background operations" msgstr "" -#: lxc/info.go:480 lxc/storage_volume.go:1325 +#: lxc/info.go:489 lxc/storage_volume.go:1464 #, c-format msgid "Location: %s" msgstr "" @@ -3390,83 +3390,83 @@ msgstr "" msgid "Log level filtering can only be used with pretty formatting" msgstr "" -#: lxc/info.go:711 +#: lxc/info.go:720 msgid "Log:" msgstr "" -#: lxc/network.go:885 +#: lxc/network.go:978 msgid "Lower device" msgstr "" -#: lxc/network.go:866 +#: lxc/network.go:959 msgid "Lower devices" msgstr "" -#: lxc/network.go:1053 +#: lxc/network.go:1162 msgid "MAC ADDRESS" msgstr "" -#: lxc/info.go:561 +#: lxc/info.go:570 msgid "MAC address" msgstr "" -#: lxc/network.go:834 +#: lxc/network.go:927 #, c-format msgid "MAC address: %s" msgstr "" -#: lxc/info.go:233 +#: lxc/info.go:242 #, c-format msgid "MAD: %s (%s)" msgstr "" -#: lxc/network.go:982 +#: lxc/network.go:1083 msgid "MANAGED" msgstr "" -#: lxc/cluster_group.go:461 +#: lxc/cluster_group.go:505 msgid "MEMBERS" msgstr "" -#: lxc/list.go:562 +#: lxc/list.go:571 msgid "MEMORY USAGE" msgstr "" -#: lxc/list.go:563 +#: lxc/list.go:572 #, c-format msgid "MEMORY USAGE%" msgstr "" -#: lxc/cluster.go:190 +#: lxc/cluster.go:199 msgid "MESSAGE" msgstr "" -#: lxc/network.go:864 +#: lxc/network.go:957 msgid "MII Frequency" msgstr "" -#: lxc/network.go:865 +#: lxc/network.go:958 msgid "MII state" msgstr "" -#: lxc/info.go:565 +#: lxc/info.go:574 msgid "MTU" msgstr "" -#: lxc/network.go:835 +#: lxc/network.go:928 #, c-format msgid "MTU: %d" msgstr "" -#: lxc/image.go:164 lxc/image.go:669 +#: lxc/image.go:165 lxc/image.go:702 msgid "Make image public" msgstr "" -#: lxc/publish.go:37 +#: lxc/publish.go:38 msgid "Make the image public" msgstr "" -#: lxc/network.go:31 lxc/network.go:32 +#: lxc/network.go:32 lxc/network.go:33 msgid "Manage and attach instances to networks" msgstr "" @@ -3474,11 +3474,11 @@ msgstr "" msgid "Manage cluster groups" msgstr "" -#: lxc/cluster.go:28 lxc/cluster.go:29 +#: lxc/cluster.go:29 lxc/cluster.go:30 msgid "Manage cluster members" msgstr "" -#: lxc/cluster_role.go:22 lxc/cluster_role.go:23 +#: lxc/cluster_role.go:23 lxc/cluster_role.go:24 msgid "Manage cluster roles" msgstr "" @@ -3486,7 +3486,7 @@ msgstr "" msgid "Manage command aliases" msgstr "" -#: lxc/config_device.go:23 lxc/config_device.go:24 +#: lxc/config_device.go:24 lxc/config_device.go:25 msgid "Manage devices" msgstr "" @@ -3514,11 +3514,11 @@ msgstr "" msgid "Manage image aliases" msgstr "" -#: lxc/image.go:36 +#: lxc/image.go:37 msgid "Manage images" msgstr "" -#: lxc/image.go:37 +#: lxc/image.go:38 msgid "" "Manage images\n" "\n" @@ -3537,23 +3537,23 @@ msgid "" "hash or alias name (if one is set)." msgstr "" -#: lxc/config.go:889 lxc/config.go:890 +#: lxc/config.go:942 lxc/config.go:943 msgid "Manage instance UEFI variables" msgstr "" -#: lxc/config.go:31 lxc/config.go:32 +#: lxc/config.go:32 lxc/config.go:33 msgid "Manage instance and server configuration options" msgstr "" -#: lxc/config_template.go:26 lxc/config_template.go:27 +#: lxc/config_template.go:27 lxc/config_template.go:28 msgid "Manage instance file templates" msgstr "" -#: lxc/config_metadata.go:26 lxc/config_metadata.go:27 +#: lxc/config_metadata.go:27 lxc/config_metadata.go:28 msgid "Manage instance metadata files" msgstr "" -#: lxc/network_acl.go:755 lxc/network_acl.go:756 +#: lxc/network_acl.go:844 lxc/network_acl.go:845 msgid "Manage network ACL rules" msgstr "" @@ -3561,7 +3561,7 @@ msgstr "" msgid "Manage network ACLs" msgstr "" -#: lxc/network_forward.go:784 lxc/network_forward.go:785 +#: lxc/network_forward.go:873 lxc/network_forward.go:874 msgid "Manage network forward ports" msgstr "" @@ -3569,11 +3569,11 @@ msgstr "" msgid "Manage network forwards" msgstr "" -#: lxc/network_load_balancer.go:787 lxc/network_load_balancer.go:788 +#: lxc/network_load_balancer.go:843 lxc/network_load_balancer.go:844 msgid "Manage network load balancer backends" msgstr "" -#: lxc/network_load_balancer.go:952 lxc/network_load_balancer.go:953 +#: lxc/network_load_balancer.go:1032 lxc/network_load_balancer.go:1033 msgid "Manage network load balancer ports" msgstr "" @@ -3581,15 +3581,15 @@ msgstr "" msgid "Manage network load balancers" msgstr "" -#: lxc/network_peer.go:27 lxc/network_peer.go:28 +#: lxc/network_peer.go:28 lxc/network_peer.go:29 msgid "Manage network peerings" msgstr "" -#: lxc/network_zone.go:1233 lxc/network_zone.go:1234 +#: lxc/network_zone.go:1409 lxc/network_zone.go:1410 msgid "Manage network zone record entries" msgstr "" -#: lxc/network_zone.go:636 lxc/network_zone.go:637 +#: lxc/network_zone.go:709 lxc/network_zone.go:710 msgid "Manage network zone records" msgstr "" @@ -3601,7 +3601,7 @@ msgstr "" msgid "Manage permissions" msgstr "" -#: lxc/profile.go:28 lxc/profile.go:29 +#: lxc/profile.go:29 lxc/profile.go:30 msgid "Manage profiles" msgstr "" @@ -3629,11 +3629,11 @@ msgstr "" msgid "Manage storage pools and volumes" msgstr "" -#: lxc/storage_volume.go:43 +#: lxc/storage_volume.go:57 msgid "Manage storage volumes" msgstr "" -#: lxc/storage_volume.go:44 +#: lxc/storage_volume.go:58 msgid "" "Manage storage volumes\n" "\n" @@ -3657,62 +3657,62 @@ msgstr "" msgid "Manage warnings" msgstr "" -#: lxc/info.go:137 lxc/info.go:246 +#: lxc/info.go:146 lxc/info.go:255 #, c-format msgid "Maximum number of VFs: %d" msgstr "" -#: lxc/info.go:148 +#: lxc/info.go:157 msgid "Mdev profiles:" msgstr "" -#: lxc/cluster_role.go:86 +#: lxc/cluster_role.go:95 #, c-format msgid "Member %q already has role %q" msgstr "" -#: lxc/cluster_role.go:142 +#: lxc/cluster_role.go:163 #, c-format msgid "Member %q does not have role %q" msgstr "" -#: lxc/cluster.go:860 +#: lxc/cluster.go:957 #, c-format msgid "Member %s join token:" msgstr "" -#: lxc/cluster.go:588 +#: lxc/cluster.go:661 #, c-format msgid "Member %s removed" msgstr "" -#: lxc/cluster.go:501 +#: lxc/cluster.go:566 #, c-format msgid "Member %s renamed to %s" msgstr "" -#: lxc/info.go:529 +#: lxc/info.go:538 msgid "Memory (current)" msgstr "" -#: lxc/info.go:533 +#: lxc/info.go:542 msgid "Memory (peak)" msgstr "" -#: lxc/info.go:545 +#: lxc/info.go:554 msgid "Memory usage:" msgstr "" -#: lxc/info.go:366 +#: lxc/info.go:375 msgid "Memory:" msgstr "" -#: lxc/move.go:309 lxc/move.go:422 +#: lxc/move.go:322 lxc/move.go:435 #, c-format msgid "Migration API failure: %w" msgstr "" -#: lxc/move.go:334 lxc/move.go:427 +#: lxc/move.go:347 lxc/move.go:440 #, c-format msgid "Migration operation failure: %w" msgstr "" @@ -3735,14 +3735,14 @@ msgstr "" msgid "Missing certificate fingerprint" msgstr "" -#: lxc/cluster_group.go:203 lxc/cluster_group.go:261 lxc/cluster_group.go:313 -#: lxc/cluster_group.go:624 +#: lxc/cluster_group.go:223 lxc/cluster_group.go:289 lxc/cluster_group.go:349 +#: lxc/cluster_group.go:696 msgid "Missing cluster group name" msgstr "" -#: lxc/cluster.go:722 lxc/cluster.go:1220 lxc/cluster_group.go:117 -#: lxc/cluster_group.go:503 lxc/cluster_group.go:677 lxc/cluster_role.go:73 -#: lxc/cluster_role.go:129 +#: lxc/cluster.go:811 lxc/cluster.go:1367 lxc/cluster_group.go:129 +#: lxc/cluster_group.go:559 lxc/cluster_group.go:761 lxc/cluster_role.go:82 +#: lxc/cluster_role.go:150 msgid "Missing cluster member name" msgstr "" @@ -3763,11 +3763,11 @@ msgstr "" msgid "Missing identity provider group name argument" msgstr "" -#: lxc/config_metadata.go:103 lxc/config_metadata.go:204 -#: lxc/config_template.go:91 lxc/config_template.go:134 -#: lxc/config_template.go:176 lxc/config_template.go:265 -#: lxc/config_template.go:324 lxc/profile.go:128 lxc/profile.go:201 -#: lxc/profile.go:718 lxc/rebuild.go:60 +#: lxc/config_metadata.go:112 lxc/config_metadata.go:221 +#: lxc/config_template.go:100 lxc/config_template.go:155 +#: lxc/config_template.go:209 lxc/config_template.go:306 +#: lxc/config_template.go:377 lxc/profile.go:141 lxc/profile.go:222 +#: lxc/profile.go:808 lxc/rebuild.go:60 msgid "Missing instance name" msgstr "" @@ -3776,102 +3776,103 @@ msgstr "" msgid "Missing key name" msgstr "" -#: lxc/network_forward.go:199 lxc/network_forward.go:413 -#: lxc/network_forward.go:486 lxc/network_forward.go:632 -#: lxc/network_forward.go:751 lxc/network_forward.go:828 -#: lxc/network_forward.go:894 lxc/network_load_balancer.go:201 -#: lxc/network_load_balancer.go:416 lxc/network_load_balancer.go:489 -#: lxc/network_load_balancer.go:635 lxc/network_load_balancer.go:755 -#: lxc/network_load_balancer.go:831 lxc/network_load_balancer.go:895 -#: lxc/network_load_balancer.go:996 lxc/network_load_balancer.go:1058 +#: lxc/network_forward.go:219 lxc/network_forward.go:449 +#: lxc/network_forward.go:534 lxc/network_forward.go:709 +#: lxc/network_forward.go:840 lxc/network_forward.go:933 +#: lxc/network_forward.go:1015 lxc/network_load_balancer.go:221 +#: lxc/network_load_balancer.go:436 lxc/network_load_balancer.go:521 +#: lxc/network_load_balancer.go:679 lxc/network_load_balancer.go:811 +#: lxc/network_load_balancer.go:899 lxc/network_load_balancer.go:975 +#: lxc/network_load_balancer.go:1088 lxc/network_load_balancer.go:1162 msgid "Missing listen address" msgstr "" -#: lxc/config_device.go:119 lxc/config_device.go:232 lxc/config_device.go:314 -#: lxc/config_device.go:380 lxc/config_device.go:474 lxc/config_device.go:583 -#: lxc/config_device.go:692 +#: lxc/config_device.go:132 lxc/config_device.go:265 lxc/config_device.go:359 +#: lxc/config_device.go:433 lxc/config_device.go:545 lxc/config_device.go:674 +#: lxc/config_device.go:795 msgid "Missing name" msgstr "" -#: lxc/network_acl.go:188 lxc/network_acl.go:240 lxc/network_acl.go:291 -#: lxc/network_acl.go:355 lxc/network_acl.go:445 lxc/network_acl.go:577 -#: lxc/network_acl.go:680 lxc/network_acl.go:729 lxc/network_acl.go:849 -#: lxc/network_acl.go:916 +#: lxc/network_acl.go:204 lxc/network_acl.go:264 lxc/network_acl.go:327 +#: lxc/network_acl.go:399 lxc/network_acl.go:497 lxc/network_acl.go:650 +#: lxc/network_acl.go:761 lxc/network_acl.go:818 lxc/network_acl.go:954 +#: lxc/network_acl.go:1037 msgid "Missing network ACL name" msgstr "" -#: lxc/network.go:159 lxc/network.go:244 lxc/network.go:396 lxc/network.go:446 -#: lxc/network.go:531 lxc/network.go:636 lxc/network.go:747 lxc/network.go:815 -#: lxc/network.go:1030 lxc/network.go:1100 lxc/network.go:1158 -#: lxc/network.go:1242 lxc/network_forward.go:119 lxc/network_forward.go:195 -#: lxc/network_forward.go:264 lxc/network_forward.go:409 -#: lxc/network_forward.go:482 lxc/network_forward.go:628 -#: lxc/network_forward.go:747 lxc/network_forward.go:824 -#: lxc/network_forward.go:890 lxc/network_load_balancer.go:123 -#: lxc/network_load_balancer.go:197 lxc/network_load_balancer.go:266 -#: lxc/network_load_balancer.go:412 lxc/network_load_balancer.go:485 -#: lxc/network_load_balancer.go:631 lxc/network_load_balancer.go:751 -#: lxc/network_load_balancer.go:827 lxc/network_load_balancer.go:891 -#: lxc/network_load_balancer.go:992 lxc/network_load_balancer.go:1054 -#: lxc/network_peer.go:110 lxc/network_peer.go:180 lxc/network_peer.go:237 -#: lxc/network_peer.go:355 lxc/network_peer.go:426 lxc/network_peer.go:556 -#: lxc/network_peer.go:665 +#: lxc/network.go:172 lxc/network.go:269 lxc/network.go:437 lxc/network.go:499 +#: lxc/network.go:596 lxc/network.go:709 lxc/network.go:832 lxc/network.go:908 +#: lxc/network.go:1139 lxc/network.go:1217 lxc/network.go:1283 +#: lxc/network.go:1375 lxc/network_forward.go:127 lxc/network_forward.go:215 +#: lxc/network_forward.go:284 lxc/network_forward.go:445 +#: lxc/network_forward.go:530 lxc/network_forward.go:705 +#: lxc/network_forward.go:836 lxc/network_forward.go:929 +#: lxc/network_forward.go:1011 lxc/network_load_balancer.go:131 +#: lxc/network_load_balancer.go:217 lxc/network_load_balancer.go:286 +#: lxc/network_load_balancer.go:432 lxc/network_load_balancer.go:517 +#: lxc/network_load_balancer.go:675 lxc/network_load_balancer.go:807 +#: lxc/network_load_balancer.go:895 lxc/network_load_balancer.go:971 +#: lxc/network_load_balancer.go:1084 lxc/network_load_balancer.go:1158 +#: lxc/network_peer.go:119 lxc/network_peer.go:201 lxc/network_peer.go:266 +#: lxc/network_peer.go:401 lxc/network_peer.go:485 lxc/network_peer.go:644 +#: lxc/network_peer.go:765 msgid "Missing network name" msgstr "" -#: lxc/network_zone.go:179 lxc/network_zone.go:235 lxc/network_zone.go:299 -#: lxc/network_zone.go:387 lxc/network_zone.go:508 lxc/network_zone.go:611 -#: lxc/network_zone.go:717 lxc/network_zone.go:785 lxc/network_zone.go:901 -#: lxc/network_zone.go:985 lxc/network_zone.go:1206 lxc/network_zone.go:1271 -#: lxc/network_zone.go:1316 +#: lxc/network_zone.go:195 lxc/network_zone.go:264 lxc/network_zone.go:336 +#: lxc/network_zone.go:432 lxc/network_zone.go:573 lxc/network_zone.go:684 +#: lxc/network_zone.go:798 lxc/network_zone.go:878 lxc/network_zone.go:1023 +#: lxc/network_zone.go:1120 lxc/network_zone.go:1382 lxc/network_zone.go:1459 +#: lxc/network_zone.go:1516 msgid "Missing network zone name" msgstr "" -#: lxc/network_zone.go:838 lxc/network_zone.go:1104 +#: lxc/network_zone.go:948 lxc/network_zone.go:1268 msgid "Missing network zone record name" msgstr "" -#: lxc/network_peer.go:184 lxc/network_peer.go:241 lxc/network_peer.go:359 -#: lxc/network_peer.go:430 lxc/network_peer.go:560 lxc/network_peer.go:669 +#: lxc/network_peer.go:205 lxc/network_peer.go:270 lxc/network_peer.go:405 +#: lxc/network_peer.go:489 lxc/network_peer.go:648 lxc/network_peer.go:769 msgid "Missing peer name" msgstr "" -#: lxc/storage.go:223 lxc/storage.go:293 lxc/storage.go:399 lxc/storage.go:469 -#: lxc/storage.go:724 lxc/storage.go:822 lxc/storage_bucket.go:112 +#: lxc/storage.go:235 lxc/storage.go:313 lxc/storage.go:431 lxc/storage.go:509 +#: lxc/storage.go:780 lxc/storage.go:886 lxc/storage_bucket.go:112 #: lxc/storage_bucket.go:212 lxc/storage_bucket.go:288 #: lxc/storage_bucket.go:407 lxc/storage_bucket.go:482 #: lxc/storage_bucket.go:564 lxc/storage_bucket.go:656 #: lxc/storage_bucket.go:798 lxc/storage_bucket.go:885 #: lxc/storage_bucket.go:982 lxc/storage_bucket.go:1061 -#: lxc/storage_bucket.go:1184 lxc/storage_volume.go:190 -#: lxc/storage_volume.go:288 lxc/storage_volume.go:588 -#: lxc/storage_volume.go:683 lxc/storage_volume.go:758 -#: lxc/storage_volume.go:840 lxc/storage_volume.go:942 -#: lxc/storage_volume.go:1143 lxc/storage_volume.go:1803 -#: lxc/storage_volume.go:1930 lxc/storage_volume.go:2076 -#: lxc/storage_volume.go:2238 lxc/storage_volume.go:2339 +#: lxc/storage_bucket.go:1184 lxc/storage_volume.go:209 +#: lxc/storage_volume.go:323 lxc/storage_volume.go:643 +#: lxc/storage_volume.go:750 lxc/storage_volume.go:841 +#: lxc/storage_volume.go:939 lxc/storage_volume.go:1053 +#: lxc/storage_volume.go:1270 lxc/storage_volume.go:1974 +#: lxc/storage_volume.go:2115 lxc/storage_volume.go:2273 +#: lxc/storage_volume.go:2464 lxc/storage_volume.go:2581 msgid "Missing pool name" msgstr "" -#: lxc/profile.go:363 lxc/profile.go:418 lxc/profile.go:492 lxc/profile.go:597 -#: lxc/profile.go:794 lxc/profile.go:849 lxc/profile.go:922 +#: lxc/profile.go:467 lxc/profile.go:549 lxc/profile.go:667 lxc/profile.go:892 +#: lxc/profile.go:960 lxc/profile.go:1041 msgid "Missing profile name" msgstr "" -#: lxc/project.go:138 lxc/project.go:210 lxc/project.go:292 lxc/project.go:396 -#: lxc/project.go:570 lxc/project.go:630 lxc/project.go:737 lxc/project.go:850 +#: lxc/profile.go:404 lxc/project.go:146 lxc/project.go:226 lxc/project.go:316 +#: lxc/project.go:433 lxc/project.go:622 lxc/project.go:691 lxc/project.go:819 +#: lxc/project.go:948 msgid "Missing project name" msgstr "" -#: lxc/profile.go:277 +#: lxc/profile.go:310 msgid "Missing source profile name" msgstr "" -#: lxc/storage_volume.go:385 lxc/storage_volume.go:1725 +#: lxc/storage_volume.go:432 lxc/storage_volume.go:1884 msgid "Missing source volume name" msgstr "" -#: lxc/storage_volume.go:1255 +#: lxc/storage_volume.go:1394 msgid "Missing storage pool name" msgstr "" @@ -3879,20 +3880,20 @@ msgstr "" msgid "Missing target directory" msgstr "" -#: lxc/network_peer.go:245 +#: lxc/network_peer.go:274 msgid "Missing target network" msgstr "" -#: lxc/network.go:860 +#: lxc/network.go:953 msgid "Mode" msgstr "" -#: lxc/info.go:268 +#: lxc/info.go:277 #, c-format msgid "Model: %s" msgstr "" -#: lxc/info.go:128 +#: lxc/info.go:137 #, c-format msgid "Model: %v" msgstr "" @@ -3908,8 +3909,8 @@ msgid "" "By default the monitor will listen to all message types." msgstr "" -#: lxc/network.go:466 lxc/network.go:551 lxc/storage_volume.go:778 -#: lxc/storage_volume.go:859 +#: lxc/network.go:519 lxc/network.go:616 lxc/storage_volume.go:861 +#: lxc/storage_volume.go:958 msgid "More than one device matches, specify the device name" msgstr "" @@ -3921,16 +3922,16 @@ msgstr "" msgid "Mount files from instances" msgstr "" -#: lxc/info.go:282 lxc/info.go:292 +#: lxc/info.go:291 lxc/info.go:301 #, c-format msgid "Mounted: %v" msgstr "" -#: lxc/move.go:36 +#: lxc/move.go:37 msgid "Move instances within or in between LXD servers" msgstr "" -#: lxc/move.go:37 +#: lxc/move.go:38 msgid "" "Move instances within or in between LXD servers\n" "\n" @@ -3946,46 +3947,46 @@ msgid "" "versions.\n" msgstr "" -#: lxc/storage_volume.go:1696 lxc/storage_volume.go:1697 +#: lxc/storage_volume.go:1843 lxc/storage_volume.go:1844 msgid "Move storage volumes between pools" msgstr "" -#: lxc/move.go:62 +#: lxc/move.go:63 msgid "Move the instance without its snapshots" msgstr "" -#: lxc/storage_volume.go:1703 +#: lxc/storage_volume.go:1850 msgid "Move to a project different from the source" msgstr "" -#: lxc/storage_volume.go:465 +#: lxc/storage_volume.go:512 #, c-format msgid "Moving the storage volume: %s" msgstr "" -#: lxc/network_forward.go:938 lxc/network_load_balancer.go:1102 +#: lxc/network_forward.go:1059 lxc/network_load_balancer.go:1206 msgid "Multiple ports match. Use --force to remove them all" msgstr "" -#: lxc/network_acl.go:971 +#: lxc/network_acl.go:1092 msgid "Multiple rules match. Use --force to remove them all" msgstr "" -#: lxc/image.go:681 +#: lxc/image.go:726 msgid "Must run as root to import from directory" msgstr "" -#: lxc/action.go:233 +#: lxc/action.go:250 msgid "Must supply instance name for: " msgstr "" -#: lxc/auth.go:375 lxc/auth.go:815 lxc/auth.go:1735 lxc/cluster.go:183 -#: lxc/cluster.go:964 lxc/cluster_group.go:459 lxc/config_trust.go:409 -#: lxc/config_trust.go:514 lxc/list.go:564 lxc/network.go:980 -#: lxc/network_acl.go:148 lxc/network_peer.go:139 lxc/network_zone.go:139 -#: lxc/network_zone.go:746 lxc/profile.go:677 lxc/project.go:521 -#: lxc/remote.go:748 lxc/storage.go:667 lxc/storage_bucket.go:511 -#: lxc/storage_bucket.go:831 lxc/storage_volume.go:1584 +#: lxc/auth.go:375 lxc/auth.go:815 lxc/auth.go:1735 lxc/cluster.go:192 +#: lxc/cluster.go:1069 lxc/cluster_group.go:503 lxc/config_trust.go:409 +#: lxc/config_trust.go:514 lxc/list.go:573 lxc/network.go:1081 +#: lxc/network_acl.go:156 lxc/network_peer.go:148 lxc/network_zone.go:147 +#: lxc/network_zone.go:827 lxc/profile.go:755 lxc/project.go:565 +#: lxc/remote.go:748 lxc/storage.go:715 lxc/storage_bucket.go:511 +#: lxc/storage_bucket.go:831 lxc/storage_volume.go:1731 msgid "NAME" msgstr "" @@ -3993,48 +3994,48 @@ msgstr "" msgid "NAT" msgstr "" -#: lxc/project.go:527 +#: lxc/project.go:571 msgid "NETWORK ZONES" msgstr "" -#: lxc/project.go:526 +#: lxc/project.go:570 msgid "NETWORKS" msgstr "" -#: lxc/info.go:409 +#: lxc/info.go:418 msgid "NIC:" msgstr "" -#: lxc/info.go:412 +#: lxc/info.go:421 msgid "NICs:" msgstr "" -#: lxc/network.go:957 lxc/operation.go:154 lxc/project.go:479 -#: lxc/project.go:484 lxc/project.go:489 lxc/project.go:494 lxc/project.go:499 -#: lxc/project.go:504 lxc/remote.go:708 lxc/remote.go:713 lxc/remote.go:718 +#: lxc/network.go:1058 lxc/operation.go:154 lxc/project.go:523 +#: lxc/project.go:528 lxc/project.go:533 lxc/project.go:538 lxc/project.go:543 +#: lxc/project.go:548 lxc/remote.go:708 lxc/remote.go:713 lxc/remote.go:718 msgid "NO" msgstr "" -#: lxc/info.go:89 lxc/info.go:175 lxc/info.go:262 +#: lxc/info.go:98 lxc/info.go:184 lxc/info.go:271 #, c-format msgid "NUMA node: %v" msgstr "" -#: lxc/info.go:375 +#: lxc/info.go:384 msgid "NUMA nodes:\n" msgstr "" -#: lxc/info.go:125 +#: lxc/info.go:134 msgid "NVIDIA information:" msgstr "" -#: lxc/info.go:130 +#: lxc/info.go:139 #, c-format msgid "NVRM Version: %v" msgstr "" -#: lxc/info.go:629 lxc/info.go:680 lxc/storage_volume.go:1367 -#: lxc/storage_volume.go:1417 +#: lxc/info.go:638 lxc/info.go:689 lxc/storage_volume.go:1506 +#: lxc/storage_volume.go:1556 msgid "Name" msgstr "" @@ -4042,133 +4043,133 @@ msgstr "" msgid "Name of the project to use for this remote:" msgstr "" -#: lxc/info.go:463 lxc/network.go:833 lxc/storage_volume.go:1307 +#: lxc/info.go:472 lxc/network.go:926 lxc/storage_volume.go:1446 #, c-format msgid "Name: %s" msgstr "" -#: lxc/info.go:304 +#: lxc/info.go:313 #, c-format msgid "Name: %v" msgstr "" -#: lxc/network.go:354 +#: lxc/network.go:387 #, c-format msgid "Network %s created" msgstr "" -#: lxc/network.go:406 +#: lxc/network.go:447 #, c-format msgid "Network %s deleted" msgstr "" -#: lxc/network.go:352 +#: lxc/network.go:385 #, c-format msgid "Network %s pending on member %s" msgstr "" -#: lxc/network.go:1110 +#: lxc/network.go:1227 #, c-format msgid "Network %s renamed to %s" msgstr "" -#: lxc/network_acl.go:399 +#: lxc/network_acl.go:443 #, c-format msgid "Network ACL %s created" msgstr "" -#: lxc/network_acl.go:739 +#: lxc/network_acl.go:828 #, c-format msgid "Network ACL %s deleted" msgstr "" -#: lxc/network_acl.go:690 +#: lxc/network_acl.go:771 #, c-format msgid "Network ACL %s renamed to %s" msgstr "" -#: lxc/network_zone.go:341 +#: lxc/network_zone.go:378 #, c-format msgid "Network Zone %s created" msgstr "" -#: lxc/network_zone.go:621 +#: lxc/network_zone.go:694 #, c-format msgid "Network Zone %s deleted" msgstr "" -#: lxc/network_forward.go:366 +#: lxc/network_forward.go:386 #, c-format msgid "Network forward %s created" msgstr "" -#: lxc/network_forward.go:768 +#: lxc/network_forward.go:857 #, c-format msgid "Network forward %s deleted" msgstr "" -#: lxc/network_load_balancer.go:370 +#: lxc/network_load_balancer.go:390 #, c-format msgid "Network load balancer %s created" msgstr "" -#: lxc/network_load_balancer.go:772 +#: lxc/network_load_balancer.go:828 #, c-format msgid "Network load balancer %s deleted" msgstr "" -#: lxc/init.go:61 +#: lxc/init.go:62 msgid "Network name" msgstr "" -#: lxc/network_peer.go:308 +#: lxc/network_peer.go:337 #, c-format msgid "Network peer %s created" msgstr "" -#: lxc/network_peer.go:681 +#: lxc/network_peer.go:781 #, c-format msgid "Network peer %s deleted" msgstr "" -#: lxc/network_peer.go:312 +#: lxc/network_peer.go:341 #, c-format msgid "Network peer %s is in unexpected state %q" msgstr "" -#: lxc/network_peer.go:310 +#: lxc/network_peer.go:339 #, c-format msgid "" "Network peer %s pending (please complete mutual peering on peer network)" msgstr "" -#: lxc/network.go:301 +#: lxc/network.go:326 msgid "Network type" msgstr "" -#: lxc/info.go:586 lxc/network.go:850 +#: lxc/info.go:595 lxc/network.go:943 msgid "Network usage:" msgstr "" -#: lxc/network_zone.go:943 +#: lxc/network_zone.go:1065 #, c-format msgid "Network zone record %s created" msgstr "" -#: lxc/network_zone.go:1216 +#: lxc/network_zone.go:1392 #, c-format msgid "Network zone record %s deleted" msgstr "" -#: lxc/publish.go:38 +#: lxc/publish.go:39 msgid "New alias to define at target" msgstr "" -#: lxc/image.go:167 lxc/image.go:670 +#: lxc/image.go:168 lxc/image.go:703 msgid "New aliases to add to the image" msgstr "" -#: lxc/copy.go:54 lxc/import.go:37 lxc/init.go:59 lxc/move.go:59 +#: lxc/copy.go:55 lxc/import.go:37 lxc/init.go:60 lxc/move.go:60 msgid "New key/value to apply to a specific device" msgstr "" @@ -4177,66 +4178,66 @@ msgstr "" msgid "No certificate add token for member %s on remote: %s" msgstr "" -#: lxc/cluster.go:1047 +#: lxc/cluster.go:1161 #, c-format msgid "No cluster join token for member %s on remote: %s" msgstr "" -#: lxc/network.go:475 lxc/network.go:560 +#: lxc/network.go:528 lxc/network.go:625 msgid "No device found for this network" msgstr "" -#: lxc/storage_volume.go:787 lxc/storage_volume.go:868 +#: lxc/storage_volume.go:870 lxc/storage_volume.go:967 msgid "No device found for this storage volume" msgstr "" -#: lxc/network_load_balancer.go:926 +#: lxc/network_load_balancer.go:1006 msgid "No matching backend found" msgstr "" -#: lxc/network_forward.go:949 lxc/network_load_balancer.go:1113 +#: lxc/network_forward.go:1070 lxc/network_load_balancer.go:1217 msgid "No matching port(s) found" msgstr "" -#: lxc/network_acl.go:982 +#: lxc/network_acl.go:1103 msgid "No matching rule(s) found" msgstr "" -#: lxc/storage_volume.go:399 lxc/storage_volume.go:1734 +#: lxc/storage_volume.go:446 lxc/storage_volume.go:1893 msgid "No storage pool for source volume specified" msgstr "" -#: lxc/storage_volume.go:449 lxc/storage_volume.go:1745 +#: lxc/storage_volume.go:496 lxc/storage_volume.go:1904 msgid "No storage pool for target volume specified" msgstr "" -#: lxc/config_device.go:130 lxc/config_device.go:404 +#: lxc/config_device.go:143 lxc/config_device.go:457 #, c-format msgid "No value found in %q" msgstr "" -#: lxc/info.go:377 +#: lxc/info.go:386 #, c-format msgid "Node %d:\n" msgstr "" -#: lxc/storage_volume.go:1841 +#: lxc/storage_volume.go:2012 msgid "Not a snapshot name" msgstr "" -#: lxc/network.go:892 +#: lxc/network.go:985 msgid "OVN:" msgstr "" -#: lxc/storage_volume.go:195 lxc/storage_volume.go:308 +#: lxc/storage_volume.go:214 lxc/storage_volume.go:343 msgid "Only \"custom\" volumes can be attached to instances" msgstr "" -#: lxc/storage_volume.go:2424 +#: lxc/storage_volume.go:2678 msgid "Only \"custom\" volumes can be exported" msgstr "" -#: lxc/storage_volume.go:2251 +#: lxc/storage_volume.go:2477 msgid "Only \"custom\" volumes can be snapshotted" msgstr "" @@ -4244,15 +4245,15 @@ msgstr "" msgid "Only https URLs are supported for simplestreams" msgstr "" -#: lxc/image.go:758 +#: lxc/image.go:803 msgid "Only https:// is supported for remote image import" msgstr "" -#: lxc/storage_volume.go:1273 +#: lxc/storage_volume.go:1412 msgid "Only instance or custom volumes are supported" msgstr "" -#: lxc/network.go:662 lxc/network.go:1173 +#: lxc/network.go:735 lxc/network.go:1298 msgid "Only managed networks can be modified" msgstr "" @@ -4261,7 +4262,7 @@ msgstr "" msgid "Operation %s deleted" msgstr "" -#: lxc/info.go:684 lxc/storage_volume.go:1421 +#: lxc/info.go:693 lxc/storage_volume.go:1560 msgid "Optimized Storage" msgstr "" @@ -4273,41 +4274,41 @@ msgstr "" msgid "Override the terminal mode (auto, interactive or non-interactive)" msgstr "" -#: lxc/info.go:100 lxc/info.go:186 +#: lxc/info.go:109 lxc/info.go:195 #, c-format msgid "PCI address: %v" msgstr "" -#: lxc/network_peer.go:141 +#: lxc/network_peer.go:150 msgid "PEER" msgstr "" -#: lxc/list.go:566 +#: lxc/list.go:575 msgid "PID" msgstr "" -#: lxc/info.go:484 +#: lxc/info.go:493 #, c-format msgid "PID: %d" msgstr "" -#: lxc/storage_volume.go:1603 +#: lxc/storage_volume.go:1750 msgid "POOL" msgstr "" -#: lxc/network_forward.go:151 lxc/network_load_balancer.go:153 +#: lxc/network_forward.go:159 lxc/network_load_balancer.go:161 msgid "PORTS" msgstr "" -#: lxc/list.go:565 +#: lxc/list.go:574 msgid "PROCESSES" msgstr "" -#: lxc/list.go:567 lxc/project.go:523 +#: lxc/list.go:576 lxc/project.go:567 msgid "PROFILES" msgstr "" -#: lxc/list.go:558 lxc/storage_volume.go:1609 lxc/warning.go:212 +#: lxc/list.go:567 lxc/storage_volume.go:1756 lxc/warning.go:212 msgid "PROJECT" msgstr "" @@ -4315,32 +4316,32 @@ msgstr "" msgid "PROTOCOL" msgstr "" -#: lxc/image.go:1073 lxc/remote.go:752 +#: lxc/image.go:1134 lxc/remote.go:752 msgid "PUBLIC" msgstr "" -#: lxc/info.go:570 lxc/network.go:853 +#: lxc/info.go:579 lxc/network.go:946 msgid "Packets received" msgstr "" -#: lxc/info.go:571 lxc/network.go:854 +#: lxc/info.go:580 lxc/network.go:947 msgid "Packets sent" msgstr "" -#: lxc/info.go:286 +#: lxc/info.go:295 msgid "Partitions:" msgstr "" -#: lxc/main.go:363 +#: lxc/main.go:368 #, c-format msgid "Password for %s: " msgstr "" -#: lxc/action.go:52 lxc/action.go:53 +#: lxc/action.go:57 lxc/action.go:58 msgid "Pause instances" msgstr "" -#: lxc/copy.go:64 +#: lxc/copy.go:65 msgid "Perform an incremental copy" msgstr "" @@ -4352,7 +4353,7 @@ msgstr "" msgid "Please provide client name: " msgstr "" -#: lxc/cluster.go:834 +#: lxc/cluster.go:931 msgid "Please provide cluster member name: " msgstr "" @@ -4360,12 +4361,12 @@ msgstr "" msgid "Please type 'y', 'n' or the fingerprint:" msgstr "" -#: lxc/info.go:212 +#: lxc/info.go:221 #, c-format msgid "Port type: %s" msgstr "" -#: lxc/info.go:194 +#: lxc/info.go:203 msgid "Ports:" msgstr "" @@ -4373,16 +4374,16 @@ msgstr "" msgid "Press ctrl+c to finish" msgstr "" -#: lxc/auth.go:301 lxc/auth.go:1055 lxc/auth.go:1661 lxc/cluster.go:771 -#: lxc/cluster_group.go:362 lxc/config.go:273 lxc/config.go:348 -#: lxc/config.go:1275 lxc/config_metadata.go:148 lxc/config_template.go:206 -#: lxc/config_trust.go:315 lxc/image.go:467 lxc/network.go:687 -#: lxc/network_acl.go:626 lxc/network_forward.go:691 -#: lxc/network_load_balancer.go:695 lxc/network_peer.go:611 -#: lxc/network_zone.go:557 lxc/network_zone.go:1153 lxc/profile.go:539 -#: lxc/project.go:339 lxc/storage.go:340 lxc/storage_bucket.go:349 -#: lxc/storage_bucket.go:1126 lxc/storage_volume.go:1040 -#: lxc/storage_volume.go:1072 +#: lxc/auth.go:301 lxc/auth.go:1055 lxc/auth.go:1661 lxc/cluster.go:860 +#: lxc/cluster_group.go:398 lxc/config.go:282 lxc/config.go:357 +#: lxc/config.go:1328 lxc/config_metadata.go:157 lxc/config_template.go:239 +#: lxc/config_trust.go:315 lxc/image.go:492 lxc/network.go:760 +#: lxc/network_acl.go:699 lxc/network_forward.go:768 +#: lxc/network_load_balancer.go:739 lxc/network_peer.go:699 +#: lxc/network_zone.go:622 lxc/network_zone.go:1317 lxc/profile.go:596 +#: lxc/project.go:363 lxc/storage.go:360 lxc/storage_bucket.go:349 +#: lxc/storage_bucket.go:1126 lxc/storage_volume.go:1151 +#: lxc/storage_volume.go:1183 msgid "Press enter to open the editor again or ctrl+c to abort change" msgstr "" @@ -4402,87 +4403,87 @@ msgstr "" msgid "Print version number" msgstr "" -#: lxc/info.go:498 +#: lxc/info.go:507 #, c-format msgid "Processes: %d" msgstr "" -#: lxc/main_aliases.go:202 lxc/main_aliases.go:209 +#: lxc/main_aliases.go:223 lxc/main_aliases.go:230 #, c-format msgid "Processing aliases failed: %s" msgstr "" -#: lxc/info.go:96 lxc/info.go:182 +#: lxc/info.go:105 lxc/info.go:191 #, c-format msgid "Product: %v (%v)" msgstr "" -#: lxc/profile.go:150 +#: lxc/profile.go:163 #, c-format msgid "Profile %s added to %s" msgstr "" -#: lxc/profile.go:377 +#: lxc/profile.go:418 #, c-format msgid "Profile %s created" msgstr "" -#: lxc/profile.go:428 +#: lxc/profile.go:477 #, c-format msgid "Profile %s deleted" msgstr "" -#: lxc/profile.go:728 +#: lxc/profile.go:818 #, c-format msgid "Profile %s isn't currently applied to %s" msgstr "" -#: lxc/profile.go:753 +#: lxc/profile.go:843 #, c-format msgid "Profile %s removed from %s" msgstr "" -#: lxc/profile.go:804 +#: lxc/profile.go:902 #, c-format msgid "Profile %s renamed to %s" msgstr "" -#: lxc/image.go:171 +#: lxc/image.go:172 msgid "Profile to apply to the new image" msgstr "" -#: lxc/copy.go:55 lxc/init.go:58 +#: lxc/copy.go:56 lxc/init.go:59 msgid "Profile to apply to the new instance" msgstr "" -#: lxc/move.go:60 +#: lxc/move.go:61 msgid "Profile to apply to the target instance" msgstr "" -#: lxc/profile.go:230 +#: lxc/profile.go:251 #, c-format msgid "Profiles %s applied to %s" msgstr "" -#: lxc/image.go:1012 +#: lxc/image.go:1065 msgid "Profiles:" msgstr "" -#: lxc/image.go:1010 +#: lxc/image.go:1063 msgid "Profiles: " msgstr "" -#: lxc/project.go:164 +#: lxc/project.go:172 #, c-format msgid "Project %s created" msgstr "" -#: lxc/project.go:220 +#: lxc/project.go:236 #, c-format msgid "Project %s deleted" msgstr "" -#: lxc/project.go:585 +#: lxc/project.go:637 #, c-format msgid "Project %s renamed to %s" msgstr "" @@ -4491,15 +4492,15 @@ msgstr "" msgid "Project to use for the remote" msgstr "" -#: lxc/image.go:985 +#: lxc/image.go:1038 msgid "Properties:" msgstr "" -#: lxc/image.go:1533 +#: lxc/image.go:1619 msgid "Property not found" msgstr "" -#: lxc/storage_volume.go:1223 +#: lxc/storage_volume.go:1350 msgid "" "Provide the type of the storage volume if it is not custom.\n" "Supported types are custom, container and virtual-machine.\n" @@ -4513,7 +4514,7 @@ msgid "" "\"default\"." msgstr "" -#: lxc/storage_volume.go:1108 +#: lxc/storage_volume.go:1219 msgid "" "Provide the type of the storage volume if it is not custom.\n" "Supported types are custom, image, container and virtual-machine.\n" @@ -4529,7 +4530,7 @@ msgid "" "pool \"default\"." msgstr "" -#: lxc/storage_volume.go:2039 +#: lxc/storage_volume.go:2224 msgid "" "Provide the type of the storage volume if it is not custom.\n" "Supported types are custom, image, container and virtual-machine.\n" @@ -4550,7 +4551,7 @@ msgid "" "called \"data\" in the \"default\" pool." msgstr "" -#: lxc/storage_volume.go:899 +#: lxc/storage_volume.go:998 msgid "" "Provide the type of the storage volume if it is not custom.\n" "Supported types are custom, image, container and virtual-machine.\n" @@ -4559,7 +4560,7 @@ msgid "" " Update a storage volume using the content of pool.yaml." msgstr "" -#: lxc/storage_volume.go:1898 +#: lxc/storage_volume.go:2069 msgid "" "Provide the type of the storage volume if it is not custom.\n" "Supported types are custom, image, container and virtual-machine.\n" @@ -4572,7 +4573,7 @@ msgid "" "pool \"default\" to seven days." msgstr "" -#: lxc/storage_volume.go:2148 +#: lxc/storage_volume.go:2345 msgid "" "Provide the type of the storage volume if it is not custom.\n" "Supported types are custom, image, container and virtual-machine.\n" @@ -4589,16 +4590,16 @@ msgstr "" msgid "Public image server" msgstr "" -#: lxc/image.go:963 +#: lxc/image.go:1016 #, c-format msgid "Public: %s" msgstr "" -#: lxc/publish.go:32 lxc/publish.go:33 +#: lxc/publish.go:33 lxc/publish.go:34 msgid "Publish instances as images" msgstr "" -#: lxc/publish.go:253 +#: lxc/publish.go:266 #, c-format msgid "Publishing instance: %s" msgstr "" @@ -4625,11 +4626,11 @@ msgstr "" msgid "Query path must start with /" msgstr "" -#: lxc/image.go:505 lxc/image.go:904 lxc/image.go:1444 +#: lxc/image.go:530 lxc/image.go:949 lxc/image.go:1509 msgid "Query virtual machine images" msgstr "" -#: lxc/project.go:885 +#: lxc/project.go:983 msgid "RESOURCE" msgstr "" @@ -4637,11 +4638,11 @@ msgstr "" msgid "ROLE" msgstr "" -#: lxc/cluster.go:185 +#: lxc/cluster.go:194 msgid "ROLES" msgstr "" -#: lxc/info.go:281 lxc/info.go:291 +#: lxc/info.go:290 lxc/info.go:300 #, c-format msgid "Read-Only: %v" msgstr "" @@ -4658,31 +4659,31 @@ msgstr "" msgid "Recursively transfer files" msgstr "" -#: lxc/storage_volume.go:363 +#: lxc/storage_volume.go:398 msgid "Refresh and update the existing storage volume copies" msgstr "" -#: lxc/image.go:1353 lxc/image.go:1354 +#: lxc/image.go:1414 lxc/image.go:1415 msgid "Refresh images" msgstr "" -#: lxc/copy.go:413 +#: lxc/copy.go:426 #, c-format msgid "Refreshing instance: %s" msgstr "" -#: lxc/image.go:1386 +#: lxc/image.go:1451 #, c-format msgid "Refreshing the image: %s" msgstr "" -#: lxc/remote.go:802 +#: lxc/remote.go:810 #, c-format msgid "Remote %s already exists" msgstr "" -#: lxc/project.go:792 lxc/remote.go:793 lxc/remote.go:866 lxc/remote.go:922 -#: lxc/remote.go:962 +#: lxc/project.go:882 lxc/remote.go:801 lxc/remote.go:882 lxc/remote.go:946 +#: lxc/remote.go:994 #, c-format msgid "Remote %s doesn't exist" msgstr "" @@ -4692,12 +4693,12 @@ msgstr "" msgid "Remote %s exists as <%s>" msgstr "" -#: lxc/remote.go:874 +#: lxc/remote.go:890 #, c-format msgid "Remote %s is global and cannot be removed" msgstr "" -#: lxc/remote.go:797 lxc/remote.go:870 lxc/remote.go:966 +#: lxc/remote.go:805 lxc/remote.go:886 lxc/remote.go:998 #, c-format msgid "Remote %s is static and cannot be modified" msgstr "" @@ -4718,17 +4719,17 @@ msgstr "" msgid "Remote trust token" msgstr "" -#: lxc/info.go:283 +#: lxc/info.go:292 #, c-format msgid "Removable: %v" msgstr "" -#: lxc/delete.go:43 +#: lxc/delete.go:48 #, c-format msgid "Remove %s (yes/no): " msgstr "" -#: lxc/cluster_group.go:478 +#: lxc/cluster_group.go:522 msgid "Remove a cluster member from a cluster group" msgstr "" @@ -4736,11 +4737,11 @@ msgstr "" msgid "Remove a group from an identity" msgstr "" -#: lxc/cluster.go:520 lxc/cluster.go:521 +#: lxc/cluster.go:585 lxc/cluster.go:586 msgid "Remove a member from the cluster" msgstr "" -#: lxc/network_zone.go:1294 +#: lxc/network_zone.go:1482 msgid "Remove a network zone record entry" msgstr "" @@ -4748,23 +4749,23 @@ msgstr "" msgid "Remove aliases" msgstr "" -#: lxc/network_forward.go:866 lxc/network_load_balancer.go:1030 +#: lxc/network_forward.go:971 lxc/network_load_balancer.go:1122 msgid "Remove all ports that match" msgstr "" -#: lxc/network_acl.go:893 +#: lxc/network_acl.go:998 msgid "Remove all rules that match" msgstr "" -#: lxc/network_load_balancer.go:867 +#: lxc/network_load_balancer.go:935 msgid "Remove backend from a load balancer" msgstr "" -#: lxc/network_load_balancer.go:866 +#: lxc/network_load_balancer.go:934 msgid "Remove backends from a load balancer" msgstr "" -#: lxc/network_zone.go:1295 +#: lxc/network_zone.go:1483 msgid "Remove entries from a network zone record" msgstr "" @@ -4772,11 +4773,11 @@ msgstr "" msgid "Remove identities from groups" msgstr "" -#: lxc/config_device.go:449 lxc/config_device.go:450 +#: lxc/config_device.go:502 lxc/config_device.go:503 msgid "Remove instance devices" msgstr "" -#: lxc/cluster_group.go:477 +#: lxc/cluster_group.go:521 msgid "Remove member from group" msgstr "" @@ -4784,27 +4785,27 @@ msgstr "" msgid "Remove permissions from groups" msgstr "" -#: lxc/network_forward.go:864 lxc/network_forward.go:865 +#: lxc/network_forward.go:969 lxc/network_forward.go:970 msgid "Remove ports from a forward" msgstr "" -#: lxc/network_load_balancer.go:1028 lxc/network_load_balancer.go:1029 +#: lxc/network_load_balancer.go:1120 lxc/network_load_balancer.go:1121 msgid "Remove ports from a load balancer" msgstr "" -#: lxc/profile.go:693 lxc/profile.go:694 +#: lxc/profile.go:771 lxc/profile.go:772 msgid "Remove profiles from instances" msgstr "" -#: lxc/remote.go:844 lxc/remote.go:845 +#: lxc/remote.go:852 lxc/remote.go:853 msgid "Remove remotes" msgstr "" -#: lxc/cluster_role.go:105 lxc/cluster_role.go:106 +#: lxc/cluster_role.go:114 lxc/cluster_role.go:115 msgid "Remove roles from a cluster member" msgstr "" -#: lxc/network_acl.go:891 lxc/network_acl.go:892 +#: lxc/network_acl.go:996 lxc/network_acl.go:997 msgid "Remove rules from an ACL" msgstr "" @@ -4812,11 +4813,11 @@ msgstr "" msgid "Remove trusted client" msgstr "" -#: lxc/cluster_group.go:550 lxc/cluster_group.go:551 +#: lxc/cluster_group.go:606 lxc/cluster_group.go:607 msgid "Rename a cluster group" msgstr "" -#: lxc/cluster.go:470 lxc/cluster.go:471 +#: lxc/cluster.go:527 lxc/cluster.go:528 msgid "Rename a cluster member" msgstr "" @@ -4833,23 +4834,23 @@ msgstr "" msgid "Rename identity provider groups" msgstr "" -#: lxc/rename.go:20 lxc/rename.go:21 +#: lxc/rename.go:21 lxc/rename.go:22 msgid "Rename instances and snapshots" msgstr "" -#: lxc/network_acl.go:657 lxc/network_acl.go:658 +#: lxc/network_acl.go:730 lxc/network_acl.go:731 msgid "Rename network ACLs" msgstr "" -#: lxc/network.go:1075 lxc/network.go:1076 +#: lxc/network.go:1184 lxc/network.go:1185 msgid "Rename networks" msgstr "" -#: lxc/profile.go:769 lxc/profile.go:770 +#: lxc/profile.go:859 lxc/profile.go:860 msgid "Rename profiles" msgstr "" -#: lxc/project.go:545 lxc/project.go:546 +#: lxc/project.go:589 lxc/project.go:590 msgid "Rename projects" msgstr "" @@ -4857,52 +4858,52 @@ msgstr "" msgid "Rename remotes" msgstr "" -#: lxc/storage_volume.go:1778 +#: lxc/storage_volume.go:1937 msgid "Rename storage volumes" msgstr "" -#: lxc/storage_volume.go:1777 +#: lxc/storage_volume.go:1936 msgid "Rename storage volumes and storage volume snapshots" msgstr "" -#: lxc/storage_volume.go:1854 lxc/storage_volume.go:1874 +#: lxc/storage_volume.go:2025 lxc/storage_volume.go:2045 #, c-format msgid "Renamed storage volume from \"%s\" to \"%s\"" msgstr "" -#: lxc/info.go:120 +#: lxc/info.go:129 #, c-format msgid "Render: %s (%s)" msgstr "" -#: lxc/cluster.go:803 lxc/cluster.go:804 +#: lxc/cluster.go:892 lxc/cluster.go:893 msgid "Request a join token for adding a cluster member" msgstr "" -#: lxc/config.go:966 +#: lxc/config.go:1019 msgid "Requested UEFI variable does not exist" msgstr "" -#: lxc/delete.go:36 +#: lxc/delete.go:37 msgid "Require user confirmation" msgstr "" -#: lxc/info.go:496 +#: lxc/info.go:505 msgid "Resources:" msgstr "" -#: lxc/action.go:74 +#: lxc/action.go:83 msgid "Restart instances" msgstr "" -#: lxc/action.go:75 +#: lxc/action.go:84 msgid "" "Restart instances\n" "\n" "The opposite of \"lxc pause\" is \"lxc start\"." msgstr "" -#: lxc/cluster.go:1189 lxc/cluster.go:1190 +#: lxc/cluster.go:1328 lxc/cluster.go:1329 msgid "Restore cluster member" msgstr "" @@ -4917,11 +4918,11 @@ msgid "" "If --stateful is passed, then the running state will be restored too." msgstr "" -#: lxc/storage_volume.go:2314 lxc/storage_volume.go:2315 +#: lxc/storage_volume.go:2540 lxc/storage_volume.go:2541 msgid "Restore storage volume snapshots" msgstr "" -#: lxc/cluster.go:1247 +#: lxc/cluster.go:1394 #, c-format msgid "Restoring cluster member: %s" msgstr "" @@ -4934,7 +4935,7 @@ msgstr "" msgid "Retrieve the container's console log" msgstr "" -#: lxc/init.go:347 +#: lxc/init.go:356 #, c-format msgid "Retrieving image: %s" msgstr "" @@ -4943,7 +4944,7 @@ msgstr "" msgid "Revoke certificate add token" msgstr "" -#: lxc/cluster.go:981 +#: lxc/cluster.go:1086 msgid "Revoke cluster member join token" msgstr "" @@ -4955,7 +4956,7 @@ msgstr "" msgid "Run again a specific project" msgstr "" -#: lxc/action.go:121 +#: lxc/action.go:138 msgid "Run against all instances" msgstr "" @@ -4967,19 +4968,19 @@ msgstr "" msgid "SEVERITY" msgstr "" -#: lxc/image.go:1076 +#: lxc/image.go:1137 msgid "SIZE" msgstr "" -#: lxc/list.go:568 +#: lxc/list.go:577 msgid "SNAPSHOTS" msgstr "" -#: lxc/storage.go:672 +#: lxc/storage.go:720 msgid "SOURCE" msgstr "" -#: lxc/info.go:135 lxc/info.go:244 +#: lxc/info.go:144 lxc/info.go:253 msgid "SR-IOV information:" msgstr "" @@ -4993,8 +4994,8 @@ msgstr "" msgid "SSH client disconnected %q" msgstr "" -#: lxc/cluster.go:189 lxc/list.go:569 lxc/network.go:987 -#: lxc/network_peer.go:142 lxc/storage.go:677 +#: lxc/cluster.go:198 lxc/list.go:578 lxc/network.go:1088 +#: lxc/network_peer.go:151 lxc/storage.go:725 msgid "STATE" msgstr "" @@ -5006,19 +5007,19 @@ msgstr "" msgid "STATUS" msgstr "" -#: lxc/project.go:525 +#: lxc/project.go:569 msgid "STORAGE BUCKETS" msgstr "" -#: lxc/list.go:554 +#: lxc/list.go:563 msgid "STORAGE POOL" msgstr "" -#: lxc/project.go:524 +#: lxc/project.go:568 msgid "STORAGE VOLUMES" msgstr "" -#: lxc/network.go:874 +#: lxc/network.go:967 msgid "STP" msgstr "" @@ -5056,11 +5057,11 @@ msgstr "" msgid "Server version: %s\n" msgstr "" -#: lxc/config.go:984 lxc/config.go:985 +#: lxc/config.go:1037 lxc/config.go:1038 msgid "Set UEFI variables for instance" msgstr "" -#: lxc/cluster.go:366 +#: lxc/cluster.go:403 msgid "Set a cluster member's configuration keys" msgstr "" @@ -5068,11 +5069,11 @@ msgstr "" msgid "Set authentication user when using SSH SFTP listener" msgstr "" -#: lxc/config_device.go:545 +#: lxc/config_device.go:616 msgid "Set device configuration keys" msgstr "" -#: lxc/config_device.go:548 +#: lxc/config_device.go:619 msgid "" "Set device configuration keys\n" "\n" @@ -5081,7 +5082,7 @@ msgid "" " lxc config device set [:] " msgstr "" -#: lxc/config_device.go:555 +#: lxc/config_device.go:626 msgid "" "Set device configuration keys\n" "\n" @@ -5090,15 +5091,15 @@ msgid "" " lxc profile device set [:] " msgstr "" -#: lxc/image.go:1549 lxc/image.go:1550 +#: lxc/image.go:1635 lxc/image.go:1636 msgid "Set image properties" msgstr "" -#: lxc/config.go:516 +#: lxc/config.go:537 msgid "Set instance or server configuration keys" msgstr "" -#: lxc/config.go:517 +#: lxc/config.go:538 msgid "" "Set instance or server configuration keys\n" "\n" @@ -5107,11 +5108,11 @@ msgid "" " lxc config set [:][] " msgstr "" -#: lxc/network_acl.go:416 +#: lxc/network_acl.go:460 msgid "Set network ACL configuration keys" msgstr "" -#: lxc/network_acl.go:417 +#: lxc/network_acl.go:461 msgid "" "Set network ACL configuration keys\n" "\n" @@ -5120,11 +5121,11 @@ msgid "" " lxc network set [:] " msgstr "" -#: lxc/network.go:1127 +#: lxc/network.go:1244 msgid "Set network configuration keys" msgstr "" -#: lxc/network.go:1128 +#: lxc/network.go:1245 msgid "" "Set network configuration keys\n" "\n" @@ -5133,11 +5134,11 @@ msgid "" " lxc network set [:] " msgstr "" -#: lxc/network_forward.go:452 +#: lxc/network_forward.go:488 msgid "Set network forward keys" msgstr "" -#: lxc/network_forward.go:453 +#: lxc/network_forward.go:489 msgid "" "Set network forward keys\n" "\n" @@ -5146,11 +5147,11 @@ msgid "" " lxc network set [:] " msgstr "" -#: lxc/network_load_balancer.go:455 +#: lxc/network_load_balancer.go:475 msgid "Set network load balancer keys" msgstr "" -#: lxc/network_load_balancer.go:456 +#: lxc/network_load_balancer.go:476 msgid "" "Set network load balancer keys\n" "\n" @@ -5159,11 +5160,11 @@ msgid "" " lxc network set [:] " msgstr "" -#: lxc/network_peer.go:398 +#: lxc/network_peer.go:444 msgid "Set network peer keys" msgstr "" -#: lxc/network_peer.go:399 +#: lxc/network_peer.go:445 msgid "" "Set network peer keys\n" "\n" @@ -5172,11 +5173,11 @@ msgid "" " lxc network set [:] " msgstr "" -#: lxc/network_zone.go:358 +#: lxc/network_zone.go:395 msgid "Set network zone configuration keys" msgstr "" -#: lxc/network_zone.go:359 +#: lxc/network_zone.go:396 msgid "" "Set network zone configuration keys\n" "\n" @@ -5185,15 +5186,15 @@ msgid "" " lxc network set [:] " msgstr "" -#: lxc/network_zone.go:960 lxc/network_zone.go:961 +#: lxc/network_zone.go:1082 lxc/network_zone.go:1083 msgid "Set network zone record configuration keys" msgstr "" -#: lxc/profile.go:821 +#: lxc/profile.go:919 msgid "Set profile configuration keys" msgstr "" -#: lxc/profile.go:822 +#: lxc/profile.go:920 msgid "" "Set profile configuration keys\n" "\n" @@ -5202,11 +5203,11 @@ msgid "" " lxc profile set [:] " msgstr "" -#: lxc/project.go:602 +#: lxc/project.go:654 msgid "Set project configuration keys" msgstr "" -#: lxc/project.go:603 +#: lxc/project.go:655 msgid "" "Set project configuration keys\n" "\n" @@ -5228,11 +5229,11 @@ msgid "" " lxc storage bucket set [:] " msgstr "" -#: lxc/storage.go:693 +#: lxc/storage.go:741 msgid "Set storage pool configuration keys" msgstr "" -#: lxc/storage.go:694 +#: lxc/storage.go:742 msgid "" "Set storage pool configuration keys\n" "\n" @@ -5241,11 +5242,11 @@ msgid "" " lxc storage set [:] " msgstr "" -#: lxc/storage_volume.go:1892 +#: lxc/storage_volume.go:2063 msgid "Set storage volume configuration keys" msgstr "" -#: lxc/storage_volume.go:1893 +#: lxc/storage_volume.go:2064 msgid "" "Set storage volume configuration keys\n" "\n" @@ -5254,7 +5255,7 @@ msgid "" " lxc storage volume set [:] [/] " msgstr "" -#: lxc/remote.go:940 lxc/remote.go:941 +#: lxc/remote.go:964 lxc/remote.go:965 msgid "Set the URL for the remote" msgstr "" @@ -5270,43 +5271,43 @@ msgstr "" msgid "Set the file's uid on push" msgstr "" -#: lxc/cluster.go:369 +#: lxc/cluster.go:406 msgid "Set the key as a cluster property" msgstr "" -#: lxc/network_acl.go:423 +#: lxc/network_acl.go:467 msgid "Set the key as a network ACL property" msgstr "" -#: lxc/network_forward.go:460 +#: lxc/network_forward.go:496 msgid "Set the key as a network forward property" msgstr "" -#: lxc/network_load_balancer.go:463 +#: lxc/network_load_balancer.go:483 msgid "Set the key as a network load balancer property" msgstr "" -#: lxc/network_peer.go:406 +#: lxc/network_peer.go:452 msgid "Set the key as a network peer property" msgstr "" -#: lxc/network.go:1135 +#: lxc/network.go:1252 msgid "Set the key as a network property" msgstr "" -#: lxc/network_zone.go:366 +#: lxc/network_zone.go:403 msgid "Set the key as a network zone property" msgstr "" -#: lxc/network_zone.go:966 +#: lxc/network_zone.go:1088 msgid "Set the key as a network zone record property" msgstr "" -#: lxc/profile.go:829 +#: lxc/profile.go:927 msgid "Set the key as a profile property" msgstr "" -#: lxc/project.go:610 +#: lxc/project.go:662 msgid "Set the key as a project property" msgstr "" @@ -5314,15 +5315,15 @@ msgstr "" msgid "Set the key as a storage bucket property" msgstr "" -#: lxc/storage.go:701 +#: lxc/storage.go:749 msgid "Set the key as a storage property" msgstr "" -#: lxc/storage_volume.go:1909 +#: lxc/storage_volume.go:2080 msgid "Set the key as a storage volume property" msgstr "" -#: lxc/config.go:530 +#: lxc/config.go:551 msgid "Set the key as an instance property" msgstr "" @@ -5342,15 +5343,15 @@ msgstr "" msgid "Show an identity provider group" msgstr "" -#: lxc/cluster_group.go:598 lxc/cluster_group.go:599 +#: lxc/cluster_group.go:662 lxc/cluster_group.go:663 msgid "Show cluster group configurations" msgstr "" -#: lxc/config_template.go:299 lxc/config_template.go:300 +#: lxc/config_template.go:340 lxc/config_template.go:341 msgid "Show content of instance file templates" msgstr "" -#: lxc/cluster.go:205 lxc/cluster.go:206 +#: lxc/cluster.go:214 lxc/cluster.go:215 msgid "Show details of a cluster member" msgstr "" @@ -5362,7 +5363,7 @@ msgstr "" msgid "Show events from all projects" msgstr "" -#: lxc/config_device.go:667 lxc/config_device.go:668 +#: lxc/config_device.go:758 lxc/config_device.go:759 msgid "Show full device configuration" msgstr "" @@ -5383,23 +5384,23 @@ msgid "" "method. Use the identifier instead if this occurs.\n" msgstr "" -#: lxc/image.go:1440 lxc/image.go:1441 +#: lxc/image.go:1505 lxc/image.go:1506 msgid "Show image properties" msgstr "" -#: lxc/config.go:1106 lxc/config.go:1107 +#: lxc/config.go:1159 lxc/config.go:1160 msgid "Show instance UEFI variables" msgstr "" -#: lxc/config_metadata.go:179 lxc/config_metadata.go:180 +#: lxc/config_metadata.go:188 lxc/config_metadata.go:189 msgid "Show instance metadata files" msgstr "" -#: lxc/config.go:730 lxc/config.go:731 +#: lxc/config.go:763 lxc/config.go:764 msgid "Show instance or server configurations" msgstr "" -#: lxc/info.go:31 lxc/info.go:32 +#: lxc/info.go:32 lxc/info.go:33 msgid "Show instance or server information" msgstr "" @@ -5411,47 +5412,47 @@ msgstr "" msgid "Show local and remote versions" msgstr "" -#: lxc/network_acl.go:165 lxc/network_acl.go:166 +#: lxc/network_acl.go:173 lxc/network_acl.go:174 msgid "Show network ACL configurations" msgstr "" -#: lxc/network_acl.go:218 lxc/network_acl.go:219 +#: lxc/network_acl.go:234 lxc/network_acl.go:235 msgid "Show network ACL log" msgstr "" -#: lxc/network.go:1215 lxc/network.go:1216 +#: lxc/network.go:1340 lxc/network.go:1341 msgid "Show network configurations" msgstr "" -#: lxc/network_forward.go:170 lxc/network_forward.go:171 +#: lxc/network_forward.go:178 lxc/network_forward.go:179 msgid "Show network forward configurations" msgstr "" -#: lxc/network_load_balancer.go:172 lxc/network_load_balancer.go:173 +#: lxc/network_load_balancer.go:180 lxc/network_load_balancer.go:181 msgid "Show network load balancer configurations" msgstr "" -#: lxc/network_peer.go:157 lxc/network_peer.go:158 +#: lxc/network_peer.go:166 lxc/network_peer.go:167 msgid "Show network peer configurations" msgstr "" -#: lxc/network_zone.go:156 lxc/network_zone.go:157 +#: lxc/network_zone.go:164 lxc/network_zone.go:165 msgid "Show network zone configurations" msgstr "" -#: lxc/network_zone.go:763 +#: lxc/network_zone.go:844 msgid "Show network zone record configuration" msgstr "" -#: lxc/network_zone.go:764 +#: lxc/network_zone.go:845 msgid "Show network zone record configurations" msgstr "" -#: lxc/profile.go:897 lxc/profile.go:898 +#: lxc/profile.go:1008 lxc/profile.go:1009 msgid "Show profile configurations" msgstr "" -#: lxc/project.go:712 lxc/project.go:713 +#: lxc/project.go:786 lxc/project.go:787 msgid "Show project options" msgstr "" @@ -5463,15 +5464,15 @@ msgstr "" msgid "Show storage bucket key configurations" msgstr "" -#: lxc/storage.go:789 lxc/storage.go:790 +#: lxc/storage.go:845 lxc/storage.go:846 msgid "Show storage pool configurations and resources" msgstr "" -#: lxc/storage_volume.go:2036 lxc/storage_volume.go:2037 +#: lxc/storage_volume.go:2221 lxc/storage_volume.go:2222 msgid "Show storage volume configurations" msgstr "" -#: lxc/storage_volume.go:1220 lxc/storage_volume.go:1221 +#: lxc/storage_volume.go:1347 lxc/storage_volume.go:1348 msgid "Show storage volume state information" msgstr "" @@ -5489,23 +5490,23 @@ msgstr "" msgid "Show the default remote" msgstr "" -#: lxc/config.go:734 +#: lxc/config.go:767 msgid "Show the expanded configuration" msgstr "" -#: lxc/info.go:42 +#: lxc/info.go:43 msgid "Show the instance's last 100 log lines?" msgstr "" -#: lxc/info.go:43 +#: lxc/info.go:44 msgid "Show the resources available to the server" msgstr "" -#: lxc/storage.go:793 +#: lxc/storage.go:849 msgid "Show the resources available to the storage pool" msgstr "" -#: lxc/storage.go:446 +#: lxc/storage.go:478 msgid "Show the used and free space in bytes" msgstr "" @@ -5513,15 +5514,15 @@ msgstr "" msgid "Show trust configurations" msgstr "" -#: lxc/cluster.go:254 lxc/cluster.go:255 +#: lxc/cluster.go:271 lxc/cluster.go:272 msgid "Show useful information about a cluster member" msgstr "" -#: lxc/image.go:900 lxc/image.go:901 +#: lxc/image.go:945 lxc/image.go:946 msgid "Show useful information about images" msgstr "" -#: lxc/storage.go:442 lxc/storage.go:443 +#: lxc/storage.go:474 lxc/storage.go:475 msgid "Show useful information about storage pools" msgstr "" @@ -5529,82 +5530,82 @@ msgstr "" msgid "Show warning" msgstr "" -#: lxc/image.go:960 +#: lxc/image.go:1013 #, c-format msgid "Size: %.2fMiB" msgstr "" -#: lxc/info.go:275 lxc/info.go:293 +#: lxc/info.go:284 lxc/info.go:302 #, c-format msgid "Size: %s" msgstr "" -#: lxc/storage_volume.go:2191 lxc/storage_volume.go:2192 +#: lxc/storage_volume.go:2404 lxc/storage_volume.go:2405 msgid "Snapshot storage volumes" msgstr "" -#: lxc/storage_volume.go:1982 +#: lxc/storage_volume.go:2167 msgid "Snapshots are read-only and can't have their configuration changed" msgstr "" -#: lxc/info.go:598 lxc/storage_volume.go:1346 +#: lxc/info.go:607 lxc/storage_volume.go:1485 msgid "Snapshots:" msgstr "" -#: lxc/info.go:360 +#: lxc/info.go:369 #, c-format msgid "Socket %d:" msgstr "" -#: lxc/action.go:401 +#: lxc/action.go:418 #, c-format msgid "Some instances failed to %s" msgstr "" -#: lxc/image.go:1003 +#: lxc/image.go:1056 msgid "Source:" msgstr "" -#: lxc/action.go:31 lxc/action.go:32 +#: lxc/action.go:32 lxc/action.go:33 msgid "Start instances" msgstr "" -#: lxc/launch.go:87 +#: lxc/launch.go:95 #, c-format msgid "Starting %s" msgstr "" -#: lxc/info.go:555 +#: lxc/info.go:564 msgid "State" msgstr "" -#: lxc/network.go:836 +#: lxc/network.go:929 #, c-format msgid "State: %s" msgstr "" -#: lxc/info.go:632 +#: lxc/info.go:641 msgid "Stateful" msgstr "" -#: lxc/info.go:465 +#: lxc/info.go:474 #, c-format msgid "Status: %s" msgstr "" -#: lxc/action.go:97 lxc/action.go:98 +#: lxc/action.go:110 lxc/action.go:111 msgid "Stop instances" msgstr "" -#: lxc/publish.go:39 +#: lxc/publish.go:40 msgid "Stop the instance if currently running" msgstr "" -#: lxc/publish.go:142 +#: lxc/publish.go:155 msgid "Stopping instance failed!" msgstr "" -#: lxc/delete.go:139 +#: lxc/delete.go:144 #, c-format msgid "Stopping the instance failed: %s" msgstr "" @@ -5629,75 +5630,75 @@ msgstr "" msgid "Storage bucket key %s removed" msgstr "" -#: lxc/storage.go:181 +#: lxc/storage.go:185 #, c-format msgid "Storage pool %s created" msgstr "" -#: lxc/storage.go:233 +#: lxc/storage.go:245 #, c-format msgid "Storage pool %s deleted" msgstr "" -#: lxc/storage.go:179 +#: lxc/storage.go:183 #, c-format msgid "Storage pool %s pending on member %s" msgstr "" -#: lxc/copy.go:60 lxc/import.go:36 lxc/init.go:62 lxc/move.go:65 +#: lxc/copy.go:61 lxc/import.go:36 lxc/init.go:63 lxc/move.go:66 msgid "Storage pool name" msgstr "" -#: lxc/storage_volume.go:641 +#: lxc/storage_volume.go:696 #, c-format msgid "Storage volume %s created" msgstr "" -#: lxc/storage_volume.go:717 +#: lxc/storage_volume.go:784 #, c-format msgid "Storage volume %s deleted" msgstr "" -#: lxc/storage_volume.go:462 +#: lxc/storage_volume.go:509 msgid "Storage volume copied successfully!" msgstr "" -#: lxc/storage_volume.go:466 +#: lxc/storage_volume.go:513 msgid "Storage volume moved successfully!" msgstr "" -#: lxc/action.go:124 +#: lxc/action.go:141 msgid "Store the instance state" msgstr "" -#: lxc/cluster.go:1140 +#: lxc/cluster.go:1271 #, c-format msgid "Successfully updated cluster certificates for remote %s" msgstr "" -#: lxc/info.go:204 +#: lxc/info.go:213 #, c-format msgid "Supported modes: %s" msgstr "" -#: lxc/info.go:208 +#: lxc/info.go:217 #, c-format msgid "Supported ports: %s" msgstr "" -#: lxc/info.go:537 +#: lxc/info.go:546 msgid "Swap (current)" msgstr "" -#: lxc/info.go:541 +#: lxc/info.go:550 msgid "Swap (peak)" msgstr "" -#: lxc/project.go:765 lxc/project.go:766 +#: lxc/project.go:847 lxc/project.go:848 msgid "Switch the current project" msgstr "" -#: lxc/remote.go:900 lxc/remote.go:901 +#: lxc/remote.go:916 lxc/remote.go:917 msgid "Switch the default remote" msgstr "" @@ -5705,18 +5706,18 @@ msgstr "" msgid "TARGET" msgstr "" -#: lxc/cluster.go:965 lxc/config_trust.go:515 +#: lxc/cluster.go:1070 lxc/config_trust.go:515 msgid "TOKEN" msgstr "" -#: lxc/auth.go:814 lxc/config_trust.go:408 lxc/image.go:1078 -#: lxc/image_alias.go:236 lxc/list.go:570 lxc/network.go:981 -#: lxc/network.go:1055 lxc/network_allocations.go:26 lxc/operation.go:171 -#: lxc/storage_volume.go:1583 lxc/warning.go:215 +#: lxc/auth.go:814 lxc/config_trust.go:408 lxc/image.go:1139 +#: lxc/image_alias.go:236 lxc/list.go:579 lxc/network.go:1082 +#: lxc/network.go:1164 lxc/network_allocations.go:26 lxc/operation.go:171 +#: lxc/storage_volume.go:1730 lxc/warning.go:215 msgid "TYPE" msgstr "" -#: lxc/info.go:630 lxc/info.go:681 lxc/storage_volume.go:1418 +#: lxc/info.go:639 lxc/info.go:690 lxc/storage_volume.go:1557 msgid "Taken at" msgstr "" @@ -5728,15 +5729,15 @@ msgstr "" msgid "Target path must be a directory" msgstr "" -#: lxc/move.go:168 +#: lxc/move.go:181 msgid "The --instance-only flag can't be used with --target" msgstr "" -#: lxc/move.go:206 lxc/move.go:227 +#: lxc/move.go:219 lxc/move.go:240 msgid "The --mode flag can't be used with --storage or --target-project" msgstr "" -#: lxc/move.go:180 +#: lxc/move.go:193 msgid "The --mode flag can't be used with --target" msgstr "" @@ -5744,41 +5745,41 @@ msgstr "" msgid "The --show-log flag is only supported for by 'console' output type" msgstr "" -#: lxc/move.go:172 +#: lxc/move.go:185 msgid "The --storage flag can't be used with --target" msgstr "" -#: lxc/move.go:176 +#: lxc/move.go:189 msgid "The --target-project flag can't be used with --target" msgstr "" -#: lxc/move.go:192 +#: lxc/move.go:205 msgid "The destination LXD server is not clustered" msgstr "" -#: lxc/config_device.go:151 lxc/config_device.go:168 lxc/config_device.go:392 +#: lxc/config_device.go:164 lxc/config_device.go:181 lxc/config_device.go:445 msgid "The device already exists" msgstr "" -#: lxc/network_acl.go:882 lxc/network_acl.go:1004 +#: lxc/network_acl.go:987 lxc/network_acl.go:1125 msgid "The direction argument must be one of: ingress, egress" msgstr "" -#: lxc/delete.go:123 +#: lxc/delete.go:128 msgid "The instance is currently running, stop it first or pass --force" msgstr "" -#: lxc/publish.go:111 +#: lxc/publish.go:124 msgid "" "The instance is currently running. Use --force to have it stopped and " "restarted" msgstr "" -#: lxc/init.go:425 +#: lxc/init.go:434 msgid "The instance you are starting doesn't have any network attached to it." msgstr "" -#: lxc/cluster.go:348 +#: lxc/cluster.go:385 #, c-format msgid "The key %q does not exist on cluster member %q" msgstr "" @@ -5793,66 +5794,66 @@ msgstr "" msgid "The local image '%q' couldn't be found, trying '%q:' instead." msgstr "" -#: lxc/config_device.go:397 +#: lxc/config_device.go:450 msgid "The profile device doesn't exist" msgstr "" -#: lxc/cluster.go:339 +#: lxc/cluster.go:376 #, c-format msgid "The property %q does not exist on the cluster member %q: %v" msgstr "" -#: lxc/config.go:458 +#: lxc/config.go:479 #, c-format msgid "The property %q does not exist on the instance %q: %v" msgstr "" -#: lxc/config.go:434 +#: lxc/config.go:455 #, c-format msgid "The property %q does not exist on the instance snapshot %s/%s: %v" msgstr "" -#: lxc/network_load_balancer.go:429 +#: lxc/network_load_balancer.go:449 #, c-format msgid "The property %q does not exist on the load balancer %q: %v" msgstr "" -#: lxc/network.go:764 +#: lxc/network.go:849 #, c-format msgid "The property %q does not exist on the network %q: %v" msgstr "" -#: lxc/network_acl.go:303 +#: lxc/network_acl.go:339 #, c-format msgid "The property %q does not exist on the network ACL %q: %v" msgstr "" -#: lxc/network_forward.go:426 +#: lxc/network_forward.go:462 #, c-format msgid "The property %q does not exist on the network forward %q: %v" msgstr "" -#: lxc/network_peer.go:372 +#: lxc/network_peer.go:418 #, c-format msgid "The property %q does not exist on the network peer %q: %v" msgstr "" -#: lxc/network_zone.go:247 +#: lxc/network_zone.go:276 #, c-format msgid "The property %q does not exist on the network zone %q: %v" msgstr "" -#: lxc/network_zone.go:850 +#: lxc/network_zone.go:960 #, c-format msgid "The property %q does not exist on the network zone record %q: %v" msgstr "" -#: lxc/profile.go:610 +#: lxc/profile.go:680 #, c-format msgid "The property %q does not exist on the profile %q: %v" msgstr "" -#: lxc/project.go:409 +#: lxc/project.go:446 #, c-format msgid "The property %q does not exist on the project %q: %v" msgstr "" @@ -5862,56 +5863,56 @@ msgstr "" msgid "The property %q does not exist on the storage bucket %q: %v" msgstr "" -#: lxc/storage.go:417 +#: lxc/storage.go:449 #, c-format msgid "The property %q does not exist on the storage pool %q: %v" msgstr "" -#: lxc/storage_volume.go:1196 +#: lxc/storage_volume.go:1323 #, c-format msgid "The property %q does not exist on the storage pool volume %q: %v" msgstr "" -#: lxc/storage_volume.go:1173 +#: lxc/storage_volume.go:1300 #, c-format msgid "" "The property %q does not exist on the storage pool volume snapshot %s/%s: %v" msgstr "" -#: lxc/info.go:345 +#: lxc/info.go:354 msgid "The server doesn't implement the newer v2 resources API" msgstr "" -#: lxc/move.go:296 +#: lxc/move.go:309 msgid "The source LXD server is not clustered" msgstr "" -#: lxc/network.go:480 lxc/network.go:565 lxc/storage_volume.go:792 -#: lxc/storage_volume.go:873 +#: lxc/network.go:533 lxc/network.go:630 lxc/storage_volume.go:875 +#: lxc/storage_volume.go:972 msgid "The specified device doesn't exist" msgstr "" -#: lxc/network.go:484 lxc/network.go:569 +#: lxc/network.go:537 lxc/network.go:634 msgid "The specified device doesn't match the network" msgstr "" -#: lxc/publish.go:84 +#: lxc/publish.go:97 msgid "There is no \"image name\". Did you want an alias?" msgstr "" -#: lxc/config.go:633 +#: lxc/config.go:666 msgid "There is no config key to set on an instance snapshot." msgstr "" -#: lxc/cluster.go:658 +#: lxc/cluster.go:739 msgid "This LXD server is already clustered" msgstr "" -#: lxc/cluster.go:648 +#: lxc/cluster.go:729 msgid "This LXD server is not available on the network" msgstr "" -#: lxc/main.go:294 +#: lxc/main.go:299 msgid "" "This client hasn't been configured to use a remote LXD server yet.\n" "As your platform can't run native Linux instances, you must connect to a " @@ -5923,23 +5924,23 @@ msgid "" "https://multipass.run" msgstr "" -#: lxc/info.go:318 +#: lxc/info.go:327 msgid "Threads:" msgstr "" -#: lxc/action.go:136 +#: lxc/action.go:153 msgid "Time to wait for the instance to shutdown cleanly" msgstr "" -#: lxc/image.go:964 +#: lxc/image.go:1017 msgid "Timestamps:" msgstr "" -#: lxc/init.go:427 +#: lxc/init.go:436 msgid "To attach a network to an instance, use: lxc network attach" msgstr "" -#: lxc/init.go:426 +#: lxc/init.go:435 msgid "To create a new network, use: lxc network create" msgstr "" @@ -5947,63 +5948,63 @@ msgstr "" msgid "To detach from the console, press: +a q" msgstr "" -#: lxc/main.go:406 +#: lxc/main.go:411 msgid "" "To start your first container, try: lxc launch ubuntu:24.04\n" "Or for a virtual machine: lxc launch ubuntu:24.04 --vm" msgstr "" -#: lxc/config.go:297 lxc/config.go:478 lxc/config.go:682 lxc/config.go:774 -#: lxc/copy.go:131 lxc/info.go:337 lxc/network.go:821 lxc/storage.go:475 +#: lxc/config.go:306 lxc/config.go:499 lxc/config.go:715 lxc/config.go:815 +#: lxc/copy.go:144 lxc/info.go:346 lxc/network.go:914 lxc/storage.go:515 msgid "To use --target, the destination remote must be a cluster" msgstr "" -#: lxc/storage_volume.go:1331 +#: lxc/storage_volume.go:1470 #, c-format msgid "Total: %s" msgstr "" -#: lxc/info.go:371 lxc/info.go:382 lxc/info.go:387 lxc/info.go:393 +#: lxc/info.go:380 lxc/info.go:391 lxc/info.go:396 lxc/info.go:402 #, c-format msgid "Total: %v" msgstr "" -#: lxc/info.go:216 +#: lxc/info.go:225 #, c-format msgid "Transceiver type: %s" msgstr "" -#: lxc/storage_volume.go:1700 +#: lxc/storage_volume.go:1847 msgid "Transfer mode, one of pull (default), push or relay" msgstr "" -#: lxc/image.go:169 +#: lxc/image.go:170 msgid "Transfer mode. One of pull (default), push or relay" msgstr "" -#: lxc/storage_volume.go:358 +#: lxc/storage_volume.go:393 msgid "Transfer mode. One of pull (default), push or relay." msgstr "" -#: lxc/copy.go:57 +#: lxc/copy.go:58 msgid "Transfer mode. One of pull, push or relay" msgstr "" -#: lxc/move.go:63 +#: lxc/move.go:64 msgid "Transfer mode. One of pull, push or relay." msgstr "" -#: lxc/image.go:780 +#: lxc/image.go:825 #, c-format msgid "Transferring image: %s" msgstr "" -#: lxc/copy.go:369 lxc/move.go:314 +#: lxc/copy.go:382 lxc/move.go:327 #, c-format msgid "Transferring instance: %s" msgstr "" -#: lxc/network.go:861 +#: lxc/network.go:954 msgid "Transmit policy" msgstr "" @@ -6012,12 +6013,12 @@ msgstr "" msgid "Trust token for %s: " msgstr "" -#: lxc/action.go:287 lxc/launch.go:119 +#: lxc/action.go:304 lxc/launch.go:127 #, c-format msgid "Try `lxc info --show-log %s` for more info" msgstr "" -#: lxc/info.go:554 +#: lxc/info.go:563 msgid "Type" msgstr "" @@ -6031,36 +6032,36 @@ msgid "" "SPICE graphical output" msgstr "" -#: lxc/image.go:962 lxc/info.go:272 lxc/info.go:474 lxc/network.go:837 -#: lxc/storage_volume.go:1316 +#: lxc/image.go:1015 lxc/info.go:281 lxc/info.go:483 lxc/network.go:930 +#: lxc/storage_volume.go:1455 #, c-format msgid "Type: %s" msgstr "" -#: lxc/info.go:472 +#: lxc/info.go:481 #, c-format msgid "Type: %s (ephemeral)" msgstr "" -#: lxc/project.go:863 +#: lxc/project.go:961 msgid "UNLIMITED" msgstr "" -#: lxc/image.go:1077 +#: lxc/image.go:1138 msgid "UPLOAD DATE" msgstr "" -#: lxc/cluster.go:184 lxc/remote.go:749 +#: lxc/cluster.go:193 lxc/remote.go:749 msgid "URL" msgstr "" -#: lxc/project.go:887 lxc/storage_volume.go:1588 +#: lxc/project.go:985 lxc/storage_volume.go:1735 msgid "USAGE" msgstr "" -#: lxc/network.go:986 lxc/network_acl.go:150 lxc/network_allocations.go:24 -#: lxc/network_zone.go:141 lxc/profile.go:679 lxc/project.go:529 -#: lxc/storage.go:676 lxc/storage_volume.go:1587 +#: lxc/network.go:1087 lxc/network_acl.go:158 lxc/network_allocations.go:24 +#: lxc/network_zone.go:149 lxc/profile.go:757 lxc/project.go:573 +#: lxc/storage.go:724 lxc/storage_volume.go:1734 msgid "USED BY" msgstr "" @@ -6068,7 +6069,7 @@ msgstr "" msgid "UUID" msgstr "" -#: lxc/info.go:131 +#: lxc/info.go:140 #, c-format msgid "UUID: %v" msgstr "" @@ -6092,7 +6093,7 @@ msgstr "" msgid "Unknown channel type for client %q: %s" msgstr "" -#: lxc/image.go:1092 lxc/list.go:622 lxc/storage_volume.go:1625 +#: lxc/image.go:1153 lxc/list.go:631 lxc/storage_volume.go:1772 #: lxc/warning.go:241 #, c-format msgid "Unknown column shorthand char '%c' in '%s'" @@ -6108,7 +6109,7 @@ msgstr "" msgid "Unknown file type '%s'" msgstr "" -#: lxc/network_acl.go:819 lxc/network_acl.go:938 +#: lxc/network_acl.go:924 lxc/network_acl.go:1059 #, c-format msgid "Unknown key: %s" msgstr "" @@ -6118,75 +6119,75 @@ msgstr "" msgid "Unknown output type %q" msgstr "" -#: lxc/config.go:1075 lxc/config.go:1076 +#: lxc/config.go:1128 lxc/config.go:1129 msgid "Unset UEFI variables for instance" msgstr "" -#: lxc/cluster.go:438 +#: lxc/cluster.go:483 msgid "Unset a cluster member's configuration keys" msgstr "" -#: lxc/move.go:61 +#: lxc/move.go:62 msgid "Unset all profiles on the target instance" msgstr "" -#: lxc/config_device.go:740 lxc/config_device.go:741 +#: lxc/config_device.go:843 lxc/config_device.go:844 msgid "Unset device configuration keys" msgstr "" -#: lxc/image.go:1604 lxc/image.go:1605 +#: lxc/image.go:1698 lxc/image.go:1699 msgid "Unset image properties" msgstr "" -#: lxc/config.go:854 lxc/config.go:855 +#: lxc/config.go:895 lxc/config.go:896 msgid "Unset instance or server configuration keys" msgstr "" -#: lxc/network_acl.go:496 lxc/network_acl.go:497 +#: lxc/network_acl.go:548 lxc/network_acl.go:549 msgid "Unset network ACL configuration keys" msgstr "" -#: lxc/network.go:1279 lxc/network.go:1280 +#: lxc/network.go:1412 lxc/network.go:1413 msgid "Unset network configuration keys" msgstr "" -#: lxc/network_forward.go:550 +#: lxc/network_forward.go:598 msgid "Unset network forward configuration keys" msgstr "" -#: lxc/network_forward.go:551 +#: lxc/network_forward.go:599 msgid "Unset network forward keys" msgstr "" -#: lxc/network_load_balancer.go:553 +#: lxc/network_load_balancer.go:585 msgid "Unset network load balancer configuration keys" msgstr "" -#: lxc/network_load_balancer.go:554 +#: lxc/network_load_balancer.go:586 msgid "Unset network load balancer keys" msgstr "" -#: lxc/network_peer.go:487 +#: lxc/network_peer.go:546 msgid "Unset network peer configuration keys" msgstr "" -#: lxc/network_peer.go:488 +#: lxc/network_peer.go:547 msgid "Unset network peer keys" msgstr "" -#: lxc/network_zone.go:438 lxc/network_zone.go:439 +#: lxc/network_zone.go:483 lxc/network_zone.go:484 msgid "Unset network zone configuration keys" msgstr "" -#: lxc/network_zone.go:1036 lxc/network_zone.go:1037 +#: lxc/network_zone.go:1171 lxc/network_zone.go:1172 msgid "Unset network zone record configuration keys" msgstr "" -#: lxc/profile.go:953 lxc/profile.go:954 +#: lxc/profile.go:1072 lxc/profile.go:1073 msgid "Unset profile configuration keys" msgstr "" -#: lxc/project.go:681 lxc/project.go:682 +#: lxc/project.go:742 lxc/project.go:743 msgid "Unset project configuration keys" msgstr "" @@ -6194,51 +6195,51 @@ msgstr "" msgid "Unset storage bucket configuration keys" msgstr "" -#: lxc/storage.go:875 lxc/storage.go:876 +#: lxc/storage.go:939 lxc/storage.go:940 msgid "Unset storage pool configuration keys" msgstr "" -#: lxc/storage_volume.go:2145 lxc/storage_volume.go:2146 +#: lxc/storage_volume.go:2342 lxc/storage_volume.go:2343 msgid "Unset storage volume configuration keys" msgstr "" -#: lxc/cluster.go:441 +#: lxc/cluster.go:486 msgid "Unset the key as a cluster property" msgstr "" -#: lxc/network_acl.go:500 +#: lxc/network_acl.go:552 msgid "Unset the key as a network ACL property" msgstr "" -#: lxc/network_forward.go:554 +#: lxc/network_forward.go:602 msgid "Unset the key as a network forward property" msgstr "" -#: lxc/network_load_balancer.go:557 +#: lxc/network_load_balancer.go:589 msgid "Unset the key as a network load balancer property" msgstr "" -#: lxc/network_peer.go:491 +#: lxc/network_peer.go:550 msgid "Unset the key as a network peer property" msgstr "" -#: lxc/network.go:1284 +#: lxc/network.go:1417 msgid "Unset the key as a network property" msgstr "" -#: lxc/network_zone.go:442 +#: lxc/network_zone.go:487 msgid "Unset the key as a network zone property" msgstr "" -#: lxc/network_zone.go:1040 +#: lxc/network_zone.go:1175 msgid "Unset the key as a network zone record property" msgstr "" -#: lxc/profile.go:958 +#: lxc/profile.go:1077 msgid "Unset the key as a profile property" msgstr "" -#: lxc/project.go:686 +#: lxc/project.go:747 msgid "Unset the key as a project property" msgstr "" @@ -6246,60 +6247,60 @@ msgstr "" msgid "Unset the key as a storage bucket property" msgstr "" -#: lxc/storage.go:880 +#: lxc/storage.go:944 msgid "Unset the key as a storage property" msgstr "" -#: lxc/storage_volume.go:2159 +#: lxc/storage_volume.go:2356 msgid "Unset the key as a storage volume property" msgstr "" -#: lxc/config.go:859 +#: lxc/config.go:900 msgid "Unset the key as an instance property" msgstr "" -#: lxc/storage_volume.go:228 +#: lxc/storage_volume.go:247 msgid "Unsupported content type for attaching to instances" msgstr "" -#: lxc/info.go:703 +#: lxc/info.go:712 #, c-format msgid "Unsupported instance type: %s" msgstr "" -#: lxc/network.go:862 +#: lxc/network.go:955 msgid "Up delay" msgstr "" -#: lxc/cluster.go:1060 +#: lxc/cluster.go:1174 msgid "Update cluster certificate" msgstr "" -#: lxc/cluster.go:1062 +#: lxc/cluster.go:1176 msgid "" "Update cluster certificate with PEM certificate and key read from input " "files." msgstr "" -#: lxc/profile.go:253 +#: lxc/profile.go:274 msgid "Update the target profile from the source if it already exists" msgstr "" -#: lxc/image.go:971 +#: lxc/image.go:1024 #, c-format msgid "Uploaded: %s" msgstr "" -#: lxc/network.go:878 +#: lxc/network.go:971 msgid "Upper devices" msgstr "" -#: lxc/storage_volume.go:1329 +#: lxc/storage_volume.go:1468 #, c-format msgid "Usage: %s" msgstr "" -#: lxc/export.go:42 lxc/storage_volume.go:2387 +#: lxc/export.go:42 lxc/storage_volume.go:2629 msgid "" "Use storage driver optimized format (can only be restored on a similar pool)" msgstr "" @@ -6308,7 +6309,7 @@ msgstr "" msgid "Use with help or --help to view sub-commands" msgstr "" -#: lxc/info.go:370 lxc/info.go:381 lxc/info.go:386 lxc/info.go:392 +#: lxc/info.go:379 lxc/info.go:390 lxc/info.go:395 lxc/info.go:401 #, c-format msgid "Used: %v" msgstr "" @@ -6317,7 +6318,7 @@ msgstr "" msgid "User ID to run the command as (default 0)" msgstr "" -#: lxc/cluster.go:552 lxc/delete.go:48 +#: lxc/cluster.go:625 lxc/delete.go:53 msgid "User aborted delete operation" msgstr "" @@ -6326,34 +6327,34 @@ msgid "" "User signaled us three times, exiting. The remote operation will keep running" msgstr "" -#: lxc/info.go:139 lxc/info.go:248 +#: lxc/info.go:148 lxc/info.go:257 #, c-format msgid "VFs: %d" msgstr "" -#: lxc/network.go:886 +#: lxc/network.go:979 msgid "VLAN ID" msgstr "" -#: lxc/network.go:877 +#: lxc/network.go:970 msgid "VLAN filtering" msgstr "" -#: lxc/network.go:884 +#: lxc/network.go:977 msgid "VLAN:" msgstr "" -#: lxc/info.go:300 +#: lxc/info.go:309 #, c-format msgid "Vendor: %v" msgstr "" -#: lxc/info.go:92 lxc/info.go:178 +#: lxc/info.go:101 lxc/info.go:187 #, c-format msgid "Vendor: %v (%v)" msgstr "" -#: lxc/info.go:237 +#: lxc/info.go:246 #, c-format msgid "Verb: %s (%s)" msgstr "" @@ -6366,11 +6367,11 @@ msgstr "" msgid "View the current identity" msgstr "" -#: lxc/storage_volume.go:1420 +#: lxc/storage_volume.go:1559 msgid "Volume Only" msgstr "" -#: lxc/info.go:278 +#: lxc/info.go:287 #, c-format msgid "WWN: %s" msgstr "" @@ -6399,25 +6400,25 @@ msgid "" "re-initialize the instance if a different image or --empty is not specified." msgstr "" -#: lxc/network.go:959 lxc/operation.go:156 lxc/project.go:481 -#: lxc/project.go:486 lxc/project.go:491 lxc/project.go:496 lxc/project.go:501 -#: lxc/project.go:506 lxc/remote.go:710 lxc/remote.go:715 lxc/remote.go:720 +#: lxc/network.go:1060 lxc/operation.go:156 lxc/project.go:525 +#: lxc/project.go:530 lxc/project.go:535 lxc/project.go:540 lxc/project.go:545 +#: lxc/project.go:550 lxc/remote.go:710 lxc/remote.go:715 lxc/remote.go:720 msgid "YES" msgstr "" -#: lxc/exec.go:93 +#: lxc/exec.go:101 msgid "You can't pass -t and -T at the same time" msgstr "" -#: lxc/exec.go:97 +#: lxc/exec.go:105 msgid "You can't pass -t or -T at the same time as --mode" msgstr "" -#: lxc/copy.go:102 +#: lxc/copy.go:115 msgid "You must specify a destination instance name" msgstr "" -#: lxc/copy.go:85 lxc/move.go:280 lxc/move.go:356 +#: lxc/copy.go:98 lxc/move.go:293 lxc/move.go:369 msgid "You must specify a source instance name" msgstr "" @@ -6425,20 +6426,20 @@ msgstr "" msgid "You need to specify an image name or use --empty" msgstr "" -#: lxc/storage_volume.go:814 +#: lxc/storage_volume.go:897 msgid "[] []" msgstr "" -#: lxc/storage_volume.go:262 +#: lxc/storage_volume.go:281 msgid "[] [] []" msgstr "" #: lxc/auth.go:329 lxc/auth.go:762 lxc/auth.go:893 lxc/auth.go:1689 -#: lxc/cluster.go:119 lxc/cluster.go:878 lxc/cluster_group.go:401 +#: lxc/cluster.go:120 lxc/cluster.go:975 lxc/cluster_group.go:437 #: lxc/config_trust.go:347 lxc/config_trust.go:430 lxc/monitor.go:31 -#: lxc/network.go:909 lxc/network_acl.go:92 lxc/network_zone.go:83 -#: lxc/operation.go:103 lxc/profile.go:630 lxc/project.go:430 -#: lxc/storage.go:612 lxc/version.go:20 lxc/warning.go:68 +#: lxc/network.go:1002 lxc/network_acl.go:92 lxc/network_zone.go:83 +#: lxc/operation.go:103 lxc/profile.go:700 lxc/project.go:467 +#: lxc/storage.go:652 lxc/version.go:20 lxc/warning.go:68 msgid "[:]" msgstr "" @@ -6446,11 +6447,11 @@ msgstr "" msgid "[:] []" msgstr "" -#: lxc/cluster.go:1058 +#: lxc/cluster.go:1172 msgid "[:] " msgstr "" -#: lxc/cluster.go:602 lxc/config_trust.go:578 +#: lxc/cluster.go:675 lxc/config_trust.go:578 msgid "[:] " msgstr "" @@ -6458,7 +6459,7 @@ msgstr "" msgid "[:] []" msgstr "" -#: lxc/image.go:1032 lxc/list.go:45 +#: lxc/image.go:1085 lxc/list.go:46 msgid "[:] [...]" msgstr "" @@ -6470,28 +6471,28 @@ msgstr "" msgid "[:] [project=] [entity_type=]" msgstr "" -#: lxc/network_acl.go:164 lxc/network_acl.go:217 lxc/network_acl.go:525 -#: lxc/network_acl.go:704 +#: lxc/network_acl.go:172 lxc/network_acl.go:233 lxc/network_acl.go:590 +#: lxc/network_acl.go:785 msgid "[:]" msgstr "" -#: lxc/network_acl.go:769 lxc/network_acl.go:890 +#: lxc/network_acl.go:858 lxc/network_acl.go:995 msgid "[:] =..." msgstr "" -#: lxc/network_acl.go:265 lxc/network_acl.go:495 +#: lxc/network_acl.go:289 lxc/network_acl.go:547 msgid "[:] " msgstr "" -#: lxc/network_acl.go:415 +#: lxc/network_acl.go:459 msgid "[:] =..." msgstr "" -#: lxc/network_acl.go:655 +#: lxc/network_acl.go:728 msgid "[:] " msgstr "" -#: lxc/network_acl.go:326 +#: lxc/network_acl.go:362 msgid "[:] [key=value...]" msgstr "" @@ -6499,19 +6500,19 @@ msgstr "" msgid "[:]" msgstr "" -#: lxc/network_zone.go:155 lxc/network_zone.go:468 lxc/network_zone.go:586 +#: lxc/network_zone.go:163 lxc/network_zone.go:525 lxc/network_zone.go:651 msgid "[:]" msgstr "" -#: lxc/network_zone.go:210 lxc/network_zone.go:437 +#: lxc/network_zone.go:226 lxc/network_zone.go:482 msgid "[:] " msgstr "" -#: lxc/network_zone.go:357 +#: lxc/network_zone.go:394 msgid "[:] =..." msgstr "" -#: lxc/network_zone.go:270 +#: lxc/network_zone.go:299 msgid "[:] [key=value...]" msgstr "" @@ -6535,17 +6536,13 @@ msgstr "" msgid "[:]/ " msgstr "" -#: lxc/cluster.go:687 -msgid "[:]" -msgstr "" - #: lxc/config_trust.go:234 lxc/config_trust.go:531 lxc/config_trust.go:649 msgid "[:]" msgstr "" #: lxc/auth.go:96 lxc/auth.go:149 lxc/auth.go:199 lxc/auth.go:439 -#: lxc/auth.go:954 lxc/auth.go:1470 lxc/cluster_group.go:156 -#: lxc/cluster_group.go:233 lxc/cluster_group.go:286 lxc/cluster_group.go:597 +#: lxc/auth.go:954 lxc/auth.go:1470 lxc/cluster_group.go:168 +#: lxc/cluster_group.go:253 lxc/cluster_group.go:314 lxc/cluster_group.go:661 msgid "[:]" msgstr "" @@ -6555,7 +6552,7 @@ msgid "" "[=...]" msgstr "" -#: lxc/cluster_group.go:548 +#: lxc/cluster_group.go:604 msgid "[:] " msgstr "" @@ -6575,19 +6572,19 @@ msgstr "" msgid "[:] " msgstr "" -#: lxc/image.go:377 lxc/image.go:899 lxc/image.go:1439 +#: lxc/image.go:394 lxc/image.go:944 lxc/image.go:1504 msgid "[:]" msgstr "" -#: lxc/image.go:1497 lxc/image.go:1603 +#: lxc/image.go:1570 lxc/image.go:1697 msgid "[:] " msgstr "" -#: lxc/image.go:1548 +#: lxc/image.go:1634 msgid "[:] " msgstr "" -#: lxc/image.go:155 +#: lxc/image.go:156 msgid "[:] :" msgstr "" @@ -6595,57 +6592,57 @@ msgstr "" msgid "[:] [:]" msgstr "" -#: lxc/init.go:41 lxc/launch.go:22 +#: lxc/init.go:42 lxc/launch.go:22 msgid "[:] [:][]" msgstr "" -#: lxc/image.go:498 +#: lxc/image.go:523 msgid "[:] []" msgstr "" -#: lxc/image.go:321 lxc/image.go:1352 +#: lxc/image.go:334 lxc/image.go:1413 msgid "[:] [[:]...]" msgstr "" -#: lxc/config.go:1105 lxc/config.go:1159 lxc/config_device.go:288 -#: lxc/config_device.go:662 lxc/config_metadata.go:53 -#: lxc/config_metadata.go:178 lxc/config_template.go:238 lxc/console.go:35 +#: lxc/config.go:1158 lxc/config.go:1212 lxc/config_device.go:321 +#: lxc/config_device.go:753 lxc/config_metadata.go:54 +#: lxc/config_metadata.go:187 lxc/config_template.go:271 lxc/console.go:35 msgid "[:]" msgstr "" -#: lxc/config_device.go:202 lxc/config_device.go:735 +#: lxc/config_device.go:215 lxc/config_device.go:838 msgid "[:] " msgstr "" -#: lxc/config_device.go:547 +#: lxc/config_device.go:618 msgid "[:] =..." msgstr "" -#: lxc/config_device.go:81 +#: lxc/config_device.go:82 msgid "[:] [key=value...]" msgstr "" -#: lxc/config_device.go:354 +#: lxc/config_device.go:399 msgid "[:] [key=value...]" msgstr "" -#: lxc/config.go:928 lxc/config.go:1074 +#: lxc/config.go:981 lxc/config.go:1127 msgid "[:] " msgstr "" -#: lxc/config.go:983 +#: lxc/config.go:1036 msgid "[:] =..." msgstr "" -#: lxc/config_device.go:443 +#: lxc/config_device.go:496 msgid "[:] ..." msgstr "" -#: lxc/profile.go:102 lxc/profile.go:692 +#: lxc/profile.go:103 lxc/profile.go:770 msgid "[:] " msgstr "" -#: lxc/profile.go:164 +#: lxc/profile.go:177 msgid "[:] " msgstr "" @@ -6653,8 +6650,8 @@ msgstr "" msgid "[:] " msgstr "" -#: lxc/config_template.go:65 lxc/config_template.go:107 -#: lxc/config_template.go:150 lxc/config_template.go:298 +#: lxc/config_template.go:66 lxc/config_template.go:116 +#: lxc/config_template.go:171 lxc/config_template.go:339 msgid "[:]