Merge lp:~wallyworld/juju-core/verbose-metadata-validation into lp:~go-bot/juju-core/trunk
- verbose-metadata-validation
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Ian Booth |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2376 |
Proposed branch: | lp:~wallyworld/juju-core/verbose-metadata-validation |
Merge into: | lp:~go-bot/juju-core/trunk |
Diff against target: |
2037 lines (+389/-386) 45 files modified
cmd/plugins/juju-metadata/toolsmetadata.go (+5/-15) cmd/plugins/juju-metadata/validateimagemetadata.go (+27/-8) cmd/plugins/juju-metadata/validateimagemetadata_test.go (+18/-3) cmd/plugins/juju-metadata/validatetoolsmetadata.go (+27/-7) cmd/plugins/juju-metadata/validatetoolsmetadata_test.go (+33/-37) environs/bootstrap/bootstrap_test.go (+2/-1) environs/imagemetadata/generate.go (+2/-2) environs/imagemetadata/generate_test.go (+2/-2) environs/imagemetadata/simplestreams.go (+6/-4) environs/imagemetadata/simplestreams_test.go (+24/-7) environs/imagemetadata/testing/testing.go (+1/-1) environs/imagemetadata/urls.go (+2/-2) environs/imagemetadata/validation.go (+10/-10) environs/imagemetadata/validation_test.go (+11/-4) environs/instances/image_test.go (+2/-1) environs/simplestreams/datasource.go (+12/-2) environs/simplestreams/datasource_test.go (+4/-4) environs/simplestreams/simplestreams.go (+27/-9) environs/simplestreams/simplestreams_test.go (+9/-3) environs/storage/storage.go (+11/-5) environs/storage/storage_test.go (+6/-6) environs/sync/sync.go (+1/-1) environs/tools/boilerplate.go (+0/-153) environs/tools/simplestreams.go (+12/-9) environs/tools/simplestreams_test.go (+40/-18) environs/tools/testing/testing.go (+1/-1) environs/tools/tools.go (+2/-2) environs/tools/urls.go (+2/-2) environs/tools/validation.go (+12/-8) environs/tools/validation_test.go (+49/-34) provider/azure/environ.go (+3/-3) provider/azure/instancetype.go (+1/-1) provider/azure/instancetype_test.go (+3/-2) provider/common/mock_test.go (+1/-1) provider/dummy/environs.go (+2/-2) provider/ec2/ec2.go (+2/-2) provider/ec2/image.go (+1/-1) provider/ec2/image_test.go (+4/-2) provider/ec2/local_test.go (+1/-1) provider/local/environ.go (+1/-1) provider/maas/environ.go (+2/-2) provider/manual/environ.go (+1/-1) provider/openstack/image.go (+1/-1) provider/openstack/local_test.go (+1/-1) provider/openstack/provider.go (+5/-4) |
To merge this branch: | bzr merge lp:~wallyworld/juju-core/verbose-metadata-validation |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju Engineering | Pending | ||
Review via email: mp+209162@code.launchpad.net |
Commit message
Add metadata to simplestreams validation
juju metadata validate-
metadata to show how the lookup was performed.
Along the way, drive by fixes were done to delete
old code and improve existing code associated with
simplestreams.
Description of the change
Add metadata to simplestreams validation
juju metadata validate-
metadata to show how the lookup was performed.
Along the way, drive by fixes were done to delete
old code and improve existing code associated with
simplestreams.
A picture is worth 1000 words:
ian@wallyworld:~$ juju metadata validate-images
ImageIds:
- ami-99999af0
- ami-0d9c9f64
- ami-6f969506
- ami-0b9c9f62
- ami-359c9f5c
- ami-a18c8fc8
Region: us-east-1
Resolve Metadata:
source: default cloud images
signed: true
indexURL: http://
ian@wallyworld:~$ juju metadata validate-tools
Matching Tools Versions:
- 1.17.4-
- 1.17.4-precise-i386
Resolve Metadata:
source: default simplestreams
signed: false
indexURL: https:/
mirrorURL: https:/
Ian Booth (wallyworld) wrote : | # |
Ian Booth (wallyworld) wrote : | # |
Please take a look.
Tim Penhey (thumper) wrote : | # |
On 2014/03/04 05:51:30, wallyworld wrote:
> Please take a look.
LGTM - although was wondering why the resolve information wasn't
encapsulated in the error rather than a separate parameter.
Tim Penhey (thumper) wrote : | # |
On 2014/03/05 01:54:16, thumper wrote:
> On 2014/03/04 05:51:30, wallyworld wrote:
> > Please take a look.
> LGTM - although was wondering why the resolve information wasn't
encapsulated in
> the error rather than a separate parameter.
Ah, we show the resolution info on success as well. nm.
Preview Diff
1 | === modified file 'cmd/plugins/juju-metadata/toolsmetadata.go' |
2 | --- cmd/plugins/juju-metadata/toolsmetadata.go 2014-01-31 00:14:11 +0000 |
3 | +++ cmd/plugins/juju-metadata/toolsmetadata.go 2014-03-04 05:51:00 +0000 |
4 | @@ -5,9 +5,6 @@ |
5 | |
6 | import ( |
7 | "fmt" |
8 | - "net/url" |
9 | - "path" |
10 | - "strings" |
11 | |
12 | "github.com/loggo/loggo" |
13 | "launchpad.net/gnuflag" |
14 | @@ -60,19 +57,12 @@ |
15 | const minorVersion = -1 |
16 | toolsList, err := envtools.ReadList(sourceStorage, version.Current.Major, minorVersion) |
17 | if err == envtools.ErrNoTools { |
18 | - source := envtools.DefaultBaseURL |
19 | - var u *url.URL |
20 | - u, err = url.Parse(source) |
21 | + var source string |
22 | + source, err = envtools.ToolsURL(envtools.DefaultBaseURL) |
23 | if err != nil { |
24 | - return fmt.Errorf("invalid tools source %s: %v", source, err) |
25 | - } |
26 | - if u.Scheme == "" { |
27 | - source = "file://" + source |
28 | - if !strings.HasSuffix(source, "/"+storage.BaseToolsPath) { |
29 | - source = path.Join(source, storage.BaseToolsPath) |
30 | - } |
31 | - } |
32 | - sourceDataSource := simplestreams.NewURLDataSource(source, simplestreams.VerifySSLHostnames) |
33 | + return err |
34 | + } |
35 | + sourceDataSource := simplestreams.NewURLDataSource("local source", source, simplestreams.VerifySSLHostnames) |
36 | toolsList, err = envtools.FindToolsForCloud( |
37 | []simplestreams.DataSource{sourceDataSource}, simplestreams.CloudSpec{}, |
38 | version.Current.Major, minorVersion, coretools.Filter{}) |
39 | |
40 | === modified file 'cmd/plugins/juju-metadata/validateimagemetadata.go' |
41 | --- cmd/plugins/juju-metadata/validateimagemetadata.go 2014-02-13 02:46:58 +0000 |
42 | +++ cmd/plugins/juju-metadata/validateimagemetadata.go 2014-03-04 05:51:00 +0000 |
43 | @@ -22,6 +22,7 @@ |
44 | // ValidateImageMetadataCommand |
45 | type ValidateImageMetadataCommand struct { |
46 | cmd.EnvCommandBase |
47 | + out cmd.Output |
48 | providerType string |
49 | metadataDir string |
50 | series string |
51 | @@ -79,6 +80,7 @@ |
52 | |
53 | func (c *ValidateImageMetadataCommand) SetFlags(f *gnuflag.FlagSet) { |
54 | c.EnvCommandBase.SetFlags(f) |
55 | + c.out.AddFlags(f, "smart", cmd.DefaultFormatters) |
56 | f.StringVar(&c.providerType, "p", "", "the provider type eg ec2, openstack") |
57 | f.StringVar(&c.metadataDir, "d", "", "directory where metadata files are found") |
58 | f.StringVar(&c.series, "s", "", "the series for which to validate (overrides env config series)") |
59 | @@ -180,26 +182,43 @@ |
60 | if _, err := os.Stat(dir); err != nil { |
61 | return err |
62 | } |
63 | - params.Sources = []simplestreams.DataSource{simplestreams.NewURLDataSource("file://"+dir, simplestreams.VerifySSLHostnames)} |
64 | + params.Sources = []simplestreams.DataSource{ |
65 | + simplestreams.NewURLDataSource( |
66 | + "local metadata directory", "file://"+dir, simplestreams.VerifySSLHostnames), |
67 | + } |
68 | } |
69 | params.Stream = c.stream |
70 | |
71 | - image_ids, err := imagemetadata.ValidateImageMetadata(params) |
72 | + image_ids, resolveInfo, err := imagemetadata.ValidateImageMetadata(params) |
73 | if err != nil { |
74 | + if resolveInfo != nil { |
75 | + metadata := map[string]interface{}{ |
76 | + "Resolve Metadata": *resolveInfo, |
77 | + } |
78 | + if metadataYaml, yamlErr := cmd.FormatYaml(metadata); yamlErr == nil { |
79 | + err = fmt.Errorf("%v\n%v", err, string(metadataYaml)) |
80 | + } |
81 | + } |
82 | return err |
83 | } |
84 | - |
85 | if len(image_ids) > 0 { |
86 | - fmt.Fprintf(context.Stdout, "matching image ids for region %q:\n%s\n", params.Region, strings.Join(image_ids, "\n")) |
87 | + metadata := map[string]interface{}{ |
88 | + "ImageIds": image_ids, |
89 | + "Region": params.Region, |
90 | + "Resolve Metadata": *resolveInfo, |
91 | + } |
92 | + c.out.Write(context, metadata) |
93 | } else { |
94 | - var urls []string |
95 | + var sources []string |
96 | for _, s := range params.Sources { |
97 | url, err := s.URL("") |
98 | - if err != nil { |
99 | - urls = append(urls, url) |
100 | + if err == nil { |
101 | + sources = append(sources, fmt.Sprintf("- %s (%s)", s.Description(), url)) |
102 | } |
103 | } |
104 | - return fmt.Errorf("no matching image ids for region %s using URLs:\n%s", params.Region, strings.Join(urls, "\n")) |
105 | + return fmt.Errorf( |
106 | + "no matching image ids for region %s using sources:\n%s", |
107 | + params.Region, strings.Join(sources, "\n")) |
108 | } |
109 | return nil |
110 | } |
111 | |
112 | === modified file 'cmd/plugins/juju-metadata/validateimagemetadata_test.go' |
113 | --- cmd/plugins/juju-metadata/validateimagemetadata_test.go 2014-01-29 02:09:39 +0000 |
114 | +++ cmd/plugins/juju-metadata/validateimagemetadata_test.go 2014-03-04 05:51:00 +0000 |
115 | @@ -133,7 +133,9 @@ |
116 | c.Assert(code, gc.Equals, 0) |
117 | errOut := ctx.Stdout.(*bytes.Buffer).String() |
118 | strippedOut := strings.Replace(errOut, "\n", "", -1) |
119 | - c.Check(strippedOut, gc.Matches, `matching image ids for region "us-east-1":.*`) |
120 | + c.Check( |
121 | + strippedOut, gc.Matches, |
122 | + `ImageIds:.*"1234".*Region:.*us-east-1.*Resolve Metadata:.*source: local metadata directory.*`) |
123 | } |
124 | |
125 | func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataUsingEnvironment(c *gc.C) { |
126 | @@ -169,7 +171,9 @@ |
127 | c.Assert(code, gc.Equals, 0) |
128 | errOut := ctx.Stdout.(*bytes.Buffer).String() |
129 | strippedOut := strings.Replace(errOut, "\n", "", -1) |
130 | - c.Check(strippedOut, gc.Matches, `matching image ids for region "us-west-1":.*`) |
131 | + c.Check( |
132 | + strippedOut, gc.Matches, |
133 | + `ImageIds:.*"1234".*Region:.*us-west-1.*Resolve Metadata:.*source: local metadata directory.*`) |
134 | } |
135 | |
136 | func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataNoMatch(c *gc.C) { |
137 | @@ -187,6 +191,9 @@ |
138 | "-u", "https://ec2.region.amazonaws.com", "-d", s.metadataDir}, |
139 | ) |
140 | c.Assert(code, gc.Equals, 1) |
141 | + errOut := ctx.Stderr.(*bytes.Buffer).String() |
142 | + strippedOut := strings.Replace(errOut, "\n", "", -1) |
143 | + c.Check(strippedOut, gc.Matches, `.*Resolve Metadata:.*`) |
144 | } |
145 | |
146 | func (s *ValidateImageMetadataSuite) TestOpenstackLocalMetadataWithManualParams(c *gc.C) { |
147 | @@ -200,7 +207,9 @@ |
148 | c.Assert(code, gc.Equals, 0) |
149 | errOut := ctx.Stdout.(*bytes.Buffer).String() |
150 | strippedOut := strings.Replace(errOut, "\n", "", -1) |
151 | - c.Check(strippedOut, gc.Matches, `matching image ids for region "region-2":.*`) |
152 | + c.Check( |
153 | + strippedOut, gc.Matches, |
154 | + `ImageIds:.*"1234".*Region:.*region-2.*Resolve Metadata:.*source: local metadata directory.*`) |
155 | } |
156 | |
157 | func (s *ValidateImageMetadataSuite) TestOpenstackLocalMetadataNoMatch(c *gc.C) { |
158 | @@ -212,10 +221,16 @@ |
159 | "-u", "some-auth-url", "-d", s.metadataDir}, |
160 | ) |
161 | c.Assert(code, gc.Equals, 1) |
162 | + errOut := ctx.Stderr.(*bytes.Buffer).String() |
163 | + strippedOut := strings.Replace(errOut, "\n", "", -1) |
164 | + c.Check(strippedOut, gc.Matches, `.*Resolve Metadata:.*`) |
165 | code = cmd.Main( |
166 | &ValidateImageMetadataCommand{}, ctx, []string{ |
167 | "-p", "openstack", "-s", "raring", "-r", "region-3", |
168 | "-u", "some-auth-url", "-d", s.metadataDir}, |
169 | ) |
170 | c.Assert(code, gc.Equals, 1) |
171 | + errOut = ctx.Stderr.(*bytes.Buffer).String() |
172 | + strippedOut = strings.Replace(errOut, "\n", "", -1) |
173 | + c.Check(strippedOut, gc.Matches, `.*Resolve Metadata:.*`) |
174 | } |
175 | |
176 | === modified file 'cmd/plugins/juju-metadata/validatetoolsmetadata.go' |
177 | --- cmd/plugins/juju-metadata/validatetoolsmetadata.go 2014-02-28 03:05:47 +0000 |
178 | +++ cmd/plugins/juju-metadata/validatetoolsmetadata.go 2014-03-04 05:51:00 +0000 |
179 | @@ -21,6 +21,7 @@ |
180 | // ValidateToolsMetadataCommand |
181 | type ValidateToolsMetadataCommand struct { |
182 | cmd.EnvCommandBase |
183 | + out cmd.Output |
184 | providerType string |
185 | metadataDir string |
186 | series string |
187 | @@ -100,6 +101,7 @@ |
188 | |
189 | func (c *ValidateToolsMetadataCommand) SetFlags(f *gnuflag.FlagSet) { |
190 | c.EnvCommandBase.SetFlags(f) |
191 | + c.out.AddFlags(f, "smart", cmd.DefaultFormatters) |
192 | f.StringVar(&c.providerType, "p", "", "the provider type eg ec2, openstack") |
193 | f.StringVar(&c.metadataDir, "d", "", "directory where metadata files are found") |
194 | f.StringVar(&c.series, "s", "", "the series for which to validate (overrides env config series)") |
195 | @@ -191,30 +193,48 @@ |
196 | if _, err := os.Stat(c.metadataDir); err != nil { |
197 | return err |
198 | } |
199 | - params.Sources = []simplestreams.DataSource{simplestreams.NewURLDataSource("file://"+c.metadataDir, simplestreams.VerifySSLHostnames)} |
200 | + toolsURL, err := tools.ToolsURL(c.metadataDir) |
201 | + if err != nil { |
202 | + return err |
203 | + } |
204 | + params.Sources = []simplestreams.DataSource{simplestreams.NewURLDataSource( |
205 | + "local metadata directory", toolsURL, simplestreams.VerifySSLHostnames), |
206 | + } |
207 | } |
208 | |
209 | - versions, err := tools.ValidateToolsMetadata(&tools.ToolsMetadataLookupParams{ |
210 | + versions, resolveInfo, err := tools.ValidateToolsMetadata(&tools.ToolsMetadataLookupParams{ |
211 | MetadataLookupParams: *params, |
212 | Version: c.exactVersion, |
213 | Major: c.major, |
214 | Minor: c.minor, |
215 | }) |
216 | if err != nil { |
217 | + if resolveInfo != nil { |
218 | + metadata := map[string]interface{}{ |
219 | + "Resolve Metadata": *resolveInfo, |
220 | + } |
221 | + if metadataYaml, yamlErr := cmd.FormatYaml(metadata); yamlErr == nil { |
222 | + err = fmt.Errorf("%v\n%v", err, string(metadataYaml)) |
223 | + } |
224 | + } |
225 | return err |
226 | } |
227 | |
228 | if len(versions) > 0 { |
229 | - fmt.Fprintf(context.Stdout, "matching tools versions:\n%s\n", strings.Join(versions, "\n")) |
230 | + metadata := map[string]interface{}{ |
231 | + "Matching Tools Versions": versions, |
232 | + "Resolve Metadata": *resolveInfo, |
233 | + } |
234 | + c.out.Write(context, metadata) |
235 | } else { |
236 | - var urls []string |
237 | + var sources []string |
238 | for _, s := range params.Sources { |
239 | url, err := s.URL("") |
240 | - if err != nil { |
241 | - urls = append(urls, url) |
242 | + if err == nil { |
243 | + sources = append(sources, fmt.Sprintf("- %s (%s)", s.Description(), url)) |
244 | } |
245 | } |
246 | - return fmt.Errorf("no matching tools using URLs:\n%s", strings.Join(urls, "\n")) |
247 | + return fmt.Errorf("no matching tools using sources:\n%s", strings.Join(sources, "\n")) |
248 | } |
249 | return nil |
250 | } |
251 | |
252 | === modified file 'cmd/plugins/juju-metadata/validatetoolsmetadata_test.go' |
253 | --- cmd/plugins/juju-metadata/validatetoolsmetadata_test.go 2014-01-22 22:48:54 +0000 |
254 | +++ cmd/plugins/juju-metadata/validatetoolsmetadata_test.go 2014-03-04 05:51:00 +0000 |
255 | @@ -11,9 +11,8 @@ |
256 | gc "launchpad.net/gocheck" |
257 | |
258 | "launchpad.net/juju-core/cmd" |
259 | - "launchpad.net/juju-core/environs/simplestreams" |
260 | + "launchpad.net/juju-core/environs/filestorage" |
261 | "launchpad.net/juju-core/environs/tools" |
262 | - "launchpad.net/juju-core/juju/osenv" |
263 | coretesting "launchpad.net/juju-core/testing" |
264 | "launchpad.net/juju-core/testing/testbase" |
265 | "launchpad.net/juju-core/version" |
266 | @@ -21,7 +20,8 @@ |
267 | |
268 | type ValidateToolsMetadataSuite struct { |
269 | testbase.LoggingSuite |
270 | - home *coretesting.FakeHome |
271 | + home *coretesting.FakeHome |
272 | + metadataDir string |
273 | } |
274 | |
275 | var _ = gc.Suite(&ValidateToolsMetadataSuite{}) |
276 | @@ -72,16 +72,14 @@ |
277 | } |
278 | |
279 | func (s *ValidateToolsMetadataSuite) makeLocalMetadata(c *gc.C, version, region, series, endpoint string) error { |
280 | - tm := tools.ToolsMetadata{ |
281 | + tm := []*tools.ToolsMetadata{{ |
282 | Version: version, |
283 | Arch: "amd64", |
284 | Release: series, |
285 | - } |
286 | - cloudSpec := simplestreams.CloudSpec{ |
287 | - Region: region, |
288 | - Endpoint: endpoint, |
289 | - } |
290 | - _, err := tools.MakeBoilerplate(&tm, &cloudSpec, false) |
291 | + }} |
292 | + targetStorage, err := filestorage.NewFileStorageWriter(s.metadataDir, filestorage.UseDefaultTmpDir) |
293 | + c.Assert(err, gc.IsNil) |
294 | + err = tools.WriteMetadata(targetStorage, tm, false) |
295 | if err != nil { |
296 | return err |
297 | } |
298 | @@ -91,6 +89,7 @@ |
299 | func (s *ValidateToolsMetadataSuite) SetUpTest(c *gc.C) { |
300 | s.LoggingSuite.SetUpTest(c) |
301 | s.home = coretesting.MakeFakeHome(c, metadataTestEnvConfig) |
302 | + s.metadataDir = c.MkDir() |
303 | restore := testbase.PatchEnvironment("AWS_ACCESS_KEY_ID", "access") |
304 | s.AddCleanup(func(*gc.C) { restore() }) |
305 | restore = testbase.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "secret") |
306 | @@ -114,14 +113,13 @@ |
307 | func (s *ValidateToolsMetadataSuite) TestEc2LocalMetadataUsingEnvironment(c *gc.C) { |
308 | s.setupEc2LocalMetadata(c, "us-east-1") |
309 | ctx := coretesting.Context(c) |
310 | - metadataDir := osenv.JujuHomePath("") |
311 | code := cmd.Main( |
312 | - &ValidateToolsMetadataCommand{}, ctx, []string{"-e", "ec2", "-j", "1.11.4", "-d", metadataDir}, |
313 | + &ValidateToolsMetadataCommand{}, ctx, []string{"-e", "ec2", "-j", "1.11.4", "-d", s.metadataDir}, |
314 | ) |
315 | c.Assert(code, gc.Equals, 0) |
316 | errOut := ctx.Stdout.(*bytes.Buffer).String() |
317 | strippedOut := strings.Replace(errOut, "\n", "", -1) |
318 | - c.Check(strippedOut, gc.Matches, `matching tools versions:.*`) |
319 | + c.Check(strippedOut, gc.Matches, `Matching Tools Versions:.*Resolve Metadata.*`) |
320 | } |
321 | |
322 | func (s *ValidateToolsMetadataSuite) TestEc2LocalMetadataUsingIncompleteEnvironment(c *gc.C) { |
323 | @@ -141,123 +139,121 @@ |
324 | func (s *ValidateToolsMetadataSuite) TestEc2LocalMetadataWithManualParams(c *gc.C) { |
325 | s.setupEc2LocalMetadata(c, "us-west-1") |
326 | ctx := coretesting.Context(c) |
327 | - metadataDir := osenv.JujuHomePath("") |
328 | code := cmd.Main( |
329 | &ValidateToolsMetadataCommand{}, ctx, []string{ |
330 | "-p", "ec2", "-s", "precise", "-r", "us-west-1", "-j", "1.11.4", |
331 | - "-u", "https://ec2.us-west-1.amazonaws.com", "-d", metadataDir}, |
332 | + "-u", "https://ec2.us-west-1.amazonaws.com", "-d", s.metadataDir}, |
333 | ) |
334 | c.Assert(code, gc.Equals, 0) |
335 | errOut := ctx.Stdout.(*bytes.Buffer).String() |
336 | strippedOut := strings.Replace(errOut, "\n", "", -1) |
337 | - c.Check(strippedOut, gc.Matches, `matching tools versions:.*`) |
338 | + c.Check(strippedOut, gc.Matches, `Matching Tools Versions:.*Resolve Metadata.*`) |
339 | } |
340 | |
341 | func (s *ValidateToolsMetadataSuite) TestEc2LocalMetadataNoMatch(c *gc.C) { |
342 | s.setupEc2LocalMetadata(c, "us-east-1") |
343 | ctx := coretesting.Context(c) |
344 | - metadataDir := osenv.JujuHomePath("") |
345 | code := cmd.Main( |
346 | &ValidateToolsMetadataCommand{}, ctx, []string{ |
347 | "-p", "ec2", "-s", "raring", "-r", "us-west-1", |
348 | - "-u", "https://ec2.us-west-1.amazonaws.com", "-d", metadataDir}, |
349 | + "-u", "https://ec2.us-west-1.amazonaws.com", "-d", s.metadataDir}, |
350 | ) |
351 | c.Assert(code, gc.Equals, 1) |
352 | code = cmd.Main( |
353 | &ValidateToolsMetadataCommand{}, ctx, []string{ |
354 | "-p", "ec2", "-s", "precise", "-r", "region", |
355 | - "-u", "https://ec2.region.amazonaws.com", "-d", metadataDir}, |
356 | + "-u", "https://ec2.region.amazonaws.com", "-d", s.metadataDir}, |
357 | ) |
358 | c.Assert(code, gc.Equals, 1) |
359 | + errOut := ctx.Stderr.(*bytes.Buffer).String() |
360 | + strippedOut := strings.Replace(errOut, "\n", "", -1) |
361 | + c.Check(strippedOut, gc.Matches, `.*Resolve Metadata:.*`) |
362 | } |
363 | |
364 | func (s *ValidateToolsMetadataSuite) TestOpenstackLocalMetadataWithManualParams(c *gc.C) { |
365 | s.makeLocalMetadata(c, "1.11.4", "region-2", "raring", "some-auth-url") |
366 | ctx := coretesting.Context(c) |
367 | - metadataDir := osenv.JujuHomePath("") |
368 | code := cmd.Main( |
369 | &ValidateToolsMetadataCommand{}, ctx, []string{ |
370 | "-p", "openstack", "-s", "raring", "-r", "region-2", "-j", "1.11.4", |
371 | - "-u", "some-auth-url", "-d", metadataDir}, |
372 | + "-u", "some-auth-url", "-d", s.metadataDir}, |
373 | ) |
374 | c.Assert(code, gc.Equals, 0) |
375 | errOut := ctx.Stdout.(*bytes.Buffer).String() |
376 | strippedOut := strings.Replace(errOut, "\n", "", -1) |
377 | - c.Check(strippedOut, gc.Matches, `matching tools versions:.*`) |
378 | + c.Check(strippedOut, gc.Matches, `Matching Tools Versions:.*Resolve Metadata.*`) |
379 | } |
380 | |
381 | func (s *ValidateToolsMetadataSuite) TestOpenstackLocalMetadataNoMatch(c *gc.C) { |
382 | s.makeLocalMetadata(c, "1.11.4", "region-2", "raring", "some-auth-url") |
383 | ctx := coretesting.Context(c) |
384 | - metadataDir := osenv.JujuHomePath("") |
385 | code := cmd.Main( |
386 | &ValidateToolsMetadataCommand{}, ctx, []string{ |
387 | "-p", "openstack", "-s", "precise", "-r", "region-2", |
388 | - "-u", "some-auth-url", "-d", metadataDir}, |
389 | + "-u", "some-auth-url", "-d", s.metadataDir}, |
390 | ) |
391 | c.Assert(code, gc.Equals, 1) |
392 | code = cmd.Main( |
393 | &ValidateToolsMetadataCommand{}, ctx, []string{ |
394 | "-p", "openstack", "-s", "raring", "-r", "region-3", |
395 | - "-u", "some-auth-url", "-d", metadataDir}, |
396 | + "-u", "some-auth-url", "-d", s.metadataDir}, |
397 | ) |
398 | c.Assert(code, gc.Equals, 1) |
399 | + errOut := ctx.Stderr.(*bytes.Buffer).String() |
400 | + strippedOut := strings.Replace(errOut, "\n", "", -1) |
401 | + c.Check(strippedOut, gc.Matches, `.*Resolve Metadata:.*`) |
402 | } |
403 | |
404 | func (s *ValidateToolsMetadataSuite) TestDefaultVersion(c *gc.C) { |
405 | s.makeLocalMetadata(c, version.Current.Number.String(), "region-2", "raring", "some-auth-url") |
406 | ctx := coretesting.Context(c) |
407 | - metadataDir := osenv.JujuHomePath("") |
408 | code := cmd.Main( |
409 | &ValidateToolsMetadataCommand{}, ctx, []string{ |
410 | "-p", "openstack", "-s", "raring", "-r", "region-2", |
411 | - "-u", "some-auth-url", "-d", metadataDir}, |
412 | + "-u", "some-auth-url", "-d", s.metadataDir}, |
413 | ) |
414 | c.Assert(code, gc.Equals, 0) |
415 | errOut := ctx.Stdout.(*bytes.Buffer).String() |
416 | strippedOut := strings.Replace(errOut, "\n", "", -1) |
417 | - c.Check(strippedOut, gc.Matches, `matching tools versions:.*`) |
418 | + c.Check(strippedOut, gc.Matches, `Matching Tools Versions:.*Resolve Metadata.*`) |
419 | } |
420 | |
421 | func (s *ValidateToolsMetadataSuite) TestMajorVersionMatch(c *gc.C) { |
422 | s.makeLocalMetadata(c, "1.11.4", "region-2", "raring", "some-auth-url") |
423 | ctx := coretesting.Context(c) |
424 | - metadataDir := osenv.JujuHomePath("") |
425 | code := cmd.Main( |
426 | &ValidateToolsMetadataCommand{}, ctx, []string{ |
427 | "-p", "openstack", "-s", "raring", "-r", "region-2", |
428 | - "-u", "some-auth-url", "-d", metadataDir, "-m", "1"}, |
429 | + "-u", "some-auth-url", "-d", s.metadataDir, "-m", "1"}, |
430 | ) |
431 | c.Assert(code, gc.Equals, 0) |
432 | errOut := ctx.Stdout.(*bytes.Buffer).String() |
433 | strippedOut := strings.Replace(errOut, "\n", "", -1) |
434 | - c.Check(strippedOut, gc.Matches, `matching tools versions:.*`) |
435 | + c.Check(strippedOut, gc.Matches, `Matching Tools Versions:.*Resolve Metadata.*`) |
436 | } |
437 | |
438 | func (s *ValidateToolsMetadataSuite) TestMajorMinorVersionMatch(c *gc.C) { |
439 | s.makeLocalMetadata(c, "1.12.1", "region-2", "raring", "some-auth-url") |
440 | ctx := coretesting.Context(c) |
441 | - metadataDir := osenv.JujuHomePath("") |
442 | code := cmd.Main( |
443 | &ValidateToolsMetadataCommand{}, ctx, []string{ |
444 | "-p", "openstack", "-s", "raring", "-r", "region-2", |
445 | - "-u", "some-auth-url", "-d", metadataDir, "-m", "1.12"}, |
446 | + "-u", "some-auth-url", "-d", s.metadataDir, "-m", "1.12"}, |
447 | ) |
448 | c.Assert(code, gc.Equals, 0) |
449 | errOut := ctx.Stdout.(*bytes.Buffer).String() |
450 | strippedOut := strings.Replace(errOut, "\n", "", -1) |
451 | - c.Check(strippedOut, gc.Matches, `matching tools versions:.*`) |
452 | + c.Check(strippedOut, gc.Matches, `Matching Tools Versions:.*Resolve Metadata.*`) |
453 | } |
454 | |
455 | func (s *ValidateToolsMetadataSuite) TestJustDirectory(c *gc.C) { |
456 | s.makeLocalMetadata(c, version.Current.Number.String(), "region-2", "raring", "some-auth-url") |
457 | ctx := coretesting.Context(c) |
458 | - metadataDir := osenv.JujuHomePath("") |
459 | code := cmd.Main( |
460 | - &ValidateToolsMetadataCommand{}, ctx, []string{"-s", "raring", "-d", metadataDir}, |
461 | + &ValidateToolsMetadataCommand{}, ctx, []string{"-s", "raring", "-d", s.metadataDir}, |
462 | ) |
463 | c.Assert(code, gc.Equals, 0) |
464 | errOut := ctx.Stdout.(*bytes.Buffer).String() |
465 | strippedOut := strings.Replace(errOut, "\n", "", -1) |
466 | - c.Check(strippedOut, gc.Matches, `matching tools versions:.*`) |
467 | + c.Check(strippedOut, gc.Matches, `Matching Tools Versions:.*Resolve Metadata.*`) |
468 | } |
469 | |
470 | === modified file 'environs/bootstrap/bootstrap_test.go' |
471 | --- environs/bootstrap/bootstrap_test.go 2014-02-13 02:46:58 +0000 |
472 | +++ environs/bootstrap/bootstrap_test.go 2014-03-04 05:51:00 +0000 |
473 | @@ -218,7 +218,8 @@ |
474 | // GetToolsSources returns a list of sources which are used to search for simplestreams tools metadata. |
475 | func (e *bootstrapEnviron) GetToolsSources() ([]simplestreams.DataSource, error) { |
476 | // Add the simplestreams source off the control bucket. |
477 | - return []simplestreams.DataSource{storage.NewStorageSimpleStreamsDataSource(e.Storage(), storage.BaseToolsPath)}, nil |
478 | + return []simplestreams.DataSource{ |
479 | + storage.NewStorageSimpleStreamsDataSource("cloud storage", e.Storage(), storage.BaseToolsPath)}, nil |
480 | } |
481 | |
482 | func newEnviron(name string, defaultKeys bool) *bootstrapEnviron { |
483 | |
484 | === modified file 'environs/imagemetadata/generate.go' |
485 | --- environs/imagemetadata/generate.go 2014-01-21 22:26:08 +0000 |
486 | +++ environs/imagemetadata/generate.go 2014-03-04 05:51:00 +0000 |
487 | @@ -34,9 +34,9 @@ |
488 | // readMetadata reads the image metadata from metadataStore. |
489 | func readMetadata(metadataStore storage.Storage) ([]*ImageMetadata, error) { |
490 | // Read any existing metadata so we can merge the new tools metadata with what's there. |
491 | - dataSource := storage.NewStorageSimpleStreamsDataSource(metadataStore, storage.BaseImagesPath) |
492 | + dataSource := storage.NewStorageSimpleStreamsDataSource("existing metadata", metadataStore, storage.BaseImagesPath) |
493 | imageConstraint := NewImageConstraint(simplestreams.LookupParams{}) |
494 | - existingMetadata, err := Fetch( |
495 | + existingMetadata, _, err := Fetch( |
496 | []simplestreams.DataSource{dataSource}, simplestreams.DefaultIndexPath, imageConstraint, false) |
497 | if err != nil && !errors.IsNotFoundError(err) { |
498 | return nil, err |
499 | |
500 | === modified file 'environs/imagemetadata/generate_test.go' |
501 | --- environs/imagemetadata/generate_test.go 2014-01-21 22:26:08 +0000 |
502 | +++ environs/imagemetadata/generate_test.go 2014-03-04 05:51:00 +0000 |
503 | @@ -28,8 +28,8 @@ |
504 | Series: []string{series}, |
505 | Arches: []string{arch}, |
506 | }) |
507 | - dataSource := storage.NewStorageSimpleStreamsDataSource(stor, "images") |
508 | - metadata, err := imagemetadata.Fetch( |
509 | + dataSource := storage.NewStorageSimpleStreamsDataSource("test datasource", stor, "images") |
510 | + metadata, _, err := imagemetadata.Fetch( |
511 | []simplestreams.DataSource{dataSource}, simplestreams.DefaultIndexPath, cons, false) |
512 | c.Assert(err, gc.IsNil) |
513 | c.Assert(metadata, gc.HasLen, 1) |
514 | |
515 | === modified file 'environs/imagemetadata/simplestreams.go' |
516 | --- environs/imagemetadata/simplestreams.go 2014-02-28 03:05:47 +0000 |
517 | +++ environs/imagemetadata/simplestreams.go 2014-03-04 05:51:00 +0000 |
518 | @@ -164,22 +164,24 @@ |
519 | // The base URL locations are as specified - the first location which has a file is the one used. |
520 | // Signed data is preferred, but if there is no signed data available and onlySigned is false, |
521 | // then unsigned data is used. |
522 | -func Fetch(sources []simplestreams.DataSource, indexPath string, cons *ImageConstraint, onlySigned bool) ([]*ImageMetadata, error) { |
523 | +func Fetch( |
524 | + sources []simplestreams.DataSource, indexPath string, cons *ImageConstraint, |
525 | + onlySigned bool) ([]*ImageMetadata, *simplestreams.ResolveInfo, error) { |
526 | params := simplestreams.ValueParams{ |
527 | DataType: ImageIds, |
528 | FilterFunc: appendMatchingImages, |
529 | ValueTemplate: ImageMetadata{}, |
530 | PublicKey: simplestreamsImagesPublicKey, |
531 | } |
532 | - items, err := simplestreams.GetMetadata(sources, indexPath, cons, onlySigned, params) |
533 | + items, resolveInfo, err := simplestreams.GetMetadata(sources, indexPath, cons, onlySigned, params) |
534 | if err != nil { |
535 | - return nil, err |
536 | + return nil, resolveInfo, err |
537 | } |
538 | metadata := make([]*ImageMetadata, len(items)) |
539 | for i, md := range items { |
540 | metadata[i] = md.(*ImageMetadata) |
541 | } |
542 | - return metadata, nil |
543 | + return metadata, resolveInfo, nil |
544 | } |
545 | |
546 | type imageKey struct { |
547 | |
548 | === modified file 'environs/imagemetadata/simplestreams_test.go' |
549 | --- environs/imagemetadata/simplestreams_test.go 2014-01-29 00:14:51 +0000 |
550 | +++ environs/imagemetadata/simplestreams_test.go 2014-03-04 05:51:00 +0000 |
551 | @@ -66,7 +66,8 @@ |
552 | func registerSimpleStreamsTests() { |
553 | gc.Suite(&simplestreamsSuite{ |
554 | LocalLiveSimplestreamsSuite: sstesting.LocalLiveSimplestreamsSuite{ |
555 | - Source: simplestreams.NewURLDataSource("test:", simplestreams.VerifySSLHostnames), |
556 | + Source: simplestreams.NewURLDataSource( |
557 | + "test roundtripper", "test:", simplestreams.VerifySSLHostnames), |
558 | RequireSigned: false, |
559 | DataType: imagemetadata.ImageIds, |
560 | ValidConstraint: imagemetadata.NewImageConstraint(simplestreams.LookupParams{ |
561 | @@ -84,7 +85,7 @@ |
562 | |
563 | func registerLiveSimpleStreamsTests(baseURL string, validImageConstraint simplestreams.LookupConstraint, requireSigned bool) { |
564 | gc.Suite(&sstesting.LocalLiveSimplestreamsSuite{ |
565 | - Source: simplestreams.NewURLDataSource(baseURL, simplestreams.VerifySSLHostnames), |
566 | + Source: simplestreams.NewURLDataSource("test", baseURL, simplestreams.VerifySSLHostnames), |
567 | RequireSigned: requireSigned, |
568 | DataType: imagemetadata.ImageIds, |
569 | ValidConstraint: validImageConstraint, |
570 | @@ -265,7 +266,11 @@ |
571 | Series: []string{"precise"}, |
572 | Arches: t.arches, |
573 | }) |
574 | - images, err := imagemetadata.Fetch([]simplestreams.DataSource{s.Source}, simplestreams.DefaultIndexPath, imageConstraint, s.RequireSigned) |
575 | + // Add invalid datasource and check later that resolveInfo is correct. |
576 | + invalidSource := simplestreams.NewURLDataSource("invalid", "file://invalid", simplestreams.VerifySSLHostnames) |
577 | + images, resolveInfo, err := imagemetadata.Fetch( |
578 | + []simplestreams.DataSource{invalidSource, s.Source}, simplestreams.DefaultIndexPath, |
579 | + imageConstraint, s.RequireSigned) |
580 | if !c.Check(err, gc.IsNil) { |
581 | continue |
582 | } |
583 | @@ -273,6 +278,12 @@ |
584 | testImage.Version = t.version |
585 | } |
586 | c.Check(images, gc.DeepEquals, t.images) |
587 | + c.Check(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{ |
588 | + Source: "test roundtripper", |
589 | + Signed: s.RequireSigned, |
590 | + IndexURL: "test:/streams/v1/index.json", |
591 | + MirrorURL: "", |
592 | + }) |
593 | } |
594 | } |
595 | |
596 | @@ -364,28 +375,34 @@ |
597 | } |
598 | |
599 | func (s *signedSuite) TestSignedImageMetadata(c *gc.C) { |
600 | - signedSource := simplestreams.NewURLDataSource("signedtest://host/signed", simplestreams.VerifySSLHostnames) |
601 | + signedSource := simplestreams.NewURLDataSource("test", "signedtest://host/signed", simplestreams.VerifySSLHostnames) |
602 | imageConstraint := imagemetadata.NewImageConstraint(simplestreams.LookupParams{ |
603 | CloudSpec: simplestreams.CloudSpec{"us-east-1", "https://ec2.us-east-1.amazonaws.com"}, |
604 | Series: []string{"precise"}, |
605 | Arches: []string{"amd64"}, |
606 | }) |
607 | - images, err := imagemetadata.Fetch( |
608 | + images, resolveInfo, err := imagemetadata.Fetch( |
609 | []simplestreams.DataSource{signedSource}, simplestreams.DefaultIndexPath, imageConstraint, true) |
610 | c.Assert(err, gc.IsNil) |
611 | c.Assert(len(images), gc.Equals, 1) |
612 | c.Assert(images[0].Id, gc.Equals, "ami-123456") |
613 | + c.Check(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{ |
614 | + Source: "test", |
615 | + Signed: true, |
616 | + IndexURL: "signedtest://host/signed/streams/v1/index.sjson", |
617 | + MirrorURL: "", |
618 | + }) |
619 | } |
620 | |
621 | func (s *signedSuite) TestSignedImageMetadataInvalidSignature(c *gc.C) { |
622 | - signedSource := simplestreams.NewURLDataSource("signedtest://host/signed", simplestreams.VerifySSLHostnames) |
623 | + signedSource := simplestreams.NewURLDataSource("test", "signedtest://host/signed", simplestreams.VerifySSLHostnames) |
624 | imageConstraint := imagemetadata.NewImageConstraint(simplestreams.LookupParams{ |
625 | CloudSpec: simplestreams.CloudSpec{"us-east-1", "https://ec2.us-east-1.amazonaws.com"}, |
626 | Series: []string{"precise"}, |
627 | Arches: []string{"amd64"}, |
628 | }) |
629 | imagemetadata.SetSigningPublicKey(s.origKey) |
630 | - _, err := imagemetadata.Fetch( |
631 | + _, _, err := imagemetadata.Fetch( |
632 | []simplestreams.DataSource{signedSource}, simplestreams.DefaultIndexPath, imageConstraint, true) |
633 | c.Assert(err, gc.ErrorMatches, "cannot read index data.*") |
634 | } |
635 | |
636 | === modified file 'environs/imagemetadata/testing/testing.go' |
637 | --- environs/imagemetadata/testing/testing.go 2014-01-21 22:26:08 +0000 |
638 | +++ environs/imagemetadata/testing/testing.go 2014-03-04 05:51:00 +0000 |
639 | @@ -27,7 +27,7 @@ |
640 | |
641 | // ParseMetadataFromStorage loads ImageMetadata from the specified storage reader. |
642 | func ParseMetadataFromStorage(c *gc.C, stor storage.StorageReader) []*imagemetadata.ImageMetadata { |
643 | - source := storage.NewStorageSimpleStreamsDataSource(stor, "images") |
644 | + source := storage.NewStorageSimpleStreamsDataSource("test storage reader", stor, "images") |
645 | |
646 | // Find the simplestreams index file. |
647 | params := simplestreams.ValueParams{ |
648 | |
649 | === modified file 'environs/imagemetadata/urls.go' |
650 | --- environs/imagemetadata/urls.go 2014-01-29 06:45:16 +0000 |
651 | +++ environs/imagemetadata/urls.go 2014-03-04 05:51:00 +0000 |
652 | @@ -31,7 +31,7 @@ |
653 | if !config.SSLHostnameVerification() { |
654 | verify = simplestreams.NoVerifySSLHostnames |
655 | } |
656 | - sources = append(sources, simplestreams.NewURLDataSource(userURL, verify)) |
657 | + sources = append(sources, simplestreams.NewURLDataSource("image-metadata-url", userURL, verify)) |
658 | } |
659 | if custom, ok := env.(SupportsCustomSources); ok { |
660 | customSources, err := custom.GetImageSources() |
661 | @@ -46,7 +46,7 @@ |
662 | return nil, err |
663 | } |
664 | if defaultURL != "" { |
665 | - sources = append(sources, simplestreams.NewURLDataSource(defaultURL, simplestreams.VerifySSLHostnames)) |
666 | + sources = append(sources, simplestreams.NewURLDataSource("default cloud images", defaultURL, simplestreams.VerifySSLHostnames)) |
667 | } |
668 | return sources, nil |
669 | } |
670 | |
671 | === modified file 'environs/imagemetadata/validation.go' |
672 | --- environs/imagemetadata/validation.go 2014-01-29 06:45:16 +0000 |
673 | +++ environs/imagemetadata/validation.go 2014-03-04 05:51:00 +0000 |
674 | @@ -11,21 +11,21 @@ |
675 | |
676 | // ValidateImageMetadata attempts to load image metadata for the specified cloud attributes and stream |
677 | // and returns any image ids found, or an error if the metadata could not be loaded. |
678 | -func ValidateImageMetadata(params *simplestreams.MetadataLookupParams) ([]string, error) { |
679 | +func ValidateImageMetadata(params *simplestreams.MetadataLookupParams) ([]string, *simplestreams.ResolveInfo, error) { |
680 | if params.Series == "" { |
681 | - return nil, fmt.Errorf("required parameter series not specified") |
682 | + return nil, nil, fmt.Errorf("required parameter series not specified") |
683 | } |
684 | if params.Region == "" { |
685 | - return nil, fmt.Errorf("required parameter region not specified") |
686 | + return nil, nil, fmt.Errorf("required parameter region not specified") |
687 | } |
688 | if params.Endpoint == "" { |
689 | - return nil, fmt.Errorf("required parameter endpoint not specified") |
690 | + return nil, nil, fmt.Errorf("required parameter endpoint not specified") |
691 | } |
692 | if len(params.Architectures) == 0 { |
693 | - return nil, fmt.Errorf("required parameter arches not specified") |
694 | + return nil, nil, fmt.Errorf("required parameter arches not specified") |
695 | } |
696 | if len(params.Sources) == 0 { |
697 | - return nil, fmt.Errorf("required parameter sources not specified") |
698 | + return nil, nil, fmt.Errorf("required parameter sources not specified") |
699 | } |
700 | imageConstraint := NewImageConstraint(simplestreams.LookupParams{ |
701 | CloudSpec: simplestreams.CloudSpec{params.Region, params.Endpoint}, |
702 | @@ -33,16 +33,16 @@ |
703 | Arches: params.Architectures, |
704 | Stream: params.Stream, |
705 | }) |
706 | - matchingImages, err := Fetch(params.Sources, simplestreams.DefaultIndexPath, imageConstraint, false) |
707 | + matchingImages, resolveInfo, err := Fetch(params.Sources, simplestreams.DefaultIndexPath, imageConstraint, false) |
708 | if err != nil { |
709 | - return nil, err |
710 | + return nil, resolveInfo, err |
711 | } |
712 | if len(matchingImages) == 0 { |
713 | - return nil, fmt.Errorf("no matching images found for constraint %+v", imageConstraint) |
714 | + return nil, resolveInfo, fmt.Errorf("no matching images found for constraint %+v", imageConstraint) |
715 | } |
716 | image_ids := make([]string, len(matchingImages)) |
717 | for i, im := range matchingImages { |
718 | image_ids[i] = im.Id |
719 | } |
720 | - return image_ids, nil |
721 | + return image_ids, resolveInfo, nil |
722 | } |
723 | |
724 | === modified file 'environs/imagemetadata/validation_test.go' |
725 | --- environs/imagemetadata/validation_test.go 2014-01-29 06:45:16 +0000 |
726 | +++ environs/imagemetadata/validation_test.go 2014-03-04 05:51:00 +0000 |
727 | @@ -4,6 +4,7 @@ |
728 | package imagemetadata_test |
729 | |
730 | import ( |
731 | + "path" |
732 | "path/filepath" |
733 | |
734 | gc "launchpad.net/gocheck" |
735 | @@ -57,11 +58,17 @@ |
736 | Endpoint: "some-auth-url", |
737 | Stream: stream, |
738 | Sources: []simplestreams.DataSource{ |
739 | - simplestreams.NewURLDataSource("file://"+metadataPath, simplestreams.VerifySSLHostnames)}, |
740 | + simplestreams.NewURLDataSource("test", "file://"+metadataPath, simplestreams.VerifySSLHostnames)}, |
741 | } |
742 | - imageIds, err := imagemetadata.ValidateImageMetadata(params) |
743 | + imageIds, resolveInfo, err := imagemetadata.ValidateImageMetadata(params) |
744 | c.Assert(err, gc.IsNil) |
745 | c.Assert(imageIds, gc.DeepEquals, []string{"1234"}) |
746 | + c.Check(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{ |
747 | + Source: "test", |
748 | + Signed: false, |
749 | + IndexURL: "file://" + path.Join(metadataPath, "streams/v1/index.json"), |
750 | + MirrorURL: "", |
751 | + }) |
752 | } |
753 | |
754 | func (s *ValidateSuite) TestMatch(c *gc.C) { |
755 | @@ -79,9 +86,9 @@ |
756 | Endpoint: "some-auth-url", |
757 | Stream: stream, |
758 | Sources: []simplestreams.DataSource{ |
759 | - simplestreams.NewURLDataSource("file://"+s.metadataDir, simplestreams.VerifySSLHostnames)}, |
760 | + simplestreams.NewURLDataSource("test", "file://"+s.metadataDir, simplestreams.VerifySSLHostnames)}, |
761 | } |
762 | - _, err := imagemetadata.ValidateImageMetadata(params) |
763 | + _, _, err := imagemetadata.ValidateImageMetadata(params) |
764 | c.Assert(err, gc.Not(gc.IsNil)) |
765 | } |
766 | |
767 | |
768 | === modified file 'environs/instances/image_test.go' |
769 | --- environs/instances/image_test.go 2014-01-29 00:14:51 +0000 |
770 | +++ environs/instances/image_test.go 2014-03-04 05:51:00 +0000 |
771 | @@ -240,7 +240,8 @@ |
772 | Stream: t.stream, |
773 | }) |
774 | imageMeta, err := imagemetadata.GetLatestImageIdMetadata( |
775 | - []byte(jsonImagesContent), simplestreams.NewURLDataSource("some-url", simplestreams.VerifySSLHostnames), cons) |
776 | + []byte(jsonImagesContent), |
777 | + simplestreams.NewURLDataSource("test", "some-url", simplestreams.VerifySSLHostnames), cons) |
778 | c.Assert(err, gc.IsNil) |
779 | var images []Image |
780 | for _, imageMetadata := range imageMeta { |
781 | |
782 | === modified file 'environs/simplestreams/datasource.go' |
783 | --- environs/simplestreams/datasource.go 2013-10-17 22:48:19 +0000 |
784 | +++ environs/simplestreams/datasource.go 2014-03-04 05:51:00 +0000 |
785 | @@ -15,6 +15,9 @@ |
786 | |
787 | // A DataSource retrieves simplestreams metadata. |
788 | type DataSource interface { |
789 | + // Description describes the origin of this datasource. |
790 | + // eg tools-metadata-url, cloud storage, keystone catalog etc. |
791 | + Description() string |
792 | // Fetch loads the data at the specified relative path. It returns a reader from which |
793 | // the data can be retrieved as well as the full URL of the file. The full URL is typically |
794 | // used in log messages to help diagnose issues accessing the data. |
795 | @@ -43,20 +46,27 @@ |
796 | |
797 | // A urlDataSource retrieves data from an HTTP URL. |
798 | type urlDataSource struct { |
799 | + description string |
800 | baseURL string |
801 | hostnameVerification SSLHostnameVerification |
802 | } |
803 | |
804 | // NewURLDataSource returns a new datasource reading from the specified baseURL. |
805 | -func NewURLDataSource(baseURL string, verify SSLHostnameVerification) DataSource { |
806 | +func NewURLDataSource(description, baseURL string, verify SSLHostnameVerification) DataSource { |
807 | return &urlDataSource{ |
808 | + description: description, |
809 | baseURL: baseURL, |
810 | hostnameVerification: verify, |
811 | } |
812 | } |
813 | |
814 | +// Description is defined in simplestreams.DataSource. |
815 | +func (u *urlDataSource) Description() string { |
816 | + return u.description |
817 | +} |
818 | + |
819 | func (u *urlDataSource) GoString() string { |
820 | - return fmt.Sprintf("urlDataSource(%q)", u.baseURL) |
821 | + return fmt.Sprintf("%v: urlDataSource(%q)", u.description, u.baseURL) |
822 | } |
823 | |
824 | // urlJoin returns baseURL + relpath making sure to have a '/' inbetween them |
825 | |
826 | === modified file 'environs/simplestreams/datasource_test.go' |
827 | --- environs/simplestreams/datasource_test.go 2013-09-17 09:18:36 +0000 |
828 | +++ environs/simplestreams/datasource_test.go 2014-03-04 05:51:00 +0000 |
829 | @@ -24,7 +24,7 @@ |
830 | } |
831 | |
832 | func (s *datasourceSuite) TestFetch(c *gc.C) { |
833 | - ds := simplestreams.NewURLDataSource("test:", simplestreams.VerifySSLHostnames) |
834 | + ds := simplestreams.NewURLDataSource("test", "test:", simplestreams.VerifySSLHostnames) |
835 | rc, url, err := ds.Fetch("streams/v1/tools_metadata.json") |
836 | c.Assert(err, gc.IsNil) |
837 | defer rc.Close() |
838 | @@ -36,7 +36,7 @@ |
839 | } |
840 | |
841 | func (s *datasourceSuite) TestURL(c *gc.C) { |
842 | - ds := simplestreams.NewURLDataSource("foo", simplestreams.VerifySSLHostnames) |
843 | + ds := simplestreams.NewURLDataSource("test", "foo", simplestreams.VerifySSLHostnames) |
844 | url, err := ds.URL("bar") |
845 | c.Assert(err, gc.IsNil) |
846 | c.Assert(url, gc.Equals, "foo/bar") |
847 | @@ -64,7 +64,7 @@ |
848 | } |
849 | |
850 | func (s *datasourceHTTPSSuite) TestNormalClientFails(c *gc.C) { |
851 | - ds := simplestreams.NewURLDataSource(s.Server.URL, simplestreams.VerifySSLHostnames) |
852 | + ds := simplestreams.NewURLDataSource("test", s.Server.URL, simplestreams.VerifySSLHostnames) |
853 | url, err := ds.URL("bar") |
854 | c.Assert(err, gc.IsNil) |
855 | c.Check(url, gc.Equals, s.Server.URL+"/bar") |
856 | @@ -76,7 +76,7 @@ |
857 | } |
858 | |
859 | func (s *datasourceHTTPSSuite) TestNonVerifyingClientSucceeds(c *gc.C) { |
860 | - ds := simplestreams.NewURLDataSource(s.Server.URL, simplestreams.NoVerifySSLHostnames) |
861 | + ds := simplestreams.NewURLDataSource("test", s.Server.URL, simplestreams.NoVerifySSLHostnames) |
862 | url, err := ds.URL("bar") |
863 | c.Assert(err, gc.IsNil) |
864 | c.Check(url, gc.Equals, s.Server.URL+"/bar") |
865 | |
866 | === modified file 'environs/simplestreams/simplestreams.go' |
867 | --- environs/simplestreams/simplestreams.go 2014-02-25 04:47:53 +0000 |
868 | +++ environs/simplestreams/simplestreams.go 2014-03-04 05:51:00 +0000 |
869 | @@ -30,6 +30,13 @@ |
870 | |
871 | var logger = loggo.GetLogger("juju.environs.simplestreams") |
872 | |
873 | +type ResolveInfo struct { |
874 | + Source string `yaml:"source" json:"source"` |
875 | + Signed bool `yaml:"signed" json:"signed"` |
876 | + IndexURL string `yaml:"indexURL" json:"indexURL"` |
877 | + MirrorURL string `yaml:"mirrorURL,omitempty" json:"mirrorURL,omitempty"` |
878 | +} |
879 | + |
880 | // CloudSpec uniquely defines a specific cloud deployment. |
881 | type CloudSpec struct { |
882 | Region string `json:"region"` |
883 | @@ -422,12 +429,14 @@ |
884 | // GetMetadata returns metadata records matching the specified constraint,looking in each source for signed metadata. |
885 | // If onlySigned is false and no signed metadata is found in a source, the source is used to look for unsigned metadata. |
886 | // Each source is tried in turn until at least one signed (or unsigned) match is found. |
887 | -func GetMetadata(sources []DataSource, baseIndexPath string, cons LookupConstraint, onlySigned bool, params ValueParams) (items []interface{}, err error) { |
888 | +func GetMetadata( |
889 | + sources []DataSource, baseIndexPath string, cons LookupConstraint, onlySigned bool, |
890 | + params ValueParams) (items []interface{}, resolveInfo *ResolveInfo, err error) { |
891 | for _, source := range sources { |
892 | - items, err = getMaybeSignedMetadata(source, baseIndexPath, cons, true, params) |
893 | + items, resolveInfo, err = getMaybeSignedMetadata(source, baseIndexPath, cons, true, params) |
894 | // If no items are found using signed metadata, check unsigned. |
895 | if err != nil && len(items) == 0 && !onlySigned { |
896 | - items, err = getMaybeSignedMetadata(source, baseIndexPath, cons, false, params) |
897 | + items, resolveInfo, err = getMaybeSignedMetadata(source, baseIndexPath, cons, false, params) |
898 | } |
899 | if err == nil { |
900 | break |
901 | @@ -437,11 +446,14 @@ |
902 | // no matching products is an internal error only |
903 | err = nil |
904 | } |
905 | - return items, err |
906 | + return items, resolveInfo, err |
907 | } |
908 | |
909 | // getMaybeSignedMetadata returns metadata records matching the specified constraint. |
910 | -func getMaybeSignedMetadata(source DataSource, baseIndexPath string, cons LookupConstraint, signed bool, params ValueParams) ([]interface{}, error) { |
911 | +func getMaybeSignedMetadata(source DataSource, baseIndexPath string, cons LookupConstraint, |
912 | + signed bool, params ValueParams) ([]interface{}, *ResolveInfo, error) { |
913 | + |
914 | + resolveInfo := &ResolveInfo{} |
915 | indexPath := baseIndexPath + UnsignedSuffix |
916 | if signed { |
917 | indexPath = baseIndexPath + signedSuffix |
918 | @@ -453,25 +465,31 @@ |
919 | // So the best we can do is use the relative path for the URL when logging messages. |
920 | indexURL = indexPath |
921 | } |
922 | + resolveInfo.Source = source.Description() |
923 | + resolveInfo.Signed = signed |
924 | + resolveInfo.IndexURL = indexURL |
925 | indexRef, err := GetIndexWithFormat(source, indexPath, "index:1.0", signed, cons.Params().CloudSpec, params) |
926 | if err != nil { |
927 | if errors.IsNotFoundError(err) || errors.IsUnauthorizedError(err) { |
928 | logger.Debugf("cannot load index %q: %v", indexURL, err) |
929 | } |
930 | - return nil, err |
931 | + return nil, resolveInfo, err |
932 | } |
933 | logger.Debugf("read metadata index at %q", indexURL) |
934 | items, err = indexRef.getLatestMetadataWithFormat(cons, "products:1.0", signed) |
935 | if err != nil { |
936 | if errors.IsNotFoundError(err) { |
937 | logger.Debugf("skipping index because of error getting latest metadata %q: %v", indexURL, err) |
938 | - return nil, err |
939 | + return nil, resolveInfo, err |
940 | } |
941 | if _, ok := err.(*noMatchingProductsError); ok { |
942 | logger.Debugf("%v", err) |
943 | } |
944 | } |
945 | - return items, err |
946 | + if indexRef.Source.Description() == "mirror" { |
947 | + resolveInfo.MirrorURL = indexRef.Source.(*urlDataSource).baseURL |
948 | + } |
949 | + return items, resolveInfo, err |
950 | } |
951 | |
952 | // fetchData gets all the data from the given source located at the specified path. |
953 | @@ -534,7 +552,7 @@ |
954 | source, mirrors, params.DataType, params.MirrorContentId, cloudSpec, requireSigned, params.PublicKey) |
955 | if err == nil { |
956 | logger.Debugf("using mirrored products path: %s", path.Join(mirrorInfo.MirrorURL, mirrorInfo.Path)) |
957 | - indexRef.Source = NewURLDataSource(mirrorInfo.MirrorURL, VerifySSLHostnames) |
958 | + indexRef.Source = NewURLDataSource("mirror", mirrorInfo.MirrorURL, VerifySSLHostnames) |
959 | indexRef.MirroredProductsPath = mirrorInfo.Path |
960 | } else { |
961 | logger.Debugf("no mirror information available for %s: %v", cloudSpec, err) |
962 | |
963 | === modified file 'environs/simplestreams/simplestreams_test.go' |
964 | --- environs/simplestreams/simplestreams_test.go 2014-02-11 03:40:13 +0000 |
965 | +++ environs/simplestreams/simplestreams_test.go 2014-03-04 05:51:00 +0000 |
966 | @@ -27,7 +27,7 @@ |
967 | func registerSimpleStreamsTests() { |
968 | gc.Suite(&simplestreamsSuite{ |
969 | LocalLiveSimplestreamsSuite: sstesting.LocalLiveSimplestreamsSuite{ |
970 | - Source: simplestreams.NewURLDataSource("test:", simplestreams.VerifySSLHostnames), |
971 | + Source: simplestreams.NewURLDataSource("test", "test:", simplestreams.VerifySSLHostnames), |
972 | RequireSigned: false, |
973 | DataType: "image-ids", |
974 | ValidConstraint: sstesting.NewTestConstraint(simplestreams.LookupParams{ |
975 | @@ -316,7 +316,7 @@ |
976 | func (s *simplestreamsSuite) TestGetMetadataNoMatching(c *gc.C) { |
977 | source := &countingSource{ |
978 | DataSource: simplestreams.NewURLDataSource( |
979 | - "test:/daily", simplestreams.VerifySSLHostnames, |
980 | + "test", "test:/daily", simplestreams.VerifySSLHostnames, |
981 | ), |
982 | } |
983 | sources := []simplestreams.DataSource{source, source, source} |
984 | @@ -330,7 +330,7 @@ |
985 | Arches: []string{"not-a-real-arch"}, // never matches |
986 | }) |
987 | |
988 | - items, err := simplestreams.GetMetadata( |
989 | + items, resolveInfo, err := simplestreams.GetMetadata( |
990 | sources, |
991 | simplestreams.DefaultIndexPath, |
992 | constraint, |
993 | @@ -339,6 +339,12 @@ |
994 | ) |
995 | c.Assert(err, gc.IsNil) |
996 | c.Assert(items, gc.HasLen, 0) |
997 | + c.Assert(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{ |
998 | + Source: "test", |
999 | + Signed: false, |
1000 | + IndexURL: "test:/daily/streams/v1/index.json", |
1001 | + MirrorURL: "", |
1002 | + }) |
1003 | |
1004 | // There should be 2 calls to each data-source: |
1005 | // one for .sjson, one for .json. |
1006 | |
1007 | === modified file 'environs/storage/storage.go' |
1008 | --- environs/storage/storage.go 2014-01-09 05:27:24 +0000 |
1009 | +++ environs/storage/storage.go 2014-03-04 05:51:00 +0000 |
1010 | @@ -72,9 +72,10 @@ |
1011 | |
1012 | // A storageSimpleStreamsDataSource retrieves data from a StorageReader. |
1013 | type storageSimpleStreamsDataSource struct { |
1014 | - basePath string |
1015 | - storage StorageReader |
1016 | - allowRetry bool |
1017 | + description string |
1018 | + basePath string |
1019 | + storage StorageReader |
1020 | + allowRetry bool |
1021 | } |
1022 | |
1023 | // TestingGetAllowRetry is used in tests which need to see if allowRetry has been |
1024 | @@ -87,8 +88,8 @@ |
1025 | } |
1026 | |
1027 | // NewStorageSimpleStreamsDataSource returns a new datasource reading from the specified storage. |
1028 | -func NewStorageSimpleStreamsDataSource(storage StorageReader, basePath string) simplestreams.DataSource { |
1029 | - return &storageSimpleStreamsDataSource{basePath, storage, false} |
1030 | +func NewStorageSimpleStreamsDataSource(description string, storage StorageReader, basePath string) simplestreams.DataSource { |
1031 | + return &storageSimpleStreamsDataSource{description, basePath, storage, false} |
1032 | } |
1033 | |
1034 | func (s *storageSimpleStreamsDataSource) relpath(storagePath string) string { |
1035 | @@ -99,6 +100,11 @@ |
1036 | return relpath |
1037 | } |
1038 | |
1039 | +// Description is defined in simplestreams.DataSource. |
1040 | +func (s *storageSimpleStreamsDataSource) Description() string { |
1041 | + return s.description |
1042 | +} |
1043 | + |
1044 | // Fetch is defined in simplestreams.DataSource. |
1045 | func (s *storageSimpleStreamsDataSource) Fetch(path string) (io.ReadCloser, string, error) { |
1046 | relpath := s.relpath(path) |
1047 | |
1048 | === modified file 'environs/storage/storage_test.go' |
1049 | --- environs/storage/storage_test.go 2014-02-13 02:46:58 +0000 |
1050 | +++ environs/storage/storage_test.go 2014-03-04 05:51:00 +0000 |
1051 | @@ -57,7 +57,7 @@ |
1052 | func (s *datasourceSuite) TestFetch(c *gc.C) { |
1053 | sampleData := "hello world" |
1054 | s.stor.Put("foo/bar/data.txt", bytes.NewReader([]byte(sampleData)), int64(len(sampleData))) |
1055 | - ds := storage.NewStorageSimpleStreamsDataSource(s.stor, "") |
1056 | + ds := storage.NewStorageSimpleStreamsDataSource("test datasource", s.stor, "") |
1057 | rc, url, err := ds.Fetch("foo/bar/data.txt") |
1058 | c.Assert(err, gc.IsNil) |
1059 | defer rc.Close() |
1060 | @@ -69,7 +69,7 @@ |
1061 | func (s *datasourceSuite) TestFetchWithBasePath(c *gc.C) { |
1062 | sampleData := "hello world" |
1063 | s.stor.Put("base/foo/bar/data.txt", bytes.NewReader([]byte(sampleData)), int64(len(sampleData))) |
1064 | - ds := storage.NewStorageSimpleStreamsDataSource(s.stor, "base") |
1065 | + ds := storage.NewStorageSimpleStreamsDataSource("test datasource", s.stor, "base") |
1066 | rc, url, err := ds.Fetch("foo/bar/data.txt") |
1067 | c.Assert(err, gc.IsNil) |
1068 | defer rc.Close() |
1069 | @@ -80,7 +80,7 @@ |
1070 | |
1071 | func (s *datasourceSuite) TestFetchWithRetry(c *gc.C) { |
1072 | stor := &fakeStorage{shouldRetry: true} |
1073 | - ds := storage.NewStorageSimpleStreamsDataSource(stor, "base") |
1074 | + ds := storage.NewStorageSimpleStreamsDataSource("test datasource", stor, "base") |
1075 | ds.SetAllowRetry(true) |
1076 | _, _, err := ds.Fetch("foo/bar/data.txt") |
1077 | c.Assert(err, gc.ErrorMatches, "an error") |
1078 | @@ -92,7 +92,7 @@ |
1079 | // NB shouldRetry below is true indicating the fake storage is capable of |
1080 | // retrying, not that it will retry. |
1081 | stor := &fakeStorage{shouldRetry: true} |
1082 | - ds := storage.NewStorageSimpleStreamsDataSource(stor, "base") |
1083 | + ds := storage.NewStorageSimpleStreamsDataSource("test datasource", stor, "base") |
1084 | _, _, err := ds.Fetch("foo/bar/data.txt") |
1085 | c.Assert(err, gc.ErrorMatches, "an error") |
1086 | c.Assert(stor.getName, gc.Equals, "base/foo/bar/data.txt") |
1087 | @@ -102,7 +102,7 @@ |
1088 | func (s *datasourceSuite) TestURL(c *gc.C) { |
1089 | sampleData := "hello world" |
1090 | s.stor.Put("bar/data.txt", bytes.NewReader([]byte(sampleData)), int64(len(sampleData))) |
1091 | - ds := storage.NewStorageSimpleStreamsDataSource(s.stor, "") |
1092 | + ds := storage.NewStorageSimpleStreamsDataSource("test datasource", s.stor, "") |
1093 | url, err := ds.URL("bar") |
1094 | c.Assert(err, gc.IsNil) |
1095 | expectedURL, _ := s.stor.URL("bar") |
1096 | @@ -112,7 +112,7 @@ |
1097 | func (s *datasourceSuite) TestURLWithBasePath(c *gc.C) { |
1098 | sampleData := "hello world" |
1099 | s.stor.Put("base/bar/data.txt", bytes.NewReader([]byte(sampleData)), int64(len(sampleData))) |
1100 | - ds := storage.NewStorageSimpleStreamsDataSource(s.stor, "base") |
1101 | + ds := storage.NewStorageSimpleStreamsDataSource("test datasource", s.stor, "base") |
1102 | url, err := ds.URL("bar") |
1103 | c.Assert(err, gc.IsNil) |
1104 | expectedURL, _ := s.stor.URL("base/bar") |
1105 | |
1106 | === modified file 'environs/sync/sync.go' |
1107 | --- environs/sync/sync.go 2014-01-30 14:11:27 +0000 |
1108 | +++ environs/sync/sync.go 2014-03-04 05:51:00 +0000 |
1109 | @@ -140,7 +140,7 @@ |
1110 | return nil, err |
1111 | } |
1112 | logger.Infof("using sync tools source: %v", sourceURL) |
1113 | - return simplestreams.NewURLDataSource(sourceURL, simplestreams.VerifySSLHostnames), nil |
1114 | + return simplestreams.NewURLDataSource("sync tools source", sourceURL, simplestreams.VerifySSLHostnames), nil |
1115 | } |
1116 | |
1117 | // copyTools copies a set of tools from the source to the target. |
1118 | |
1119 | === removed file 'environs/tools/boilerplate.go' |
1120 | --- environs/tools/boilerplate.go 2014-01-22 22:48:54 +0000 |
1121 | +++ environs/tools/boilerplate.go 1970-01-01 00:00:00 +0000 |
1122 | @@ -1,153 +0,0 @@ |
1123 | -// Copyright 2013 Canonical Ltd. |
1124 | -// Licensed under the AGPLv3, see LICENCE file for details. |
1125 | - |
1126 | -package tools |
1127 | - |
1128 | -import ( |
1129 | - "bytes" |
1130 | - "fmt" |
1131 | - "io/ioutil" |
1132 | - "os" |
1133 | - "path/filepath" |
1134 | - "text/template" |
1135 | - "time" |
1136 | - |
1137 | - "launchpad.net/juju-core/environs/simplestreams" |
1138 | - "launchpad.net/juju-core/juju/osenv" |
1139 | -) |
1140 | - |
1141 | -const ( |
1142 | - defaultIndexFileName = "index.json" |
1143 | - defaultToolsFileName = "toolsmetadata.json" |
1144 | - streamsDir = "streams/v1" |
1145 | -) |
1146 | - |
1147 | -// Boilerplate generates some basic simplestreams metadata using the specified cloud and tools details. |
1148 | -func Boilerplate(tm *ToolsMetadata, cloudSpec *simplestreams.CloudSpec) ([]string, error) { |
1149 | - return MakeBoilerplate(tm, cloudSpec, true) |
1150 | -} |
1151 | - |
1152 | -// MakeBoilerplate exists so it can be called by tests. See Boilerplate above. It provides an option to retain |
1153 | -// the streams directories when writing the generated metadata files. |
1154 | -func MakeBoilerplate(tm *ToolsMetadata, cloudSpec *simplestreams.CloudSpec, flattenPath bool) ([]string, error) { |
1155 | - indexFileName := defaultIndexFileName |
1156 | - toolsFileName := defaultToolsFileName |
1157 | - now := time.Now() |
1158 | - imparams := toolsMetadataParams{ |
1159 | - ToolsBinarySize: tm.Size, |
1160 | - ToolsBinaryPath: tm.Path, |
1161 | - ToolsBinarySHA256: tm.SHA256, |
1162 | - Version: tm.Version, |
1163 | - Arch: tm.Arch, |
1164 | - Series: tm.Release, |
1165 | - Region: cloudSpec.Region, |
1166 | - URL: cloudSpec.Endpoint, |
1167 | - Path: streamsDir, |
1168 | - ToolsFileName: toolsFileName, |
1169 | - Updated: now.Format(time.RFC1123Z), |
1170 | - VersionKey: now.Format("20060102"), |
1171 | - } |
1172 | - |
1173 | - var err error |
1174 | - imparams.SeriesVersion, err = simplestreams.SeriesVersion(tm.Release) |
1175 | - if err != nil { |
1176 | - return nil, fmt.Errorf("invalid series %q", tm.Release) |
1177 | - } |
1178 | - |
1179 | - if !flattenPath { |
1180 | - streamsPath := osenv.JujuHomePath(streamsDir) |
1181 | - if err := os.MkdirAll(streamsPath, 0755); err != nil { |
1182 | - return nil, err |
1183 | - } |
1184 | - indexFileName = filepath.Join(streamsDir, indexFileName) |
1185 | - toolsFileName = filepath.Join(streamsDir, toolsFileName) |
1186 | - } |
1187 | - err = writeJsonFile(imparams, indexFileName, indexBoilerplate) |
1188 | - if err != nil { |
1189 | - return nil, err |
1190 | - } |
1191 | - err = writeJsonFile(imparams, toolsFileName, productBoilerplate) |
1192 | - if err != nil { |
1193 | - return nil, err |
1194 | - } |
1195 | - return []string{indexFileName, toolsFileName}, nil |
1196 | -} |
1197 | - |
1198 | -type toolsMetadataParams struct { |
1199 | - ToolsBinaryPath string |
1200 | - ToolsBinarySize int64 |
1201 | - ToolsBinarySHA256 string |
1202 | - Region string |
1203 | - URL string |
1204 | - Updated string |
1205 | - Arch string |
1206 | - Path string |
1207 | - Series string |
1208 | - SeriesVersion string |
1209 | - Version string |
1210 | - VersionKey string |
1211 | - ToolsFileName string |
1212 | -} |
1213 | - |
1214 | -func writeJsonFile(imparams toolsMetadataParams, filename, boilerplate string) error { |
1215 | - t := template.Must(template.New("").Parse(boilerplate)) |
1216 | - var metadata bytes.Buffer |
1217 | - if err := t.Execute(&metadata, imparams); err != nil { |
1218 | - panic(fmt.Errorf("cannot generate %s metdata: %v", filename, err)) |
1219 | - } |
1220 | - data := metadata.Bytes() |
1221 | - path := osenv.JujuHomePath(filename) |
1222 | - if err := ioutil.WriteFile(path, data, 0666); err != nil { |
1223 | - return err |
1224 | - } |
1225 | - return nil |
1226 | -} |
1227 | - |
1228 | -var indexBoilerplate = ` |
1229 | -{ |
1230 | - "index": { |
1231 | - "com.ubuntu.juju:custom": { |
1232 | - "updated": "{{.Updated}}", |
1233 | - "cloudname": "custom", |
1234 | - "datatype": "content-download", |
1235 | - "format": "products:1.0", |
1236 | - "products": [ |
1237 | - "com.ubuntu.juju:{{.SeriesVersion}}:{{.Arch}}" |
1238 | - ], |
1239 | - "path": "{{.Path}}/{{.ToolsFileName}}" |
1240 | - } |
1241 | - }, |
1242 | - "updated": "{{.Updated}}", |
1243 | - "format": "index:1.0" |
1244 | -} |
1245 | -` |
1246 | - |
1247 | -var productBoilerplate = ` |
1248 | -{ |
1249 | - "content_id": "com.ubuntu.juju:custom", |
1250 | - "format": "products:1.0", |
1251 | - "updated": "{{.Updated}}", |
1252 | - "datatype": "content-download", |
1253 | - "products": { |
1254 | - "com.ubuntu.juju:{{.SeriesVersion}}:{{.Arch}}": { |
1255 | - "release": "{{.Series}}", |
1256 | - "arch": "{{.Arch}}", |
1257 | - "versions": { |
1258 | - "{{.VersionKey}}": { |
1259 | - "items": { |
1260 | - "{{.Series}}{{.Version}}": { |
1261 | - "version": "{{.Version}}", |
1262 | - "size": {{.ToolsBinarySize}}, |
1263 | - "path": "{{.ToolsBinaryPath}}", |
1264 | - "ftype": "tar.gz", |
1265 | - "sha256": "{{.ToolsBinarySHA256}}" |
1266 | - } |
1267 | - }, |
1268 | - "pubname": "juju-{{.Series}}-{{.Arch}}-{{.VersionKey}}", |
1269 | - "label": "custom" |
1270 | - } |
1271 | - } |
1272 | - } |
1273 | - } |
1274 | -} |
1275 | -` |
1276 | |
1277 | === modified file 'environs/tools/simplestreams.go' |
1278 | --- environs/tools/simplestreams.go 2014-01-30 06:21:03 +0000 |
1279 | +++ environs/tools/simplestreams.go 2014-03-04 05:51:00 +0000 |
1280 | @@ -102,9 +102,8 @@ |
1281 | } |
1282 | |
1283 | // NewVersionedToolsConstraint returns a ToolsConstraint for a tools with a specific version. |
1284 | -func NewVersionedToolsConstraint(vers string, params simplestreams.LookupParams) *ToolsConstraint { |
1285 | - versNum := version.MustParse(vers) |
1286 | - return &ToolsConstraint{LookupParams: params, Version: versNum} |
1287 | +func NewVersionedToolsConstraint(vers version.Number, params simplestreams.LookupParams) *ToolsConstraint { |
1288 | + return &ToolsConstraint{LookupParams: params, Version: vers} |
1289 | } |
1290 | |
1291 | // NewGeneralToolsConstraint returns a ToolsConstraint for tools with matching major/minor version numbers. |
1292 | @@ -168,7 +167,10 @@ |
1293 | // The base URL locations are as specified - the first location which has a file is the one used. |
1294 | // Signed data is preferred, but if there is no signed data available and onlySigned is false, |
1295 | // then unsigned data is used. |
1296 | -func Fetch(sources []simplestreams.DataSource, indexPath string, cons *ToolsConstraint, onlySigned bool) ([]*ToolsMetadata, error) { |
1297 | +func Fetch( |
1298 | + sources []simplestreams.DataSource, indexPath string, cons *ToolsConstraint, |
1299 | + onlySigned bool) ([]*ToolsMetadata, *simplestreams.ResolveInfo, error) { |
1300 | + |
1301 | params := simplestreams.ValueParams{ |
1302 | DataType: ContentDownload, |
1303 | FilterFunc: appendMatchingTools, |
1304 | @@ -176,15 +178,15 @@ |
1305 | ValueTemplate: ToolsMetadata{}, |
1306 | PublicKey: simplestreamsToolsPublicKey, |
1307 | } |
1308 | - items, err := simplestreams.GetMetadata(sources, indexPath, cons, onlySigned, params) |
1309 | + items, resolveInfo, err := simplestreams.GetMetadata(sources, indexPath, cons, onlySigned, params) |
1310 | if err != nil { |
1311 | - return nil, err |
1312 | + return nil, nil, err |
1313 | } |
1314 | metadata := make([]*ToolsMetadata, len(items)) |
1315 | for i, md := range items { |
1316 | metadata[i] = md.(*ToolsMetadata) |
1317 | } |
1318 | - return metadata, nil |
1319 | + return metadata, resolveInfo, nil |
1320 | } |
1321 | |
1322 | // appendMatchingTools updates matchingTools with tools metadata records from tools which belong to the |
1323 | @@ -311,12 +313,13 @@ |
1324 | |
1325 | // ReadMetadata returns the tools metadata from the given storage. |
1326 | func ReadMetadata(store storage.StorageReader) ([]*ToolsMetadata, error) { |
1327 | - dataSource := storage.NewStorageSimpleStreamsDataSource(store, storage.BaseToolsPath) |
1328 | + dataSource := storage.NewStorageSimpleStreamsDataSource("existing metadata", store, storage.BaseToolsPath) |
1329 | toolsConstraint, err := makeToolsConstraint(simplestreams.CloudSpec{}, -1, -1, coretools.Filter{}) |
1330 | if err != nil { |
1331 | return nil, err |
1332 | } |
1333 | - metadata, err := Fetch([]simplestreams.DataSource{dataSource}, simplestreams.DefaultIndexPath, toolsConstraint, false) |
1334 | + metadata, _, err := Fetch( |
1335 | + []simplestreams.DataSource{dataSource}, simplestreams.DefaultIndexPath, toolsConstraint, false) |
1336 | if err != nil && !errors.IsNotFoundError(err) { |
1337 | return nil, err |
1338 | } |
1339 | |
1340 | === modified file 'environs/tools/simplestreams_test.go' |
1341 | --- environs/tools/simplestreams_test.go 2014-01-30 06:21:03 +0000 |
1342 | +++ environs/tools/simplestreams_test.go 2014-03-04 05:51:00 +0000 |
1343 | @@ -62,7 +62,7 @@ |
1344 | t.Fatalf("Unknown vendor %s. Must be one of %s", *vendor, keys) |
1345 | } |
1346 | registerLiveSimpleStreamsTests(testData.baseURL, |
1347 | - tools.NewVersionedToolsConstraint("1.13.0", simplestreams.LookupParams{ |
1348 | + tools.NewVersionedToolsConstraint(version.MustParse("1.13.0"), simplestreams.LookupParams{ |
1349 | CloudSpec: testData.validCloudSpec, |
1350 | Series: []string{version.Current.Series}, |
1351 | Arches: []string{"amd64"}, |
1352 | @@ -74,10 +74,10 @@ |
1353 | func registerSimpleStreamsTests() { |
1354 | gc.Suite(&simplestreamsSuite{ |
1355 | LocalLiveSimplestreamsSuite: sstesting.LocalLiveSimplestreamsSuite{ |
1356 | - Source: simplestreams.NewURLDataSource("test:", simplestreams.VerifySSLHostnames), |
1357 | + Source: simplestreams.NewURLDataSource("test", "test:", simplestreams.VerifySSLHostnames), |
1358 | RequireSigned: false, |
1359 | DataType: tools.ContentDownload, |
1360 | - ValidConstraint: tools.NewVersionedToolsConstraint("1.13.0", simplestreams.LookupParams{ |
1361 | + ValidConstraint: tools.NewVersionedToolsConstraint(version.MustParse("1.13.0"), simplestreams.LookupParams{ |
1362 | CloudSpec: simplestreams.CloudSpec{ |
1363 | Region: "us-east-1", |
1364 | Endpoint: "https://ec2.us-east-1.amazonaws.com", |
1365 | @@ -92,7 +92,7 @@ |
1366 | |
1367 | func registerLiveSimpleStreamsTests(baseURL string, validToolsConstraint simplestreams.LookupConstraint, requireSigned bool) { |
1368 | gc.Suite(&sstesting.LocalLiveSimplestreamsSuite{ |
1369 | - Source: simplestreams.NewURLDataSource(baseURL, simplestreams.VerifySSLHostnames), |
1370 | + Source: simplestreams.NewURLDataSource("test", baseURL, simplestreams.VerifySSLHostnames), |
1371 | RequireSigned: requireSigned, |
1372 | DataType: tools.ContentDownload, |
1373 | ValidConstraint: validToolsConstraint, |
1374 | @@ -238,14 +238,18 @@ |
1375 | Arches: t.arches, |
1376 | }) |
1377 | } else { |
1378 | - toolsConstraint = tools.NewVersionedToolsConstraint(t.version, simplestreams.LookupParams{ |
1379 | - CloudSpec: simplestreams.CloudSpec{"us-east-1", "https://ec2.us-east-1.amazonaws.com"}, |
1380 | - Series: []string{t.series}, |
1381 | - Arches: t.arches, |
1382 | - }) |
1383 | + toolsConstraint = tools.NewVersionedToolsConstraint(version.MustParse(t.version), |
1384 | + simplestreams.LookupParams{ |
1385 | + CloudSpec: simplestreams.CloudSpec{"us-east-1", "https://ec2.us-east-1.amazonaws.com"}, |
1386 | + Series: []string{t.series}, |
1387 | + Arches: t.arches, |
1388 | + }) |
1389 | } |
1390 | - tools, err := tools.Fetch( |
1391 | - []simplestreams.DataSource{s.Source}, simplestreams.DefaultIndexPath, toolsConstraint, s.RequireSigned) |
1392 | + // Add invalid datasource and check later that resolveInfo is correct. |
1393 | + invalidSource := simplestreams.NewURLDataSource("invalid", "file://invalid", simplestreams.VerifySSLHostnames) |
1394 | + tools, resolveInfo, err := tools.Fetch( |
1395 | + []simplestreams.DataSource{invalidSource, s.Source}, |
1396 | + simplestreams.DefaultIndexPath, toolsConstraint, s.RequireSigned) |
1397 | if !c.Check(err, gc.IsNil) { |
1398 | continue |
1399 | } |
1400 | @@ -254,6 +258,12 @@ |
1401 | c.Assert(err, gc.IsNil) |
1402 | } |
1403 | c.Check(tools, gc.DeepEquals, t.tools) |
1404 | + c.Check(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{ |
1405 | + Source: "test", |
1406 | + Signed: s.RequireSigned, |
1407 | + IndexURL: "test:/streams/v1/index.json", |
1408 | + MirrorURL: "", |
1409 | + }) |
1410 | } |
1411 | } |
1412 | |
1413 | @@ -263,7 +273,7 @@ |
1414 | Series: []string{"precise"}, |
1415 | Arches: []string{"amd64"}, |
1416 | }) |
1417 | - toolsMetadata, err := tools.Fetch( |
1418 | + toolsMetadata, resolveInfo, err := tools.Fetch( |
1419 | []simplestreams.DataSource{s.Source}, simplestreams.DefaultIndexPath, toolsConstraint, s.RequireSigned) |
1420 | c.Assert(err, gc.IsNil) |
1421 | c.Assert(len(toolsMetadata), gc.Equals, 1) |
1422 | @@ -280,6 +290,12 @@ |
1423 | } |
1424 | c.Assert(err, gc.IsNil) |
1425 | c.Assert(toolsMetadata[0], gc.DeepEquals, expectedMetadata) |
1426 | + c.Assert(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{ |
1427 | + Source: "test", |
1428 | + Signed: s.RequireSigned, |
1429 | + IndexURL: "test:/streams/v1/index.json", |
1430 | + MirrorURL: "test:/", |
1431 | + }) |
1432 | } |
1433 | |
1434 | func assertMetadataMatches(c *gc.C, storageDir string, toolList coretools.List, metadata []*tools.ToolsMetadata) { |
1435 | @@ -396,7 +412,7 @@ |
1436 | var _ = gc.Suite(&productSpecSuite{}) |
1437 | |
1438 | func (s *productSpecSuite) TestId(c *gc.C) { |
1439 | - toolsConstraint := tools.NewVersionedToolsConstraint("1.13.0", simplestreams.LookupParams{ |
1440 | + toolsConstraint := tools.NewVersionedToolsConstraint(version.MustParse("1.13.0"), simplestreams.LookupParams{ |
1441 | Series: []string{"precise"}, |
1442 | Arches: []string{"amd64"}, |
1443 | }) |
1444 | @@ -406,7 +422,7 @@ |
1445 | } |
1446 | |
1447 | func (s *productSpecSuite) TestIdMultiArch(c *gc.C) { |
1448 | - toolsConstraint := tools.NewVersionedToolsConstraint("1.11.3", simplestreams.LookupParams{ |
1449 | + toolsConstraint := tools.NewVersionedToolsConstraint(version.MustParse("1.11.3"), simplestreams.LookupParams{ |
1450 | Series: []string{"precise"}, |
1451 | Arches: []string{"amd64", "arm"}, |
1452 | }) |
1453 | @@ -418,7 +434,7 @@ |
1454 | } |
1455 | |
1456 | func (s *productSpecSuite) TestIdMultiSeries(c *gc.C) { |
1457 | - toolsConstraint := tools.NewVersionedToolsConstraint("1.11.3", simplestreams.LookupParams{ |
1458 | + toolsConstraint := tools.NewVersionedToolsConstraint(version.MustParse("1.11.3"), simplestreams.LookupParams{ |
1459 | Series: []string{"precise", "raring"}, |
1460 | Arches: []string{"amd64"}, |
1461 | }) |
1462 | @@ -752,17 +768,23 @@ |
1463 | } |
1464 | |
1465 | func (s *signedSuite) TestSignedToolsMetadata(c *gc.C) { |
1466 | - signedSource := simplestreams.NewURLDataSource("signedtest://host/signed", simplestreams.VerifySSLHostnames) |
1467 | - toolsConstraint := tools.NewVersionedToolsConstraint("1.13.0", simplestreams.LookupParams{ |
1468 | + signedSource := simplestreams.NewURLDataSource("test", "signedtest://host/signed", simplestreams.VerifySSLHostnames) |
1469 | + toolsConstraint := tools.NewVersionedToolsConstraint(version.MustParse("1.13.0"), simplestreams.LookupParams{ |
1470 | CloudSpec: simplestreams.CloudSpec{"us-east-1", "https://ec2.us-east-1.amazonaws.com"}, |
1471 | Series: []string{"precise"}, |
1472 | Arches: []string{"amd64"}, |
1473 | }) |
1474 | - toolsMetadata, err := tools.Fetch( |
1475 | + toolsMetadata, resolveInfo, err := tools.Fetch( |
1476 | []simplestreams.DataSource{signedSource}, simplestreams.DefaultIndexPath, toolsConstraint, true) |
1477 | c.Assert(err, gc.IsNil) |
1478 | c.Assert(len(toolsMetadata), gc.Equals, 1) |
1479 | c.Assert(toolsMetadata[0].Path, gc.Equals, "tools/releases/20130806/juju-1.13.1-precise-amd64.tgz") |
1480 | + c.Assert(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{ |
1481 | + Source: "test", |
1482 | + Signed: true, |
1483 | + IndexURL: "signedtest://host/signed/streams/v1/index.sjson", |
1484 | + MirrorURL: "", |
1485 | + }) |
1486 | } |
1487 | |
1488 | var unsignedIndex = ` |
1489 | |
1490 | === modified file 'environs/tools/testing/testing.go' |
1491 | --- environs/tools/testing/testing.go 2014-01-30 14:11:27 +0000 |
1492 | +++ environs/tools/testing/testing.go 2014-03-04 05:51:00 +0000 |
1493 | @@ -83,7 +83,7 @@ |
1494 | |
1495 | // ParseMetadataFromStorage loads ToolsMetadata from the specified storage reader. |
1496 | func ParseMetadataFromStorage(c *gc.C, stor storage.StorageReader, expectMirrors bool) []*tools.ToolsMetadata { |
1497 | - source := storage.NewStorageSimpleStreamsDataSource(stor, "tools") |
1498 | + source := storage.NewStorageSimpleStreamsDataSource("test storage reader", stor, "tools") |
1499 | params := simplestreams.ValueParams{ |
1500 | DataType: tools.ContentDownload, |
1501 | ValueTemplate: tools.ToolsMetadata{}, |
1502 | |
1503 | === modified file 'environs/tools/tools.go' |
1504 | --- environs/tools/tools.go 2014-02-28 03:05:47 +0000 |
1505 | +++ environs/tools/tools.go 2014-03-04 05:51:00 +0000 |
1506 | @@ -32,7 +32,7 @@ |
1507 | if majorMismatch || minorMismacth { |
1508 | return nil, coretools.ErrNoMatches |
1509 | } |
1510 | - toolsConstraint = NewVersionedToolsConstraint(filter.Number.String(), |
1511 | + toolsConstraint = NewVersionedToolsConstraint(filter.Number, |
1512 | simplestreams.LookupParams{CloudSpec: cloudSpec}) |
1513 | } else { |
1514 | toolsConstraint = NewGeneralToolsConstraint(majorVersion, minorVersion, filter.Released, |
1515 | @@ -117,7 +117,7 @@ |
1516 | if err != nil { |
1517 | return nil, err |
1518 | } |
1519 | - toolsMetadata, err := Fetch(sources, simplestreams.DefaultIndexPath, toolsConstraint, false) |
1520 | + toolsMetadata, _, err := Fetch(sources, simplestreams.DefaultIndexPath, toolsConstraint, false) |
1521 | if err != nil { |
1522 | if errors.IsNotFoundError(err) { |
1523 | err = ErrNoTools |
1524 | |
1525 | === modified file 'environs/tools/urls.go' |
1526 | --- environs/tools/urls.go 2014-01-20 23:32:00 +0000 |
1527 | +++ environs/tools/urls.go 2014-03-04 05:51:00 +0000 |
1528 | @@ -39,7 +39,7 @@ |
1529 | if !config.SSLHostnameVerification() { |
1530 | verify = simplestreams.NoVerifySSLHostnames |
1531 | } |
1532 | - sources = append(sources, simplestreams.NewURLDataSource(userURL, verify)) |
1533 | + sources = append(sources, simplestreams.NewURLDataSource("tools-metadata-url", userURL, verify)) |
1534 | } |
1535 | if custom, ok := env.(SupportsCustomSources); ok { |
1536 | customSources, err := custom.GetToolsSources() |
1537 | @@ -54,7 +54,7 @@ |
1538 | return nil, err |
1539 | } |
1540 | if defaultURL != "" { |
1541 | - sources = append(sources, simplestreams.NewURLDataSource(defaultURL, simplestreams.VerifySSLHostnames)) |
1542 | + sources = append(sources, simplestreams.NewURLDataSource("default simplestreams", defaultURL, simplestreams.VerifySSLHostnames)) |
1543 | } |
1544 | for _, source := range sources { |
1545 | source.SetAllowRetry(allowRetry) |
1546 | |
1547 | === modified file 'environs/tools/validation.go' |
1548 | --- environs/tools/validation.go 2013-09-20 18:46:47 +0000 |
1549 | +++ environs/tools/validation.go 2014-03-04 05:51:00 +0000 |
1550 | @@ -20,12 +20,12 @@ |
1551 | |
1552 | // ValidateToolsMetadata attempts to load tools metadata for the specified cloud attributes and returns |
1553 | // any tools versions found, or an error if the metadata could not be loaded. |
1554 | -func ValidateToolsMetadata(params *ToolsMetadataLookupParams) ([]string, error) { |
1555 | +func ValidateToolsMetadata(params *ToolsMetadataLookupParams) ([]string, *simplestreams.ResolveInfo, error) { |
1556 | if len(params.Architectures) == 0 { |
1557 | - return nil, fmt.Errorf("required parameter arches not specified") |
1558 | + return nil, nil, fmt.Errorf("required parameter arches not specified") |
1559 | } |
1560 | if len(params.Sources) == 0 { |
1561 | - return nil, fmt.Errorf("required parameter sources not specified") |
1562 | + return nil, nil, fmt.Errorf("required parameter sources not specified") |
1563 | } |
1564 | if params.Version == "" && params.Major == 0 { |
1565 | params.Version = version.Current.Number.String() |
1566 | @@ -38,23 +38,27 @@ |
1567 | Arches: params.Architectures, |
1568 | }) |
1569 | } else { |
1570 | - toolsConstraint = NewVersionedToolsConstraint(params.Version, simplestreams.LookupParams{ |
1571 | + versNum, err := version.Parse(params.Version) |
1572 | + if err != nil { |
1573 | + return nil, nil, err |
1574 | + } |
1575 | + toolsConstraint = NewVersionedToolsConstraint(versNum, simplestreams.LookupParams{ |
1576 | CloudSpec: simplestreams.CloudSpec{params.Region, params.Endpoint}, |
1577 | Series: []string{params.Series}, |
1578 | Arches: params.Architectures, |
1579 | }) |
1580 | } |
1581 | - matchingTools, err := Fetch(params.Sources, simplestreams.DefaultIndexPath, toolsConstraint, false) |
1582 | + matchingTools, resolveInfo, err := Fetch(params.Sources, simplestreams.DefaultIndexPath, toolsConstraint, false) |
1583 | if err != nil { |
1584 | - return nil, err |
1585 | + return nil, resolveInfo, err |
1586 | } |
1587 | if len(matchingTools) == 0 { |
1588 | - return nil, fmt.Errorf("no matching tools found for constraint %+v", toolsConstraint) |
1589 | + return nil, resolveInfo, fmt.Errorf("no matching tools found for constraint %+v", toolsConstraint) |
1590 | } |
1591 | versions := make([]string, len(matchingTools)) |
1592 | for i, tm := range matchingTools { |
1593 | vers := version.Binary{version.MustParse(tm.Version), tm.Release, tm.Arch} |
1594 | versions[i] = vers.String() |
1595 | } |
1596 | - return versions, nil |
1597 | + return versions, resolveInfo, nil |
1598 | } |
1599 | |
1600 | === modified file 'environs/tools/validation_test.go' |
1601 | --- environs/tools/validation_test.go 2014-01-22 22:48:54 +0000 |
1602 | +++ environs/tools/validation_test.go 2014-03-04 05:51:00 +0000 |
1603 | @@ -4,23 +4,24 @@ |
1604 | package tools |
1605 | |
1606 | import ( |
1607 | + "path" |
1608 | + |
1609 | gc "launchpad.net/gocheck" |
1610 | |
1611 | + "launchpad.net/juju-core/environs/filestorage" |
1612 | "launchpad.net/juju-core/environs/simplestreams" |
1613 | - "launchpad.net/juju-core/juju/osenv" |
1614 | - coretesting "launchpad.net/juju-core/testing" |
1615 | "launchpad.net/juju-core/testing/testbase" |
1616 | ) |
1617 | |
1618 | type ValidateSuite struct { |
1619 | testbase.LoggingSuite |
1620 | - home *coretesting.FakeHome |
1621 | + metadataDir string |
1622 | } |
1623 | |
1624 | var _ = gc.Suite(&ValidateSuite{}) |
1625 | |
1626 | -func (s *ValidateSuite) makeLocalMetadata(c *gc.C, version, region, series, endpoint string) error { |
1627 | - tm := ToolsMetadata{ |
1628 | +func (s *ValidateSuite) makeLocalMetadata(c *gc.C, version, series string) error { |
1629 | + tm := []*ToolsMetadata{{ |
1630 | Version: version, |
1631 | Release: series, |
1632 | Arch: "amd64", |
1633 | @@ -28,31 +29,26 @@ |
1634 | Size: 1234, |
1635 | FileType: "tar.gz", |
1636 | SHA256: "f65a92b3b41311bdf398663ee1c5cd0c", |
1637 | - } |
1638 | - cloudSpec := simplestreams.CloudSpec{ |
1639 | - Region: region, |
1640 | - Endpoint: endpoint, |
1641 | - } |
1642 | - _, err := MakeBoilerplate(&tm, &cloudSpec, false) |
1643 | - if err != nil { |
1644 | - return err |
1645 | - } |
1646 | + }} |
1647 | + |
1648 | + stor, err := filestorage.NewFileStorageWriter(s.metadataDir, filestorage.UseDefaultTmpDir) |
1649 | + c.Assert(err, gc.IsNil) |
1650 | + err = WriteMetadata(stor, tm, false) |
1651 | + c.Assert(err, gc.IsNil) |
1652 | return nil |
1653 | } |
1654 | |
1655 | func (s *ValidateSuite) SetUpTest(c *gc.C) { |
1656 | s.LoggingSuite.SetUpTest(c) |
1657 | - s.home = coretesting.MakeEmptyFakeHome(c) |
1658 | + s.metadataDir = c.MkDir() |
1659 | } |
1660 | |
1661 | -func (s *ValidateSuite) TearDownTest(c *gc.C) { |
1662 | - s.home.Restore() |
1663 | - s.LoggingSuite.TearDownTest(c) |
1664 | +func (s *ValidateSuite) toolsURL() string { |
1665 | + return "file://" + path.Join(s.metadataDir, "tools") |
1666 | } |
1667 | |
1668 | func (s *ValidateSuite) TestExactVersionMatch(c *gc.C) { |
1669 | - s.makeLocalMetadata(c, "1.11.2", "region-2", "raring", "some-auth-url") |
1670 | - metadataDir := osenv.JujuHomePath("") |
1671 | + s.makeLocalMetadata(c, "1.11.2", "raring") |
1672 | params := &ToolsMetadataLookupParams{ |
1673 | Version: "1.11.2", |
1674 | MetadataLookupParams: simplestreams.MetadataLookupParams{ |
1675 | @@ -60,17 +56,23 @@ |
1676 | Series: "raring", |
1677 | Architectures: []string{"amd64"}, |
1678 | Endpoint: "some-auth-url", |
1679 | - Sources: []simplestreams.DataSource{simplestreams.NewURLDataSource("file://"+metadataDir, simplestreams.VerifySSLHostnames)}, |
1680 | + Sources: []simplestreams.DataSource{ |
1681 | + simplestreams.NewURLDataSource("test", s.toolsURL(), simplestreams.VerifySSLHostnames)}, |
1682 | }, |
1683 | } |
1684 | - versions, err := ValidateToolsMetadata(params) |
1685 | + versions, resolveInfo, err := ValidateToolsMetadata(params) |
1686 | c.Assert(err, gc.IsNil) |
1687 | c.Assert(versions, gc.DeepEquals, []string{"1.11.2-raring-amd64"}) |
1688 | + c.Check(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{ |
1689 | + Source: "test", |
1690 | + Signed: false, |
1691 | + IndexURL: "file://" + path.Join(s.metadataDir, "tools/streams/v1/index.json"), |
1692 | + MirrorURL: "", |
1693 | + }) |
1694 | } |
1695 | |
1696 | func (s *ValidateSuite) TestMajorVersionMatch(c *gc.C) { |
1697 | - s.makeLocalMetadata(c, "1.11.2", "region-2", "raring", "some-auth-url") |
1698 | - metadataDir := osenv.JujuHomePath("") |
1699 | + s.makeLocalMetadata(c, "1.11.2", "raring") |
1700 | params := &ToolsMetadataLookupParams{ |
1701 | Major: 1, |
1702 | Minor: -1, |
1703 | @@ -79,17 +81,23 @@ |
1704 | Series: "raring", |
1705 | Architectures: []string{"amd64"}, |
1706 | Endpoint: "some-auth-url", |
1707 | - Sources: []simplestreams.DataSource{simplestreams.NewURLDataSource("file://"+metadataDir, simplestreams.VerifySSLHostnames)}, |
1708 | + Sources: []simplestreams.DataSource{ |
1709 | + simplestreams.NewURLDataSource("test", s.toolsURL(), simplestreams.VerifySSLHostnames)}, |
1710 | }, |
1711 | } |
1712 | - versions, err := ValidateToolsMetadata(params) |
1713 | + versions, resolveInfo, err := ValidateToolsMetadata(params) |
1714 | c.Assert(err, gc.IsNil) |
1715 | c.Assert(versions, gc.DeepEquals, []string{"1.11.2-raring-amd64"}) |
1716 | + c.Check(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{ |
1717 | + Source: "test", |
1718 | + Signed: false, |
1719 | + IndexURL: "file://" + path.Join(s.metadataDir, "tools/streams/v1/index.json"), |
1720 | + MirrorURL: "", |
1721 | + }) |
1722 | } |
1723 | |
1724 | func (s *ValidateSuite) TestMajorMinorVersionMatch(c *gc.C) { |
1725 | - s.makeLocalMetadata(c, "1.11.2", "region-2", "raring", "some-auth-url") |
1726 | - metadataDir := osenv.JujuHomePath("") |
1727 | + s.makeLocalMetadata(c, "1.11.2", "raring") |
1728 | params := &ToolsMetadataLookupParams{ |
1729 | Major: 1, |
1730 | Minor: 11, |
1731 | @@ -98,17 +106,23 @@ |
1732 | Series: "raring", |
1733 | Architectures: []string{"amd64"}, |
1734 | Endpoint: "some-auth-url", |
1735 | - Sources: []simplestreams.DataSource{simplestreams.NewURLDataSource("file://"+metadataDir, simplestreams.VerifySSLHostnames)}, |
1736 | + Sources: []simplestreams.DataSource{ |
1737 | + simplestreams.NewURLDataSource("test", s.toolsURL(), simplestreams.VerifySSLHostnames)}, |
1738 | }, |
1739 | } |
1740 | - versions, err := ValidateToolsMetadata(params) |
1741 | + versions, resolveInfo, err := ValidateToolsMetadata(params) |
1742 | c.Assert(err, gc.IsNil) |
1743 | c.Assert(versions, gc.DeepEquals, []string{"1.11.2-raring-amd64"}) |
1744 | + c.Check(resolveInfo, gc.DeepEquals, &simplestreams.ResolveInfo{ |
1745 | + Source: "test", |
1746 | + Signed: false, |
1747 | + IndexURL: "file://" + path.Join(s.metadataDir, "tools/streams/v1/index.json"), |
1748 | + MirrorURL: "", |
1749 | + }) |
1750 | } |
1751 | |
1752 | func (s *ValidateSuite) TestNoMatch(c *gc.C) { |
1753 | - s.makeLocalMetadata(c, "1.11.2", "region-2", "raring", "some-auth-url") |
1754 | - metadataDir := osenv.JujuHomePath("") |
1755 | + s.makeLocalMetadata(c, "1.11.2", "raring") |
1756 | params := &ToolsMetadataLookupParams{ |
1757 | Version: "1.11.2", |
1758 | MetadataLookupParams: simplestreams.MetadataLookupParams{ |
1759 | @@ -116,9 +130,10 @@ |
1760 | Series: "precise", |
1761 | Architectures: []string{"amd64"}, |
1762 | Endpoint: "some-auth-url", |
1763 | - Sources: []simplestreams.DataSource{simplestreams.NewURLDataSource("file://"+metadataDir, simplestreams.VerifySSLHostnames)}, |
1764 | + Sources: []simplestreams.DataSource{ |
1765 | + simplestreams.NewURLDataSource("test", s.toolsURL(), simplestreams.VerifySSLHostnames)}, |
1766 | }, |
1767 | } |
1768 | - _, err := ValidateToolsMetadata(params) |
1769 | + _, _, err := ValidateToolsMetadata(params) |
1770 | c.Assert(err, gc.Not(gc.IsNil)) |
1771 | } |
1772 | |
1773 | === modified file 'provider/azure/environ.go' |
1774 | --- provider/azure/environ.go 2014-02-18 03:18:16 +0000 |
1775 | +++ provider/azure/environ.go 2014-03-04 05:51:00 +0000 |
1776 | @@ -860,9 +860,9 @@ |
1777 | // GetImageSources returns a list of sources which are used to search for simplestreams image metadata. |
1778 | func (env *azureEnviron) GetImageSources() ([]simplestreams.DataSource, error) { |
1779 | sources := make([]simplestreams.DataSource, 1+len(baseURLs)) |
1780 | - sources[0] = storage.NewStorageSimpleStreamsDataSource(env.Storage(), storage.BaseImagesPath) |
1781 | + sources[0] = storage.NewStorageSimpleStreamsDataSource("cloud storage", env.Storage(), storage.BaseImagesPath) |
1782 | for i, url := range baseURLs { |
1783 | - sources[i+1] = simplestreams.NewURLDataSource(url, simplestreams.VerifySSLHostnames) |
1784 | + sources[i+1] = simplestreams.NewURLDataSource("Azure base URL", url, simplestreams.VerifySSLHostnames) |
1785 | } |
1786 | return sources, nil |
1787 | } |
1788 | @@ -871,7 +871,7 @@ |
1789 | func (env *azureEnviron) GetToolsSources() ([]simplestreams.DataSource, error) { |
1790 | // Add the simplestreams source off the control bucket. |
1791 | sources := []simplestreams.DataSource{ |
1792 | - storage.NewStorageSimpleStreamsDataSource(env.Storage(), storage.BaseToolsPath)} |
1793 | + storage.NewStorageSimpleStreamsDataSource("cloud storage", env.Storage(), storage.BaseToolsPath)} |
1794 | return sources, nil |
1795 | } |
1796 | |
1797 | |
1798 | === modified file 'provider/azure/instancetype.go' |
1799 | --- provider/azure/instancetype.go 2014-01-29 06:45:16 +0000 |
1800 | +++ provider/azure/instancetype.go 2014-03-04 05:51:00 +0000 |
1801 | @@ -142,7 +142,7 @@ |
1802 | return nil, err |
1803 | } |
1804 | indexPath := simplestreams.DefaultIndexPath |
1805 | - images, err := fetchImageMetadata(sources, indexPath, constraint, signedImageDataOnly) |
1806 | + images, _, err := fetchImageMetadata(sources, indexPath, constraint, signedImageDataOnly) |
1807 | if len(images) == 0 || errors.IsNotFoundError(err) { |
1808 | return nil, fmt.Errorf("no OS images found for location %q, series %q, architectures %q (and endpoint: %q)", location, series, arches, endpoint) |
1809 | } else if err != nil { |
1810 | |
1811 | === modified file 'provider/azure/instancetype_test.go' |
1812 | --- provider/azure/instancetype_test.go 2014-01-29 06:45:16 +0000 |
1813 | +++ provider/azure/instancetype_test.go 2014-03-04 05:51:00 +0000 |
1814 | @@ -482,8 +482,9 @@ |
1815 | // It returns a cleanup function, which you must call when done. |
1816 | func patchFetchImageMetadata(cannedResponse []*imagemetadata.ImageMetadata, cannedError error) func() { |
1817 | original := fetchImageMetadata |
1818 | - fetchImageMetadata = func([]simplestreams.DataSource, string, *imagemetadata.ImageConstraint, bool) ([]*imagemetadata.ImageMetadata, error) { |
1819 | - return cannedResponse, cannedError |
1820 | + fetchImageMetadata = func([]simplestreams.DataSource, string, *imagemetadata.ImageConstraint, bool) ( |
1821 | + []*imagemetadata.ImageMetadata, *simplestreams.ResolveInfo, error) { |
1822 | + return cannedResponse, nil, cannedError |
1823 | } |
1824 | return func() { fetchImageMetadata = original } |
1825 | } |
1826 | |
1827 | === modified file 'provider/common/mock_test.go' |
1828 | --- provider/common/mock_test.go 2013-10-15 04:38:40 +0000 |
1829 | +++ provider/common/mock_test.go 2014-03-04 05:51:00 +0000 |
1830 | @@ -72,7 +72,7 @@ |
1831 | if env.getToolsSources != nil { |
1832 | return env.getToolsSources() |
1833 | } |
1834 | - datasource := storage.NewStorageSimpleStreamsDataSource(env.Storage(), storage.BaseToolsPath) |
1835 | + datasource := storage.NewStorageSimpleStreamsDataSource("test cloud storage", env.Storage(), storage.BaseToolsPath) |
1836 | return []simplestreams.DataSource{datasource}, nil |
1837 | } |
1838 | |
1839 | |
1840 | === modified file 'provider/dummy/environs.go' |
1841 | --- provider/dummy/environs.go 2014-02-20 08:23:40 +0000 |
1842 | +++ provider/dummy/environs.go 2014-03-04 05:51:00 +0000 |
1843 | @@ -529,13 +529,13 @@ |
1844 | // GetImageSources returns a list of sources which are used to search for simplestreams image metadata. |
1845 | func (e *environ) GetImageSources() ([]simplestreams.DataSource, error) { |
1846 | return []simplestreams.DataSource{ |
1847 | - storage.NewStorageSimpleStreamsDataSource(e.Storage(), storage.BaseImagesPath)}, nil |
1848 | + storage.NewStorageSimpleStreamsDataSource("cloud storage", e.Storage(), storage.BaseImagesPath)}, nil |
1849 | } |
1850 | |
1851 | // GetToolsSources returns a list of sources which are used to search for simplestreams tools metadata. |
1852 | func (e *environ) GetToolsSources() ([]simplestreams.DataSource, error) { |
1853 | return []simplestreams.DataSource{ |
1854 | - storage.NewStorageSimpleStreamsDataSource(e.Storage(), storage.BaseToolsPath)}, nil |
1855 | + storage.NewStorageSimpleStreamsDataSource("cloud storage", e.Storage(), storage.BaseToolsPath)}, nil |
1856 | } |
1857 | |
1858 | func (e *environ) Bootstrap(ctx environs.BootstrapContext, cons constraints.Value) error { |
1859 | |
1860 | === modified file 'provider/ec2/ec2.go' |
1861 | --- provider/ec2/ec2.go 2014-02-28 03:05:47 +0000 |
1862 | +++ provider/ec2/ec2.go 2014-03-04 05:51:00 +0000 |
1863 | @@ -1057,7 +1057,7 @@ |
1864 | func (e *environ) GetImageSources() ([]simplestreams.DataSource, error) { |
1865 | // Add the simplestreams source off the control bucket. |
1866 | sources := []simplestreams.DataSource{ |
1867 | - storage.NewStorageSimpleStreamsDataSource(e.Storage(), storage.BaseImagesPath)} |
1868 | + storage.NewStorageSimpleStreamsDataSource("cloud storage", e.Storage(), storage.BaseImagesPath)} |
1869 | return sources, nil |
1870 | } |
1871 | |
1872 | @@ -1065,6 +1065,6 @@ |
1873 | func (e *environ) GetToolsSources() ([]simplestreams.DataSource, error) { |
1874 | // Add the simplestreams source off the control bucket. |
1875 | sources := []simplestreams.DataSource{ |
1876 | - storage.NewStorageSimpleStreamsDataSource(e.Storage(), storage.BaseToolsPath)} |
1877 | + storage.NewStorageSimpleStreamsDataSource("cloud storage", e.Storage(), storage.BaseToolsPath)} |
1878 | return sources, nil |
1879 | } |
1880 | |
1881 | === modified file 'provider/ec2/image.go' |
1882 | --- provider/ec2/image.go 2014-01-29 00:14:51 +0000 |
1883 | +++ provider/ec2/image.go 2014-03-04 05:51:00 +0000 |
1884 | @@ -48,7 +48,7 @@ |
1885 | Arches: ic.Arches, |
1886 | Stream: stream, |
1887 | }) |
1888 | - matchingImages, err := imagemetadata.Fetch( |
1889 | + matchingImages, _, err := imagemetadata.Fetch( |
1890 | sources, simplestreams.DefaultIndexPath, imageConstraint, signedImageDataOnly) |
1891 | if err != nil { |
1892 | return nil, err |
1893 | |
1894 | === modified file 'provider/ec2/image_test.go' |
1895 | --- provider/ec2/image_test.go 2014-02-14 01:03:03 +0000 |
1896 | +++ provider/ec2/image_test.go 2014-03-04 05:51:00 +0000 |
1897 | @@ -128,7 +128,8 @@ |
1898 | c.Logf("test %d", i) |
1899 | stor := ebsStorage |
1900 | spec, err := findInstanceSpec( |
1901 | - []simplestreams.DataSource{simplestreams.NewURLDataSource("test:", simplestreams.VerifySSLHostnames)}, |
1902 | + []simplestreams.DataSource{ |
1903 | + simplestreams.NewURLDataSource("test", "test:", simplestreams.VerifySSLHostnames)}, |
1904 | "released", |
1905 | &instances.InstanceConstraint{ |
1906 | Region: "test", |
1907 | @@ -169,7 +170,8 @@ |
1908 | for i, t := range findInstanceSpecErrorTests { |
1909 | c.Logf("test %d", i) |
1910 | _, err := findInstanceSpec( |
1911 | - []simplestreams.DataSource{simplestreams.NewURLDataSource("test:", simplestreams.VerifySSLHostnames)}, |
1912 | + []simplestreams.DataSource{ |
1913 | + simplestreams.NewURLDataSource("test", "test:", simplestreams.VerifySSLHostnames)}, |
1914 | "released", |
1915 | &instances.InstanceConstraint{ |
1916 | Region: "test", |
1917 | |
1918 | === modified file 'provider/ec2/local_test.go' |
1919 | --- provider/ec2/local_test.go 2014-02-20 08:23:40 +0000 |
1920 | +++ provider/ec2/local_test.go 2014-03-04 05:51:00 +0000 |
1921 | @@ -383,7 +383,7 @@ |
1922 | params.Endpoint = "https://ec2.endpoint.com" |
1923 | params.Sources, err = imagemetadata.GetMetadataSources(env) |
1924 | c.Assert(err, gc.IsNil) |
1925 | - image_ids, err := imagemetadata.ValidateImageMetadata(params) |
1926 | + image_ids, _, err := imagemetadata.ValidateImageMetadata(params) |
1927 | c.Assert(err, gc.IsNil) |
1928 | sort.Strings(image_ids) |
1929 | c.Assert(image_ids, gc.DeepEquals, []string{"ami-00000033", "ami-00000034", "ami-00000035"}) |
1930 | |
1931 | === modified file 'provider/local/environ.go' |
1932 | --- provider/local/environ.go 2014-02-28 09:13:21 +0000 |
1933 | +++ provider/local/environ.go 2014-03-04 05:51:00 +0000 |
1934 | @@ -65,7 +65,7 @@ |
1935 | func (e *localEnviron) GetToolsSources() ([]simplestreams.DataSource, error) { |
1936 | // Add the simplestreams source off the control bucket. |
1937 | return []simplestreams.DataSource{ |
1938 | - storage.NewStorageSimpleStreamsDataSource(e.Storage(), storage.BaseToolsPath)}, nil |
1939 | + storage.NewStorageSimpleStreamsDataSource("cloud storage", e.Storage(), storage.BaseToolsPath)}, nil |
1940 | } |
1941 | |
1942 | // Name is specified in the Environ interface. |
1943 | |
1944 | === modified file 'provider/maas/environ.go' |
1945 | --- provider/maas/environ.go 2013-12-19 09:15:40 +0000 |
1946 | +++ provider/maas/environ.go 2014-03-04 05:51:00 +0000 |
1947 | @@ -421,12 +421,12 @@ |
1948 | func (e *maasEnviron) GetImageSources() ([]simplestreams.DataSource, error) { |
1949 | // Add the simplestreams source off the control bucket. |
1950 | return []simplestreams.DataSource{ |
1951 | - storage.NewStorageSimpleStreamsDataSource(e.Storage(), storage.BaseImagesPath)}, nil |
1952 | + storage.NewStorageSimpleStreamsDataSource("cloud storage", e.Storage(), storage.BaseImagesPath)}, nil |
1953 | } |
1954 | |
1955 | // GetToolsSources returns a list of sources which are used to search for simplestreams tools metadata. |
1956 | func (e *maasEnviron) GetToolsSources() ([]simplestreams.DataSource, error) { |
1957 | // Add the simplestreams source off the control bucket. |
1958 | return []simplestreams.DataSource{ |
1959 | - storage.NewStorageSimpleStreamsDataSource(e.Storage(), storage.BaseToolsPath)}, nil |
1960 | + storage.NewStorageSimpleStreamsDataSource("cloud storage", e.Storage(), storage.BaseToolsPath)}, nil |
1961 | } |
1962 | |
1963 | === modified file 'provider/manual/environ.go' |
1964 | --- provider/manual/environ.go 2014-02-20 08:23:40 +0000 |
1965 | +++ provider/manual/environ.go 2014-03-04 05:51:00 +0000 |
1966 | @@ -200,7 +200,7 @@ |
1967 | func (e *manualEnviron) GetToolsSources() ([]simplestreams.DataSource, error) { |
1968 | // Add the simplestreams source off private storage. |
1969 | return []simplestreams.DataSource{ |
1970 | - storage.NewStorageSimpleStreamsDataSource(e.Storage(), storage.BaseToolsPath), |
1971 | + storage.NewStorageSimpleStreamsDataSource("cloud storage", e.Storage(), storage.BaseToolsPath), |
1972 | }, nil |
1973 | } |
1974 | |
1975 | |
1976 | === modified file 'provider/openstack/image.go' |
1977 | --- provider/openstack/image.go 2014-01-29 06:45:16 +0000 |
1978 | +++ provider/openstack/image.go 2014-03-04 05:51:00 +0000 |
1979 | @@ -43,7 +43,7 @@ |
1980 | return nil, err |
1981 | } |
1982 | // TODO (wallyworld): use an env parameter (default true) to mandate use of only signed image metadata. |
1983 | - matchingImages, err := imagemetadata.Fetch(sources, simplestreams.DefaultIndexPath, imageConstraint, false) |
1984 | + matchingImages, _, err := imagemetadata.Fetch(sources, simplestreams.DefaultIndexPath, imageConstraint, false) |
1985 | if err != nil { |
1986 | return nil, err |
1987 | } |
1988 | |
1989 | === modified file 'provider/openstack/local_test.go' |
1990 | --- provider/openstack/local_test.go 2014-02-20 08:23:40 +0000 |
1991 | +++ provider/openstack/local_test.go 2014-03-04 05:51:00 +0000 |
1992 | @@ -605,7 +605,7 @@ |
1993 | params.Sources, err = imagemetadata.GetMetadataSources(env) |
1994 | c.Assert(err, gc.IsNil) |
1995 | params.Series = "raring" |
1996 | - image_ids, err := imagemetadata.ValidateImageMetadata(params) |
1997 | + image_ids, _, err := imagemetadata.ValidateImageMetadata(params) |
1998 | c.Assert(err, gc.IsNil) |
1999 | c.Assert(image_ids, gc.DeepEquals, []string{"id-y"}) |
2000 | } |
2001 | |
2002 | === modified file 'provider/openstack/provider.go' |
2003 | --- provider/openstack/provider.go 2014-02-28 03:05:47 +0000 |
2004 | +++ provider/openstack/provider.go 2014-03-04 05:51:00 +0000 |
2005 | @@ -585,7 +585,7 @@ |
2006 | } |
2007 | // Add the simplestreams source off the control bucket. |
2008 | e.imageSources = append(e.imageSources, storage.NewStorageSimpleStreamsDataSource( |
2009 | - e.Storage(), storage.BaseImagesPath)) |
2010 | + "cloud storage", e.Storage(), storage.BaseImagesPath)) |
2011 | // Add the simplestreams base URL from keystone if it is defined. |
2012 | productStreamsURL, err := e.client.MakeServiceURL("product-streams", nil) |
2013 | if err == nil { |
2014 | @@ -593,7 +593,7 @@ |
2015 | if !e.Config().SSLHostnameVerification() { |
2016 | verify = simplestreams.NoVerifySSLHostnames |
2017 | } |
2018 | - source := simplestreams.NewURLDataSource(productStreamsURL, verify) |
2019 | + source := simplestreams.NewURLDataSource("keystone catalog", productStreamsURL, verify) |
2020 | e.imageSources = append(e.imageSources, source) |
2021 | } |
2022 | return e.imageSources, nil |
2023 | @@ -618,11 +618,12 @@ |
2024 | verify = simplestreams.NoVerifySSLHostnames |
2025 | } |
2026 | // Add the simplestreams source off the control bucket. |
2027 | - e.toolsSources = append(e.toolsSources, storage.NewStorageSimpleStreamsDataSource(e.Storage(), storage.BaseToolsPath)) |
2028 | + e.toolsSources = append(e.toolsSources, storage.NewStorageSimpleStreamsDataSource( |
2029 | + "cloud storage", e.Storage(), storage.BaseToolsPath)) |
2030 | // Add the simplestreams base URL from keystone if it is defined. |
2031 | toolsURL, err := e.client.MakeServiceURL("juju-tools", nil) |
2032 | if err == nil { |
2033 | - source := simplestreams.NewURLDataSource(toolsURL, verify) |
2034 | + source := simplestreams.NewURLDataSource("keystone catalog", toolsURL, verify) |
2035 | e.toolsSources = append(e.toolsSources, source) |
2036 | } |
2037 | return e.toolsSources, nil |
Reviewers: mp+209162_ code.launchpad. net,
Message:
Please take a look.
Description:
Add metadata to simplestreams validation
juju metadata validate- [images| tools] now prints
metadata to show how the lookup was performed.
Along the way, drive by fixes were done to delete
old code and improve existing code associated with
simplestreams.
A picture is worth 1000 words:
ian@wallyworld:~$ juju metadata validate-images
ImageIds:
- ami-99999af0
- ami-0d9c9f64
- ami-6f969506
- ami-0b9c9f62
- ami-359c9f5c
- ami-a18c8fc8
Region: us-east-1
Resolve Metadata:
source: default cloud images
signed: true
indexURL: cloud-images. ubuntu. com/releases/ streams/ v1/index. sjson
http://
ian@wallyworld:~$ juju metadata validate-tools precise- amd64 /streams. canonical. com/juju/ tools/streams/ v1/index. json /juju-dist. s3.amazonaws. com/tools
Matching Tools Versions:
- 1.17.4-
- 1.17.4-precise-i386
Resolve Metadata:
source: default simplestreams
signed: false
indexURL:
https:/
mirrorURL: https:/
https:/ /code.launchpad .net/~wallyworl d/juju- core/verbose- metadata- validation/ +merge/ 209162
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/70960044/
Affected files (+330, -361 lines): juju-metadata/ toolsmetadata. go juju-metadata/ validateimageme tadata. go juju-metadata/ validateimageme tadata_ test.go juju-metadata/ validatetoolsme tadata. go juju-metadata/ validatetoolsme tadata_ test.go bootstrap/ bootstrap_ test.go imagemetadata/ generate. go imagemetadata/ generate_ test.go imagemetadata/ simplestreams. go imagemetadata/ simplestreams_ test.go imagemetadata/ testing/ testing. go imagemetadata/ urls.go imagemetadata/ validation. go imagemetadata/ validation_ test.go instances/ image_test. go simplestreams/ datasource. go simplestreams/ datasource_ test.go simplestreams/ simplestreams. go simplestreams/ simplestreams_ test.go storage/ storage. go storage/ storage_ test.go sync/sync. go tools/boilerpla te.go tools/simplestr eams.go tools/simplestr eams_test. go tools/testing/ testing. go tools/tools. go tools/urls. go tools/validatio n.go tools/validatio n_test. go azure/environ. go azure/instancet ype.go azure/instancet ype_test. go common/ mock_test. go dummy/environs. go ec2/image. go ec2/image_ test.go ec2/local_ test.go local/environ. go maas/environ. go manual/ environ. go openstack/ image.go openstack/ local_test. go openstack/ provider. go
A [revision details]
M cmd/plugins/
M cmd/plugins/
M cmd/plugins/
M cmd/plugins/
M cmd/plugins/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
D environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M environs/
M provider/
M provider/
M provider/
M provider/
M provider/
M provider/ec2/ec2.go
M provider/
M provider/
M provider/
M provider/
M provider/
M provider/
M provider/
M provider/
M provider/