github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/vsphere/image_metadata.go (about)

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