77 lines
2.0 KiB
Go
77 lines
2.0 KiB
Go
package openstack
|
|
|
|
import (
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/gophercloud/gophercloud"
|
|
"github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes"
|
|
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
|
|
)
|
|
|
|
// WaitForVolume waits for the given volume to become available.
|
|
func WaitForVolume(blockStorageClient *gophercloud.ServiceClient, volumeID string) error {
|
|
maxNumErrors := 10
|
|
numErrors := 0
|
|
|
|
for {
|
|
status, err := GetVolumeStatus(blockStorageClient, volumeID)
|
|
if err != nil {
|
|
errCode, ok := err.(*gophercloud.ErrUnexpectedResponseCode)
|
|
if ok && (errCode.Actual == 500 || errCode.Actual == 404) {
|
|
numErrors++
|
|
if numErrors >= maxNumErrors {
|
|
log.Printf("[ERROR] Maximum number of errors (%d) reached; failing with: %s", numErrors, err)
|
|
return err
|
|
}
|
|
log.Printf("[ERROR] %d error received, will ignore and retry: %s", errCode.Actual, err)
|
|
time.Sleep(2 * time.Second)
|
|
continue
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
if status == "available" {
|
|
return nil
|
|
}
|
|
|
|
log.Printf("Waiting for volume creation status: %s", status)
|
|
time.Sleep(2 * time.Second)
|
|
}
|
|
}
|
|
|
|
// GetVolumeSize returns volume size in gigabytes based on the image min disk
|
|
// value if it's not empty.
|
|
// Or it calculates needed gigabytes size from the image bytes size.
|
|
func GetVolumeSize(imageClient *gophercloud.ServiceClient, imageID string) (int, error) {
|
|
sourceImage, err := images.Get(imageClient, imageID).Extract()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
if sourceImage.MinDiskGigabytes != 0 {
|
|
return sourceImage.MinDiskGigabytes, nil
|
|
}
|
|
|
|
volumeSizeMB := sourceImage.SizeBytes / 1024 / 1024
|
|
volumeSizeGB := int(sourceImage.SizeBytes / 1024 / 1024 / 1024)
|
|
|
|
// Increment gigabytes size if the initial size can't be divided without
|
|
// remainder.
|
|
if volumeSizeMB%1024 > 0 {
|
|
volumeSizeGB++
|
|
}
|
|
|
|
return volumeSizeGB, nil
|
|
}
|
|
|
|
func GetVolumeStatus(blockStorageClient *gophercloud.ServiceClient, volumeID string) (string, error) {
|
|
volume, err := volumes.Get(blockStorageClient, volumeID).Extract()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return volume.Status, nil
|
|
}
|