github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/pkg/os/device.go (about) 1 package os 2 3 import ( 4 "fmt" 5 "math" 6 "os" 7 "regexp" 8 "strconv" 9 10 "github.com/emc-advanced-dev/pkg/errors" 11 ) 12 13 type DiskSize interface { 14 ToPartedFormat() string 15 ToBytes() Bytes 16 } 17 18 type Bytes int64 19 20 func (s Bytes) ToPartedFormat() string { 21 return fmt.Sprintf("%dB", uint64(s)) 22 } 23 24 func (s Bytes) ToBytes() Bytes { 25 return s 26 } 27 28 // ToMegaBytes returns lowest whole number of size_MB so that size_MB >= (size_B / 1024^2) 29 func (s Bytes) ToMegaBytes() MegaBytes { 30 return MegaBytes(int(math.Ceil(float64(s) / float64(MegaBytes(1).ToBytes())))) 31 } 32 33 type MegaBytes int64 34 35 func (s MegaBytes) ToPartedFormat() string { 36 return fmt.Sprintf("%dMiB", uint64(s)) 37 } 38 39 func (s MegaBytes) ToBytes() Bytes { 40 return Bytes(s << 20) 41 } 42 43 type GigaBytes int64 44 45 func (s GigaBytes) ToPartedFormat() string { 46 return fmt.Sprintf("%dGiB", uint64(s)) 47 } 48 49 func (s GigaBytes) ToBytes() Bytes { 50 return Bytes(s << 30) 51 } 52 53 type Sectors int64 54 55 const SectorSize = 512 56 57 func (s Sectors) ToPartedFormat() string { 58 return fmt.Sprintf("%ds", uint64(s)) 59 } 60 61 func (s Sectors) ToBytes() Bytes { 62 return Bytes(s * SectorSize) 63 } 64 65 func ToSectors(b DiskSize) (Sectors, error) { 66 inBytes := b.ToBytes() 67 if inBytes%SectorSize != 0 { 68 return 0, errors.New("can't convert to sectors", nil) 69 } 70 return Sectors(inBytes / SectorSize), nil 71 } 72 73 type BlockDevice string 74 75 func (b BlockDevice) Name() string { 76 return string(b) 77 } 78 79 type Partitioner interface { 80 MakeTable() error 81 MakePart(partType string, start, size DiskSize) error 82 } 83 84 type Resource interface { 85 Acquire() (BlockDevice, error) 86 Release() error 87 } 88 89 type Part interface { 90 Resource 91 92 Size() DiskSize 93 Offset() DiskSize 94 95 Get() BlockDevice 96 } 97 98 func IsExists(f string) bool { 99 _, err := os.Stat(f) 100 return !os.IsNotExist(err) 101 } 102 103 // ParseSize parses disk size string (e.g. "10GB" or "150MB") into MegaBytes 104 // If no unit string is provided, megabytes are assumed 105 func ParseSize(sizeStr string) (MegaBytes, error) { 106 r, _ := regexp.Compile("^([0-9]+)(m|mb|M|MB|g|gb|G|GB)?$") 107 match := r.FindStringSubmatch(sizeStr) 108 if len(match) != 3 { 109 return -1, fmt.Errorf("%s: unrecognized size", sizeStr) 110 } 111 size, _ := strconv.ParseInt(match[1], 10, 64) 112 unit := match[2] 113 switch unit { 114 case "g", "gb", "G", "GB": 115 size *= 1024 116 } 117 if size == 0 { 118 return -1, fmt.Errorf("%s: size must be larger than zero", sizeStr) 119 } 120 return MegaBytes(size), nil 121 }