1
0
mirror of https://github.com/gluster/glusterd2.git synced 2026-02-05 21:45:43 +01:00
Files
glusterd2/glustercli/cmd/utils.go
Madhu Rajanna c198e1173b add regex for different volume size format
we should be able to create volume size with
different formats like KB, Kib, Mb, MiB etc

Fixes: #1398

```
[root@dhcp43-209 build]# ./glustercli volume create size1 --size=20MB --replica=3 -v
size1 Volume created successfully
Volume ID:  b2693574-8489-4d4b-94ab-3564776d1cce

[root@dhcp43-209 build]# ./glustercli volume create size2 --size=20MiB --replica=3 -v
size2 Volume created successfully
Volume ID:  b1153478-4912-4481-a047-8d67258ab08c

[root@dhcp43-209 build]# ./glustercli volume create size3 --size=20M --replica=3 -v
size3 Volume created successfully
Volume ID:  8ac1c9a5-cc84-45ec-b382-eff17369d024

[root@dhcp43-209 build]# ./glustercli volume create size35 --size=20 --replica=3 -v
size35 Volume created successfully
Volume ID:  560da74f-b7cf-466c-994c-0f03ba07bb24

[root@dhcp43-209 build]# ./glustercli volume create size --size=21mb --replica=3 -v
7size Volume created successfully
Volume ID:  638d4108-bf2e-48e9-9d1d-982a34882586

[root@dhcp43-209 build]# ./glustercli volume create sizes6 --size=20971520 --replica=3 -v
sizes6 Volume created successfully
Volume ID:  c4de7f7e-e4b4-46e6-80d1-92a9e060c4c0

[root@dhcp43-209 build]# ./glustercli volume create size6 --size=20971520sadf --replica=3 -v
Invalid Volume Size specified
```

Signed-off-by: Madhu Rajanna <mrajanna@redhat.com>
2018-12-17 18:03:23 +05:30

118 lines
2.5 KiB
Go

package cmd
import (
"errors"
"fmt"
"math"
"regexp"
"strconv"
"strings"
"github.com/gluster/glusterd2/pkg/utils"
)
var (
validSizeFormat = regexp.MustCompile(`^([0-9]+)\s*([kKmMgGtT]?[iI]?[bB]?)$`)
)
func formatBoolYesNo(value bool) string {
if value == true {
return "yes"
}
return "no"
}
func formatPID(pid int) string {
if pid == 0 {
return ""
}
return strconv.Itoa(pid)
}
func sizeToBytes(value string) (uint64, error) {
if value == "" {
return 0, nil
}
sizeParts := validSizeFormat.FindStringSubmatch(value)
if len(sizeParts) == 0 {
return 0, errors.New("invalid size format")
}
// If Size unit is specified as M/K/G/T, Default Size unit is bytes
var sizeUnit string
if len(sizeParts) == 3 {
sizeUnit = sizeParts[2]
}
sizeValue, err := strconv.ParseUint(sizeParts[1], 10, 64)
if err != nil {
return 0, err
}
var size uint64
switch strings.ToLower(sizeUnit) {
case "k", "kib":
size = sizeValue * utils.KiB
case "kb":
size = sizeValue * utils.KB
case "m", "mib":
size = sizeValue * utils.MiB
case "mb":
size = sizeValue * utils.MB
case "g", "gib":
size = sizeValue * utils.GiB
case "gb":
size = sizeValue * utils.GB
case "t", "tib":
size = sizeValue * utils.TiB
case "tb":
size = sizeValue * utils.TB
case "b", "":
size = sizeValue
default:
return 0, fmt.Errorf("invalid size unit specified %s", sizeUnit)
}
return size, nil
}
// logn is used to find the unit size the given bytes belongs to.
// 1024 will return 1
// 1048576 will return 2 and so on
func logn(n, b float64) float64 {
return math.Log(n) / math.Log(b)
}
// humanReadable converts size given in bytes into a more human readable unit
//
// humanReadable(1024) returns 1.0 KiB
// humanReadable(1536) returns 1.5 KiB
// humanReadable(1048576) returns 1.0 MiB
func humanReadable(value uint64) string {
units := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}
// If less than 1024 we return it as such
if value < 1024 {
return fmt.Sprintf("%.1f B", float64(value))
}
e := math.Floor(logn(float64(value), 1024))
suffix := units[int(e)]
size := math.Floor(float64(value)/math.Pow(1024, e)*10+0.5) / 10
return fmt.Sprintf("%.1f %s", size, suffix)
}
func readString(prompt string, args ...interface{}) string {
var s string
fmt.Printf(prompt, args...)
fmt.Scanln(&s)
return s
}
// PromptConfirm prompts for confirmation
func PromptConfirm(prompt string, args ...interface{}) bool {
switch strings.ToLower(readString(prompt, args...)) {
case "yes", "y":
return true
default:
return false
}
}