github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/provider/ec2/image.go (about) 1 // Copyright 2011, 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package ec2 5 6 import ( 7 "fmt" 8 9 "github.com/juju/juju/environs/imagemetadata" 10 "github.com/juju/juju/environs/instances" 11 "github.com/juju/juju/environs/simplestreams" 12 ) 13 14 // signedImageDataOnly is defined here to allow tests to override the content. 15 // If true, only inline PGP signed image metadata will be used. 16 var signedImageDataOnly = true 17 18 // defaultCpuPower is larger the smallest instance's cpuPower, and no larger than 19 // any other instance type's cpuPower. It is used when no explicit CpuPower 20 // constraint exists, preventing the smallest instance from being chosen unless 21 // the user has clearly indicated that they are willing to accept poor performance. 22 const defaultCpuPower = 100 23 24 // filterImages returns only that subset of the input (in the same order) that 25 // this provider finds suitable. 26 func filterImages(images []*imagemetadata.ImageMetadata) []*imagemetadata.ImageMetadata { 27 result := make([]*imagemetadata.ImageMetadata, 0, len(images)) 28 for _, image := range images { 29 // For now, we only want images with "ebs" storage. 30 if image.Storage == ebsStorage { 31 result = append(result, image) 32 } 33 } 34 return result 35 } 36 37 // findInstanceSpec returns an InstanceSpec satisfying the supplied instanceConstraint. 38 func findInstanceSpec( 39 sources []simplestreams.DataSource, stream string, ic *instances.InstanceConstraint) (*instances.InstanceSpec, error) { 40 41 if ic.Constraints.CpuPower == nil { 42 ic.Constraints.CpuPower = instances.CpuPower(defaultCpuPower) 43 } 44 ec2Region := allRegions[ic.Region] 45 imageConstraint := imagemetadata.NewImageConstraint(simplestreams.LookupParams{ 46 CloudSpec: simplestreams.CloudSpec{ic.Region, ec2Region.EC2Endpoint}, 47 Series: []string{ic.Series}, 48 Arches: ic.Arches, 49 Stream: stream, 50 }) 51 matchingImages, _, err := imagemetadata.Fetch( 52 sources, simplestreams.DefaultIndexPath, imageConstraint, signedImageDataOnly) 53 if err != nil { 54 return nil, err 55 } 56 if len(matchingImages) == 0 { 57 logger.Warningf("no matching image meta data for constraints: %v", ic) 58 } 59 suitableImages := filterImages(matchingImages) 60 images := instances.ImageMetadataToImages(suitableImages) 61 62 // Make a copy of the known EC2 instance types, filling in the cost for the specified region. 63 regionCosts := allRegionCosts[ic.Region] 64 if len(regionCosts) == 0 && len(allRegionCosts) > 0 { 65 return nil, fmt.Errorf("no instance types found in %s", ic.Region) 66 } 67 68 var itypesWithCosts []instances.InstanceType 69 for _, itype := range allInstanceTypes { 70 cost, ok := regionCosts[itype.Name] 71 if !ok { 72 continue 73 } 74 itWithCost := itype 75 itWithCost.Cost = cost 76 itypesWithCosts = append(itypesWithCosts, itWithCost) 77 } 78 return instances.FindInstanceSpec(images, ic, itypesWithCosts) 79 }