Merge pull request #7050 from chhaj5236/feature/force_delete_copied

alicloud: delete copied image and snapshots if corresponding options are specified
This commit is contained in:
chhaj5236 2018-12-09 19:39:14 +08:00 committed by GitHub
commit c4782807de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 77 additions and 34 deletions

View File

@ -57,6 +57,11 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
return nil, err
}
if b.config.PackerConfig.PackerForce {
b.config.AlicloudImageForceDelete = true
b.config.AlicloudImageForceDeleteSnapshots = true
}
// Accumulate any errors
var errs *packer.MultiError
errs = packer.MultiErrorAppend(errs, b.config.AlicloudAccessConfig.Prepare(&b.config.ctx)...)
@ -169,6 +174,8 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
AlicloudImageForceDeleteSnapshots: b.config.AlicloudImageForceDeleteSnapshots,
AlicloudImageForceDelete: b.config.AlicloudImageForceDelete,
AlicloudImageName: b.config.AlicloudImageName,
AlicloudImageDestinationRegions: b.config.AlicloudImageConfig.AlicloudImageDestinationRegions,
AlicloudImageDestinationNames: b.config.AlicloudImageConfig.AlicloudImageDestinationNames,
})
if b.config.AlicloudImageIgnoreDataDisks {

View File

@ -24,7 +24,10 @@ func message(state multistep.StateBag, module string) {
func halt(state multistep.StateBag, err error, prefix string) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
err = fmt.Errorf("%s: %s", prefix, err)
if prefix != "" {
err = fmt.Errorf("%s: %s", prefix, err)
}
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt

View File

@ -15,53 +15,82 @@ type stepDeleteAlicloudImageSnapshots struct {
AlicloudImageForceDelete bool
AlicloudImageForceDeleteSnapshots bool
AlicloudImageName string
AlicloudImageDestinationRegions []string
AlicloudImageDestinationNames []string
}
func (s *stepDeleteAlicloudImageSnapshots) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
client := state.Get("client").(*ecs.Client)
ui := state.Get("ui").(packer.Ui)
config := state.Get("config").(*Config)
// Check for force delete
if s.AlicloudImageForceDelete {
images, _, err := client.DescribeImages(&ecs.DescribeImagesArgs{
RegionId: common.Region(config.AlicloudRegion),
ImageName: s.AlicloudImageName,
})
if len(images) < 1 {
err := s.deleteImageAndSnapshots(state, s.AlicloudImageName, config.AlicloudRegion)
if err != nil {
return halt(state, err, "")
}
numberOfName := len(s.AlicloudImageDestinationNames)
if numberOfName == 0 {
return multistep.ActionContinue
}
ui.Say(fmt.Sprintf("Deleting duplicated image and snapshot: %s", s.AlicloudImageName))
for _, image := range images {
if image.ImageOwnerAlias != string(ecs.ImageOwnerSelf) {
log.Printf("You can only delete instances based on customized images %s ", image.ImageId)
for index, destinationRegion := range s.AlicloudImageDestinationRegions {
if destinationRegion == config.AlicloudRegion {
continue
}
err = client.DeleteImage(common.Region(config.AlicloudRegion), image.ImageId)
if err != nil {
err := fmt.Errorf("Failed to delete image: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
if s.AlicloudImageForceDeleteSnapshots {
for _, diskDevice := range image.DiskDeviceMappings.DiskDeviceMapping {
if err := client.DeleteSnapshot(diskDevice.SnapshotId); err != nil {
err := fmt.Errorf("Deleting ECS snapshot failed: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
if index < numberOfName {
err = s.deleteImageAndSnapshots(state, s.AlicloudImageDestinationNames[index], destinationRegion)
if err != nil {
return halt(state, err, "")
}
} else {
break
}
}
}
return multistep.ActionContinue
}
func (s *stepDeleteAlicloudImageSnapshots) deleteImageAndSnapshots(state multistep.StateBag, imageName string, region string) error {
client := state.Get("client").(*ecs.Client)
ui := state.Get("ui").(packer.Ui)
images, _, err := client.DescribeImages(&ecs.DescribeImagesArgs{
RegionId: common.Region(region),
ImageName: imageName,
})
if len(images) < 1 {
return nil
}
ui.Say(fmt.Sprintf("Deleting duplicated image and snapshot in %s: %s", region, imageName))
for _, image := range images {
if image.ImageOwnerAlias != string(ecs.ImageOwnerSelf) {
log.Printf("You can not delete non-customized images: %s ", image.ImageId)
continue
}
err = client.DeleteImage(common.Region(region), image.ImageId)
if err != nil {
err := fmt.Errorf("Failed to delete image: %s", err)
return err
}
if s.AlicloudImageForceDeleteSnapshots {
for _, diskDevice := range image.DiskDeviceMappings.DiskDeviceMapping {
if err := client.DeleteSnapshot(diskDevice.SnapshotId); err != nil {
err := fmt.Errorf("Deleting ECS snapshot failed: %s", err)
return err
}
}
}
}
return nil
}
func (s *stepDeleteAlicloudImageSnapshots) Cleanup(state multistep.StateBag) {
}

View File

@ -158,13 +158,17 @@ builder.
those disks containing lots of data, it may require a higher timeout value.
- `image_force_delete` (boolean) - If this value is true, when the target
image name is duplicated with an existing image, it will delete the
existing image and then create the target image, otherwise, the creation
will fail. The default value is false.
image names including those copied are duplicated with existing images,
it will delete the existing images and then create the target images,
otherwise, the creation will fail. The default value is false. Check
`image_name` and `image_copy_names` options for names of target images.
If [-force](https://packer.io/docs/commands/build.html#force) option is provided
in `build` command, this option can be omitted and taken as true.
- `image_force_delete_snapshots` (boolean) - If this value is true, when
delete the duplicated existing image, the source snapshot of this image
will be delete either.
delete the duplicated existing images, the source snapshots of those images
will be delete either. If [-force](https://packer.io/docs/commands/build.html#force)
option is provided in `build` command, this option can be omitted and taken as true.
- `image_share_account` (array of string) - The IDs of to-be-added Aliyun
accounts to which the image is shared. The number of accounts is 1 to 10.