github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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 "github.com/juju/juju/core/constraints" 8 "github.com/juju/juju/environs/imagemetadata" 9 "github.com/juju/juju/environs/instances" 10 ) 11 12 // filterImages returns only that subset of the input (in the same order) that 13 // this provider finds suitable. 14 func filterImages(images []*imagemetadata.ImageMetadata, ic *instances.InstanceConstraint) []*imagemetadata.ImageMetadata { 15 // Gather the images for each available storage type. 16 imagesByStorage := make(map[string][]*imagemetadata.ImageMetadata) 17 for _, image := range images { 18 imagesByStorage[image.Storage] = append(imagesByStorage[image.Storage], image) 19 } 20 logger.Debugf("images by storage type %+v", imagesByStorage) 21 // If a storage constraint has been specified, use that or else default to ssd. 22 storageTypes := []string{ssdStorage} 23 if ic != nil && len(ic.Storage) > 0 { 24 storageTypes = ic.Storage 25 } 26 logger.Debugf("filtering storage types %+v", storageTypes) 27 // Return the first set of images for which we have a storage type match. 28 for _, storageType := range storageTypes { 29 if len(imagesByStorage[storageType]) > 0 { 30 return imagesByStorage[storageType] 31 } 32 } 33 // If the user specifies an image ID during bootstrap, then it will not 34 // have a storage type. 35 return imagesByStorage[""] 36 } 37 38 // findInstanceSpec returns an InstanceSpec satisfying the supplied instanceConstraint. 39 func findInstanceSpec( 40 controller bool, 41 allImageMetadata []*imagemetadata.ImageMetadata, 42 instanceTypes []instances.InstanceType, 43 ic *instances.InstanceConstraint, 44 ) (*instances.InstanceSpec, error) { 45 logger.Debugf("received %d image(s)", len(allImageMetadata)) 46 if !controller { 47 ic.Constraints = withDefaultNonControllerConstraints(ic.Constraints) 48 } 49 suitableImages := filterImages(allImageMetadata, ic) 50 logger.Debugf("found %d suitable image(s)", len(suitableImages)) 51 images := instances.ImageMetadataToImages(suitableImages) 52 return instances.FindInstanceSpec(images, ic, instanceTypes) 53 } 54 55 // withDefaultNonControllerConstraints returns the given constraints, 56 // updated to choose a default instance type appropriate for a 57 // non-controller machine. We use this only if the user does not 58 // specify an instance-type, or cpu-power. 59 // 60 // At the time of writing, this will choose the cheapest non-burstable 61 // instance available in the account/region. At the time of writing, that 62 // is, for example: 63 // - m3.medium (for EC2-Classic) 64 // - c4.large (e.g. in ap-south-1) 65 func withDefaultNonControllerConstraints(cons constraints.Value) constraints.Value { 66 if !cons.HasInstanceType() && !cons.HasCpuPower() { 67 cons.CpuPower = instances.CpuPower(100) 68 } 69 return cons 70 }