github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/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  )
    12  
    13  // defaultCpuPower is larger the smallest instance's cpuPower, and no larger than
    14  // any other instance type's cpuPower. It is used when no explicit CpuPower
    15  // constraint exists, preventing the smallest instance from being chosen unless
    16  // the user has clearly indicated that they are willing to accept poor performance.
    17  const defaultCpuPower = 100
    18  
    19  // filterImages returns only that subset of the input (in the same order) that
    20  // this provider finds suitable.
    21  func filterImages(images []*imagemetadata.ImageMetadata, ic *instances.InstanceConstraint) []*imagemetadata.ImageMetadata {
    22  	// Gather the images for each available storage type.
    23  	imagesByStorage := make(map[string][]*imagemetadata.ImageMetadata)
    24  	for _, image := range images {
    25  		imagesByStorage[image.Storage] = append(imagesByStorage[image.Storage], image)
    26  	}
    27  	// If a storage constraint has been specified, use that or else default to ssd.
    28  	storageTypes := []string{ssdStorage}
    29  	if ic != nil && len(ic.Storage) > 0 {
    30  		storageTypes = ic.Storage
    31  	}
    32  	// Return the first set of images for which we have a storage type match.
    33  	for _, storageType := range storageTypes {
    34  		if len(imagesByStorage[storageType]) > 0 {
    35  			return imagesByStorage[storageType]
    36  		}
    37  	}
    38  	// If the user specifies an image ID during bootstrap, then it will not
    39  	// have a storage type.
    40  	return imagesByStorage[""]
    41  }
    42  
    43  // findInstanceSpec returns an InstanceSpec satisfying the supplied instanceConstraint.
    44  func findInstanceSpec(
    45  	allImageMetadata []*imagemetadata.ImageMetadata,
    46  	ic *instances.InstanceConstraint,
    47  ) (*instances.InstanceSpec, error) {
    48  
    49  	// If the instance type is set, don't also set a default CPU power
    50  	// as this is implied.
    51  	cons := ic.Constraints
    52  	if cons.CpuPower == nil && (cons.InstanceType == nil || *cons.InstanceType == "") {
    53  		ic.Constraints.CpuPower = instances.CpuPower(defaultCpuPower)
    54  	}
    55  	suitableImages := filterImages(allImageMetadata, ic)
    56  	images := instances.ImageMetadataToImages(suitableImages)
    57  
    58  	// Make a copy of the known EC2 instance types, filling in the cost for the specified region.
    59  	regionCosts := allRegionCosts[ic.Region]
    60  	if len(regionCosts) == 0 && len(allRegionCosts) > 0 {
    61  		return nil, fmt.Errorf("no instance types found in %s", ic.Region)
    62  	}
    63  
    64  	var itypesWithCosts []instances.InstanceType
    65  	for _, itype := range allInstanceTypes {
    66  		cost, ok := regionCosts[itype.Name]
    67  		if !ok {
    68  			continue
    69  		}
    70  		itWithCost := itype
    71  		itWithCost.Cost = cost
    72  		itypesWithCosts = append(itypesWithCosts, itWithCost)
    73  	}
    74  	return instances.FindInstanceSpec(images, ic, itypesWithCosts)
    75  }