github.com/rothwerx/packer@v0.9.0/builder/amazon/chroot/step_register_ami.go (about) 1 package chroot 2 3 import ( 4 "fmt" 5 6 "github.com/aws/aws-sdk-go/aws" 7 "github.com/aws/aws-sdk-go/service/ec2" 8 "github.com/mitchellh/multistep" 9 awscommon "github.com/mitchellh/packer/builder/amazon/common" 10 "github.com/mitchellh/packer/packer" 11 ) 12 13 // StepRegisterAMI creates the AMI. 14 type StepRegisterAMI struct { 15 RootVolumeSize int64 16 } 17 18 func (s *StepRegisterAMI) Run(state multistep.StateBag) multistep.StepAction { 19 config := state.Get("config").(*Config) 20 ec2conn := state.Get("ec2").(*ec2.EC2) 21 image := state.Get("source_image").(*ec2.Image) 22 snapshotId := state.Get("snapshot_id").(string) 23 ui := state.Get("ui").(packer.Ui) 24 25 ui.Say("Registering the AMI...") 26 blockDevices := make([]*ec2.BlockDeviceMapping, len(image.BlockDeviceMappings)) 27 for i, device := range image.BlockDeviceMappings { 28 newDevice := device 29 if *newDevice.DeviceName == *image.RootDeviceName { 30 if newDevice.Ebs != nil { 31 newDevice.Ebs.SnapshotId = aws.String(snapshotId) 32 } else { 33 newDevice.Ebs = &ec2.EbsBlockDevice{SnapshotId: aws.String(snapshotId)} 34 } 35 36 if s.RootVolumeSize > *newDevice.Ebs.VolumeSize { 37 newDevice.Ebs.VolumeSize = aws.Int64(s.RootVolumeSize) 38 } 39 } 40 41 // assume working from a snapshot, so we unset the Encrypted field if set, 42 // otherwise AWS API will return InvalidParameter 43 if newDevice.Ebs != nil && newDevice.Ebs.Encrypted != nil { 44 newDevice.Ebs.Encrypted = nil 45 } 46 47 blockDevices[i] = newDevice 48 } 49 50 registerOpts := buildRegisterOpts(config, image, blockDevices) 51 52 // Set SriovNetSupport to "simple". See http://goo.gl/icuXh5 53 if config.AMIEnhancedNetworking { 54 registerOpts.SriovNetSupport = aws.String("simple") 55 } 56 57 registerResp, err := ec2conn.RegisterImage(registerOpts) 58 if err != nil { 59 state.Put("error", fmt.Errorf("Error registering AMI: %s", err)) 60 ui.Error(state.Get("error").(error).Error()) 61 return multistep.ActionHalt 62 } 63 64 // Set the AMI ID in the state 65 ui.Say(fmt.Sprintf("AMI: %s", *registerResp.ImageId)) 66 amis := make(map[string]string) 67 amis[*ec2conn.Config.Region] = *registerResp.ImageId 68 state.Put("amis", amis) 69 70 // Wait for the image to become ready 71 stateChange := awscommon.StateChangeConf{ 72 Pending: []string{"pending"}, 73 Target: "available", 74 Refresh: awscommon.AMIStateRefreshFunc(ec2conn, *registerResp.ImageId), 75 StepState: state, 76 } 77 78 ui.Say("Waiting for AMI to become ready...") 79 if _, err := awscommon.WaitForState(&stateChange); err != nil { 80 err := fmt.Errorf("Error waiting for AMI: %s", err) 81 state.Put("error", err) 82 ui.Error(err.Error()) 83 return multistep.ActionHalt 84 } 85 86 return multistep.ActionContinue 87 } 88 89 func (s *StepRegisterAMI) Cleanup(state multistep.StateBag) {} 90 91 func buildRegisterOpts(config *Config, image *ec2.Image, blockDevices []*ec2.BlockDeviceMapping) *ec2.RegisterImageInput { 92 registerOpts := &ec2.RegisterImageInput{ 93 Name: &config.AMIName, 94 Architecture: image.Architecture, 95 RootDeviceName: image.RootDeviceName, 96 BlockDeviceMappings: blockDevices, 97 VirtualizationType: image.VirtualizationType, 98 } 99 100 if config.AMIVirtType != "" { 101 registerOpts.VirtualizationType = aws.String(config.AMIVirtType) 102 } 103 104 if config.AMIVirtType != "hvm" { 105 registerOpts.KernelId = image.KernelId 106 registerOpts.RamdiskId = image.RamdiskId 107 } 108 109 return registerOpts 110 }