github.com/sneal/packer@v0.5.2/builder/openstack/step_create_image.go (about)

     1  package openstack
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/mitchellh/multistep"
     6  	"github.com/mitchellh/packer/packer"
     7  	"github.com/rackspace/gophercloud"
     8  	"log"
     9  	"time"
    10  )
    11  
    12  type stepCreateImage struct{}
    13  
    14  func (s *stepCreateImage) Run(state multistep.StateBag) multistep.StepAction {
    15  	csp := state.Get("csp").(gophercloud.CloudServersProvider)
    16  	config := state.Get("config").(config)
    17  	server := state.Get("server").(*gophercloud.Server)
    18  	ui := state.Get("ui").(packer.Ui)
    19  
    20  	// Create the image
    21  	ui.Say(fmt.Sprintf("Creating the image: %s", config.ImageName))
    22  	createOpts := gophercloud.CreateImage{
    23  		Name: config.ImageName,
    24  	}
    25  	imageId, err := csp.CreateImage(server.Id, createOpts)
    26  	if err != nil {
    27  		err := fmt.Errorf("Error creating image: %s", err)
    28  		state.Put("error", err)
    29  		ui.Error(err.Error())
    30  		return multistep.ActionHalt
    31  	}
    32  
    33  	// Set the Image ID in the state
    34  	ui.Say(fmt.Sprintf("Image: %s", imageId))
    35  	state.Put("image", imageId)
    36  
    37  	// Wait for the image to become ready
    38  	ui.Say("Waiting for image to become ready...")
    39  	if err := WaitForImage(csp, imageId); err != nil {
    40  		err := fmt.Errorf("Error waiting for image: %s", err)
    41  		state.Put("error", err)
    42  		ui.Error(err.Error())
    43  		return multistep.ActionHalt
    44  	}
    45  
    46  	return multistep.ActionContinue
    47  }
    48  
    49  func (s *stepCreateImage) Cleanup(multistep.StateBag) {
    50  	// No cleanup...
    51  }
    52  
    53  // WaitForImage waits for the given Image ID to become ready.
    54  func WaitForImage(csp gophercloud.CloudServersProvider, imageId string) error {
    55  	for {
    56  		image, err := csp.ImageById(imageId)
    57  		if err != nil {
    58  			return err
    59  		}
    60  
    61  		if image.Status == "ACTIVE" {
    62  			return nil
    63  		}
    64  
    65  		log.Printf("Waiting for image creation status: %s (%d%%)", image.Status, image.Progress)
    66  		time.Sleep(2 * time.Second)
    67  	}
    68  }