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