72 lines
1.8 KiB
Go
72 lines
1.8 KiB
Go
|
package openstack
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"github.com/mitchellh/multistep"
|
||
|
"github.com/mitchellh/packer/packer"
|
||
|
"github.com/rackspace/gophercloud"
|
||
|
"log"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type stepCreateImage struct{}
|
||
|
|
||
|
func (s *stepCreateImage) Run(state map[string]interface{}) multistep.StepAction {
|
||
|
accessor := state["accessor"].(*gophercloud.Access)
|
||
|
api := state["api"].(*gophercloud.ApiCriteria)
|
||
|
config := state["config"].(config)
|
||
|
server := state["server"].(*gophercloud.Server)
|
||
|
ui := state["ui"].(packer.Ui)
|
||
|
|
||
|
// Create the image
|
||
|
ui.Say(fmt.Sprintf("Creating the image: %s", config.ImageName))
|
||
|
createOpts := gophercloud.CreateImage{
|
||
|
Name: config.ImageName,
|
||
|
}
|
||
|
csp, err := gophercloud.ServersApi(accessor, *api)
|
||
|
imageId, err := csp.CreateImage(server.Id, createOpts)
|
||
|
if err != nil {
|
||
|
err := fmt.Errorf("Error creating image: %s", err)
|
||
|
state["error"] = err
|
||
|
ui.Error(err.Error())
|
||
|
return multistep.ActionHalt
|
||
|
}
|
||
|
|
||
|
// Set the Image ID in the state
|
||
|
ui.Say(fmt.Sprintf("Image: %s", imageId))
|
||
|
state["image"] = imageId
|
||
|
|
||
|
// Wait for the image to become ready
|
||
|
ui.Say("Waiting for image to become ready...")
|
||
|
if err := WaitForImage(accessor, api, imageId); err != nil {
|
||
|
err := fmt.Errorf("Error waiting for image: %s", err)
|
||
|
state["error"] = err
|
||
|
ui.Error(err.Error())
|
||
|
return multistep.ActionHalt
|
||
|
}
|
||
|
|
||
|
return multistep.ActionContinue
|
||
|
}
|
||
|
|
||
|
func (s *stepCreateImage) Cleanup(map[string]interface{}) {
|
||
|
// No cleanup...
|
||
|
}
|
||
|
|
||
|
// WaitForImage waits for the given Image ID to become ready.
|
||
|
func WaitForImage(accessor *gophercloud.Access, api *gophercloud.ApiCriteria, imageId string) error {
|
||
|
for {
|
||
|
csp, err := gophercloud.ServersApi(accessor, *api)
|
||
|
image, err := csp.ImageById(imageId)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if image.Status == "ACTIVE" {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
log.Printf("Waiting for image creation status: %s (%d%%)", image.Status, image.Progress)
|
||
|
time.Sleep(2 * time.Second)
|
||
|
}
|
||
|
}
|