github.com/raghuse92/packer@v1.3.2/builder/openstack/volume.go (about)

     1  package openstack
     2  
     3  import (
     4  	"log"
     5  	"time"
     6  
     7  	"github.com/gophercloud/gophercloud"
     8  	"github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes"
     9  	"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
    10  )
    11  
    12  // WaitForVolume waits for the given volume to become available.
    13  func WaitForVolume(blockStorageClient *gophercloud.ServiceClient, volumeID string) error {
    14  	maxNumErrors := 10
    15  	numErrors := 0
    16  
    17  	for {
    18  		status, err := GetVolumeStatus(blockStorageClient, volumeID)
    19  		if err != nil {
    20  			errCode, ok := err.(*gophercloud.ErrUnexpectedResponseCode)
    21  			if ok && (errCode.Actual == 500 || errCode.Actual == 404) {
    22  				numErrors++
    23  				if numErrors >= maxNumErrors {
    24  					log.Printf("[ERROR] Maximum number of errors (%d) reached; failing with: %s", numErrors, err)
    25  					return err
    26  				}
    27  				log.Printf("[ERROR] %d error received, will ignore and retry: %s", errCode.Actual, err)
    28  				time.Sleep(2 * time.Second)
    29  				continue
    30  			}
    31  
    32  			return err
    33  		}
    34  
    35  		if status == "available" {
    36  			return nil
    37  		}
    38  
    39  		log.Printf("Waiting for volume creation status: %s", status)
    40  		time.Sleep(2 * time.Second)
    41  	}
    42  }
    43  
    44  // GetVolumeSize returns volume size in gigabytes based on the image min disk
    45  // value if it's not empty.
    46  // Or it calculates needed gigabytes size from the image bytes size.
    47  func GetVolumeSize(imageClient *gophercloud.ServiceClient, imageID string) (int, error) {
    48  	sourceImage, err := images.Get(imageClient, imageID).Extract()
    49  	if err != nil {
    50  		return 0, err
    51  	}
    52  
    53  	if sourceImage.MinDiskGigabytes != 0 {
    54  		return sourceImage.MinDiskGigabytes, nil
    55  	}
    56  
    57  	volumeSizeMB := sourceImage.SizeBytes / 1024 / 1024
    58  	volumeSizeGB := int(sourceImage.SizeBytes / 1024 / 1024 / 1024)
    59  
    60  	// Increment gigabytes size if the initial size can't be divided without
    61  	// remainder.
    62  	if volumeSizeMB%1024 > 0 {
    63  		volumeSizeGB++
    64  	}
    65  
    66  	return volumeSizeGB, nil
    67  }
    68  
    69  func GetVolumeStatus(blockStorageClient *gophercloud.ServiceClient, volumeID string) (string, error) {
    70  	volume, err := volumes.Get(blockStorageClient, volumeID).Extract()
    71  	if err != nil {
    72  		return "", err
    73  	}
    74  
    75  	return volume.Status, nil
    76  }