github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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  			Stream: env.ecfg.ImageStream(),
    44  		},
    45  	}
    46  	sources, err := environs.ImageMetadataSources(env)
    47  	if err != nil {
    48  		return nil, errors.Trace(err)
    49  	}
    50  
    51  	matchingImages, err := imageMetadataFetch(sources, ic)
    52  	if err != nil {
    53  		return nil, errors.Trace(err)
    54  	}
    55  	if len(matchingImages) == 0 {
    56  		return nil, errors.Errorf("no matching images found for given constraints: %v", ic)
    57  	}
    58  
    59  	return matchingImages[0], nil
    60  }
    61  
    62  func imageMetadataFetch(sources []simplestreams.DataSource, cons *imagemetadata.ImageConstraint) ([]*OvaFileMetadata, error) {
    63  	params := simplestreams.GetMetadataParams{
    64  		StreamsVersion:   imagemetadata.StreamsVersionV1,
    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  }