[lxc-devel] [lxd/master] Rework all the `set` commands to allow key=value
stgraber on Github
lxc-bot at linuxcontainers.org
Sat Jul 27 20:58:09 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190727/10000af6/attachment-0001.bin>
-------------- next part --------------
From 8a4044b0ed5ead1718a745ed82df87d25ac8cbba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 26 Jul 2019 19:21:44 -0400
Subject: [PATCH 1/8] lxc/utils: Add getConfig
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/utils.go | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/lxc/utils.go b/lxc/utils.go
index 5ef1c93e88..c113c64716 100644
--- a/lxc/utils.go
+++ b/lxc/utils.go
@@ -2,11 +2,17 @@ package main
import (
"fmt"
+ "io/ioutil"
+ "os"
"sort"
+ "strings"
+
+ "github.com/pkg/errors"
"github.com/lxc/lxd/client"
"github.com/lxc/lxd/shared/api"
"github.com/lxc/lxd/shared/i18n"
+ "github.com/lxc/lxd/shared/termios"
)
// Lists
@@ -217,3 +223,40 @@ func GetExistingAliases(aliases []string, allAliases []api.ImageAliasesEntry) []
}
return existing
}
+
+func getConfig(args ...string) (map[string]string, error) {
+ if len(args) == 2 && !strings.Contains(args[0], "=") {
+ if args[1] == "-" && !termios.IsTerminal(getStdinFd()) {
+ buf, err := ioutil.ReadAll(os.Stdin)
+ if err != nil {
+ return nil, errors.Wrap(err, i18n.G("Can't read from stdin: %s"))
+ }
+
+ args[1] = string(buf[:])
+ }
+
+ return map[string]string{args[0]: args[1]}, nil
+ }
+
+ values := map[string]string{}
+
+ for _, arg := range args {
+ fields := strings.SplitN(arg, "=", 2)
+ if len(fields) != 2 {
+ return nil, fmt.Errorf("Invalid key=value configuration: %s", arg)
+ }
+
+ if fields[1] == "-" && !termios.IsTerminal(getStdinFd()) {
+ buf, err := ioutil.ReadAll(os.Stdin)
+ if err != nil {
+ return nil, fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
+ }
+
+ fields[1] = string(buf[:])
+ }
+
+ values[fields[0]] = fields[1]
+ }
+
+ return values, nil
+}
From e655097bd562c773d7b8fa208d45f3dc891c71ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 26 Jul 2019 19:22:01 -0400
Subject: [PATCH 2/8] lxc/config: Rework config set
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/config.go | 66 +++++++++++++++++++++++++++++++--------------------
1 file changed, 40 insertions(+), 26 deletions(-)
diff --git a/lxc/config.go b/lxc/config.go
index 50b13dac8b..fb97012239 100644
--- a/lxc/config.go
+++ b/lxc/config.go
@@ -449,18 +449,21 @@ type cmdConfigSet struct {
func (c *cmdConfigSet) Command() *cobra.Command {
cmd := &cobra.Command{}
- cmd.Use = i18n.G("set [<remote>:][<container>] <key> <value>")
+ cmd.Use = i18n.G("set [<remote>:][<container>] <key>=<value>...")
cmd.Short = i18n.G("Set container or server configuration keys")
cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
- `Set container or server configuration keys`))
+ `Set container or server configuration keys
+
+For backward compatibility, a single configuration key may still be set with:
+ lxc config set [<remote>:][<container>] <key> <value>`))
cmd.Example = cli.FormatSection("", i18n.G(
- `lxc config set [<remote>:]<container> limits.cpu 2
+ `lxc config set [<remote>:]<container> limits.cpu=2
Will set a CPU limit of "2" for the container.
-lxc config set core.https_address [::]:8443
+lxc config set core.https_address=[::]:8443
Will have LXD listen on IPv4 and IPv6 port 8443.
-lxc config set core.trust_password blah
+lxc config set core.trust_password=blah
Will set the server's trust password to blah.`))
cmd.Flags().StringVar(&c.config.flagTarget, "target", "", i18n.G("Cluster member name")+"``")
@@ -471,14 +474,14 @@ lxc config set core.trust_password blah
func (c *cmdConfigSet) Run(cmd *cobra.Command, args []string) error {
// Sanity checks
- exit, err := c.global.CheckArgs(cmd, args, 2, 3)
+ exit, err := c.global.CheckArgs(cmd, args, 1, -1)
if exit {
return err
}
// Parse remote
remote := ""
- if len(args) > 2 {
+ if len(args) != 2 && !strings.Contains(args[0], "=") {
remote = args[0]
}
@@ -489,22 +492,16 @@ func (c *cmdConfigSet) Run(cmd *cobra.Command, args []string) error {
resource := resources[0]
- // Set the config key
+ // Set the config keys
if resource.name != "" {
// Sanity checks
if c.config.flagTarget != "" {
return fmt.Errorf(i18n.G("--target cannot be used with containers"))
}
- key := args[len(args)-2]
- value := args[len(args)-1]
-
- if !termios.IsTerminal(getStdinFd()) && value == "-" {
- buf, err := ioutil.ReadAll(os.Stdin)
- if err != nil {
- return fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
- }
- value = string(buf[:])
+ keys, err := getConfig(args[1:]...)
+ if err != nil {
+ return err
}
container, etag, err := resource.server.GetContainer(resource.name)
@@ -512,15 +509,17 @@ func (c *cmdConfigSet) Run(cmd *cobra.Command, args []string) error {
return err
}
- if cmd.Name() == "unset" {
- _, ok := container.Config[key]
- if !ok {
- return fmt.Errorf(i18n.G("Can't unset key '%s', it's not currently set"), key)
- }
+ for k, v := range keys {
+ if cmd.Name() == "unset" {
+ _, ok := container.Config[k]
+ if !ok {
+ return fmt.Errorf(i18n.G("Can't unset key '%s', it's not currently set"), k)
+ }
- delete(container.Config, key)
- } else {
- container.Config[key] = value
+ delete(container.Config, k)
+ } else {
+ container.Config[k] = v
+ }
}
op, err := resource.server.UpdateContainer(resource.name, container.Writable(), etag)
@@ -546,7 +545,22 @@ func (c *cmdConfigSet) Run(cmd *cobra.Command, args []string) error {
return err
}
- server.Config[args[len(args)-2]] = args[len(args)-1]
+ var keys map[string]string
+ if remote == "" {
+ keys, err = getConfig(args[0:]...)
+ if err != nil {
+ return err
+ }
+ } else {
+ keys, err = getConfig(args[1:]...)
+ if err != nil {
+ return err
+ }
+ }
+
+ for k, v := range keys {
+ server.Config[k] = v
+ }
return resource.server.UpdateServer(server.Writable(), etag)
}
From 80c8e8a1143582b732f6b3a4697bf21d520be700 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 27 Jul 2019 16:15:06 -0400
Subject: [PATCH 3/8] lxc/network: Rework network set
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/network.go | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/lxc/network.go b/lxc/network.go
index fc130590e7..45d59ce449 100644
--- a/lxc/network.go
+++ b/lxc/network.go
@@ -1049,10 +1049,13 @@ type cmdNetworkSet struct {
func (c *cmdNetworkSet) Command() *cobra.Command {
cmd := &cobra.Command{}
- cmd.Use = i18n.G("set [<remote>:]<network> <key> <value>")
+ cmd.Use = i18n.G("set [<remote>:]<network> <key>=<value>...")
cmd.Short = i18n.G("Set network configuration keys")
cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
- `Set network configuration keys`))
+ `Set network configuration keys
+
+For backward compatibility, a single configuration key may still be set with:
+ lxc network set [<remote>:]<network> <key> <value>`))
cmd.Flags().StringVar(&c.network.flagTarget, "target", "", i18n.G("Cluster member name")+"``")
cmd.RunE = c.Run
@@ -1062,7 +1065,7 @@ func (c *cmdNetworkSet) Command() *cobra.Command {
func (c *cmdNetworkSet) Run(cmd *cobra.Command, args []string) error {
// Sanity checks
- exit, err := c.global.CheckArgs(cmd, args, 3, 3)
+ exit, err := c.global.CheckArgs(cmd, args, 2, -1)
if exit {
return err
}
@@ -1080,11 +1083,12 @@ func (c *cmdNetworkSet) Run(cmd *cobra.Command, args []string) error {
return fmt.Errorf(i18n.G("Missing network name"))
}
- // Set the config key
+ // Handle targeting
if c.network.flagTarget != "" {
client = client.UseTarget(c.network.flagTarget)
}
+ // Get the network
network, etag, err := client.GetNetwork(resource.name)
if err != nil {
return err
@@ -1094,18 +1098,15 @@ func (c *cmdNetworkSet) Run(cmd *cobra.Command, args []string) error {
return fmt.Errorf(i18n.G("Only managed networks can be modified"))
}
- key := args[1]
- value := args[2]
-
- if !termios.IsTerminal(getStdinFd()) && value == "-" {
- buf, err := ioutil.ReadAll(os.Stdin)
- if err != nil {
- return fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
- }
- value = string(buf[:])
+ // Set the keys
+ keys, err := getConfig(args[1:]...)
+ if err != nil {
+ return err
}
- network.Config[key] = value
+ for k, v := range keys {
+ network.Config[k] = v
+ }
return client.UpdateNetwork(resource.name, network.Writable(), etag)
}
From 813c98890a8b555843c8ecfb61d75a45ade8f0ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 27 Jul 2019 16:21:05 -0400
Subject: [PATCH 4/8] lxc/profile: Rework profile set
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/profile.go | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/lxc/profile.go b/lxc/profile.go
index 26526bcb9b..e8c1acf632 100644
--- a/lxc/profile.go
+++ b/lxc/profile.go
@@ -798,10 +798,13 @@ type cmdProfileSet struct {
func (c *cmdProfileSet) Command() *cobra.Command {
cmd := &cobra.Command{}
- cmd.Use = i18n.G("set [<remote>:]<profile> <key> <value>")
+ cmd.Use = i18n.G("set [<remote>:]<profile> <key><value>...")
cmd.Short = i18n.G("Set profile configuration keys")
cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
- `Set profile configuration keys`))
+ `Set profile configuration keys
+
+For backward compatibility, a single configuration key may still be set with:
+ lxc profile set [<remote>:]<profile> <key> <value>`))
cmd.RunE = c.Run
@@ -810,7 +813,7 @@ func (c *cmdProfileSet) Command() *cobra.Command {
func (c *cmdProfileSet) Run(cmd *cobra.Command, args []string) error {
// Sanity checks
- exit, err := c.global.CheckArgs(cmd, args, 3, 3)
+ exit, err := c.global.CheckArgs(cmd, args, 2, -1)
if exit {
return err
}
@@ -827,24 +830,21 @@ func (c *cmdProfileSet) Run(cmd *cobra.Command, args []string) error {
return fmt.Errorf(i18n.G("Missing profile name"))
}
- // Set the configuration key
- key := args[1]
- value := args[2]
-
- if !termios.IsTerminal(getStdinFd()) && value == "-" {
- buf, err := ioutil.ReadAll(os.Stdin)
- if err != nil {
- return fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
- }
- value = string(buf[:])
+ // Get the profile
+ profile, etag, err := resource.server.GetProfile(resource.name)
+ if err != nil {
+ return err
}
- profile, etag, err := resource.server.GetProfile(resource.name)
+ // Set the configuration key
+ keys, err := getConfig(args[1:]...)
if err != nil {
return err
}
- profile.Config[key] = value
+ for k, v := range keys {
+ profile.Config[k] = v
+ }
return resource.server.UpdateProfile(resource.name, profile.Writable(), etag)
}
From 24e4f32f09f8484332a64351570bd64a5697a683 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 27 Jul 2019 16:24:45 -0400
Subject: [PATCH 5/8] lxc/project: Rework project set
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/project.go | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/lxc/project.go b/lxc/project.go
index 645778be5e..bd62dca6d9 100644
--- a/lxc/project.go
+++ b/lxc/project.go
@@ -521,10 +521,13 @@ type cmdProjectSet struct {
func (c *cmdProjectSet) Command() *cobra.Command {
cmd := &cobra.Command{}
- cmd.Use = i18n.G("set [<remote>:]<project> <key> <value>")
+ cmd.Use = i18n.G("set [<remote>:]<project> <key>=<value>...")
cmd.Short = i18n.G("Set project configuration keys")
cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
- `Set project configuration keys`))
+ `Set project configuration keys
+
+For backward compatibility, a single configuration key may still be set with:
+ lxc project set [<remote>:]<project> <key> <value>`))
cmd.RunE = c.Run
@@ -533,7 +536,7 @@ func (c *cmdProjectSet) Command() *cobra.Command {
func (c *cmdProjectSet) Run(cmd *cobra.Command, args []string) error {
// Sanity checks
- exit, err := c.global.CheckArgs(cmd, args, 3, 3)
+ exit, err := c.global.CheckArgs(cmd, args, 2, -1)
if exit {
return err
}
@@ -550,24 +553,21 @@ func (c *cmdProjectSet) Run(cmd *cobra.Command, args []string) error {
return fmt.Errorf(i18n.G("Missing project name"))
}
- // Set the configuration key
- key := args[1]
- value := args[2]
-
- if !termios.IsTerminal(getStdinFd()) && value == "-" {
- buf, err := ioutil.ReadAll(os.Stdin)
- if err != nil {
- return fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
- }
- value = string(buf[:])
+ // Get the project
+ project, etag, err := resource.server.GetProject(resource.name)
+ if err != nil {
+ return err
}
- project, etag, err := resource.server.GetProject(resource.name)
+ // Set the configuration key
+ keys, err := getConfig(args[1:]...)
if err != nil {
return err
}
- project.Config[key] = value
+ for k, v := range keys {
+ project.Config[k] = v
+ }
return resource.server.UpdateProject(resource.name, project.Writable(), etag)
}
From 2f1ee6a3f7458a26a7850249878abd06544199e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 27 Jul 2019 16:28:46 -0400
Subject: [PATCH 6/8] lxc/config: Rework config device set
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/config_device.go | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/lxc/config_device.go b/lxc/config_device.go
index 0cb5b0e5b4..bbff5aa95f 100644
--- a/lxc/config_device.go
+++ b/lxc/config_device.go
@@ -495,10 +495,13 @@ type cmdConfigDeviceSet struct {
func (c *cmdConfigDeviceSet) Command() *cobra.Command {
cmd := &cobra.Command{}
- cmd.Use = i18n.G("set [<remote>:]<container|profile> <device> <key> <value>")
+ cmd.Use = i18n.G("set [<remote>:]<container|profile> <device> <key>=<value>...")
cmd.Short = i18n.G("Set container device configuration keys")
cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
- `Set container device configuration keys`))
+ `Set container device configuration keys
+
+For backward compatibility, a single configuration key may still be set with:
+ lxc config device set [<remote>:]<container|profile> <device> <key> <value>`))
cmd.RunE = c.Run
@@ -507,7 +510,7 @@ func (c *cmdConfigDeviceSet) Command() *cobra.Command {
func (c *cmdConfigDeviceSet) Run(cmd *cobra.Command, args []string) error {
// Sanity checks
- exit, err := c.global.CheckArgs(cmd, args, 4, 4)
+ exit, err := c.global.CheckArgs(cmd, args, 3, -1)
if exit {
return err
}
@@ -526,8 +529,11 @@ func (c *cmdConfigDeviceSet) Run(cmd *cobra.Command, args []string) error {
// Set the device config key
devname := args[1]
- key := args[2]
- value := args[3]
+
+ keys, err := getConfig(args[2:]...)
+ if err != nil {
+ return err
+ }
if c.profile != nil {
profile, etag, err := resource.server.GetProfile(resource.name)
@@ -540,7 +546,9 @@ func (c *cmdConfigDeviceSet) Run(cmd *cobra.Command, args []string) error {
return fmt.Errorf(i18n.G("The device doesn't exist"))
}
- dev[key] = value
+ for k, v := range keys {
+ dev[k] = v
+ }
profile.Devices[devname] = dev
err = resource.server.UpdateProfile(resource.name, profile.Writable(), etag)
@@ -557,7 +565,9 @@ func (c *cmdConfigDeviceSet) Run(cmd *cobra.Command, args []string) error {
return fmt.Errorf(i18n.G("The device doesn't exist"))
}
- dev[key] = value
+ for k, v := range keys {
+ dev[k] = v
+ }
container.Devices[devname] = dev
op, err := resource.server.UpdateContainer(resource.name, container.Writable(), etag)
From 4fd05be5f986338cd50f3f7fe6d6f99915469bc6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 27 Jul 2019 16:34:33 -0400
Subject: [PATCH 7/8] lxc/storage: Rework storage set
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/storage.go | 29 +++++++++++++----------------
1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/lxc/storage.go b/lxc/storage.go
index ef0e8cacdd..63f5eccbb9 100644
--- a/lxc/storage.go
+++ b/lxc/storage.go
@@ -586,7 +586,10 @@ func (c *cmdStorageSet) Command() *cobra.Command {
cmd.Use = i18n.G("set [<remote>:]<pool> <key> <value>")
cmd.Short = i18n.G("Set storage pool configuration keys")
cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
- `Set storage pool configuration keys`))
+ `Set storage pool configuration keys
+
+For backward compatibility, a single configuration key may still be set with:
+ lxc storage set [<remote>:]<pool> <key> <value>`))
cmd.Flags().StringVar(&c.storage.flagTarget, "target", "", i18n.G("Cluster member name")+"``")
cmd.RunE = c.Run
@@ -596,16 +599,13 @@ func (c *cmdStorageSet) Command() *cobra.Command {
func (c *cmdStorageSet) Run(cmd *cobra.Command, args []string) error {
// Sanity checks
- exit, err := c.global.CheckArgs(cmd, args, 3, 3)
+ exit, err := c.global.CheckArgs(cmd, args, 2, -1)
if exit {
return err
}
// Parse remote
- remote := ""
- if len(args) > 0 {
- remote = args[0]
- }
+ remote := args[0]
resources, err := c.global.ParseServers(remote)
if err != nil {
@@ -613,7 +613,6 @@ func (c *cmdStorageSet) Run(cmd *cobra.Command, args []string) error {
}
resource := resources[0]
-
if resource.name == "" {
return fmt.Errorf(i18n.G("Missing pool name"))
}
@@ -624,18 +623,16 @@ func (c *cmdStorageSet) Run(cmd *cobra.Command, args []string) error {
return err
}
- // Read the value
- value := args[2]
- if !termios.IsTerminal(getStdinFd()) && value == "-" {
- buf, err := ioutil.ReadAll(os.Stdin)
- if err != nil {
- return fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
- }
- value = string(buf[:])
+ // Parse key/values
+ keys, err := getConfig(args[1:]...)
+ if err != nil {
+ return err
}
// Update the pool
- pool.Config[args[1]] = value
+ for k, v := range keys {
+ pool.Config[k] = v
+ }
err = resource.server.UpdateStoragePool(resource.name, pool.Writable(), etag)
if err != nil {
From 684a697bdede9192e39d501bf9d94241471c52e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Sat, 27 Jul 2019 16:41:01 -0400
Subject: [PATCH 8/8] lxc/storage: Rework storage volume set
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxc/storage_volume.go | 29 ++++++++++++++---------------
1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/lxc/storage_volume.go b/lxc/storage_volume.go
index b167c6d203..e2d55d6ce9 100644
--- a/lxc/storage_volume.go
+++ b/lxc/storage_volume.go
@@ -1276,10 +1276,13 @@ type cmdStorageVolumeSet struct {
func (c *cmdStorageVolumeSet) Command() *cobra.Command {
cmd := &cobra.Command{}
- cmd.Use = i18n.G("set [<remote>:]<pool> <volume> <key> <value>")
+ cmd.Use = i18n.G("set [<remote>:]<pool> <volume> <key>=<value>...")
cmd.Short = i18n.G("Set storage volume configuration keys")
cmd.Long = cli.FormatSection(i18n.G("Description"), i18n.G(
- `Set storage volume configuration keys`))
+ `Set storage volume configuration keys
+
+For backward compatibility, a single configuration key may still be set with:
+ lxc storage volume set [<remote>:]<pool> <volume> <key> <value>`))
cmd.Flags().StringVar(&c.storage.flagTarget, "target", "", i18n.G("Cluster member name")+"``")
cmd.RunE = c.Run
@@ -1289,7 +1292,7 @@ func (c *cmdStorageVolumeSet) Command() *cobra.Command {
func (c *cmdStorageVolumeSet) Run(cmd *cobra.Command, args []string) error {
// Sanity checks
- exit, err := c.global.CheckArgs(cmd, args, 4, 4)
+ exit, err := c.global.CheckArgs(cmd, args, 3, -1)
if exit {
return err
}
@@ -1301,7 +1304,6 @@ func (c *cmdStorageVolumeSet) Run(cmd *cobra.Command, args []string) error {
}
resource := resources[0]
-
if resource.name == "" {
return fmt.Errorf(i18n.G("Missing pool name"))
}
@@ -1322,20 +1324,17 @@ func (c *cmdStorageVolumeSet) Run(cmd *cobra.Command, args []string) error {
return err
}
- // Get the value
- key := args[2]
- value := args[3]
-
- if !termios.IsTerminal(getStdinFd()) && value == "-" {
- buf, err := ioutil.ReadAll(os.Stdin)
- if err != nil {
- return fmt.Errorf(i18n.G("Can't read from stdin: %s"), err)
- }
- value = string(buf[:])
+ // Get the values
+ keys, err := getConfig(args[2:]...)
+ if err != nil {
+ return err
}
// Update the volume
- vol.Config[key] = value
+ for k, v := range keys {
+ vol.Config[k] = v
+ }
+
err = client.UpdateStoragePoolVolume(resource.name, vol.Type, vol.Name, vol.Writable(), etag)
if err != nil {
return err
More information about the lxc-devel
mailing list