github.com/sneal/packer@v0.5.2/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 Pending: []string{"pending"}, 41 StepState: state, 42 Target: "completed", 43 Refresh: func() (interface{}, string, error) { 44 resp, err := ec2conn.Snapshots([]string{s.snapshotId}, ec2.NewFilter()) 45 if err != nil { 46 return nil, "", err 47 } 48 49 if len(resp.Snapshots) == 0 { 50 return nil, "", errors.New("No snapshots found.") 51 } 52 53 s := resp.Snapshots[0] 54 return s, s.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.Put("error", err) 62 ui.Error(err.Error()) 63 return multistep.ActionHalt 64 } 65 66 state.Put("snapshot_id", s.snapshotId) 67 return multistep.ActionContinue 68 } 69 70 func (s *StepSnapshot) Cleanup(state multistep.StateBag) { 71 if s.snapshotId == "" { 72 return 73 } 74 75 _, cancelled := state.GetOk(multistep.StateCancelled) 76 _, halted := state.GetOk(multistep.StateHalted) 77 78 if cancelled || halted { 79 ec2conn := state.Get("ec2").(*ec2.EC2) 80 ui := state.Get("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 }