github.com/mhilton/juju-juju@v0.0.0-20150901100907-a94dd2c73455/provider/vsphere/image_metadata.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // +build !gccgo
     5  
     6  package vsphere
     7  
     8  import (
     9  	"github.com/juju/errors"
    10  
    11  	"github.com/juju/juju/environs"
    12  	"github.com/juju/juju/environs/imagemetadata"
    13  	"github.com/juju/juju/environs/simplestreams"
    14  )
    15  
    16  /*
    17  Vmware provider use "image-download" data type for simplestream. That's why we use custom implementation of imagemetadata.Fetch function.
    18  We also use custom struct OvfFileMetadata that corresponds to the format used in "image-downloads" simplestream datatype.
    19  Also we use custom append function to filter content of the stream and keep only items, that have ova FileType
    20  */
    21  
    22  type OvaFileMetadata struct {
    23  	Url      string
    24  	Arch     string `json:"arch"`
    25  	Size     int    `json:"size"`
    26  	Path     string `json:"path"`
    27  	FileType string `json:"ftype"`
    28  	Sha256   string `json:"sha256"`
    29  	Md5      string `json:"md5"`
    30  }
    31  
    32  func init() {
    33  	simplestreams.RegisterStructTags(OvaFileMetadata{})
    34  }
    35  
    36  func findImageMetadata(env *environ, args environs.StartInstanceParams) (*OvaFileMetadata, error) {
    37  	arches := args.Tools.Arches()
    38  	series := args.Tools.OneSeries()
    39  	ic := &imagemetadata.ImageConstraint{
    40  		LookupParams: simplestreams.LookupParams{
    41  			Series: []string{series},
    42  			Arches: arches,
    43  		},
    44  	}
    45  	sources, err := environs.ImageMetadataSources(env)
    46  	if err != nil {
    47  		return nil, errors.Trace(err)
    48  	}
    49  
    50  	matchingImages, err := imageMetadataFetch(sources, ic)
    51  	if err != nil {
    52  		return nil, errors.Trace(err)
    53  	}
    54  	if len(matchingImages) == 0 {
    55  		return nil, errors.Errorf("no matching images found for given constraints: %v", ic)
    56  	}
    57  
    58  	return matchingImages[0], nil
    59  }
    60  
    61  func imageMetadataFetch(sources []simplestreams.DataSource, cons *imagemetadata.ImageConstraint) ([]*OvaFileMetadata, error) {
    62  	params := simplestreams.GetMetadataParams{
    63  		StreamsVersion:   imagemetadata.StreamsVersionV1,
    64  		OnlySigned:       false,
    65  		LookupConstraint: cons,
    66  		ValueParams: simplestreams.ValueParams{
    67  			DataType:      "image-downloads",
    68  			FilterFunc:    appendMatchingFunc,
    69  			ValueTemplate: OvaFileMetadata{},
    70  		},
    71  	}
    72  	items, _, err := simplestreams.GetMetadata(sources, params)
    73  	if err != nil {
    74  		return nil, errors.Trace(err)
    75  	}
    76  	metadata := make([]*OvaFileMetadata, len(items))
    77  	for i, md := range items {
    78  		metadata[i] = md.(*OvaFileMetadata)
    79  	}
    80  	return metadata, nil
    81  }
    82  
    83  func appendMatchingFunc(source simplestreams.DataSource, matchingImages []interface{},
    84  	images map[string]interface{}, cons simplestreams.LookupConstraint) ([]interface{}, error) {
    85  
    86  	for _, val := range images {
    87  		file := val.(*OvaFileMetadata)
    88  		if file.FileType == "ova" {
    89  			//ignore error for url data source
    90  			url, _ := source.URL(file.Path)
    91  			file.Url = url
    92  			matchingImages = append(matchingImages, file)
    93  		}
    94  	}
    95  	return matchingImages, nil
    96  }