The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6019

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===

From 8a4044b0ed5ead1718a745ed82df87d25ac8cbba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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?= <stgra...@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 <stgra...@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
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to