mirror of
https://github.com/gluster/glusterd2.git
synced 2026-02-05 21:45:43 +01:00
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>
118 lines
2.5 KiB
Go
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
|
|
}
|
|
}
|