[lxc-devel] [lxd/master] Move units functions to separate package

stgraber on Github lxc-bot at linuxcontainers.org
Thu Jul 4 04:00:41 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 396 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190703/f09d5d49/attachment-0001.bin>
-------------- next part --------------
From bd2e6ad0471b7a747e6c789b64e4218749494273 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 2 Jul 2019 00:13:29 -0400
Subject: [PATCH 1/6] doc: Fix underscore escaping
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>
---
 doc/api-extensions.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index a8514e4a98..811e69e16b 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -759,7 +759,7 @@ by a container that a registered syscall has been performed. LXD can then
 decide to trigger various actions.
 
 ## lxc\_features
-This introduces the `lxc_features` section output from the `lxc info` command
+This introduces the `lxc\_features` section output from the `lxc info` command
 via the `GET /1.0/` route. It outputs the result of checks for key features being present in the
 underlying LXC library.
 
@@ -767,7 +767,7 @@ underlying LXC library.
 This introduces the `ipvlan` "nic" device type.
 
 ## network\_vlan\_sriov
-This introduces VLAN (`vlan`) and MAC filtering (`security.mac_filtering`) support for SR-IOV devices.
+This introduces VLAN (`vlan`) and MAC filtering (`security.mac\_filtering`) support for SR-IOV devices.
 
 ## storage\_cephfs
 Add support for CEPHFS as a storage pool driver. This can only be used
@@ -775,4 +775,4 @@ for custom volumes, images and containers should be on CEPH (RBD)
 instead.
 
 ## container\_nic\_ipfilter
-This introduces container IP filtering (`security.ipv4_filtering` and `security.ipv6_filtering`) support for `bridged` nic devices.
+This introduces container IP filtering (`security.ipv4\_filtering` and `security.ipv6\_filtering`) support for `bridged` nic devices.

From e0c977209ab58fc6b383f2eed48362f62e299d1b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 2 Jul 2019 10:29:30 -0400
Subject: [PATCH 2/6] shared/units: Move unit functions
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>
---
 shared/units/units.go | 162 ++++++++++++++++++++++++++++++++++++++++++
 shared/util.go        | 154 ---------------------------------------
 2 files changed, 162 insertions(+), 154 deletions(-)
 create mode 100644 shared/units/units.go

diff --git a/shared/units/units.go b/shared/units/units.go
new file mode 100644
index 0000000000..23514c9c30
--- /dev/null
+++ b/shared/units/units.go
@@ -0,0 +1,162 @@
+package units
+
+import (
+	"fmt"
+	"strconv"
+)
+
+// ParseByteSizeString parses a human representation of an amount of
+// data into a number of bytes
+func ParseByteSizeString(input string) (int64, error) {
+	// Empty input
+	if input == "" {
+		return 0, nil
+	}
+
+	// Find where the suffix begins
+	suffixLen := 0
+	for i, chr := range []byte(input) {
+		_, err := strconv.Atoi(string([]byte{chr}))
+		if err != nil {
+			suffixLen = len(input) - i
+			break
+		}
+	}
+
+	if suffixLen == len(input) {
+		return -1, fmt.Errorf("Invalid value: %s", input)
+	}
+
+	// Extract the suffix
+	suffix := input[len(input)-suffixLen:]
+
+	// Extract the value
+	value := input[0 : len(input)-suffixLen]
+	valueInt, err := strconv.ParseInt(value, 10, 64)
+	if err != nil {
+		return -1, fmt.Errorf("Invalid integer: %s", input)
+	}
+
+	// Figure out the multiplicator
+	multiplicator := int64(0)
+	switch suffix {
+	case "", "B", " bytes":
+		multiplicator = 1
+	case "kB":
+		multiplicator = 1000
+	case "MB":
+		multiplicator = 1000 * 1000
+	case "GB":
+		multiplicator = 1000 * 1000 * 1000
+	case "TB":
+		multiplicator = 1000 * 1000 * 1000 * 1000
+	case "PB":
+		multiplicator = 1000 * 1000 * 1000 * 1000 * 1000
+	case "EB":
+		multiplicator = 1000 * 1000 * 1000 * 1000 * 1000 * 1000
+	case "KiB":
+		multiplicator = 1024
+	case "MiB":
+		multiplicator = 1024 * 1024
+	case "GiB":
+		multiplicator = 1024 * 1024 * 1024
+	case "TiB":
+		multiplicator = 1024 * 1024 * 1024 * 1024
+	case "PiB":
+		multiplicator = 1024 * 1024 * 1024 * 1024 * 1024
+	case "EiB":
+		multiplicator = 1024 * 1024 * 1024 * 1024 * 1024 * 1024
+	default:
+		return -1, fmt.Errorf("Invalid value: %s", input)
+	}
+
+	return valueInt * multiplicator, nil
+}
+
+// ParseBitSizeString parses a human representation of an amount of
+// data into a number of bits
+func ParseBitSizeString(input string) (int64, error) {
+	// Empty input
+	if input == "" {
+		return 0, nil
+	}
+
+	// Find where the suffix begins
+	suffixLen := 0
+	for i, chr := range []byte(input) {
+		_, err := strconv.Atoi(string([]byte{chr}))
+		if err != nil {
+			suffixLen = len(input) - i
+			break
+		}
+	}
+
+	if suffixLen == len(input) {
+		return -1, fmt.Errorf("Invalid value: %s", input)
+	}
+
+	// Extract the suffix
+	suffix := input[len(input)-suffixLen:]
+
+	// Extract the value
+	value := input[0 : len(input)-suffixLen]
+	valueInt, err := strconv.ParseInt(value, 10, 64)
+	if err != nil {
+		return -1, fmt.Errorf("Invalid integer: %s", input)
+	}
+
+	// Figure out the multiplicator
+	multiplicator := int64(0)
+	switch suffix {
+	case "", "bit":
+		multiplicator = 1
+	case "kbit":
+		multiplicator = 1000
+	case "Mbit":
+		multiplicator = 1000 * 1000
+	case "Gbit":
+		multiplicator = 1000 * 1000 * 1000
+	case "Tbit":
+		multiplicator = 1000 * 1000 * 1000 * 1000
+	case "Pbit":
+		multiplicator = 1000 * 1000 * 1000 * 1000 * 1000
+	case "Ebit":
+		multiplicator = 1000 * 1000 * 1000 * 1000 * 1000 * 1000
+	case "Kibit":
+		multiplicator = 1024
+	case "Mibit":
+		multiplicator = 1024 * 1024
+	case "Gibit":
+		multiplicator = 1024 * 1024 * 1024
+	case "Tibit":
+		multiplicator = 1024 * 1024 * 1024 * 1024
+	case "Pibit":
+		multiplicator = 1024 * 1024 * 1024 * 1024 * 1024
+	case "Eibit":
+		multiplicator = 1024 * 1024 * 1024 * 1024 * 1024 * 1024
+
+	default:
+		return -1, fmt.Errorf("Unsupported suffix: %s", suffix)
+	}
+
+	return valueInt * multiplicator, nil
+}
+
+// GetByteSizeString takes a number of bytes and precision and returns a
+// human representation of the amount of data
+func GetByteSizeString(input int64, precision uint) string {
+	if input < 1000 {
+		return fmt.Sprintf("%dB", input)
+	}
+
+	value := float64(input)
+
+	for _, unit := range []string{"kB", "MB", "GB", "TB", "PB", "EB"} {
+		value = value / 1000
+		if value < 1000 {
+			return fmt.Sprintf("%.*f%s", precision, value, unit)
+		}
+	}
+
+	return fmt.Sprintf("%.*fEB", precision, value)
+}
diff --git a/shared/util.go b/shared/util.go
index fb03e2ee4a..b57dc9e139 100644
--- a/shared/util.go
+++ b/shared/util.go
@@ -751,160 +751,6 @@ func ParseMetadata(metadata interface{}) (map[string]interface{}, error) {
 	return newMetadata, nil
 }
 
