github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/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 "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 tools metadata at provider specific sources. 18 type SupportsCustomSources interface { 19 GetToolsSources() ([]simplestreams.DataSource, error) 20 } 21 22 // GetMetadataSources returns the sources to use when looking for 23 // simplestreams tools metadata. If env implements SupportsCustomSurces, 24 // the sources returned from that method will also be considered. 25 // The sources are configured to not use retries. 26 func GetMetadataSources(env environs.ConfigGetter) ([]simplestreams.DataSource, error) { 27 return GetMetadataSourcesWithRetries(env, false) 28 } 29 30 // GetMetadataSourcesWithRetries returns the sources to use when looking for 31 // simplestreams tools metadata. If env implements SupportsCustomSurces, 32 // the sources returned from that method will also be considered. 33 // The sources are configured to use retries according to the value of allowRetry. 34 func GetMetadataSourcesWithRetries(env environs.ConfigGetter, allowRetry bool) ([]simplestreams.DataSource, error) { 35 var sources []simplestreams.DataSource 36 config := env.Config() 37 if userURL, ok := config.ToolsURL(); ok { 38 verify := simplestreams.VerifySSLHostnames 39 if !config.SSLHostnameVerification() { 40 verify = simplestreams.NoVerifySSLHostnames 41 } 42 sources = append(sources, simplestreams.NewURLDataSource("tools-metadata-url", userURL, verify)) 43 } 44 if custom, ok := env.(SupportsCustomSources); ok { 45 customSources, err := custom.GetToolsSources() 46 if err != nil { 47 return nil, err 48 } 49 sources = append(sources, customSources...) 50 } 51 52 defaultURL, err := ToolsURL(DefaultBaseURL) 53 if err != nil { 54 return nil, err 55 } 56 if defaultURL != "" { 57 sources = append(sources, simplestreams.NewURLDataSource("default simplestreams", defaultURL, simplestreams.VerifySSLHostnames)) 58 } 59 for _, source := range sources { 60 source.SetAllowRetry(allowRetry) 61 } 62 return sources, nil 63 } 64 65 // ToolsURL returns a valid tools URL constructed from source. 66 // source may be a directory, or a URL like file://foo or http://foo. 67 func ToolsURL(source string) (string, error) { 68 if source == "" { 69 return "", nil 70 } 71 // If source is a raw directory, we need to append the file:// prefix 72 // so it can be used as a URL. 73 defaultURL := source 74 u, err := url.Parse(source) 75 if err != nil { 76 return "", fmt.Errorf("invalid default tools URL %s: %v", defaultURL, err) 77 } 78 if u.Scheme == "" { 79 defaultURL = "file://" + defaultURL 80 if !strings.HasSuffix(defaultURL, "/"+storage.BaseToolsPath) { 81 defaultURL = fmt.Sprintf("%s/%s", defaultURL, storage.BaseToolsPath) 82 } 83 } 84 return defaultURL, nil 85 }