launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/environs/imagemetadata/urls.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package imagemetadata 5 6 import ( 7 "fmt" 8 "net/url" 9 "strings" 10 11 "launchpad.net/juju-core/environs" 12 "launchpad.net/juju-core/environs/simplestreams" 13 "launchpad.net/juju-core/environs/storage" 14 ) 15 16 // SupportsCustomSources represents an environment that 17 // can host image metadata at provider specific sources. 18 type SupportsCustomSources interface { 19 GetImageSources() ([]simplestreams.DataSource, error) 20 } 21 22 // GetMetadataSources returns the sources to use when looking for 23 // simplestreams image id metadata for the given stream. If env implements 24 // SupportsCustomSources, the sources returned from that method will also 25 // be considered. 26 func GetMetadataSources(env environs.ConfigGetter) ([]simplestreams.DataSource, error) { 27 var sources []simplestreams.DataSource 28 config := env.Config() 29 if userURL, ok := config.ImageMetadataURL(); ok { 30 verify := simplestreams.VerifySSLHostnames 31 if !config.SSLHostnameVerification() { 32 verify = simplestreams.NoVerifySSLHostnames 33 } 34 sources = append(sources, simplestreams.NewURLDataSource(userURL, verify)) 35 } 36 if custom, ok := env.(SupportsCustomSources); ok { 37 customSources, err := custom.GetImageSources() 38 if err != nil { 39 return nil, err 40 } 41 sources = append(sources, customSources...) 42 } 43 44 defaultURL, err := ImageMetadataURL(DefaultBaseURL, config.ImageStream()) 45 if err != nil { 46 return nil, err 47 } 48 if defaultURL != "" { 49 sources = append(sources, simplestreams.NewURLDataSource(defaultURL, simplestreams.VerifySSLHostnames)) 50 } 51 return sources, nil 52 } 53 54 // ImageMetadataURL returns a valid image metadata URL constructed from source. 55 // source may be a directory, or a URL like file://foo or http://foo. 56 func ImageMetadataURL(source, stream string) (string, error) { 57 if source == "" { 58 return "", nil 59 } 60 // If the image metadata is coming from the official cloud images site, 61 // set up the correct path according to the images stream requested. 62 if source == UbuntuCloudImagesURL { 63 cloudImagesPath := ReleasedImagesPath 64 if stream != "" && stream != ReleasedStream { 65 cloudImagesPath = stream 66 } 67 source = fmt.Sprintf("%s/%s", source, cloudImagesPath) 68 } 69 // If source is a raw directory, we need to append the file:// prefix 70 // so it can be used as a URL. 71 defaultURL := source 72 u, err := url.Parse(source) 73 if err != nil { 74 return "", fmt.Errorf("invalid default image metadata URL %s: %v", defaultURL, err) 75 } 76 if u.Scheme == "" { 77 defaultURL = "file://" + defaultURL 78 if !strings.HasSuffix(defaultURL, "/"+storage.BaseImagesPath) { 79 defaultURL = fmt.Sprintf("%s/%s", defaultURL, storage.BaseImagesPath) 80 } 81 } 82 return defaultURL, nil 83 }