Merge pull request #4223 from artburkart/closes_3320

Adds `force_delete_snapshot` flag
This commit is contained in:
Matthew Hooker 2016-11-30 12:53:34 -08:00 committed by GitHub
commit f9f9d82419
9 changed files with 80 additions and 12 deletions

View File

@ -244,8 +244,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
&StepEarlyCleanup{}, &StepEarlyCleanup{},
&StepSnapshot{}, &StepSnapshot{},
&awscommon.StepDeregisterAMI{ &awscommon.StepDeregisterAMI{
ForceDeregister: b.config.AMIForceDeregister, ForceDeregister: b.config.AMIForceDeregister,
AMIName: b.config.AMIName, ForceDeleteSnapshot: b.config.AMIForceDeleteSnapshot,
AMIName: b.config.AMIName,
}, },
&StepRegisterAMI{ &StepRegisterAMI{
RootVolumeSize: b.config.RootVolumeSize, RootVolumeSize: b.config.RootVolumeSize,

View File

@ -19,6 +19,7 @@ type AMIConfig struct {
AMITags map[string]string `mapstructure:"tags"` AMITags map[string]string `mapstructure:"tags"`
AMIEnhancedNetworking bool `mapstructure:"enhanced_networking"` AMIEnhancedNetworking bool `mapstructure:"enhanced_networking"`
AMIForceDeregister bool `mapstructure:"force_deregister"` AMIForceDeregister bool `mapstructure:"force_deregister"`
AMIForceDeleteSnapshot bool `mapstructure:"force_delete_snapshot"`
AMIEncryptBootVolume bool `mapstructure:"encrypt_boot"` AMIEncryptBootVolume bool `mapstructure:"encrypt_boot"`
SnapshotTags map[string]string `mapstructure:"snapshot_tags"` SnapshotTags map[string]string `mapstructure:"snapshot_tags"`
} }

View File

@ -10,15 +10,16 @@ import (
) )
type StepDeregisterAMI struct { type StepDeregisterAMI struct {
ForceDeregister bool ForceDeregister bool
AMIName string ForceDeleteSnapshot bool
AMIName string
} }
func (s *StepDeregisterAMI) Run(state multistep.StateBag) multistep.StepAction { func (s *StepDeregisterAMI) Run(state multistep.StateBag) multistep.StepAction {
ec2conn := state.Get("ec2").(*ec2.EC2) ec2conn := state.Get("ec2").(*ec2.EC2)
ui := state.Get("ui").(packer.Ui) ui := state.Get("ui").(packer.Ui)
// check for force deregister // Check for force deregister
if s.ForceDeregister { if s.ForceDeregister {
resp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ resp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{
Filters: []*ec2.Filter{{ Filters: []*ec2.Filter{{
@ -33,7 +34,7 @@ func (s *StepDeregisterAMI) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionHalt return multistep.ActionHalt
} }
// deregister image(s) by that name // Deregister image(s) by name
for _, i := range resp.Images { for _, i := range resp.Images {
_, err := ec2conn.DeregisterImage(&ec2.DeregisterImageInput{ _, err := ec2conn.DeregisterImage(&ec2.DeregisterImageInput{
ImageId: i.ImageId, ImageId: i.ImageId,
@ -46,6 +47,25 @@ func (s *StepDeregisterAMI) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionHalt return multistep.ActionHalt
} }
ui.Say(fmt.Sprintf("Deregistered AMI %s, id: %s", s.AMIName, *i.ImageId)) ui.Say(fmt.Sprintf("Deregistered AMI %s, id: %s", s.AMIName, *i.ImageId))
// Delete snapshot(s) by image
if s.ForceDeleteSnapshot {
for _, b := range i.BlockDeviceMappings {
if b.Ebs != nil {
_, err := ec2conn.DeleteSnapshot(&ec2.DeleteSnapshotInput{
SnapshotId: b.Ebs.SnapshotId,
})
if err != nil {
err := fmt.Errorf("Error deleting existing snapshot: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
ui.Say(fmt.Sprintf("Deleted snapshot: %s", *b.Ebs.SnapshotId))
}
}
}
} }
} }

View File

@ -166,8 +166,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
EnableEnhancedNetworking: b.config.AMIEnhancedNetworking, EnableEnhancedNetworking: b.config.AMIEnhancedNetworking,
}, },
&awscommon.StepDeregisterAMI{ &awscommon.StepDeregisterAMI{
ForceDeregister: b.config.AMIForceDeregister, ForceDeregister: b.config.AMIForceDeregister,
AMIName: b.config.AMIName, ForceDeleteSnapshot: b.config.AMIForceDeleteSnapshot,
AMIName: b.config.AMIName,
}, },
&stepCreateAMI{}, &stepCreateAMI{},
&stepCreateEncryptedAMICopy{}, &stepCreateEncryptedAMICopy{},

View File

@ -46,6 +46,22 @@ func TestBuilderAcc_forceDeregister(t *testing.T) {
}) })
} }
func TestBuilderAcc_forceDeleteSnapshot(t *testing.T) {
// Build the same AMI name twice, with force_delete_snapshot on the second run
builderT.Test(t, builderT.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Builder: &Builder{},
Template: buildForceDeleteSnapshotConfig("false", "dereg"),
SkipArtifactTeardown: true,
})
builderT.Test(t, builderT.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Builder: &Builder{},
Template: buildForceDeleteSnapshotConfig("true", "dereg"),
})
}
func TestBuilderAcc_amiSharing(t *testing.T) { func TestBuilderAcc_amiSharing(t *testing.T) {
builderT.Test(t, builderT.TestCase{ builderT.Test(t, builderT.TestCase{
PreCheck: func() { testAccPreCheck(t) }, PreCheck: func() { testAccPreCheck(t) },
@ -254,6 +270,21 @@ const testBuilderAccForceDeregister = `
} }
` `
const testBuilderAccForceDeleteSnapshot = `
{
"builders": [{
"type": "test",
"region": "us-east-1",
"instance_type": "m3.medium",
"source_ami": "ami-76b2a71e",
"ssh_username": "ubuntu",
"force_deregister": "%s",
"force_delete_snapshot": "%s",
"ami_name": "packer-test-%s"
}]
}
`
// share with catsby // share with catsby
const testBuilderAccSharing = ` const testBuilderAccSharing = `
{ {
@ -284,6 +315,10 @@ const testBuilderAccEncrypted = `
} }
` `
func buildForceDeregisterConfig(name, flag string) string { func buildForceDeregisterConfig(val, name string) string {
return fmt.Sprintf(testBuilderAccForceDeregister, name, flag) return fmt.Sprintf(testBuilderAccForceDeregister, val, name)
}
func buildForceDeleteSnapshotConfig(val, name string) string {
return fmt.Sprintf(testBuilderAccForceDeleteSnapshot, val, val, name)
} }

View File

@ -248,8 +248,9 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Debug: b.config.PackerDebug, Debug: b.config.PackerDebug,
}, },
&awscommon.StepDeregisterAMI{ &awscommon.StepDeregisterAMI{
ForceDeregister: b.config.AMIForceDeregister, ForceDeregister: b.config.AMIForceDeregister,
AMIName: b.config.AMIName, ForceDeleteSnapshot: b.config.AMIForceDeleteSnapshot,
AMIName: b.config.AMIName,
}, },
&StepRegisterAMI{}, &StepRegisterAMI{},
&awscommon.StepAMIRegionCopy{ &awscommon.StepAMIRegionCopy{

View File

@ -124,6 +124,9 @@ each category, the available configuration keys are alphabetized.
- `force_deregister` (boolean) - Force Packer to first deregister an existing - `force_deregister` (boolean) - Force Packer to first deregister an existing
AMI if one with the same name already exists. Default `false`. AMI if one with the same name already exists. Default `false`.
- `force_delete_snapshot` (boolean) - Force Packer to delete snapshots associated with
AMIs, which have been deregistered by `force_deregister`. Default `false`.
- `from_scratch` (boolean) - Build a new volume instead of starting from an - `from_scratch` (boolean) - Build a new volume instead of starting from an
existing AMI root volume snapshot. Default `false`. If true, `source_ami` is existing AMI root volume snapshot. Default `false`. If true, `source_ami` is
no longer used and the following options become required: no longer used and the following options become required:

View File

@ -155,6 +155,9 @@ builder.
- `force_deregister` (boolean) - Force Packer to first deregister an existing - `force_deregister` (boolean) - Force Packer to first deregister an existing
AMI if one with the same name already exists. Default `false`. AMI if one with the same name already exists. Default `false`.
- `force_delete_snapshot` (boolean) - Force Packer to delete snapshots associated with
AMIs, which have been deregistered by `force_deregister`. Default `false`.
- `encrypt_boot` (boolean) - Instruct packer to automatically create a copy of the - `encrypt_boot` (boolean) - Instruct packer to automatically create a copy of the
AMI with an encrypted boot volume (discarding the initial unencrypted AMI in the AMI with an encrypted boot volume (discarding the initial unencrypted AMI in the
process). Default `false`. process). Default `false`.

View File

@ -179,6 +179,9 @@ builder.
- `force_deregister` (boolean) - Force Packer to first deregister an existing - `force_deregister` (boolean) - Force Packer to first deregister an existing
AMI if one with the same name already exists. Default `false`. AMI if one with the same name already exists. Default `false`.
- `force_delete_snapshot` (boolean) - Force Packer to delete snapshots associated with
AMIs, which have been deregistered by `force_deregister`. Default `false`.
- `iam_instance_profile` (string) - The name of an [IAM instance - `iam_instance_profile` (string) - The name of an [IAM instance
profile](https://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html) profile](https://docs.aws.amazon.com/IAM/latest/UserGuide/instance-profiles.html)
to launch the EC2 instance with. to launch the EC2 instance with.