github.com/supr/packer@v0.3.10-0.20131015195147-7b09e24ac3c1/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 multistep.StateBag) multistep.StepAction {
    21  	ec2conn := state.Get("ec2").(*ec2.EC2)
    22  	ui := state.Get("ui").(packer.Ui)
    23  	volumeId := state.Get("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.Put("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  			s := resp.Snapshots[0]
    55  			return s, s.Status, nil
    56  		},
    57  	}
    58  
    59  	_, err = awscommon.WaitForState(&stateChange)
    60  	if err != nil {
    61  		err := fmt.Errorf("Error waiting for snapshot: %s", err)
    62  		state.Put("error", err)
    63  		ui.Error(err.Error())
    64  		return multistep.ActionHalt
    65  	}
    66  
    67  	state.Put("snapshot_id", s.snapshotId)
    68  	return multistep.ActionContinue
    69  }
    70  
    71  func (s *StepSnapshot) Cleanup(state multistep.StateBag) {
    72  	if s.snapshotId == "" {
    73  		return
    74  	}
    75  
    76  	_, cancelled := state.GetOk(multistep.StateCancelled)
    77  	_, halted := state.GetOk(multistep.StateHalted)
    78  
    79  	if cancelled || halted {
    80  		ec2conn := state.Get("ec2").(*ec2.EC2)
    81  		ui := state.Get("ui").(packer.Ui)
    82  		ui.Say("Removing snapshot since we cancelled or halted...")
    83  		_, err := ec2conn.DeleteSnapshots([]string{s.snapshotId})
    84  		if err != nil {
    85  			ui.Error(fmt.Sprintf("Error: %s", err))
    86  		}
    87  	}
    88  }