github.com/ttysteale/packer@v0.8.2-0.20150708160520-e5f8ea386ed8/builder/amazon/common/artifact.go (about) 1 package common 2 3 import ( 4 "fmt" 5 "log" 6 "sort" 7 "strings" 8 9 "github.com/aws/aws-sdk-go/aws" 10 "github.com/aws/aws-sdk-go/service/ec2" 11 "github.com/mitchellh/packer/packer" 12 ) 13 14 // Artifact is an artifact implementation that contains built AMIs. 15 type Artifact struct { 16 // A map of regions to AMI IDs. 17 Amis map[string]string 18 19 // BuilderId is the unique ID for the builder that created this AMI 20 BuilderIdValue string 21 22 // EC2 connection for performing API stuff. 23 Conn *ec2.EC2 24 } 25 26 func (a *Artifact) BuilderId() string { 27 return a.BuilderIdValue 28 } 29 30 func (*Artifact) Files() []string { 31 // We have no files 32 return nil 33 } 34 35 func (a *Artifact) Id() string { 36 parts := make([]string, 0, len(a.Amis)) 37 for region, amiId := range a.Amis { 38 parts = append(parts, fmt.Sprintf("%s:%s", region, amiId)) 39 } 40 41 sort.Strings(parts) 42 return strings.Join(parts, ",") 43 } 44 45 func (a *Artifact) String() string { 46 amiStrings := make([]string, 0, len(a.Amis)) 47 for region, id := range a.Amis { 48 single := fmt.Sprintf("%s: %s", region, id) 49 amiStrings = append(amiStrings, single) 50 } 51 52 sort.Strings(amiStrings) 53 return fmt.Sprintf("AMIs were created:\n\n%s", strings.Join(amiStrings, "\n")) 54 } 55 56 func (a *Artifact) State(name string) interface{} { 57 switch name { 58 case "atlas.artifact.metadata": 59 return a.stateAtlasMetadata() 60 default: 61 return nil 62 } 63 } 64 65 func (a *Artifact) Destroy() error { 66 errors := make([]error, 0) 67 68 for region, imageId := range a.Amis { 69 log.Printf("Deregistering image ID (%s) from region (%s)", imageId, region) 70 71 regionConfig := &aws.Config{ 72 Credentials: a.Conn.Config.Credentials, 73 Region: region, 74 } 75 regionConn := ec2.New(regionConfig) 76 77 input := &ec2.DeregisterImageInput{ 78 ImageID: &imageId, 79 } 80 if _, err := regionConn.DeregisterImage(input); err != nil { 81 errors = append(errors, err) 82 } 83 84 // TODO(mitchellh): Delete the snapshots associated with an AMI too 85 } 86 87 if len(errors) > 0 { 88 if len(errors) == 1 { 89 return errors[0] 90 } else { 91 return &packer.MultiError{errors} 92 } 93 } 94 95 return nil 96 } 97 98 func (a *Artifact) stateAtlasMetadata() interface{} { 99 metadata := make(map[string]string) 100 for region, imageId := range a.Amis { 101 k := fmt.Sprintf("region.%s", region) 102 metadata[k] = imageId 103 } 104 105 return metadata 106 }