github.phpd.cn/hashicorp/packer@v1.3.2/builder/amazon/chroot/step_snapshot.go (about)

     1  package chroot
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/aws/aws-sdk-go/service/ec2"
     9  	awscommon "github.com/hashicorp/packer/builder/amazon/common"
    10  	"github.com/hashicorp/packer/helper/multistep"
    11  	"github.com/hashicorp/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(ctx context.Context, 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  	description := fmt.Sprintf("Packer: %s", time.Now().String())
    29  
    30  	createSnapResp, err := ec2conn.CreateSnapshot(&ec2.CreateSnapshotInput{
    31  		VolumeId:    &volumeId,
    32  		Description: &description,
    33  	})
    34  	if err != nil {
    35  		err := fmt.Errorf("Error creating snapshot: %s", err)
    36  		state.Put("error", err)
    37  		ui.Error(err.Error())
    38  		return multistep.ActionHalt
    39  	}
    40  
    41  	// Set the snapshot ID so we can delete it later
    42  	s.snapshotId = *createSnapResp.SnapshotId
    43  	ui.Message(fmt.Sprintf("Snapshot ID: %s", s.snapshotId))
    44  
    45  	// Wait for the snapshot to be ready
    46  	err = awscommon.WaitUntilSnapshotDone(ctx, ec2conn, s.snapshotId)
    47  	if err != nil {
    48  		err := fmt.Errorf("Error waiting for snapshot: %s", err)
    49  		state.Put("error", err)
    50  		ui.Error(err.Error())
    51  		return multistep.ActionHalt
    52  	}
    53  
    54  	state.Put("snapshot_id", s.snapshotId)
    55  
    56  	snapshots := map[string][]string{
    57  		*ec2conn.Config.Region: {s.snapshotId},
    58  	}
    59  	state.Put("snapshots", snapshots)
    60  
    61  	return multistep.ActionContinue
    62  }
    63  
    64  func (s *StepSnapshot) Cleanup(state multistep.StateBag) {
    65  	if s.snapshotId == "" {
    66  		return
    67  	}
    68  
    69  	_, cancelled := state.GetOk(multistep.StateCancelled)
    70  	_, halted := state.GetOk(multistep.StateHalted)
    71  
    72  	if cancelled || halted {
    73  		ec2conn := state.Get("ec2").(*ec2.EC2)
    74  		ui := state.Get("ui").(packer.Ui)
    75  		ui.Say("Removing snapshot since we cancelled or halted...")
    76  		_, err := ec2conn.DeleteSnapshot(&ec2.DeleteSnapshotInput{SnapshotId: &s.snapshotId})
    77  		if err != nil {
    78  			ui.Error(fmt.Sprintf("Error: %s", err))
    79  		}
    80  	}
    81  }