github.com/timsutton/packer@v1.3.2/builder/amazon/chroot/step_register_ami.go (about) 1 package chroot 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/aws/aws-sdk-go/aws" 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 // StepRegisterAMI creates the AMI. 15 type StepRegisterAMI struct { 16 RootVolumeSize int64 17 EnableAMIENASupport *bool 18 EnableAMISriovNetSupport bool 19 } 20 21 func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction { 22 config := state.Get("config").(*Config) 23 ec2conn := state.Get("ec2").(*ec2.EC2) 24 snapshotId := state.Get("snapshot_id").(string) 25 ui := state.Get("ui").(packer.Ui) 26 27 ui.Say("Registering the AMI...") 28 29 var ( 30 registerOpts *ec2.RegisterImageInput 31 mappings []*ec2.BlockDeviceMapping 32 image *ec2.Image 33 rootDeviceName string 34 ) 35 36 if config.FromScratch { 37 mappings = config.AMIBlockDevices.BuildAMIDevices() 38 rootDeviceName = config.RootDeviceName 39 } else { 40 image = state.Get("source_image").(*ec2.Image) 41 mappings = image.BlockDeviceMappings 42 rootDeviceName = *image.RootDeviceName 43 } 44 45 newMappings := make([]*ec2.BlockDeviceMapping, len(mappings)) 46 for i, device := range mappings { 47 newDevice := device 48 if *newDevice.DeviceName == rootDeviceName { 49 if newDevice.Ebs != nil { 50 newDevice.Ebs.SnapshotId = aws.String(snapshotId) 51 } else { 52 newDevice.Ebs = &ec2.EbsBlockDevice{SnapshotId: aws.String(snapshotId)} 53 } 54 55 if config.FromScratch || s.RootVolumeSize > *newDevice.Ebs.VolumeSize { 56 newDevice.Ebs.VolumeSize = aws.Int64(s.RootVolumeSize) 57 } 58 } 59 60 // assume working from a snapshot, so we unset the Encrypted field if set, 61 // otherwise AWS API will return InvalidParameter 62 if newDevice.Ebs != nil && newDevice.Ebs.Encrypted != nil { 63 newDevice.Ebs.Encrypted = nil 64 } 65 66 newMappings[i] = newDevice 67 } 68 69 if config.FromScratch { 70 registerOpts = &ec2.RegisterImageInput{ 71 Name: &config.AMIName, 72 Architecture: aws.String(ec2.ArchitectureValuesX8664), 73 RootDeviceName: aws.String(rootDeviceName), 74 VirtualizationType: aws.String(config.AMIVirtType), 75 BlockDeviceMappings: newMappings, 76 } 77 } else { 78 registerOpts = buildRegisterOpts(config, image, newMappings) 79 } 80 81 if s.EnableAMISriovNetSupport { 82 // Set SriovNetSupport to "simple". See http://goo.gl/icuXh5 83 // As of February 2017, this applies to C3, C4, D2, I2, R3, and M4 (excluding m4.16xlarge) 84 registerOpts.SriovNetSupport = aws.String("simple") 85 } 86 if s.EnableAMIENASupport != nil && *s.EnableAMIENASupport { 87 // Set EnaSupport to true 88 // As of February 2017, this applies to C5, I3, P2, R4, X1, and m4.16xlarge 89 registerOpts.EnaSupport = aws.Bool(true) 90 } 91 92 registerResp, err := ec2conn.RegisterImage(registerOpts) 93 if err != nil { 94 state.Put("error", fmt.Errorf("Error registering AMI: %s", err)) 95 ui.Error(state.Get("error").(error).Error()) 96 return multistep.ActionHalt 97 } 98 99 // Set the AMI ID in the state 100 ui.Say(fmt.Sprintf("AMI: %s", *registerResp.ImageId)) 101 amis := make(map[string]string) 102 amis[*ec2conn.Config.Region] = *registerResp.ImageId 103 state.Put("amis", amis) 104 105 ui.Say("Waiting for AMI to become ready...") 106 if err := awscommon.WaitUntilAMIAvailable(ctx, ec2conn, *registerResp.ImageId); err != nil { 107 err := fmt.Errorf("Error waiting for AMI: %s", err) 108 state.Put("error", err) 109 ui.Error(err.Error()) 110 return multistep.ActionHalt 111 } 112 113 return multistep.ActionContinue 114 } 115 116 func (s *StepRegisterAMI) Cleanup(state multistep.StateBag) {} 117 118 func buildRegisterOpts(config *Config, image *ec2.Image, mappings []*ec2.BlockDeviceMapping) *ec2.RegisterImageInput { 119 registerOpts := &ec2.RegisterImageInput{ 120 Name: &config.AMIName, 121 Architecture: image.Architecture, 122 RootDeviceName: image.RootDeviceName, 123 BlockDeviceMappings: mappings, 124 VirtualizationType: image.VirtualizationType, 125 } 126 127 if config.AMIVirtType != "" { 128 registerOpts.VirtualizationType = aws.String(config.AMIVirtType) 129 } 130 131 if config.AMIVirtType != "hvm" { 132 registerOpts.KernelId = image.KernelId 133 registerOpts.RamdiskId = image.RamdiskId 134 } 135 return registerOpts 136 }