github.com/phobos182/packer@v0.2.3-0.20130819023704-c84d2aeffc68/builder/amazon/chroot/step_snapshot.go (about)

     1  package chroot
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"github.com/mitchellh/goamz/ec2"
     7  	"github.com/mitchellh/multistep"
     8  	awscommon "github.com/mitchellh/packer/builder/amazon/common"
     9  	"github.com/mitchellh/packer/packer"
    10  )
    11  
    12  // StepSnapshot creates a snapshot of the created volume.
    13  //
    14  // Produces:
    15  //   snapshot_id string - ID of the created snapshot
    16  type StepSnapshot struct {
    17  	snapshotId string
    18  }
    19  
    20  func (s *StepSnapshot) Run(state map[string]interface{}) multistep.StepAction {
    21  	ec2conn := state["ec2"].(*ec2.EC2)
    22  	ui := state["ui"].(packer.Ui)
    23  	volumeId := state["volume_id"].(string)
    24  
    25  	ui.Say("Creating snapshot...")
    26  	createSnapResp, err := ec2conn.CreateSnapshot(volumeId, "")
    27  	if err != nil {
    28  		err := fmt.Errorf("Error creating snapshot: %s", err)
    29  		state["error"] = err
    30  		ui.Error(err.Error())
    31  		return multistep.ActionHalt
    32  	}
    33  
    34  	// Set the snapshot ID so we can delete it later
    35  	s.snapshotId = createSnapResp.Id
    36  	ui.Message(fmt.Sprintf("Snapshot ID: %s", s.snapshotId))
    37  
    38  	// Wait for the snapshot to be ready
    39  	stateChange := awscommon.StateChangeConf{
    40  		Conn:      ec2conn,
    41  		Pending:   []string{"pending"},
    42  		StepState: state,
    43  		Target:    "completed",
    44  		Refresh: func() (interface{}, string, error) {
    45  			resp, err := ec2conn.Snapshots([]string{s.snapshotId}, ec2.NewFilter())
    46  			if err != nil {
    47  				return nil, "", err
    48  			}
    49  
    50  			if len(resp.Snapshots) == 0 {
    51  				return nil, "", errors.New("No snapshots found.")
    52  			}
    53  
    54  			return nil, resp.Snapshots[0].Status, nil
    55  		},
    56  	}
    57  
    58  	_, err = awscommon.WaitForState(&stateChange)
    59  	if err != nil {
    60  		err := fmt.Errorf("Error waiting for snapshot: %s", err)
    61  		state["error"] = err
    62  		ui.Error(err.Error())
    63  		return multistep.ActionHalt
    64  	}
    65  
    66  	state["snapshot_id"] = s.snapshotId
    67  	return multistep.ActionContinue
    68  }
    69  
    70  func (s *StepSnapshot) Cleanup(state map[string]interface{}) {
    71  	if s.snapshotId == "" {
    72  		return
    73  	}
    74  
    75  	_, cancelled := state[multistep.StateCancelled]
    76  	_, halted := state[multistep.StateHalted]
    77  
    78  	if cancelled || halted {
    79  		ec2conn := state["ec2"].(*ec2.EC2)
    80  		ui := state["ui"].(packer.Ui)
    81  		ui.Say("Removing snapshot since we cancelled or halted...")
    82  		_, err := ec2conn.DeleteSnapshots([]string{s.snapshotId})
    83  		if err != nil {
    84  			ui.Error(fmt.Sprintf("Error: %s", err))
    85  		}
    86  	}
    87  }