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