simplify block devices utilisation by removing intermediary types

This commit is contained in:
Adrien Delorme 2019-06-18 12:37:47 +02:00
parent 78b29d1a74
commit ff2e0298ba
16 changed files with 65 additions and 101 deletions

View File

@ -26,10 +26,11 @@ const BuilderId = "mitchellh.amazon.chroot"
// Config is the configuration that is chained through the steps and
// settable from the template.
type Config struct {
common.PackerConfig `mapstructure:",squash"`
awscommon.AMIBlockDevices `mapstructure:",squash"`
awscommon.AMIConfig `mapstructure:",squash"`
awscommon.AccessConfig `mapstructure:",squash"`
common.PackerConfig `mapstructure:",squash"`
AMIMappings awscommon.BlockDevices `mapstructure:"ami_block_device_mappings" required:"false"`
LaunchMappings awscommon.BlockDevices `mapstructure:"launch_block_device_mappings" required:"false"`
awscommon.AMIConfig `mapstructure:",squash"`
awscommon.AccessConfig `mapstructure:",squash"`
// This is a list of devices to
// mount into the chroot environment. This configuration parameter requires
// some additional documentation which is in the Chroot

View File

@ -82,7 +82,7 @@ func buildBaseRegisterOpts(config *Config, sourceImage *ec2.Image, rootVolumeSiz
generatingNewBlockDeviceMappings := config.FromScratch || len(config.AMIMappings) > 0
if generatingNewBlockDeviceMappings {
mappings = config.AMIBlockDevices.BuildAMIDevices()
mappings = config.AMIMappings.Build()
rootDeviceName = config.RootDeviceName
} else {
// If config.FromScratch is false, source image must be set

View File

@ -92,11 +92,9 @@ func TestStepRegisterAmi_buildRegisterOptsFromScratch(t *testing.T) {
config := Config{
FromScratch: true,
PackerConfig: common.PackerConfig{},
AMIBlockDevices: amazon.AMIBlockDevices{
AMIMappings: []amazon.BlockDevice{
{
DeviceName: rootDeviceName,
},
AMIMappings: []amazon.BlockDevice{
{
DeviceName: rootDeviceName,
},
},
RootDeviceName: rootDeviceName,
@ -169,11 +167,9 @@ func TestStepRegisterAmi_buildRegisterOptFromExistingImageWithBlockDeviceMapping
config := Config{
FromScratch: false,
PackerConfig: common.PackerConfig{},
AMIBlockDevices: amazon.AMIBlockDevices{
AMIMappings: []amazon.BlockDevice{
{
DeviceName: rootDeviceName,
},
AMIMappings: []amazon.BlockDevice{
{
DeviceName: rootDeviceName,
},
},
RootDeviceName: rootDeviceName,

View File

@ -56,23 +56,12 @@ type BlockDevice struct {
OmitFromArtifact bool `mapstructure:"omit_from_artifact"`
}
type BlockDevices struct {
AMIBlockDevices `mapstructure:",squash"`
LaunchBlockDevices `mapstructure:",squash"`
}
type BlockDevices []BlockDevice
type AMIBlockDevices struct {
AMIMappings []BlockDevice `mapstructure:"ami_block_device_mappings" required:"false"`
}
type LaunchBlockDevices struct {
LaunchMappings []BlockDevice `mapstructure:"launch_block_device_mappings" required:"false"`
}
func buildBlockDevices(b []BlockDevice) []*ec2.BlockDeviceMapping {
func (bds BlockDevices) Build() []*ec2.BlockDeviceMapping {
var blockDevices []*ec2.BlockDeviceMapping
for _, blockDevice := range b {
for _, blockDevice := range bds {
mapping := &ec2.BlockDeviceMapping{
DeviceName: aws.String(blockDevice.DeviceName),
}
@ -133,32 +122,19 @@ func (b *BlockDevice) Prepare(ctx *interpolate.Context) error {
return nil
}
func (b *BlockDevices) Prepare(ctx *interpolate.Context) (errs []error) {
for _, d := range b.AMIMappings {
if err := d.Prepare(ctx); err != nil {
errs = append(errs, fmt.Errorf("AMIMapping: %s", err.Error()))
}
}
for _, d := range b.LaunchMappings {
if err := d.Prepare(ctx); err != nil {
errs = append(errs, fmt.Errorf("LaunchMapping: %s", err.Error()))
func (bds BlockDevices) Prepare(ctx *interpolate.Context) (errs []error) {
for _, block := range bds {
if err := block.Prepare(ctx); err != nil {
errs = append(errs, err)
}
}
return errs
}
func (b *AMIBlockDevices) BuildAMIDevices() []*ec2.BlockDeviceMapping {
return buildBlockDevices(b.AMIMappings)
}
func (b *LaunchBlockDevices) BuildLaunchDevices() []*ec2.BlockDeviceMapping {
return buildBlockDevices(b.LaunchMappings)
}
func (b *LaunchBlockDevices) GetOmissions() map[string]bool {
func (b BlockDevices) GetOmissions() map[string]bool {
omitMap := make(map[string]bool)
for _, blockDevice := range b.LaunchMappings {
for _, blockDevice := range b {
omitMap[blockDevice.DeviceName] = blockDevice.OmitFromArtifact
}

View File

@ -145,23 +145,19 @@ func TestBlockDevice(t *testing.T) {
}
for _, tc := range cases {
amiBlockDevices := AMIBlockDevices{
AMIMappings: []BlockDevice{*tc.Config},
}
var amiBlockDevices BlockDevices = []BlockDevice{*tc.Config}
launchBlockDevices := LaunchBlockDevices{
LaunchMappings: []BlockDevice{*tc.Config},
}
var launchBlockDevices BlockDevices = []BlockDevice{*tc.Config}
expected := []*ec2.BlockDeviceMapping{tc.Result}
amiResults := amiBlockDevices.BuildAMIDevices()
amiResults := amiBlockDevices.Build()
if !reflect.DeepEqual(expected, amiResults) {
t.Fatalf("Bad block device, \nexpected: %#v\n\ngot: %#v",
expected, amiResults)
}
launchResults := launchBlockDevices.BuildLaunchDevices()
launchResults := launchBlockDevices.Build()
if !reflect.DeepEqual(expected, launchResults) {
t.Fatalf("Bad block device, \nexpected: %#v\n\ngot: %#v",
expected, launchResults)

View File

@ -14,7 +14,7 @@ import (
// remain after termination of the instance. These volumes are typically ones
// that are marked as "delete on terminate:false" in the source_ami of a build.
type StepCleanupVolumes struct {
BlockDevices BlockDevices
LaunchMappings BlockDevices
}
func (s *StepCleanupVolumes) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
@ -79,7 +79,7 @@ func (s *StepCleanupVolumes) Cleanup(state multistep.StateBag) {
// Filter out any devices created as part of the launch mappings, since
// we'll let amazon follow the `delete_on_termination` setting.
for _, b := range s.BlockDevices.LaunchMappings {
for _, b := range s.LaunchMappings {
for volKey, volName := range volList {
if volName == b.DeviceName {
delete(volList, volKey)

View File

@ -21,7 +21,7 @@ import (
type StepRunSourceInstance struct {
AssociatePublicIpAddress bool
BlockDevices BlockDevices
LaunchMappings BlockDevices
Comm *communicator.Config
Ctx interpolate.Context
Debug bool
@ -111,7 +111,7 @@ func (s *StepRunSourceInstance) Run(ctx context.Context, state multistep.StateBa
MaxCount: aws.Int64(1),
MinCount: aws.Int64(1),
IamInstanceProfile: &ec2.IamInstanceProfileSpecification{Name: &s.IamInstanceProfile},
BlockDeviceMappings: s.BlockDevices.BuildLaunchDevices(),
BlockDeviceMappings: s.LaunchMappings.Build(),
Placement: &ec2.Placement{AvailabilityZone: &az},
EbsOptimized: &s.EbsOptimized,
}

View File

@ -23,7 +23,7 @@ import (
type StepRunSpotInstance struct {
AssociatePublicIpAddress bool
BlockDevices BlockDevices
LaunchMappings BlockDevices
BlockDurationMinutes int64
Debug bool
Comm *communicator.Config
@ -106,7 +106,7 @@ func (s *StepRunSpotInstance) CreateTemplateData(userData *string, az string,
// LaunchTemplateEbsBlockDeviceRequest structs are themselves
// identical except for the struct's name, so you can cast one directly
// into the other.
blockDeviceMappings := s.BlockDevices.BuildLaunchDevices()
blockDeviceMappings := s.LaunchMappings.Build()
var launchMappingRequests []*ec2.LaunchTemplateBlockDeviceMappingRequest
for _, mapping := range blockDeviceMappings {
launchRequest := &ec2.LaunchTemplateBlockDeviceMappingRequest{

View File

@ -71,7 +71,7 @@ func tStateSpot() multistep.StateBag {
state.Put("ui", &packer.BasicUi{
Reader: new(bytes.Buffer),
Writer: new(bytes.Buffer),
})
})
state.Put("availability_zone", "us-east-1c")
state.Put("securityGroupIds", []string{"sg-0b8984db72f213dc3"})
state.Put("subnet_id", "subnet-077fde4e")
@ -82,16 +82,9 @@ func tStateSpot() multistep.StateBag {
func getBasicStep() *StepRunSpotInstance {
stepRunSpotInstance := StepRunSpotInstance{
AssociatePublicIpAddress: false,
BlockDevices: BlockDevices{
AMIBlockDevices: AMIBlockDevices{
AMIMappings: []BlockDevice(nil),
},
LaunchBlockDevices: LaunchBlockDevices{
LaunchMappings: []BlockDevice(nil),
},
},
BlockDurationMinutes: 0,
Debug: false,
LaunchMappings: []BlockDevice(nil),
BlockDurationMinutes: 0,
Debug: false,
Comm: &communicator.Config{
SSH: communicator.SSH{
SSHKeyPairName: "foo",

View File

@ -28,7 +28,8 @@ type Config struct {
common.PackerConfig `mapstructure:",squash"`
awscommon.AccessConfig `mapstructure:",squash"`
awscommon.AMIConfig `mapstructure:",squash"`
awscommon.BlockDevices `mapstructure:",squash"`
AMIMappings awscommon.BlockDevices `mapstructure:"ami_block_device_mappings" required:"false"`
LaunchMappings awscommon.BlockDevices `mapstructure:"launch_block_device_mappings" required:"false"`
awscommon.RunConfig `mapstructure:",squash"`
// Tags to apply to the volumes that are *launched* to create the AMI.
// These tags are *not* applied to the resulting AMI unless they're
@ -74,7 +75,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs,
b.config.AMIConfig.Prepare(&b.config.AccessConfig, &b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.BlockDevices.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.AMIMappings.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.LaunchMappings.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...)
if b.config.IsSpotInstance() && ((b.config.AMIENASupport != nil && *b.config.AMIENASupport) || b.config.AMISriovNetSupport) {
@ -116,7 +118,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
if b.config.IsSpotInstance() {
instanceStep = &awscommon.StepRunSpotInstance{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
BlockDevices: b.config.BlockDevices,
LaunchMappings: b.config.LaunchMappings,
BlockDurationMinutes: b.config.BlockDurationMinutes,
Ctx: b.config.ctx,
Comm: &b.config.RunConfig.Comm,
@ -139,7 +141,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
} else {
instanceStep = &awscommon.StepRunSourceInstance{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
BlockDevices: b.config.BlockDevices,
LaunchMappings: b.config.LaunchMappings,
Comm: &b.config.RunConfig.Comm,
Ctx: b.config.ctx,
Debug: b.config.PackerDebug,
@ -192,7 +194,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
TemporarySGSourceCidrs: b.config.TemporarySGSourceCidrs,
},
&awscommon.StepCleanupVolumes{
BlockDevices: b.config.BlockDevices,
LaunchMappings: b.config.LaunchMappings,
},
instanceStep,
&awscommon.StepGetPassword{

View File

@ -35,7 +35,7 @@ func (s *stepCreateAMI) Run(ctx context.Context, state multistep.StateBag) multi
createOpts := &ec2.CreateImageInput{
InstanceId: instance.InstanceId,
Name: &amiName,
BlockDeviceMappings: config.BlockDevices.BuildAMIDevices(),
BlockDeviceMappings: config.AMIMappings.Build(),
}
createResp, err := ec2conn.CreateImage(createOpts)

View File

@ -25,7 +25,8 @@ type Config struct {
common.PackerConfig `mapstructure:",squash"`
awscommon.AccessConfig `mapstructure:",squash"`
awscommon.RunConfig `mapstructure:",squash"`
awscommon.BlockDevices `mapstructure:",squash"`
AMIMappings awscommon.BlockDevices `mapstructure:"ami_block_device_mappings" required:"false"`
LaunchMappings awscommon.BlockDevices `mapstructure:"launch_block_device_mappings" required:"false"`
awscommon.AMIConfig `mapstructure:",squash"`
// A block device mapping describing the root device of the AMI. This looks
// like the mappings in `ami_block_device_mapping`, except with an
@ -83,7 +84,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs,
b.config.AMIConfig.Prepare(&b.config.AccessConfig, &b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.BlockDevices.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.AMIMappings.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.LaunchMappings.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.RootDevice.Prepare(&b.config.ctx)...)
if b.config.AMIVirtType == "" {
@ -91,7 +93,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
}
foundRootVolume := false
for _, launchDevice := range b.config.BlockDevices.LaunchMappings {
for _, launchDevice := range b.config.LaunchMappings {
if launchDevice.DeviceName == b.config.RootDevice.SourceDeviceName {
foundRootVolume = true
if launchDevice.OmitFromArtifact {
@ -154,7 +156,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
if b.config.IsSpotInstance() {
instanceStep = &awscommon.StepRunSpotInstance{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
BlockDevices: b.config.BlockDevices,
LaunchMappings: b.config.LaunchMappings,
BlockDurationMinutes: b.config.BlockDurationMinutes,
Ctx: b.config.ctx,
Comm: &b.config.RunConfig.Comm,
@ -177,7 +179,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
} else {
instanceStep = &awscommon.StepRunSourceInstance{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
BlockDevices: b.config.BlockDevices,
LaunchMappings: b.config.LaunchMappings,
Comm: &b.config.RunConfig.Comm,
Ctx: b.config.ctx,
Debug: b.config.PackerDebug,
@ -196,8 +198,8 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
}
}
amiDevices := b.config.BuildAMIDevices()
launchDevices := b.config.BuildLaunchDevices()
amiDevices := b.config.AMIMappings.Build()
launchDevices := b.config.LaunchMappings.Build()
// Build the steps
steps := []multistep.Step{
@ -233,7 +235,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
TemporarySGSourceCidrs: b.config.TemporarySGSourceCidrs,
},
&awscommon.StepCleanupVolumes{
BlockDevices: b.config.BlockDevices,
LaunchMappings: b.config.LaunchMappings,
},
instanceStep,
&awscommon.StepGetPassword{
@ -263,7 +265,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
},
&StepSnapshotVolumes{
LaunchDevices: launchDevices,
SnapshotOmitMap: b.config.GetOmissions(),
SnapshotOmitMap: b.config.LaunchMappings.GetOmissions(),
},
&awscommon.StepDeregisterAMI{
AccessConfig: &b.config.AccessConfig,
@ -279,7 +281,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
EnableAMISriovNetSupport: b.config.AMISriovNetSupport,
EnableAMIENASupport: b.config.AMIENASupport,
Architecture: b.config.Architecture,
LaunchOmitMap: b.config.GetOmissions(),
LaunchOmitMap: b.config.LaunchMappings.GetOmissions(),
},
&awscommon.StepAMIRegionCopy{
AccessConfig: &b.config.AccessConfig,

View File

@ -26,9 +26,5 @@ func commonBlockDevices(mappings []BlockDevice, ctx *interpolate.Context) (awsco
result[i] = *interpolateBlockDev.(*awscommon.BlockDevice)
}
return awscommon.BlockDevices{
LaunchBlockDevices: awscommon.LaunchBlockDevices{
LaunchMappings: result,
},
}, nil
return result, nil
}

View File

@ -124,7 +124,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
if b.config.IsSpotInstance() {
instanceStep = &awscommon.StepRunSpotInstance{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
BlockDevices: b.config.launchBlockDevices,
LaunchMappings: b.config.launchBlockDevices,
BlockDurationMinutes: b.config.BlockDurationMinutes,
Ctx: b.config.ctx,
Comm: &b.config.RunConfig.Comm,
@ -146,7 +146,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
} else {
instanceStep = &awscommon.StepRunSourceInstance{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
BlockDevices: b.config.launchBlockDevices,
LaunchMappings: b.config.launchBlockDevices,
Comm: &b.config.RunConfig.Comm,
Ctx: b.config.ctx,
Debug: b.config.PackerDebug,

View File

@ -30,7 +30,8 @@ type Config struct {
common.PackerConfig `mapstructure:",squash"`
awscommon.AccessConfig `mapstructure:",squash"`
awscommon.AMIConfig `mapstructure:",squash"`
awscommon.BlockDevices `mapstructure:",squash"`
AMIMappings awscommon.BlockDevices `mapstructure:"ami_block_device_mappings" required:"false"`
LaunchMappings awscommon.BlockDevices `mapstructure:"launch_block_device_mappings" required:"false"`
awscommon.RunConfig `mapstructure:",squash"`
// Your AWS account ID. This is required for bundling
// the AMI. This is not the same as the access key. You can find your
@ -157,7 +158,8 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
// Accumulate any errors
var errs *packer.MultiError
errs = packer.MultiErrorAppend(errs, b.config.AccessConfig.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.BlockDevices.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.AMIMappings.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.LaunchMappings.Prepare(&b.config.ctx)...)
errs = packer.MultiErrorAppend(errs,
b.config.AMIConfig.Prepare(&b.config.AccessConfig, &b.config.ctx)...)
errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...)
@ -222,7 +224,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
if b.config.IsSpotInstance() {
instanceStep = &awscommon.StepRunSpotInstance{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
BlockDevices: b.config.BlockDevices,
LaunchMappings: b.config.LaunchMappings,
BlockDurationMinutes: b.config.BlockDurationMinutes,
Ctx: b.config.ctx,
Comm: &b.config.RunConfig.Comm,
@ -242,7 +244,7 @@ func (b *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (pack
} else {
instanceStep = &awscommon.StepRunSourceInstance{
AssociatePublicIpAddress: b.config.AssociatePublicIpAddress,
BlockDevices: b.config.BlockDevices,
LaunchMappings: b.config.LaunchMappings,
Comm: &b.config.RunConfig.Comm,
Ctx: b.config.ctx,
Debug: b.config.PackerDebug,

View File

@ -26,7 +26,7 @@ func (s *StepRegisterAMI) Run(ctx context.Context, state multistep.StateBag) mul
registerOpts := &ec2.RegisterImageInput{
ImageLocation: &manifestPath,
Name: aws.String(config.AMIName),
BlockDeviceMappings: config.BlockDevices.BuildAMIDevices(),
BlockDeviceMappings: config.AMIMappings.Build(),
}
if config.AMIVirtType != "" {