-// Parse a size string in bytes (e.g. 200kB or 5GB) into the number of bytes it
-// represents. Supports suffixes up to EB. "" == 0.
-func ParseByteSizeString(input string) (int64, error) {
-	// Empty input
-	if input == "" {
-		return 0, nil
-	}
-
-	// Find where the suffix begins
-	suffixLen := 0
-	for i, chr := range []byte(input) {
-		_, err := strconv.Atoi(string([]byte{chr}))
-		if err != nil {
-			suffixLen = len(input) - i
-			break
-		}
-	}
-
-	if suffixLen == len(input) {
-		return -1, fmt.Errorf("Invalid value: %s", input)
-	}
-
-	// Extract the suffix
-	suffix := input[len(input)-suffixLen:]
-
-	// Extract the value
-	value := input[0 : len(input)-suffixLen]
-	valueInt, err := strconv.ParseInt(value, 10, 64)
-	if err != nil {
-		return -1, fmt.Errorf("Invalid integer: %s", input)
-	}
-
-	// Figure out the multiplicator
-	multiplicator := int64(0)
-	switch suffix {
-	case "", "B", " bytes":
-		multiplicator = 1
-	case "kB":
-		multiplicator = 1000
-	case "MB":
-		multiplicator = 1000 * 1000
-	case "GB":
-		multiplicator = 1000 * 1000 * 1000
-	case "TB":
-		multiplicator = 1000 * 1000 * 1000 * 1000
-	case "PB":
-		multiplicator = 1000 * 1000 * 1000 * 1000 * 1000
-	case "EB":
-		multiplicator = 1000 * 1000 * 1000 * 1000 * 1000 * 1000
-	case "KiB":
-		multiplicator = 1024
-	case "MiB":
-		multiplicator = 1024 * 1024
-	case "GiB":
-		multiplicator = 1024 * 1024 * 1024
-	case "TiB":
-		multiplicator = 1024 * 1024 * 1024 * 1024
-	case "PiB":
-		multiplicator = 1024 * 1024 * 1024 * 1024 * 1024
-	case "EiB":
-		multiplicator = 1024 * 1024 * 1024 * 1024 * 1024 * 1024
-	default:
-		return -1, fmt.Errorf("Invalid value: %s", input)
-	}
-
-	return valueInt * multiplicator, nil
-}
-
-// Parse a size string in bits (e.g. 200kbit or 5Gbit) into the number of bits
-// it represents. Supports suffixes up to Ebit. "" == 0.
-func ParseBitSizeString(input string) (int64, error) {
-	// Empty input
-	if input == "" {
-		return 0, nil
-	}
-
-	// Find where the suffix begins
-	suffixLen := 0
-	for i, chr := range []byte(input) {
-		_, err := strconv.Atoi(string([]byte{chr}))
-		if err != nil {
-			suffixLen = len(input) - i
-			break
-		}
-	}
-
-	if suffixLen == len(input) {
-		return -1, fmt.Errorf("Invalid value: %s", input)
-	}
-
-	// Extract the suffix
-	suffix := input[len(input)-suffixLen:]
-
-	// Extract the value
-	value := input[0 : len(input)-suffixLen]
-	valueInt, err := strconv.ParseInt(value, 10, 64)
-	if err != nil {
-		return -1, fmt.Errorf("Invalid integer: %s", input)
-	}
-
-	// Figure out the multiplicator
-	multiplicator := int64(0)
-	switch suffix {
-	case "", "bit":
-		multiplicator = 1
-	case "kbit":
-		multiplicator = 1000
-	case "Mbit":
-		multiplicator = 1000 * 1000
-	case "Gbit":
-		multiplicator = 1000 * 1000 * 1000
-	case "Tbit":
-		multiplicator = 1000 * 1000 * 1000 * 1000
-	case "Pbit":
-		multiplicator = 1000 * 1000 * 1000 * 1000 * 1000
-	case "Ebit":
-		multiplicator = 1000 * 1000 * 1000 * 1000 * 1000 * 1000
-	case "Kibit":
-		multiplicator = 1024
-	case "Mibit":
-		multiplicator = 1024 * 1024
-	case "Gibit":
-		multiplicator = 1024 * 1024 * 1024
-	case "Tibit":
-		multiplicator = 1024 * 1024 * 1024 * 1024
-	case "Pibit":
-		multiplicator = 1024 * 1024 * 1024 * 1024 * 1024
-	case "Eibit":
-		multiplicator = 1024 * 1024 * 1024 * 1024 * 1024 * 1024
-
-	default:
-		return -1, fmt.Errorf("Unsupported suffix: %s", suffix)
-	}
-
-	return valueInt * multiplicator, nil
-}
-
-func GetByteSizeString(input int64, precision uint) string {
-	if input < 1000 {
-		return fmt.Sprintf("%dB", input)
-	}
-
-	value := float64(input)
-
-	for _, unit := range []string{"kB", "MB", "GB", "TB", "PB", "EB"} {
-		value = value / 1000
-		if value < 1000 {
-			return fmt.Sprintf("%.*f%s", precision, value, unit)
-		}
-	}
-
-	return fmt.Sprintf("%.*fEB", precision, value)
-}
-
 // RemoveDuplicatesFromString removes all duplicates of the string 'sep'
 // from the specified string 's'.  Leading and trailing occurrences of sep
 // are NOT removed (duplicate leading/trailing are).  Performs poorly if

From bcb18b74256051872c21f2f0b23bf363a23fbe1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 2 Jul 2019 14:09:33 -0400
Subject: [PATCH 3/6] client: Move to units package
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>
---
 client/lxd_containers.go | 3 ++-
 client/lxd_images.go     | 5 +++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/client/lxd_containers.go b/client/lxd_containers.go
index 4351c7f632..4f459f8ced 100644
--- a/client/lxd_containers.go
+++ b/client/lxd_containers.go
@@ -14,6 +14,7 @@ import (
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/cancel"
 	"github.com/lxc/lxd/shared/ioprogress"
+	"github.com/lxc/lxd/shared/units"
 )
 
 // Container handling functions
@@ -1890,7 +1891,7 @@ func (r *ProtocolLXD) GetContainerBackupFile(containerName string, name string,
 			Tracker: &ioprogress.ProgressTracker{
 				Length: response.ContentLength,
 				Handler: func(percent int64, speed int64) {
-					req.ProgressHandler(ioprogress.ProgressData{Text: fmt.Sprintf("%d%% (%s/s)", percent, shared.GetByteSizeString(speed, 2))})
+					req.ProgressHandler(ioprogress.ProgressData{Text: fmt.Sprintf("%d%% (%s/s)", percent, units.GetByteSizeString(speed, 2))})
 				},
 			},
 		}
diff --git a/client/lxd_images.go b/client/lxd_images.go
index bdaeaee9ef..fb78256e7d 100644
--- a/client/lxd_images.go
+++ b/client/lxd_images.go
@@ -16,6 +16,7 @@ import (
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/cancel"
 	"github.com/lxc/lxd/shared/ioprogress"
+	"github.com/lxc/lxd/shared/units"
 )
 
 // Image handling functions
