github.phpd.cn/hashicorp/packer@v1.3.2/builder/alicloud/ecs/artifact.go (about) 1 package ecs 2 3 import ( 4 "fmt" 5 "log" 6 "sort" 7 "strings" 8 9 "github.com/denverdino/aliyungo/common" 10 "github.com/denverdino/aliyungo/ecs" 11 "github.com/hashicorp/packer/packer" 12 ) 13 14 type Artifact struct { 15 // A map of regions to alicloud image IDs. 16 AlicloudImages map[string]string 17 18 // BuilderId is the unique ID for the builder that created this alicloud image 19 BuilderIdValue string 20 21 // Alcloud connection for performing API stuff. 22 Client *ecs.Client 23 } 24 25 func (a *Artifact) BuilderId() string { 26 return a.BuilderIdValue 27 } 28 29 func (*Artifact) Files() []string { 30 // We have no files 31 return nil 32 } 33 34 func (a *Artifact) Id() string { 35 parts := make([]string, 0, len(a.AlicloudImages)) 36 for region, ecsImageId := range a.AlicloudImages { 37 parts = append(parts, fmt.Sprintf("%s:%s", region, ecsImageId)) 38 } 39 40 sort.Strings(parts) 41 return strings.Join(parts, ",") 42 } 43 44 func (a *Artifact) String() string { 45 alicloudImageStrings := make([]string, 0, len(a.AlicloudImages)) 46 for region, id := range a.AlicloudImages { 47 single := fmt.Sprintf("%s: %s", region, id) 48 alicloudImageStrings = append(alicloudImageStrings, single) 49 } 50 51 sort.Strings(alicloudImageStrings) 52 return fmt.Sprintf("Alicloud images were created:\n\n%s", strings.Join(alicloudImageStrings, "\n")) 53 } 54 55 func (a *Artifact) State(name string) interface{} { 56 switch name { 57 case "atlas.artifact.metadata": 58 return a.stateAtlasMetadata() 59 default: 60 return nil 61 } 62 } 63 64 func (a *Artifact) Destroy() error { 65 errors := make([]error, 0) 66 67 for region, imageId := range a.AlicloudImages { 68 log.Printf("Delete alicloud image ID (%s) from region (%s)", imageId, region) 69 70 // Get alicloud image metadata 71 images, _, err := a.Client.DescribeImages(&ecs.DescribeImagesArgs{ 72 RegionId: common.Region(region), 73 ImageId: imageId}) 74 if err != nil { 75 errors = append(errors, err) 76 } 77 if len(images) == 0 { 78 err := fmt.Errorf("Error retrieving details for alicloud image(%s), no alicloud images found", imageId) 79 errors = append(errors, err) 80 continue 81 } 82 //Unshared the shared account before destroy 83 sharePermissions, err := a.Client.DescribeImageSharePermission(&ecs.ModifyImageSharePermissionArgs{RegionId: common.Region(region), ImageId: imageId}) 84 if err != nil { 85 errors = append(errors, err) 86 } 87 accountsNumber := len(sharePermissions.Accounts.Account) 88 if accountsNumber > 0 { 89 accounts := make([]string, accountsNumber) 90 for index, account := range sharePermissions.Accounts.Account { 91 accounts[index] = account.AliyunId 92 } 93 err := a.Client.ModifyImageSharePermission(&ecs.ModifyImageSharePermissionArgs{ 94 95 RegionId: common.Region(region), 96 ImageId: imageId, 97 RemoveAccount: accounts, 98 }) 99 if err != nil { 100 errors = append(errors, err) 101 } 102 } 103 // Delete alicloud images 104 if err := a.Client.DeleteImage(common.Region(region), imageId); err != nil { 105 errors = append(errors, err) 106 } 107 //Delete the snapshot of this images 108 for _, diskDevices := range images[0].DiskDeviceMappings.DiskDeviceMapping { 109 if err := a.Client.DeleteSnapshot(diskDevices.SnapshotId); err != nil { 110 errors = append(errors, err) 111 } 112 } 113 114 } 115 116 if len(errors) > 0 { 117 if len(errors) == 1 { 118 return errors[0] 119 } else { 120 return &packer.MultiError{Errors: errors} 121 } 122 } 123 124 return nil 125 } 126 127 func (a *Artifact) stateAtlasMetadata() interface{} { 128 metadata := make(map[string]string) 129 for region, imageId := range a.AlicloudImages { 130 k := fmt.Sprintf("region.%s", region) 131 metadata[k] = imageId 132 } 133 134 return metadata 135 }