mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #66464 from wongma7/round-overflow
Automatic merge from submit-queue (batch tested with PRs 66464, 66488). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Avoid overflowing int64 in RoundUpSize and return error if overflow int **What this PR does / why we need it**: There are many places in plugins (some I may have missed) that we naively convert a resource.Quantity.Value() which is an int64, to an int, which may be only 32 bits long. Background, optional to read :): Kubernetes canonicalizes resource.Quantities, and from what I have seen testing creating PVCs, decimalSI is the default. If a quantity is in `decimalSI` format and its value in bytes would overflow an int64, e.g. `10E`, nothing happens. If it is in binarySI and its value in bytes would overflow an int64, e.g. `10Ei`, it is set down to 2^63-1 and there's no overflow of the field value. But there may be overflow later in the code which is what this PR is addressing. * Change `RoundUpSize` implementation to avoid overflowing `int64` * Add `RoundUp*Int` functions for use when an `int` is expected instead of an `int64`, because `int` may be 32bits and naively doing `int($INT64_VALUE)` can lead to silent overflow. These functions return an error if overflow has occurred. * Rename `*GB` variables to `*GiB` where appropriate for maximum clarity * Use `RoundUpToGiB` instead of `RoundUpSize` where possible **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes # **Special notes for your reviewer**: please review carefully as we don't have e2e tests for most plugins! **Release note**: ```release-note NONE ``` edit: remove 'we do not need to worry about...'. yes we do, i worded that badly :))
This commit is contained in:
commit
35c3764bbb
@ -2510,9 +2510,8 @@ func (c *Cloud) ResizeDisk(
|
|||||||
descErr := fmt.Errorf("AWS.ResizeDisk Error describing volume %s with %v", diskName, err)
|
descErr := fmt.Errorf("AWS.ResizeDisk Error describing volume %s with %v", diskName, err)
|
||||||
return oldSize, descErr
|
return oldSize, descErr
|
||||||
}
|
}
|
||||||
requestBytes := newSize.Value()
|
|
||||||
// AWS resizes in chunks of GiB (not GB)
|
// AWS resizes in chunks of GiB (not GB)
|
||||||
requestGiB := volumeutil.RoundUpSize(requestBytes, 1024*1024*1024)
|
requestGiB := volumeutil.RoundUpToGiB(newSize)
|
||||||
newSizeQuant := resource.MustParse(fmt.Sprintf("%dGi", requestGiB))
|
newSizeQuant := resource.MustParse(fmt.Sprintf("%dGi", requestGiB))
|
||||||
|
|
||||||
// If disk already if of greater or equal size than requested we return
|
// If disk already if of greater or equal size than requested we return
|
||||||
|
@ -746,9 +746,8 @@ func (gce *GCECloud) ResizeDisk(diskToResize string, oldSize resource.Quantity,
|
|||||||
return oldSize, err
|
return oldSize, err
|
||||||
}
|
}
|
||||||
|
|
||||||
requestBytes := newSize.Value()
|
|
||||||
// GCE resizes in chunks of GiBs
|
// GCE resizes in chunks of GiBs
|
||||||
requestGIB := volumeutil.RoundUpSize(requestBytes, volumeutil.GIB)
|
requestGIB := volumeutil.RoundUpToGiB(newSize)
|
||||||
newSizeQuant := resource.MustParse(fmt.Sprintf("%dGi", requestGIB))
|
newSizeQuant := resource.MustParse(fmt.Sprintf("%dGi", requestGIB))
|
||||||
|
|
||||||
// If disk is already of size equal or greater than requested size, we simply return
|
// If disk is already of size equal or greater than requested size, we simply return
|
||||||
|
@ -411,13 +411,15 @@ func (os *OpenStack) ExpandVolume(volumeID string, oldSize resource.Quantity, ne
|
|||||||
return oldSize, fmt.Errorf("volume status is not available")
|
return oldSize, fmt.Errorf("volume status is not available")
|
||||||
}
|
}
|
||||||
|
|
||||||
volSizeBytes := newSize.Value()
|
|
||||||
// Cinder works with gigabytes, convert to GiB with rounding up
|
// Cinder works with gigabytes, convert to GiB with rounding up
|
||||||
volSizeGB := int(volumeutil.RoundUpSize(volSizeBytes, 1024*1024*1024))
|
volSizeGiB, err := volumeutil.RoundUpToGiBInt(newSize)
|
||||||
newSizeQuant := resource.MustParse(fmt.Sprintf("%dGi", volSizeGB))
|
if err != nil {
|
||||||
|
return oldSize, err
|
||||||
|
}
|
||||||
|
newSizeQuant := resource.MustParse(fmt.Sprintf("%dGi", volSizeGiB))
|
||||||
|
|
||||||
// if volume size equals to or greater than the newSize, return nil
|
// if volume size equals to or greater than the newSize, return nil
|
||||||
if volume.Size >= volSizeGB {
|
if volume.Size >= volSizeGiB {
|
||||||
return newSizeQuant, nil
|
return newSizeQuant, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,7 +428,7 @@ func (os *OpenStack) ExpandVolume(volumeID string, oldSize resource.Quantity, ne
|
|||||||
return oldSize, err
|
return oldSize, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = volumes.expandVolume(volumeID, volSizeGB)
|
err = volumes.expandVolume(volumeID, volSizeGiB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return oldSize, err
|
return oldSize, err
|
||||||
}
|
}
|
||||||
|
@ -83,11 +83,13 @@ func (util *AWSDiskUtil) CreateVolume(c *awsElasticBlockStoreProvisioner) (aws.K
|
|||||||
tags["Name"] = volumeutil.GenerateVolumeName(c.options.ClusterName, c.options.PVName, 255) // AWS tags can have 255 characters
|
tags["Name"] = volumeutil.GenerateVolumeName(c.options.ClusterName, c.options.PVName, 255) // AWS tags can have 255 characters
|
||||||
|
|
||||||
capacity := c.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
capacity := c.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||||
requestBytes := capacity.Value()
|
|
||||||
// AWS works with gigabytes, convert to GiB with rounding up
|
// AWS works with gigabytes, convert to GiB with rounding up
|
||||||
requestGB := int(volumeutil.RoundUpSize(requestBytes, 1024*1024*1024))
|
requestGiB, err := volumeutil.RoundUpToGiBInt(capacity)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, nil, "", err
|
||||||
|
}
|
||||||
volumeOptions := &aws.VolumeOptions{
|
volumeOptions := &aws.VolumeOptions{
|
||||||
CapacityGB: requestGB,
|
CapacityGB: requestGiB,
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
PVCName: c.options.PVC.Name,
|
PVCName: c.options.PVC.Name,
|
||||||
}
|
}
|
||||||
@ -147,7 +149,7 @@ func (util *AWSDiskUtil) CreateVolume(c *awsElasticBlockStoreProvisioner) (aws.K
|
|||||||
glog.Errorf("error building labels for new EBS volume %q: %v", name, err)
|
glog.Errorf("error building labels for new EBS volume %q: %v", name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return name, int(requestGB), labels, fstype, nil
|
return name, requestGiB, labels, fstype, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the first path that exists, or empty string if none exist.
|
// Returns the first path that exists, or empty string if none exist.
|
||||||
|
@ -100,8 +100,10 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie
|
|||||||
// maxLength = 79 - (4 for ".vhd") = 75
|
// maxLength = 79 - (4 for ".vhd") = 75
|
||||||
name := util.GenerateVolumeName(p.options.ClusterName, p.options.PVName, 75)
|
name := util.GenerateVolumeName(p.options.ClusterName, p.options.PVName, 75)
|
||||||
capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||||
requestBytes := capacity.Value()
|
requestGiB, err := util.RoundUpToGiBInt(capacity)
|
||||||
requestGB := int(util.RoundUpSize(requestBytes, 1024*1024*1024))
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
for k, v := range p.options.Parameters {
|
for k, v := range p.options.Parameters {
|
||||||
switch strings.ToLower(k) {
|
switch strings.ToLower(k) {
|
||||||
@ -157,18 +159,18 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie
|
|||||||
if p.options.CloudTags != nil {
|
if p.options.CloudTags != nil {
|
||||||
tags = *(p.options.CloudTags)
|
tags = *(p.options.CloudTags)
|
||||||
}
|
}
|
||||||
diskURI, err = diskController.CreateManagedDisk(name, skuName, resourceGroup, requestGB, tags)
|
diskURI, err = diskController.CreateManagedDisk(name, skuName, resourceGroup, requestGiB, tags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if kind == v1.AzureDedicatedBlobDisk {
|
if kind == v1.AzureDedicatedBlobDisk {
|
||||||
_, diskURI, _, err = diskController.CreateVolume(name, account, storageAccountType, location, requestGB)
|
_, diskURI, _, err = diskController.CreateVolume(name, account, storageAccountType, location, requestGiB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
diskURI, err = diskController.CreateBlobDisk(name, skuName, requestGB)
|
diskURI, err = diskController.CreateBlobDisk(name, skuName, requestGiB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -196,7 +198,7 @@ func (p *azureDiskProvisioner) Provision(selectedNode *v1.Node, allowedTopologie
|
|||||||
PersistentVolumeReclaimPolicy: p.options.PersistentVolumeReclaimPolicy,
|
PersistentVolumeReclaimPolicy: p.options.PersistentVolumeReclaimPolicy,
|
||||||
AccessModes: supportedModes,
|
AccessModes: supportedModes,
|
||||||
Capacity: v1.ResourceList{
|
Capacity: v1.ResourceList{
|
||||||
v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", requestGB)),
|
v1.ResourceName(v1.ResourceStorage): resource.MustParse(fmt.Sprintf("%dGi", requestGiB)),
|
||||||
},
|
},
|
||||||
VolumeMode: volumeMode,
|
VolumeMode: volumeMode,
|
||||||
PersistentVolumeSource: v1.PersistentVolumeSource{
|
PersistentVolumeSource: v1.PersistentVolumeSource{
|
||||||
|
@ -169,9 +169,12 @@ func (util *DiskUtil) CreateVolume(c *cinderVolumeProvisioner) (volumeID string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
capacity := c.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
capacity := c.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||||
volSizeBytes := capacity.Value()
|
|
||||||
// Cinder works with gigabytes, convert to GiB with rounding up
|
// Cinder works with gigabytes, convert to GiB with rounding up
|
||||||
volSizeGB := int(volutil.RoundUpSize(volSizeBytes, 1024*1024*1024))
|
volSizeGiB, err := volutil.RoundUpToGiBInt(capacity)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
name := volutil.GenerateVolumeName(c.options.ClusterName, c.options.PVName, 255) // Cinder volume name can have up to 255 characters
|
name := volutil.GenerateVolumeName(c.options.ClusterName, c.options.PVName, 255) // Cinder volume name can have up to 255 characters
|
||||||
vtype := ""
|
vtype := ""
|
||||||
availability := ""
|
availability := ""
|
||||||
@ -208,7 +211,7 @@ func (util *DiskUtil) CreateVolume(c *cinderVolumeProvisioner) (volumeID string,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
volumeID, volumeAZ, volumeRegion, IgnoreVolumeAZ, err := cloud.CreateVolume(name, volSizeGB, vtype, availability, c.options.CloudTags)
|
volumeID, volumeAZ, volumeRegion, IgnoreVolumeAZ, err := cloud.CreateVolume(name, volSizeGiB, vtype, availability, c.options.CloudTags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(2).Infof("Error creating cinder volume: %v", err)
|
glog.V(2).Infof("Error creating cinder volume: %v", err)
|
||||||
return "", 0, nil, "", err
|
return "", 0, nil, "", err
|
||||||
@ -221,7 +224,7 @@ func (util *DiskUtil) CreateVolume(c *cinderVolumeProvisioner) (volumeID string,
|
|||||||
volumeLabels[kubeletapis.LabelZoneFailureDomain] = volumeAZ
|
volumeLabels[kubeletapis.LabelZoneFailureDomain] = volumeAZ
|
||||||
volumeLabels[kubeletapis.LabelZoneRegion] = volumeRegion
|
volumeLabels[kubeletapis.LabelZoneRegion] = volumeRegion
|
||||||
}
|
}
|
||||||
return volumeID, volSizeGB, volumeLabels, fstype, nil
|
return volumeID, volSizeGiB, volumeLabels, fstype, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func probeAttachedVolume() error {
|
func probeAttachedVolume() error {
|
||||||
|
@ -49,7 +49,7 @@ func (util *FlockerUtil) DeleteVolume(d *flockerVolumeDeleter) error {
|
|||||||
return d.flockerClient.DeleteDataset(datasetUUID)
|
return d.flockerClient.DeleteDataset(datasetUUID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (util *FlockerUtil) CreateVolume(c *flockerVolumeProvisioner) (datasetUUID string, volumeSizeGB int, labels map[string]string, err error) {
|
func (util *FlockerUtil) CreateVolume(c *flockerVolumeProvisioner) (datasetUUID string, volumeSizeGiB int, labels map[string]string, err error) {
|
||||||
|
|
||||||
if c.flockerClient == nil {
|
if c.flockerClient == nil {
|
||||||
c.flockerClient, err = c.plugin.newFlockerClient("")
|
c.flockerClient, err = c.plugin.newFlockerClient("")
|
||||||
@ -74,7 +74,10 @@ func (util *FlockerUtil) CreateVolume(c *flockerVolumeProvisioner) (datasetUUID
|
|||||||
|
|
||||||
capacity := c.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
capacity := c.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||||
requestBytes := capacity.Value()
|
requestBytes := capacity.Value()
|
||||||
volumeSizeGB = int(volutil.RoundUpSize(requestBytes, 1024*1024*1024))
|
volumeSizeGiB, err = volutil.RoundUpToGiBInt(capacity)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
createOptions := &flockerapi.CreateDatasetOptions{
|
createOptions := &flockerapi.CreateDatasetOptions{
|
||||||
MaximumSize: requestBytes,
|
MaximumSize: requestBytes,
|
||||||
|
@ -744,7 +744,10 @@ func (p *glusterfsVolumeProvisioner) CreateVolume(gid int) (r *v1.GlusterfsVolum
|
|||||||
capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||||
|
|
||||||
// GlusterFS/heketi creates volumes in units of GiB.
|
// GlusterFS/heketi creates volumes in units of GiB.
|
||||||
sz := int(volutil.RoundUpToGiB(capacity))
|
sz, err := volutil.RoundUpToGiBInt(capacity)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, "", err
|
||||||
|
}
|
||||||
glog.V(2).Infof("create volume of size %dGiB", sz)
|
glog.V(2).Infof("create volume of size %dGiB", sz)
|
||||||
|
|
||||||
if p.url == "" {
|
if p.url == "" {
|
||||||
|
@ -88,9 +88,11 @@ func (util *PhotonDiskUtil) CreateVolume(p *photonPersistentDiskProvisioner) (pd
|
|||||||
}
|
}
|
||||||
|
|
||||||
capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||||
volSizeBytes := capacity.Value()
|
// PhotonController works with GiB, convert to GiB with rounding up
|
||||||
// PhotonController works with GB, convert to GB with rounding up
|
volSizeGB, err := volumeutil.RoundUpToGiBInt(capacity)
|
||||||
volSizeGB := int(volumeutil.RoundUpSize(volSizeBytes, 1024*1024*1024))
|
if err != nil {
|
||||||
|
return "", 0, "", err
|
||||||
|
}
|
||||||
name := volumeutil.GenerateVolumeName(p.options.ClusterName, p.options.PVName, 255)
|
name := volumeutil.GenerateVolumeName(p.options.ClusterName, p.options.PVName, 255)
|
||||||
volumeOptions := &photon.VolumeOptions{
|
volumeOptions := &photon.VolumeOptions{
|
||||||
CapacityGB: volSizeGB,
|
CapacityGB: volSizeGB,
|
||||||
|
@ -35,7 +35,10 @@ type quobyteVolumeManager struct {
|
|||||||
|
|
||||||
func (manager *quobyteVolumeManager) createVolume(provisioner *quobyteVolumeProvisioner, createQuota bool) (quobyte *v1.QuobyteVolumeSource, size int, err error) {
|
func (manager *quobyteVolumeManager) createVolume(provisioner *quobyteVolumeProvisioner, createQuota bool) (quobyte *v1.QuobyteVolumeSource, size int, err error) {
|
||||||
capacity := provisioner.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
capacity := provisioner.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||||
volumeSize := int(util.RoundUpSize(capacity.Value(), 1024*1024*1024))
|
volumeSize, err := util.RoundUpToGiBInt(capacity)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
// Quobyte has the concept of Volumes which doen't have a specific size (they can grow unlimited)
|
// Quobyte has the concept of Volumes which doen't have a specific size (they can grow unlimited)
|
||||||
// to simulate a size constraint we set here a Quota for logical space
|
// to simulate a size constraint we set here a Quota for logical space
|
||||||
volumeRequest := &quobyteapi.CreateVolumeRequest{
|
volumeRequest := &quobyteapi.CreateVolumeRequest{
|
||||||
|
@ -579,7 +579,10 @@ func (util *RBDUtil) CreateImage(p *rbdVolumeProvisioner) (r *v1.RBDPersistentVo
|
|||||||
capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||||
volSizeBytes := capacity.Value()
|
volSizeBytes := capacity.Value()
|
||||||
// Convert to MB that rbd defaults on.
|
// Convert to MB that rbd defaults on.
|
||||||
sz := int(volutil.RoundUpSize(volSizeBytes, 1024*1024))
|
sz, err := volutil.RoundUpSizeInt(volSizeBytes, 1024*1024)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
volSz := fmt.Sprintf("%d", sz)
|
volSz := fmt.Sprintf("%d", sz)
|
||||||
mon := util.kernelRBDMonitorsOpt(p.Mon)
|
mon := util.kernelRBDMonitorsOpt(p.Mon)
|
||||||
if p.rbdMounter.imageFormat == rbdImageFormat2 {
|
if p.rbdMounter.imageFormat == rbdImageFormat2 {
|
||||||
|
@ -602,7 +602,11 @@ func (c *storageosProvisioner) Provision(selectedNode *v1.Node, allowedTopologie
|
|||||||
c.labels[k] = v
|
c.labels[k] = v
|
||||||
}
|
}
|
||||||
capacity := c.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
capacity := c.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||||
c.sizeGB = int(util.RoundUpSize(capacity.Value(), 1024*1024*1024))
|
var err error
|
||||||
|
c.sizeGB, err = util.RoundUpToGiBInt(capacity)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
apiCfg, err := parsePVSecret(adminSecretNamespace, adminSecretName, c.plugin.host.GetKubeClient())
|
apiCfg, err := parsePVSecret(adminSecretNamespace, adminSecretName, c.plugin.host.GetKubeClient())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -361,7 +361,11 @@ func CalculateTimeoutForVolume(minimumTimeout, timeoutIncrement int, pv *v1.Pers
|
|||||||
// RoundUpSize(1500 * 1024*1024, 1024*1024*1024) returns '2'
|
// RoundUpSize(1500 * 1024*1024, 1024*1024*1024) returns '2'
|
||||||
// (2 GiB is the smallest allocatable volume that can hold 1500MiB)
|
// (2 GiB is the smallest allocatable volume that can hold 1500MiB)
|
||||||
func RoundUpSize(volumeSizeBytes int64, allocationUnitBytes int64) int64 {
|
func RoundUpSize(volumeSizeBytes int64, allocationUnitBytes int64) int64 {
|
||||||
return (volumeSizeBytes + allocationUnitBytes - 1) / allocationUnitBytes
|
roundedUp := volumeSizeBytes / allocationUnitBytes
|
||||||
|
if volumeSizeBytes%allocationUnitBytes > 0 {
|
||||||
|
roundedUp += 1
|
||||||
|
}
|
||||||
|
return roundedUp
|
||||||
}
|
}
|
||||||
|
|
||||||
// RoundUpToGB rounds up given quantity to chunks of GB
|
// RoundUpToGB rounds up given quantity to chunks of GB
|
||||||
@ -376,6 +380,32 @@ func RoundUpToGiB(size resource.Quantity) int64 {
|
|||||||
return RoundUpSize(requestBytes, GIB)
|
return RoundUpSize(requestBytes, GIB)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundUpToGBInt rounds up given quantity to chunks of GB. It returns an
|
||||||
|
// int instead of an int64 and an error if there's overflow
|
||||||
|
func RoundUpToGBInt(size resource.Quantity) (int, error) {
|
||||||
|
requestBytes := size.Value()
|
||||||
|
return RoundUpSizeInt(requestBytes, GB)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
requestBytes := size.Value()
|
||||||
|
return RoundUpSizeInt(requestBytes, GIB)
|
||||||
|
}
|
||||||
|
|
||||||
// GenerateVolumeName returns a PV name with clusterName prefix. The function
|
// GenerateVolumeName returns a PV name with clusterName prefix. The function
|
||||||
// should be used to generate a name of GCE PD or Cinder volume. It basically
|
// should be used to generate a name of GCE PD or Cinder volume. It basically
|
||||||
// adds "<clusterName>-dynamic-" before the PV name, making sure the resulting
|
// adds "<clusterName>-dynamic-" before the PV name, making sure the resulting
|
||||||
|
@ -93,10 +93,13 @@ func (util *VsphereDiskUtil) CreateVolume(v *vsphereVolumeProvisioner) (volSpec
|
|||||||
capacity := v.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
capacity := v.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
|
||||||
volSizeBytes := capacity.Value()
|
volSizeBytes := capacity.Value()
|
||||||
// vSphere works with kilobytes, convert to KiB with rounding up
|
// vSphere works with kilobytes, convert to KiB with rounding up
|
||||||
volSizeKB := int(volumeutil.RoundUpSize(volSizeBytes, 1024))
|
volSizeKiB, err := volumeutil.RoundUpSizeInt(volSizeBytes, 1024)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
name := volumeutil.GenerateVolumeName(v.options.ClusterName, v.options.PVName, 255)
|
name := volumeutil.GenerateVolumeName(v.options.ClusterName, v.options.PVName, 255)
|
||||||
volumeOptions := &vclib.VolumeOptions{
|
volumeOptions := &vclib.VolumeOptions{
|
||||||
CapacityKB: volSizeKB,
|
CapacityKB: volSizeKiB,
|
||||||
Tags: *v.options.CloudTags,
|
Tags: *v.options.CloudTags,
|
||||||
Name: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
@ -146,7 +149,7 @@ func (util *VsphereDiskUtil) CreateVolume(v *vsphereVolumeProvisioner) (volSpec
|
|||||||
}
|
}
|
||||||
volSpec = &VolumeSpec{
|
volSpec = &VolumeSpec{
|
||||||
Path: vmDiskPath,
|
Path: vmDiskPath,
|
||||||
Size: volSizeKB,
|
Size: volSizeKiB,
|
||||||
Fstype: fstype,
|
Fstype: fstype,
|
||||||
StoragePolicyName: volumeOptions.StoragePolicyName,
|
StoragePolicyName: volumeOptions.StoragePolicyName,
|
||||||
StoragePolicyID: volumeOptions.StoragePolicyID,
|
StoragePolicyID: volumeOptions.StoragePolicyID,
|
||||||
|
Loading…
Reference in New Issue
Block a user