github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/environs/tools/urls.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package tools 5 6 import ( 7 "fmt" 8 "net/url" 9 "strings" 10 11 "github.com/juju/utils" 12 13 "github.com/juju/juju/environs" 14 "github.com/juju/juju/environs/simplestreams" 15 "github.com/juju/juju/environs/storage" 16 ) 17 18 // SupportsCustomSources represents an environment that 19 // can host tools metadata at provider specific sources. 20 type SupportsCustomSources interface { 21 GetToolsSources() ([]simplestreams.DataSource, error) 22 } 23 24 // GetMetadataSources returns the sources to use when looking for 25 // simplestreams tools metadata. If env implements SupportsCustomSurces, 26 // the sources returned from that method will also be considered. 27 // The sources are configured to not use retries. 28 func GetMetadataSources(env environs.ConfigGetter) ([]simplestreams.DataSource, error) { 29 return GetMetadataSourcesWithRetries(env, false) 30 } 31 32 // GetMetadataSourcesWithRetries returns the sources to use when looking for 33 // simplestreams tools metadata. If env implements SupportsCustomSurces, 34 // the sources returned from that method will also be considered. 35 // The sources are configured to use retries according to the value of allowRetry. 36 func GetMetadataSourcesWithRetries(env environs.ConfigGetter, allowRetry bool) ([]simplestreams.DataSource, error) { 37 var sources []simplestreams.DataSource 38 config := env.Config() 39 if userURL, ok := config.ToolsURL(); ok { 40 verify := utils.VerifySSLHostnames 41 if !config.SSLHostnameVerification() { 42 verify = utils.NoVerifySSLHostnames 43 } 44 sources = append(sources, simplestreams.NewURLDataSource("tools-metadata-url", userURL, verify)) 45 } 46 if custom, ok := env.(SupportsCustomSources); ok { 47 customSources, err := custom.GetToolsSources() 48 if err != nil { 49 return nil, err 50 } 51 sources = append(sources, customSources...) 52 } 53 54 defaultURL, err := ToolsURL(DefaultBaseURL) 55 if err != nil { 56 return nil, err 57 } 58 if defaultURL != "" { 59 sources = append(sources, 60 simplestreams.NewURLDataSource("default simplestreams", defaultURL, utils.VerifySSLHostnames)) 61 } 62 for _, source := range sources { 63 source.SetAllowRetry(allowRetry) 64 } 65 return sources, nil 66 } 67 68 // ToolsURL returns a valid tools URL constructed from source. 69 // source may be a directory, or a URL like file://foo or http://foo. 70 func ToolsURL(source string) (string, error) { 71 if source == "" { 72 return "", nil 73 } 74 // If source is a raw directory, we need to append the file:// prefix 75 // so it can be used as a URL. 76 defaultURL := source 77 u, err := url.Parse(source) 78 if err != nil { 79 return "", fmt.Errorf("invalid default tools URL %s: %v", defaultURL, err) 80 } 81 if u.Scheme == "" { 82 defaultURL = "file://" + defaultURL 83 if !strings.HasSuffix(defaultURL, "/"+storage.BaseToolsPath) { 84 defaultURL = fmt.Sprintf("%s/%s", defaultURL, storage.BaseToolsPath) 85 } 86 } 87 return defaultURL, nil 88 }