2019-05-31 09:45:11 +00:00
|
|
|
/*
|
|
|
|
Copyright 2019 The Kubernetes Authors.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package helpers
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"k8s.io/apimachinery/pkg/api/resource"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// GB - GigaByte size
|
|
|
|
GB = 1000 * 1000 * 1000
|
|
|
|
// GiB - GibiByte size
|
|
|
|
GiB = 1024 * 1024 * 1024
|
|
|
|
|
|
|
|
// MB - MegaByte size
|
|
|
|
MB = 1000 * 1000
|
|
|
|
// MiB - MebiByte size
|
|
|
|
MiB = 1024 * 1024
|
|
|
|
|
|
|
|
// KB - KiloByte size
|
|
|
|
KB = 1000
|
|
|
|
// KiB - KibiByte size
|
|
|
|
KiB = 1024
|
|
|
|
)
|
|
|
|
|
|
|
|
// RoundUpToGiB rounds up given quantity upto chunks of GiB
|
2020-12-17 12:28:29 +00:00
|
|
|
func RoundUpToGiB(size resource.Quantity) (int64, error) {
|
|
|
|
requestBytes, ok := size.AsInt64()
|
|
|
|
if !ok {
|
|
|
|
return 0, fmt.Errorf("quantity %s is too great, overflows int64", size.String())
|
|
|
|
}
|
|
|
|
return roundUpSize(requestBytes, GiB), nil
|
2019-05-31 09:45:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RoundUpToMB rounds up given quantity to chunks of MB
|
2020-12-17 12:28:29 +00:00
|
|
|
func RoundUpToMB(size resource.Quantity) (int64, error) {
|
|
|
|
requestBytes, ok := size.AsInt64()
|
|
|
|
if !ok {
|
|
|
|
return 0, fmt.Errorf("quantity %s is too great, overflows int64", size.String())
|
|
|
|
}
|
|
|
|
return roundUpSize(requestBytes, MB), nil
|
2019-05-31 09:45:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RoundUpToMiB rounds up given quantity upto chunks of MiB
|
2020-12-17 12:28:29 +00:00
|
|
|
func RoundUpToMiB(size resource.Quantity) (int64, error) {
|
|
|
|
requestBytes, ok := size.AsInt64()
|
|
|
|
if !ok {
|
|
|
|
return 0, fmt.Errorf("quantity %s is too great, overflows int64", size.String())
|
|
|
|
}
|
|
|
|
return roundUpSize(requestBytes, MiB), nil
|
2019-05-31 09:45:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RoundUpToKB rounds up given quantity to chunks of KB
|
2020-12-17 12:28:29 +00:00
|
|
|
func RoundUpToKB(size resource.Quantity) (int64, error) {
|
|
|
|
requestBytes, ok := size.AsInt64()
|
|
|
|
if !ok {
|
|
|
|
return 0, fmt.Errorf("quantity %s is too great, overflows int64", size.String())
|
|
|
|
}
|
|
|
|
return roundUpSize(requestBytes, KB), nil
|
2019-05-31 09:45:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RoundUpToKiB rounds up given quantity upto chunks of KiB
|
2020-12-17 12:28:29 +00:00
|
|
|
func RoundUpToKiB(size resource.Quantity) (int64, error) {
|
|
|
|
requestBytes, ok := size.AsInt64()
|
|
|
|
if !ok {
|
|
|
|
return 0, fmt.Errorf("quantity %s is too great, overflows int64", size.String())
|
|
|
|
}
|
|
|
|
return roundUpSize(requestBytes, KiB), nil
|
2019-05-31 09:45:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RoundUpToGiBInt rounds up given quantity upto chunks of GiB. It returns an
|
|
|
|
// int instead of an int64 and an error if there's overflow
|
|
|
|
func RoundUpToGiBInt(size resource.Quantity) (int, error) {
|
2020-12-17 12:28:29 +00:00
|
|
|
requestBytes, ok := size.AsInt64()
|
|
|
|
if !ok {
|
|
|
|
return 0, fmt.Errorf("quantity %s is too great, overflows int64", size.String())
|
|
|
|
}
|
2019-05-31 09:45:11 +00:00
|
|
|
return roundUpSizeInt(requestBytes, GiB)
|
|
|
|
}
|
|
|
|
|
|
|
|
// RoundUpToMBInt rounds up given quantity to chunks of MB. It returns an
|
|
|
|
// int instead of an int64 and an error if there's overflow
|
|
|
|
func RoundUpToMBInt(size resource.Quantity) (int, error) {
|
2020-12-17 12:28:29 +00:00
|
|
|
requestBytes, ok := size.AsInt64()
|
|
|
|
if !ok {
|
|
|
|
return 0, fmt.Errorf("quantity %s is too great, overflows int64", size.String())
|
|
|
|
}
|
2019-05-31 09:45:11 +00:00
|
|
|
return roundUpSizeInt(requestBytes, MB)
|
|
|
|
}
|
|
|
|
|
|
|
|
// RoundUpToMiBInt rounds up given quantity upto chunks of MiB. It returns an
|
|
|
|
// int instead of an int64 and an error if there's overflow
|
|
|
|
func RoundUpToMiBInt(size resource.Quantity) (int, error) {
|
2020-12-17 12:28:29 +00:00
|
|
|
requestBytes, ok := size.AsInt64()
|
|
|
|
if !ok {
|
|
|
|
return 0, fmt.Errorf("quantity %s is too great, overflows int64", size.String())
|
|
|
|
}
|
2019-05-31 09:45:11 +00:00
|
|
|
return roundUpSizeInt(requestBytes, MiB)
|
|
|
|
}
|
|
|
|
|
|
|
|
// RoundUpToKBInt rounds up given quantity to chunks of KB. It returns an
|
|
|
|
// int instead of an int64 and an error if there's overflow
|
|
|
|
func RoundUpToKBInt(size resource.Quantity) (int, error) {
|
2020-12-17 12:28:29 +00:00
|
|
|
requestBytes, ok := size.AsInt64()
|
|
|
|
if !ok {
|
|
|
|
return 0, fmt.Errorf("quantity %s is too great, overflows int64", size.String())
|
|
|
|
}
|
2019-05-31 09:45:11 +00:00
|
|
|
return roundUpSizeInt(requestBytes, KB)
|
|
|
|
}
|
|
|
|
|
|
|
|
// RoundUpToKiBInt rounds up given quantity upto chunks of KiB. It returns an
|
|
|
|
// int instead of an int64 and an error if there's overflow
|
|
|
|
func RoundUpToKiBInt(size resource.Quantity) (int, error) {
|
|
|
|
requestBytes := size.Value()
|
|
|
|
return roundUpSizeInt(requestBytes, KiB)
|
|
|
|
}
|
|
|
|
|
2020-12-17 12:28:29 +00:00
|
|
|
// RoundUpToGiBInt32 rounds up given quantity up to chunks of GiB. It returns an
|
|
|
|
// int32 instead of an int64 and an error if there's overflow
|
|
|
|
func RoundUpToGiBInt32(size resource.Quantity) (int32, error) {
|
|
|
|
requestBytes, ok := size.AsInt64()
|
|
|
|
if !ok {
|
|
|
|
return 0, fmt.Errorf("quantity %s is too great, overflows int64", size.String())
|
|
|
|
}
|
|
|
|
return roundUpSizeInt32(requestBytes, GiB)
|
|
|
|
}
|
|
|
|
|
2019-05-31 09:45:11 +00:00
|
|
|
// roundUpSizeInt calculates how many allocation units are needed to accommodate
|
|
|
|
// a volume of given size. It returns an int instead of an int64 and an error if
|
|
|
|
// there's overflow
|
|
|
|
func roundUpSizeInt(volumeSizeBytes int64, allocationUnitBytes int64) (int, error) {
|
|
|
|
roundedUp := roundUpSize(volumeSizeBytes, allocationUnitBytes)
|
|
|
|
roundedUpInt := int(roundedUp)
|
|
|
|
if int64(roundedUpInt) != roundedUp {
|
|
|
|
return 0, fmt.Errorf("capacity %v is too great, casting results in integer overflow", roundedUp)
|
|
|
|
}
|
|
|
|
return roundedUpInt, nil
|
|
|
|
}
|
|
|
|
|
2020-12-17 12:28:29 +00:00
|
|
|
// roundUpSizeInt32 calculates how many allocation units are needed to accommodate
|
|
|
|
// a volume of given size. It returns an int32 instead of an int64 and an error if
|
|
|
|
// there's overflow
|
|
|
|
func roundUpSizeInt32(volumeSizeBytes int64, allocationUnitBytes int64) (int32, error) {
|
|
|
|
roundedUp := roundUpSize(volumeSizeBytes, allocationUnitBytes)
|
|
|
|
roundedUpInt32 := int32(roundedUp)
|
|
|
|
if int64(roundedUpInt32) != roundedUp {
|
|
|
|
return 0, fmt.Errorf("quantity %v is too great, overflows int32", roundedUp)
|
|
|
|
}
|
|
|
|
return roundedUpInt32, nil
|
|
|
|
}
|
|
|
|
|
2019-05-31 09:45:11 +00:00
|
|
|
// roundUpSize calculates how many allocation units are needed to accommodate
|
|
|
|
// a volume of given size. E.g. when user wants 1500MiB volume, while AWS EBS
|
|
|
|
// allocates volumes in gibibyte-sized chunks,
|
|
|
|
// RoundUpSize(1500 * 1024*1024, 1024*1024*1024) returns '2'
|
|
|
|
// (2 GiB is the smallest allocatable volume that can hold 1500MiB)
|
|
|
|
func roundUpSize(volumeSizeBytes int64, allocationUnitBytes int64) int64 {
|
|
|
|
roundedUp := volumeSizeBytes / allocationUnitBytes
|
|
|
|
if volumeSizeBytes%allocationUnitBytes > 0 {
|
|
|
|
roundedUp++
|
|
|
|
}
|
|
|
|
return roundedUp
|
|
|
|
}
|