@@ -184,7 +185,7 @@ func lxdDownloadImage(fingerprint string, uri string, userAgent string, client *
 			Tracker: &ioprogress.ProgressTracker{
 				Length: response.ContentLength,
 				Handler: func(percent int64, speed int64) {
-					req.ProgressHandler(ioprogress.ProgressData{Text: fmt.Sprintf("%d%% (%s/s)", percent, shared.GetByteSizeString(speed, 2))})
+					req.ProgressHandler(ioprogress.ProgressData{Text: fmt.Sprintf("%d%% (%s/s)", percent, units.GetByteSizeString(speed, 2))})
 				},
 			},
 		}
@@ -403,7 +404,7 @@ func (r *ProtocolLXD) CreateImage(image api.ImagesPost, args *ImageCreateArgs) (
 				Tracker: &ioprogress.ProgressTracker{
 					Length: size,
 					Handler: func(percent int64, speed int64) {
-						args.ProgressHandler(ioprogress.ProgressData{Text: fmt.Sprintf("%d%% (%s/s)", percent, shared.GetByteSizeString(speed, 2))})
+						args.ProgressHandler(ioprogress.ProgressData{Text: fmt.Sprintf("%d%% (%s/s)", percent, units.GetByteSizeString(speed, 2))})
 					},
 				},
 			}

From 9c67952e29fda363e30a76d29ec3f6f3c9cb3822 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 2 Jul 2019 14:09:40 -0400
Subject: [PATCH 4/6] lxc: Move to units package
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/file.go    | 13 +++++++------
 lxc/import.go  |  3 ++-
 lxc/info.go    | 21 +++++++++++----------
 lxc/network.go |  5 +++--
 lxc/storage.go |  5 +++--
 5 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/lxc/file.go b/lxc/file.go
index 16f670fbd3..b0e896f1d3 100644
--- a/lxc/file.go
+++ b/lxc/file.go
@@ -21,6 +21,7 @@ import (
 	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/termios"
+	"github.com/lxc/lxd/shared/units"
 )
 
 type cmdFile struct {
@@ -344,8 +345,8 @@ func (c *cmdFilePull) Run(cmd *cobra.Command, args []string) error {
 
 					progress.UpdateProgress(ioprogress.ProgressData{
 						Text: fmt.Sprintf("%s (%s/s)",
-							shared.GetByteSizeString(bytesReceived, 2),
-							shared.GetByteSizeString(speed, 2))})
+							units.GetByteSizeString(bytesReceived, 2),
+							units.GetByteSizeString(speed, 2))})
 				},
 			},
 		}
@@ -599,7 +600,7 @@ func (c *cmdFilePush) Run(cmd *cobra.Command, args []string) error {
 				Length: fstat.Size(),
 				Handler: func(percent int64, speed int64) {
 					progress.UpdateProgress(ioprogress.ProgressData{
-						Text: fmt.Sprintf("%d%% (%s/s)", percent, shared.GetByteSizeString(speed, 2)),
+						Text: fmt.Sprintf("%d%% (%s/s)", percent, units.GetByteSizeString(speed, 2)),
 					})
 				},
 			},
@@ -663,8 +664,8 @@ func (c *cmdFile) recursivePullFile(d lxd.ContainerServer, container string, p s
 				Handler: func(bytesReceived int64, speed int64) {
 					progress.UpdateProgress(ioprogress.ProgressData{
 						Text: fmt.Sprintf("%s (%s/s)",
-							shared.GetByteSizeString(bytesReceived, 2),
-							shared.GetByteSizeString(speed, 2))})
+							units.GetByteSizeString(bytesReceived, 2),
+							units.GetByteSizeString(speed, 2))})
 				},
 			},
 		}
@@ -767,7 +768,7 @@ func (c *cmdFile) recursivePushFile(d lxd.ContainerServer, container string, sou
 					Handler: func(percent int64, speed int64) {
 						progress.UpdateProgress(ioprogress.ProgressData{
 							Text: fmt.Sprintf("%d%% (%s/s)", percent,
-								shared.GetByteSizeString(speed, 2))})
+								units.GetByteSizeString(speed, 2))})
 					},
 				},
 			}, args.Content)
