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  }