diff --git a/lxc/import.go b/lxc/import.go
index d8d659b76e..d3593ba2c1 100644
--- a/lxc/import.go
+++ b/lxc/import.go
@@ -12,6 +12,7 @@ import (
 	cli "github.com/lxc/lxd/shared/cmd"
 	"github.com/lxc/lxd/shared/i18n"
 	"github.com/lxc/lxd/shared/ioprogress"
+	"github.com/lxc/lxd/shared/units"
 )
 
 type cmdImport struct {
@@ -78,7 +79,7 @@ func (c *cmdImport) Run(cmd *cobra.Command, args []string) error {
 			Tracker: &ioprogress.ProgressTracker{
 				Length: fstat.Size(),
 				Handler: func(percent int64, speed int64) {
-					progress.UpdateProgress(ioprogress.ProgressData{Text: fmt.Sprintf("%d%% (%s/s)", percent, shared.GetByteSizeString(speed, 2))})
+					progress.UpdateProgress(ioprogress.ProgressData{Text: fmt.Sprintf("%d%% (%s/s)", percent, units.GetByteSizeString(speed, 2))})
 				},
 			},
 		},
diff --git a/lxc/info.go b/lxc/info.go
index b9160e86a4..ff79656ec0 100644
--- a/lxc/info.go
+++ b/lxc/info.go
@@ -14,6 +14,7 @@ import (
 	"github.com/lxc/lxd/shared/api"
 	cli "github.com/lxc/lxd/shared/cmd"
 	"github.com/lxc/lxd/shared/i18n"
+	"github.com/lxc/lxd/shared/units"
 )
 
 type cmdInfo struct {
@@ -131,9 +132,9 @@ func (c *cmdInfo) remoteInfo(d lxd.ContainerServer) error {
 		}
 
 		fmt.Printf("\n" + i18n.G("Memory:") + "\n")
-		fmt.Printf("  "+i18n.G("Free: %v")+"\n", shared.GetByteSizeString(int64(resources.Memory.Total-resources.Memory.Used), 2))
-		fmt.Printf("  "+i18n.G("Used: %v")+"\n", shared.GetByteSizeString(int64(resources.Memory.Used), 2))
-		fmt.Printf("  "+i18n.G("Total: %v")+"\n", shared.GetByteSizeString(int64(resources.Memory.Total), 2))
+		fmt.Printf("  "+i18n.G("Free: %v")+"\n", units.GetByteSizeString(int64(resources.Memory.Total-resources.Memory.Used), 2))
+		fmt.Printf("  "+i18n.G("Used: %v")+"\n", units.GetByteSizeString(int64(resources.Memory.Used), 2))
+		fmt.Printf("  "+i18n.G("Total: %v")+"\n", units.GetByteSizeString(int64(resources.Memory.Total), 2))
 
 		renderGPU := func(gpu api.ResourcesGPUCard, prefix string) {
 			if gpu.Vendor != "" {
@@ -258,7 +259,7 @@ func (c *cmdInfo) containerInfo(d lxd.ContainerServer, remote config.Remote, nam
 		if cs.Disk != nil {
 			for entry, disk := range cs.Disk {
 				if disk.Usage != 0 {
-					diskInfo += fmt.Sprintf("    %s: %s\n", entry, shared.GetByteSizeString(disk.Usage, 2))
+					diskInfo += fmt.Sprintf("    %s: %s\n", entry, units.GetByteSizeString(disk.Usage, 2))
 				}
 			}
 		}
@@ -282,19 +283,19 @@ func (c *cmdInfo) containerInfo(d lxd.ContainerServer, remote config.Remote, nam
 		// Memory usage
 		memoryInfo := ""
 		if cs.Memory.Usage != 0 {
-			memoryInfo += fmt.Sprintf("    %s: %s\n", i18n.G("Memory (current)"), shared.GetByteSizeString(cs.Memory.Usage, 2))
+			memoryInfo += fmt.Sprintf("    %s: %s\n", i18n.G("Memory (current)"), units.GetByteSizeString(cs.Memory.Usage, 2))
 		}
 
 		if cs.Memory.UsagePeak != 0 {
-			memoryInfo += fmt.Sprintf("    %s: %s\n", i18n.G("Memory (peak)"), shared.GetByteSizeString(cs.Memory.UsagePeak, 2))
+			memoryInfo += fmt.Sprintf("    %s: %s\n", i18n.G("Memory (peak)"), units.GetByteSizeString(cs.Memory.UsagePeak, 2))
 		}
 
 		if cs.Memory.SwapUsage != 0 {
-			memoryInfo += fmt.Sprintf("    %s: %s\n", i18n.G("Swap (current)"), shared.GetByteSizeString(cs.Memory.SwapUsage, 2))
+			memoryInfo += fmt.Sprintf("    %s: %s\n", i18n.G("Swap (current)"), units.GetByteSizeString(cs.Memory.SwapUsage, 2))
 		}
 
 		if cs.Memory.SwapUsagePeak != 0 {
-			memoryInfo += fmt.Sprintf("    %s: %s\n", i18n.G("Swap (peak)"), shared.GetByteSizeString(cs.Memory.SwapUsagePeak, 2))
+			memoryInfo += fmt.Sprintf("    %s: %s\n", i18n.G("Swap (peak)"), units.GetByteSizeString(cs.Memory.SwapUsagePeak, 2))
 		}
 
 		if memoryInfo != "" {
@@ -307,8 +308,8 @@ func (c *cmdInfo) containerInfo(d lxd.ContainerServer, remote config.Remote, nam
 		if cs.Network != nil {
 			for netName, net := range cs.Network {
 				networkInfo += fmt.Sprintf("    %s:\n", netName)
-				networkInfo += fmt.Sprintf("      %s: %s\n", i18n.G("Bytes received"), shared.GetByteSizeString(net.Counters.BytesReceived, 2))
-				networkInfo += fmt.Sprintf("      %s: %s\n", i18n.G("Bytes sent"), shared.GetByteSizeString(net.Counters.BytesSent, 2))
+				networkInfo += fmt.Sprintf("      %s: %s\n", i18n.G("Bytes received"), units.GetByteSizeString(net.Counters.BytesReceived, 2))
+				networkInfo += fmt.Sprintf("      %s: %s\n", i18n.G("Bytes sent"), units.GetByteSizeString(net.Counters.BytesSent, 2))
 				networkInfo += fmt.Sprintf("      %s: %d\n", i18n.G("Packets received"), net.Counters.PacketsReceived)
 				networkInfo += fmt.Sprintf("      %s: %d\n", i18n.G("Packets sent"), net.Counters.PacketsSent)
 			}
diff --git a/lxc/network.go b/lxc/network.go
index 4111346962..fc130590e7 100644
--- a/lxc/network.go
+++ b/lxc/network.go
@@ -18,6 +18,7 @@ import (
 	cli "github.com/lxc/lxd/shared/cmd"
 	"github.com/lxc/lxd/shared/i18n"
 	"github.com/lxc/lxd/shared/termios"
+	"github.com/lxc/lxd/shared/units"
 )
 
 type cmdNetwork struct {
@@ -784,8 +785,8 @@ func (c *cmdNetworkInfo) Run(cmd *cobra.Command, args []string) error {
 	// Network usage
 	fmt.Println("")
 	fmt.Println(i18n.G("Network usage:"))
-	fmt.Printf("  %s: %s\n", i18n.G("Bytes received"), shared.GetByteSizeString(state.Counters.BytesReceived, 2))
-	fmt.Printf("  %s: %s\n", i18n.G("Bytes sent"), shared.GetByteSizeString(state.Counters.BytesSent, 2))
+	fmt.Printf("  %s: %s\n", i18n.G("Bytes received"), units.GetByteSizeString(state.Counters.BytesReceived, 2))
+	fmt.Printf("  %s: %s\n", i18n.G("Bytes sent"), units.GetByteSizeString(state.Counters.BytesSent, 2))
 	fmt.Printf("  %s: %d\n", i18n.G("Packets received"), state.Counters.PacketsReceived)
 	fmt.Printf("  %s: %d\n", i18n.G("Packets sent"), state.Counters.PacketsSent)
 
diff --git a/lxc/storage.go b/lxc/storage.go
index 0dc7e42a30..ef0e8cacdd 100644
--- a/lxc/storage.go
+++ b/lxc/storage.go
@@ -17,6 +17,7 @@ import (
 	cli "github.com/lxc/lxd/shared/cmd"
 	"github.com/lxc/lxd/shared/i18n"
 	"github.com/lxc/lxd/shared/termios"
+	"github.com/lxc/lxd/shared/units"
 )
 
 type cmdStorage struct {
@@ -471,8 +472,8 @@ func (c *cmdStorageInfo) Run(cmd *cobra.Command, args []string) error {
 		poolinfo[infostring][totalspacestring] = strconv.FormatUint(res.Space.Total, 10)
 		poolinfo[infostring][spaceusedstring] = strconv.FormatUint(res.Space.Used, 10)
 	} else {
-		poolinfo[infostring][totalspacestring] = shared.GetByteSizeString(int64(res.Space.Total), 2)
-		poolinfo[infostring][spaceusedstring] = shared.GetByteSizeString(int64(res.Space.Used), 2)
+		poolinfo[infostring][totalspacestring] = units.GetByteSizeString(int64(res.Space.Total), 2)
+		poolinfo[infostring][spaceusedstring] = units.GetByteSizeString(int64(res.Space.Used), 2)
 	}
 
 	poolinfodata, err := yaml.Marshal(poolinfo)

From daa6750bbcefa1ed5c11ed9933e9037ade8744d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 2 Jul 2019 14:09:48 -0400
Subject: [PATCH 5/6] shared: Move to units package
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>
---
 shared/container.go  |  4 +++-
 shared/util.go       | 11 ++++++-----
 shared/util_linux.go |  6 ++++--
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/shared/container.go b/shared/container.go
index d46ea943e1..51e13308f0 100644
--- a/shared/container.go
+++ b/shared/container.go
@@ -9,6 +9,8 @@ import (
 
 	"github.com/pkg/errors"
 	"gopkg.in/robfig/cron.v2"
+
+	"github.com/lxc/lxd/shared/units"
 )
 
 type ContainerAction string
@@ -223,7 +225,7 @@ var KnownContainerConfigKeys = map[string]func(value string) error{
 			return nil
 		}
 
-		_, err := ParseByteSizeString(value)
+		_, err := units.ParseByteSizeString(value)
 		if err != nil {
 			return err
 		}
diff --git a/shared/util.go b/shared/util.go
index b57dc9e139..d833d4e7f4 100644
--- a/shared/util.go
+++ b/shared/util.go
@@ -29,6 +29,7 @@ import (
 
 	"github.com/lxc/lxd/shared/cancel"
 	"github.com/lxc/lxd/shared/ioprogress"
+	"github.com/lxc/lxd/shared/units"
 )
 
 const SnapshotDelimiter = "/"
@@ -882,11 +883,11 @@ func SetProgressMetadata(metadata map[string]interface{}, stage, displayPrefix s
 
 	// <stage>_progress with formatted text sent for lxc cli.
 	if percent > 0 {
-		metadata[stage+"_progress"] = fmt.Sprintf("%s: %d%% (%s/s)", displayPrefix, percent, GetByteSizeString(speed, 2))
+		metadata[stage+"_progress"] = fmt.Sprintf("%s: %d%% (%s/s)", displayPrefix, percent, units.GetByteSizeString(speed, 2))
 	} else if processed > 0 {
-		metadata[stage+"_progress"] = fmt.Sprintf("%s: %s (%s/s)", displayPrefix, GetByteSizeString(processed, 2), GetByteSizeString(speed, 2))
+		metadata[stage+"_progress"] = fmt.Sprintf("%s: %s (%s/s)", displayPrefix, units.GetByteSizeString(processed, 2), units.GetByteSizeString(speed, 2))
 	} else {
-		metadata[stage+"_progress"] = fmt.Sprintf("%s: %s/s", displayPrefix, GetByteSizeString(speed, 2))
+		metadata[stage+"_progress"] = fmt.Sprintf("%s: %s/s", displayPrefix, units.GetByteSizeString(speed, 2))
 	}
 }
 
@@ -925,9 +926,9 @@ func DownloadFileHash(httpClient *http.Client, useragent string, progress func(p
 				Length: r.ContentLength,
 				Handler: func(percent int64, speed int64) {
 					if filename != "" {
-						progress(ioprogress.ProgressData{Text: fmt.Sprintf("%s: %d%% (%s/s)", filename, percent, GetByteSizeString(speed, 2))})
+						progress(ioprogress.ProgressData{Text: fmt.Sprintf("%s: %d%% (%s/s)", filename, percent, units.GetByteSizeString(speed, 2))})
 					} else {
-						progress(ioprogress.ProgressData{Text: fmt.Sprintf("%d%% (%s/s)", percent, GetByteSizeString(speed, 2))})
+						progress(ioprogress.ProgressData{Text: fmt.Sprintf("%d%% (%s/s)", percent, units.GetByteSizeString(speed, 2))})
 					}
 				},
 			},
diff --git a/shared/util_linux.go b/shared/util_linux.go
index c0b949c166..18d57938b0 100644
--- a/shared/util_linux.go
+++ b/shared/util_linux.go
@@ -13,6 +13,8 @@ import (
 	"unsafe"
 
 	"golang.org/x/sys/unix"
+
+	"github.com/lxc/lxd/shared/units"
 )
 
 // --- pure Go functions ---
@@ -380,8 +382,8 @@ func DeviceTotalMemory() (int64, error) {
 		fields := strings.Split(line, " ")
 		value := fields[len(fields)-2] + fields[len(fields)-1]
 
-		// Feed the result to shared.ParseByteSizeString to get an int value
-		valueBytes, err := ParseByteSizeString(value)
+		// Feed the result to units.ParseByteSizeString to get an int value
+		valueBytes, err := units.ParseByteSizeString(value)
 		if err != nil {
 			return -1, err
 		}

From b9dfa4f999d0f2fc3624036e605b6e75ed27c679 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 2 Jul 2019 14:11:21 -0400
Subject: [PATCH 6/6] lxd: Move to units package
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>
---
 lxd/container.go              |  5 +++--
 lxd/container_lxc.go          | 13 +++++++------
 lxd/daemon_images.go          |  3 ++-
 lxd/db/node/update.go         |  8 +++++---
 lxd/devices.go                |  3 ++-
 lxd/storage.go                |  5 +++--
 lxd/storage_btrfs.go          |  7 ++++---
 lxd/storage_ceph.go           | 13 +++++++------
 lxd/storage_ceph_utils.go     |  5 +++--
 lxd/storage_cephfs.go         |  3 ++-
 lxd/storage_dir.go            |  3 ++-
 lxd/storage_lvm.go            | 11 ++++++-----
 lxd/storage_lvm_utils.go      | 19 ++++++++++---------
 lxd/storage_pools_config.go   | 13 +++++++------
 lxd/storage_volumes_config.go |  5 +++--
 lxd/storage_zfs.go            |  9 +++++----
 16 files changed, 71 insertions(+), 54 deletions(-)

diff --git a/lxd/container.go b/lxd/container.go
index 29e4d06b1d..c01437f8f0 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -10,6 +10,7 @@ import (
 	"strings"
 	"time"
 
+	"github.com/pkg/errors"
 	"golang.org/x/net/context"
 	"gopkg.in/lxc/go-lxc.v2"
 	"gopkg.in/robfig/cron.v2"
@@ -29,7 +30,7 @@ import (
 	log "github.com/lxc/lxd/shared/log15"
 	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/osarch"
-	"github.com/pkg/errors"
+	"github.com/lxc/lxd/shared/units"
 )
 
 // Helper functions
@@ -1382,7 +1383,7 @@ func containerConfigureInternal(c container) error {
 				return err
 			}
 		} else {
-			size, err := shared.ParseByteSizeString(rootDiskDevice["size"])
+			size, err := units.ParseByteSizeString(rootDiskDevice["size"])
 			if err != nil {
 				return err
 			}
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 031e74d350..548af40a38 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -42,6 +42,7 @@ import (
 	"github.com/lxc/lxd/shared/logger"
 	"github.com/lxc/lxd/shared/netutils"
 	"github.com/lxc/lxd/shared/osarch"
+	"github.com/lxc/lxd/shared/units"
 
 	log "github.com/lxc/lxd/shared/log15"
 )
@@ -1401,7 +1402,7 @@ func (c *containerLXC) initLXC(config bool) error {
 
 				valueInt = int64((memoryTotal / 100) * percent)
 			} else {
-				valueInt, err = shared.ParseByteSizeString(memory)
+				valueInt, err = units.ParseByteSizeString(memory)
 				if err != nil {
 					return err
 				}
@@ -2172,7 +2173,7 @@ func (c *containerLXC) startCommon() (string, error) {
 			return "", errors.Wrap(err, "Initialize storage")
 		}
 
-		size, err := shared.ParseByteSizeString(newSize)
+		size, err := units.ParseByteSizeString(newSize)
 		if err != nil {
 			return "", err
 		}
@@ -5053,7 +5054,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
 		if (storageTypeName == "lvm" || storageTypeName == "ceph") && isRunning || !storageIsReady {
 			c.localConfig["volatile.apply_quota"] = newRootDiskDeviceSize
 		} else {
-			size, err := shared.ParseByteSizeString(newRootDiskDeviceSize)
+			size, err := units.ParseByteSizeString(newRootDiskDeviceSize)
 			if err != nil {
 				return err
 			}
@@ -5169,7 +5170,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
 
 					memory = fmt.Sprintf("%d", int64((memoryTotal/100)*percent))
 				} else {
-					valueInt, err := shared.ParseByteSizeString(memory)
+					valueInt, err := units.ParseByteSizeString(memory)
 					if err != nil {
 						return err
 					}
@@ -9575,7 +9576,7 @@ func (c *containerLXC) setNetworkLimits(m types.Device) error {
 	// Parse the values
 	var ingressInt int64
 	if m["limits.ingress"] != "" {
-		ingressInt, err = shared.ParseBitSizeString(m["limits.ingress"])
+		ingressInt, err = units.ParseBitSizeString(m["limits.ingress"])
 		if err != nil {
 			return err
 		}
@@ -9583,7 +9584,7 @@ func (c *containerLXC) setNetworkLimits(m types.Device) error {
 
 	var egressInt int64
 	if m["limits.egress"] != "" {
-		egressInt, err = shared.ParseBitSizeString(m["limits.egress"])
+		egressInt, err = units.ParseBitSizeString(m["limits.egress"])
 		if err != nil {
 			return err
 		}
diff --git a/lxd/daemon_images.go b/lxd/daemon_images.go
index cc2db2b25c..1ca912dfd7 100644
--- a/lxd/daemon_images.go
+++ b/lxd/daemon_images.go
@@ -24,6 +24,7 @@ import (
 	"github.com/lxc/lxd/shared/cancel"
 	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/units"
 	"github.com/lxc/lxd/shared/version"
 
 	log "github.com/lxc/lxd/shared/log15"
@@ -488,7 +489,7 @@ func (d *Daemon) ImageDownload(op *operation, server string, protocol string, ce
 			Tracker: &ioprogress.ProgressTracker{
 				Length: raw.ContentLength,
 				Handler: func(percent int64, speed int64) {
-					progress(ioprogress.ProgressData{Text: fmt.Sprintf("%d%% (%s/s)", percent, shared.GetByteSizeString(speed, 2))})
+					progress(ioprogress.ProgressData{Text: fmt.Sprintf("%d%% (%s/s)", percent, units.GetByteSizeString(speed, 2))})
 				},
 			},
 		}
diff --git a/lxd/db/node/update.go b/lxd/db/node/update.go
index aeb23b25ee..5451ae4ddd 100644
--- a/lxd/db/node/update.go
+++ b/lxd/db/node/update.go
@@ -8,11 +8,13 @@ import (
 	"strconv"
 	"strings"
 
+	"github.com/pkg/errors"
+
 	"github.com/lxc/lxd/lxd/db/query"
 	"github.com/lxc/lxd/lxd/db/schema"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
-	"github.com/pkg/errors"
+	"github.com/lxc/lxd/shared/units"
 )
 
 // Schema for the local database.
@@ -408,7 +410,7 @@ func updateFromV18(tx *sql.Tx) error {
 		value += "B"
 
 		// Deal with completely broken values
-		_, err = shared.ParseByteSizeString(value)
+		_, err = units.ParseByteSizeString(value)
 		if err != nil {
 			logger.Debugf("Invalid container memory limit, id=%d value=%s, removing", id, value)
 			_, err = tx.Exec("DELETE FROM containers_config WHERE id=?;", id)
@@ -453,7 +455,7 @@ func updateFromV18(tx *sql.Tx) error {
 		value += "B"
 
 		// Deal with completely broken values
-		_, err = shared.ParseByteSizeString(value)
+		_, err = units.ParseByteSizeString(value)
 		if err != nil {
 			logger.Debugf("Invalid profile memory limit, id=%d value=%s, removing", id, value)
 			_, err = tx.Exec("DELETE FROM profiles_config WHERE id=?;", id)
diff --git a/lxd/devices.go b/lxd/devices.go
index b7490635f9..10d00f6e07 100644
--- a/lxd/devices.go
+++ b/lxd/devices.go
@@ -28,6 +28,7 @@ import (
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/units"
 
 	log "github.com/lxc/lxd/shared/log15"
 )
@@ -1477,7 +1478,7 @@ func deviceParseDiskLimit(readSpeed string, writeSpeed string) (int64, int64, in
 				return -1, -1, err
 			}
 		} else {
-			bps, err = shared.ParseByteSizeString(value)
+			bps, err = units.ParseByteSizeString(value)
 			if err != nil {
 				return -1, -1, err
 			}
diff --git a/lxd/storage.go b/lxd/storage.go
index e67d3ee9db..eeee787303 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -19,6 +19,7 @@ import (
 	"github.com/lxc/lxd/shared/idmap"
 	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/units"
 	"github.com/lxc/lxd/shared/version"
 )
 
@@ -815,9 +816,9 @@ func progressWrapperRender(op *operation, key string, description string, progre
 		meta = make(map[string]interface{})
 	}
 
-	progress := fmt.Sprintf("%s (%s/s)", shared.GetByteSizeString(progressInt, 2), shared.GetByteSizeString(speedInt, 2))
+	progress := fmt.Sprintf("%s (%s/s)", units.GetByteSizeString(progressInt, 2), units.GetByteSizeString(speedInt, 2))
 	if description != "" {
-		progress = fmt.Sprintf("%s: %s (%s/s)", description, shared.GetByteSizeString(progressInt, 2), shared.GetByteSizeString(speedInt, 2))
+		progress = fmt.Sprintf("%s: %s (%s/s)", description, units.GetByteSizeString(progressInt, 2), units.GetByteSizeString(speedInt, 2))
 	}
 
 	if meta[key] != progress {
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 3c74393d9a..12cca23881 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -23,6 +23,7 @@ import (
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/units"
 )
 
 type storageBtrfs struct {
@@ -145,7 +146,7 @@ func (s *storageBtrfs) StoragePoolCreate() error {
 			return fmt.Errorf("Failed to chmod %s: %s", source, err)
 		}
 
-		size, err := shared.ParseByteSizeString(s.pool.Config["size"])
+		size, err := units.ParseByteSizeString(s.pool.Config["size"])
 		if err != nil {
 			return err
 		}
@@ -590,7 +591,7 @@ func (s *storageBtrfs) StoragePoolVolumeCreate() error {
 
 	// apply quota
 	if s.volume.Config["size"] != "" {
-		size, err := shared.ParseByteSizeString(s.volume.Config["size"])
+		size, err := units.ParseByteSizeString(s.volume.Config["size"])
 		if err != nil {
 			return err
 		}
@@ -724,7 +725,7 @@ func (s *storageBtrfs) StoragePoolVolumeUpdate(writable *api.StorageVolumePut, c
 		}
 
 		if s.volume.Config["size"] != writable.Config["size"] {
-			size, err := shared.ParseByteSizeString(writable.Config["size"])
+			size, err := units.ParseByteSizeString(writable.Config["size"])
 			if err != nil {
 				return err
 			}
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index be45ba899a..438d7bdca5 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -19,6 +19,7 @@ import (
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/units"
 )
 
 type storageCeph struct {
@@ -83,7 +84,7 @@ func (s *storageCeph) StoragePoolInit() error {
 
 	// set default placement group number
 	if s.pool.Config["ceph.osd.pg_num"] != "" {
-		_, err = shared.ParseByteSizeString(s.pool.Config["ceph.osd.pg_num"])
+		_, err = units.ParseByteSizeString(s.pool.Config["ceph.osd.pg_num"])
 		if err != nil {
 			return err
 		}
@@ -420,7 +421,7 @@ func (s *storageCeph) StoragePoolVolumeCreate() error {
 
 	// Apply quota
 	if s.volume.Config["size"] != "" {
-		size, err := shared.ParseByteSizeString(s.volume.Config["size"])
+		size, err := units.ParseByteSizeString(s.volume.Config["size"])
 		if err != nil {
 			return err
 		}
@@ -672,7 +673,7 @@ func (s *storageCeph) StoragePoolVolumeUpdate(writable *api.StorageVolumePut, ch
 		}
 
 		if s.volume.Config["size"] != writable.Config["size"] {
-			size, err := shared.ParseByteSizeString(writable.Config["size"])
+			size, err := units.ParseByteSizeString(writable.Config["size"])
 			if err != nil {
 				return err
 			}
@@ -937,7 +938,7 @@ func (s *storageCeph) ContainerCreateFromImage(container container, fingerprint
 	}
 
 	if s.volume.Config["size"] != "" && imageVol.Config["size"] != s.volume.Config["size"] {
-		size, err := shared.ParseByteSizeString(s.volume.Config["size"])
+		size, err := units.ParseByteSizeString(s.volume.Config["size"])
 		if err != nil {
 			return err
 		}
@@ -2455,7 +2456,7 @@ func (s *storageCeph) StorageEntitySetQuota(volumeType int, size int64, data int
 		return fmt.Errorf("Failed to get mapped RBD path")
 	}
 
-	oldSize, err := shared.ParseByteSizeString(s.volume.Config["size"])
+	oldSize, err := units.ParseByteSizeString(s.volume.Config["size"])
 	if err != nil {
 		return err
 	}
@@ -2478,7 +2479,7 @@ func (s *storageCeph) StorageEntitySetQuota(volumeType int, size int64, data int
 	}
 
 	// Update the database
-	s.volume.Config["size"] = shared.GetByteSizeString(size, 0)
+	s.volume.Config["size"] = units.GetByteSizeString(size, 0)
 	err = s.s.Cluster.StoragePoolVolumeUpdate(
 		s.volume.Name,
 		volumeType,
diff --git a/lxd/storage_ceph_utils.go b/lxd/storage_ceph_utils.go
index 742f8eca15..4f6b3cf9e3 100644
--- a/lxd/storage_ceph_utils.go
+++ b/lxd/storage_ceph_utils.go
@@ -17,6 +17,7 @@ import (
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/units"
 )
 
 // cephOSDPoolExists checks whether a given OSD pool exists.
@@ -657,14 +658,14 @@ func cephRBDVolumeRestore(clusterName string, poolName string, volumeName string
 // getRBDSize returns the size the RBD storage volume is supposed to be created
 // with
 func (s *storageCeph) getRBDSize() (string, error) {
-	sz, err := shared.ParseByteSizeString(s.volume.Config["size"])
+	sz, err := units.ParseByteSizeString(s.volume.Config["size"])
 	if err != nil {
 		return "", err
 	}
 
 	// Safety net: Set to default value.
 	if sz == 0 {
-		sz, _ = shared.ParseByteSizeString("10GB")
+		sz, _ = units.ParseByteSizeString("10GB")
 	}
 
 	return fmt.Sprintf("%dB", sz), nil
diff --git a/lxd/storage_cephfs.go b/lxd/storage_cephfs.go
index 0df8639939..49ab66008c 100644
--- a/lxd/storage_cephfs.go
+++ b/lxd/storage_cephfs.go
@@ -19,6 +19,7 @@ import (
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/units"
 )
 
 type storageCephFs struct {
@@ -533,7 +534,7 @@ func (s *storageCephFs) StoragePoolVolumeUpdate(writable *api.StorageVolumePut,
 		}
 
 		if s.volume.Config["size"] != writable.Config["size"] {
-			size, err := shared.ParseByteSizeString(writable.Config["size"])
+			size, err := units.ParseByteSizeString(writable.Config["size"])
 			if err != nil {
 				return err
 			}
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 7f22b46fcb..992f67acb3 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -19,6 +19,7 @@ import (
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/units"
 )
 
 type storageDir struct {
@@ -454,7 +455,7 @@ func (s *storageDir) StoragePoolVolumeUpdate(writable *api.StorageVolumePut, cha
 		}
 
 		if s.volume.Config["size"] != writable.Config["size"] {
-			size, err := shared.ParseByteSizeString(writable.Config["size"])
+			size, err := units.ParseByteSizeString(writable.Config["size"])
 			if err != nil {
 				return err
 			}
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index a9e3884313..2a6d6ac3fa 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -19,6 +19,7 @@ import (
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/units"
 )
 
 type storageLvm struct {
@@ -167,7 +168,7 @@ func (s *storageLvm) StoragePoolCreate() error {
 			return fmt.Errorf("Failed to chmod %s: %s", source, err)
 		}
 
-		size, err := shared.ParseByteSizeString(s.pool.Config["size"])
+		size, err := units.ParseByteSizeString(s.pool.Config["size"])
 		if err != nil {
 			return err
 		}
@@ -520,7 +521,7 @@ func (s *storageLvm) StoragePoolVolumeCreate() error {
 
 	// apply quota
 	if s.volume.Config["size"] != "" {
-		size, err := shared.ParseByteSizeString(s.volume.Config["size"])
+		size, err := units.ParseByteSizeString(s.volume.Config["size"])
 		if err != nil {
 			return err
 		}
@@ -867,7 +868,7 @@ func (s *storageLvm) StoragePoolVolumeUpdate(writable *api.StorageVolumePut,
 		}
 
 		if s.volume.Config["size"] != writable.Config["size"] {
-			size, err := shared.ParseByteSizeString(writable.Config["size"])
+			size, err := units.ParseByteSizeString(writable.Config["size"])
 			if err != nil {
 				return err
 			}
@@ -2123,7 +2124,7 @@ func (s *storageLvm) StorageEntitySetQuota(volumeType int, size int64, data inte
 		mountpoint = getStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
 	}
 
-	oldSize, err := shared.ParseByteSizeString(s.volume.Config["size"])
+	oldSize, err := units.ParseByteSizeString(s.volume.Config["size"])
 	if err != nil {
 		return err
 	}
@@ -2144,7 +2145,7 @@ func (s *storageLvm) StorageEntitySetQuota(volumeType int, size int64, data inte
 	}
 
 	// Update the database
-	s.volume.Config["size"] = shared.GetByteSizeString(size, 0)
+	s.volume.Config["size"] = units.GetByteSizeString(size, 0)
 	err = s.s.Cluster.StoragePoolVolumeUpdate(
 		s.volume.Name,
 		volumeType,
diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go
index 6edcd75f0e..b33e8e5477 100644
--- a/lxd/storage_lvm_utils.go
+++ b/lxd/storage_lvm_utils.go
@@ -15,13 +15,14 @@ import (
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/units"
 	"github.com/lxc/lxd/shared/version"
 )
 
 func (s *storageLvm) lvExtend(lvPath string, lvSize int64, fsType string, fsMntPoint string, volumeType int, data interface{}) error {
 	// Round the size to closest 512 bytes
 	lvSize = int64(lvSize/512) * 512
-	lvSizeString := shared.GetByteSizeString(lvSize, 0)
+	lvSizeString := units.GetByteSizeString(lvSize, 0)
 
 	msg, err := shared.TryRunCommand(
 		"lvextend",
@@ -65,7 +66,7 @@ func (s *storageLvm) lvReduce(lvPath string, lvSize int64, fsType string, fsMntP
 
 	// Round the size to closest 512 bytes
 	lvSize = int64(lvSize/512) * 512
-	lvSizeString := shared.GetByteSizeString(lvSize, 0)
+	lvSizeString := units.GetByteSizeString(lvSize, 0)
 
 	cleanupFunc, err := shrinkVolumeFilesystem(s, volumeType, fsType, lvPath, fsMntPoint, lvSize, data)
 	if cleanupFunc != nil {
@@ -118,14 +119,14 @@ func (s *storageLvm) getLvmFilesystem() string {
 }
 
 func (s *storageLvm) getLvmVolumeSize() (string, error) {
-	sz, err := shared.ParseByteSizeString(s.volume.Config["size"])
+	sz, err := units.ParseByteSizeString(s.volume.Config["size"])
 	if err != nil {
 		return "", err
 	}
 
 	// Safety net: Set to default value.
 	if sz == 0 {
-		sz, _ = shared.ParseByteSizeString("10GB")
+		sz, _ = units.ParseByteSizeString("10GB")
 	}
 
 	return fmt.Sprintf("%d", sz), nil
@@ -215,13 +216,13 @@ func (s *storageLvm) createSnapshotLV(project, vgName string, origLvName string,
 		}
 
 		// Round the size to closest 512 bytes
-		lvSizeInt, err := shared.ParseByteSizeString(lvSize)
+		lvSizeInt, err := units.ParseByteSizeString(lvSize)
 		if err != nil {
 			return "", err
 		}
 
 		lvSizeInt = int64(lvSizeInt/512) * 512
-		lvSizeString := shared.GetByteSizeString(lvSizeInt, 0)
+		lvSizeString := units.GetByteSizeString(lvSizeInt, 0)
 
 		args = append(args, "--size", lvSizeString)
 	}
@@ -684,7 +685,7 @@ func lvmGetLVSize(lvPath string) (string, error) {
 		return "", err
 	}
 
-	detectedSize := shared.GetByteSizeString(size, 0)
+	detectedSize := units.GetByteSizeString(size, 0)
 
 	return detectedSize, nil
 }
@@ -829,13 +830,13 @@ func lvmCreateLv(project, vgName string, thinPoolName string, lvName string, lvF
 	var err error
 
 	// Round the size to closest 512 bytes
-	lvSizeInt, err := shared.ParseByteSizeString(lvSize)
+	lvSizeInt, err := units.ParseByteSizeString(lvSize)
 	if err != nil {
 		return err
 	}
 
 	lvSizeInt = int64(lvSizeInt/512) * 512
-	lvSizeString := shared.GetByteSizeString(lvSizeInt, 0)
+	lvSizeString := units.GetByteSizeString(lvSizeInt, 0)
 
 	lvmPoolVolumeName := getPrefixedLvName(project, volumeType, lvName)
 	if makeThinLv {
diff --git a/lxd/storage_pools_config.go b/lxd/storage_pools_config.go
index 7264e0432c..b44f0659df 100644
--- a/lxd/storage_pools_config.go
+++ b/lxd/storage_pools_config.go
@@ -8,6 +8,7 @@ import (
 	"golang.org/x/sys/unix"
 
 	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/shared/units"
 )
 
 func updateStoragePoolError(unchangeable []string, driverName string) error {
@@ -62,7 +63,7 @@ var storagePoolConfigKeys = map[string]func(value string) error{
 			return nil
 		}
 
-		_, err := shared.ParseByteSizeString(value)
+		_, err := units.ParseByteSizeString(value)
 		return err
 	},
 	"ceph.rbd.clone_copy": shared.IsBool,
@@ -84,7 +85,7 @@ var storagePoolConfigKeys = map[string]func(value string) error{
 			return nil
 		}
 
-		_, err := shared.ParseByteSizeString(value)
+		_, err := units.ParseByteSizeString(value)
 		return err
 	},
 
@@ -111,7 +112,7 @@ var storagePoolConfigKeys = map[string]func(value string) error{
 			return nil
 		}
 
-		_, err := shared.ParseByteSizeString(value)
+		_, err := units.ParseByteSizeString(value)
 		return err
 	},
 
@@ -142,7 +143,7 @@ func storagePoolValidateConfig(name string, driver string, config map[string]str
 
 	v, ok := config["rsync.bwlimit"]
 	if ok && v != "" {
-		_, err := shared.ParseByteSizeString(v)
+		_, err := units.ParseByteSizeString(v)
 		if err != nil {
 			return err
 		}
@@ -225,7 +226,7 @@ func storagePoolFillDefault(name string, driver string, config map[string]string
 			}
 			config["size"] = strconv.FormatUint(uint64(size), 10) + "GB"
 		} else {
-			_, err := shared.ParseByteSizeString(config["size"])
+			_, err := units.ParseByteSizeString(config["size"])
 			if err != nil {
 				return err
 			}
@@ -247,7 +248,7 @@ func storagePoolFillDefault(name string, driver string, config map[string]string
 
 	if driver == "btrfs" || driver == "ceph" || driver == "cephfs" || driver == "lvm" || driver == "zfs" {
 		if config["volume.size"] != "" {
-			_, err := shared.ParseByteSizeString(config["volume.size"])
+			_, err := units.ParseByteSizeString(config["volume.size"])
 			if err != nil {
 				return err
 			}
diff --git a/lxd/storage_volumes_config.go b/lxd/storage_volumes_config.go
index 38054940c9..792b8a0b0d 100644
--- a/lxd/storage_volumes_config.go
+++ b/lxd/storage_volumes_config.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/api"
+	"github.com/lxc/lxd/shared/units"
 )
 
 func storageVolumePropertiesTranslate(targetConfig map[string]string, targetParentPoolDriver string) (map[string]string, error) {
@@ -101,7 +102,7 @@ var storageVolumeConfigKeys = map[string]func(value string) ([]string, error){
 			return []string{"btrfs", "ceph", "cephfs", "lvm", "zfs"}, nil
 		}
 
-		_, err := shared.ParseByteSizeString(value)
+		_, err := units.ParseByteSizeString(value)
 		if err != nil {
 			return nil, err
 		}
@@ -205,7 +206,7 @@ func storageVolumeFillDefault(name string, config map[string]string, parentPool
 		}
 	} else {
 		if config["size"] != "" {
-			_, err := shared.ParseByteSizeString(config["size"])
+			_, err := units.ParseByteSizeString(config["size"])
 			if err != nil {
 				return err
 			}
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 94abebb942..2998061f31 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -21,6 +21,7 @@ import (
 	"github.com/lxc/lxd/shared/api"
 	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logger"
+	"github.com/lxc/lxd/shared/units"
 
 	"github.com/pborman/uuid"
 )
@@ -184,7 +185,7 @@ func (s *storageZfs) zfsPoolCreate() error {
 			return fmt.Errorf("Failed to chmod %s: %s", vdev, err)
 		}
 
-		size, err := shared.ParseByteSizeString(s.pool.Config["size"])
+		size, err := units.ParseByteSizeString(s.pool.Config["size"])
 		if err != nil {
 			return err
 		}
@@ -441,7 +442,7 @@ func (s *storageZfs) StoragePoolVolumeCreate() error {
 
 	// apply quota
 	if s.volume.Config["size"] != "" {
-		size, err := shared.ParseByteSizeString(s.volume.Config["size"])
+		size, err := units.ParseByteSizeString(s.volume.Config["size"])
 		if err != nil {
 			return err
 		}
@@ -719,7 +720,7 @@ func (s *storageZfs) StoragePoolVolumeUpdate(writable *api.StorageVolumePut, cha
 		}
 
 		if s.volume.Config["size"] != writable.Config["size"] {
-			size, err := shared.ParseByteSizeString(writable.Config["size"])
+			size, err := units.ParseByteSizeString(writable.Config["size"])
 			if err != nil {
 				return err
 			}
@@ -3346,7 +3347,7 @@ func (s *storageZfs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) erro
 
 	// apply quota
 	if s.volume.Config["size"] != "" {
-		size, err := shared.ParseByteSizeString(s.volume.Config["size"])
+		size, err := units.ParseByteSizeString(s.volume.Config["size"])
 		if err != nil {
 			return err
 		}


More information about the lxc-devel mailing list