Merge lp:~natefinch/juju-core/fix-win-bootstrap into lp:~go-bot/juju-core/trunk
- fix-win-bootstrap
- Merge into trunk
Proposed by
Nate Finch
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Nate Finch | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 1995 | ||||
Proposed branch: | lp:~natefinch/juju-core/fix-win-bootstrap | ||||
Merge into: | lp:~go-bot/juju-core/trunk | ||||
Diff against target: |
624 lines (+366/-52) (has conflicts) 14 files modified
charm/repo.go (+2/-1) cmd/plugins/juju-metadata/validateimagemetadata_test.go (+38/-0) environs/configstore/disk.go (+1/-1) environs/filestorage/filestorage.go (+1/-1) environs/sync/sync.go (+10/-0) environs/sync/sync_test.go (+26/-1) environs/tools/simplestreams_test.go (+113/-0) provider/maas/instance_test.go (+93/-45) utils/file_unix.go (+15/-0) utils/file_windows.go (+35/-0) utils/fslock/fslock.go (+2/-2) utils/trivial.go (+1/-1) utils/zfile_windows.go (+25/-0) version/version.go (+4/-0) Text conflict in cmd/plugins/juju-metadata/validateimagemetadata_test.go Text conflict in environs/sync/sync_test.go Text conflict in environs/tools/simplestreams_test.go Text conflict in provider/maas/instance_test.go Text conflict in version/version.go |
||||
To merge this branch: | bzr merge lp:~natefinch/juju-core/fix-win-bootstrap | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju Engineering | Pending | ||
Review via email: mp+191688@code.launchpad.net |
Commit message
merge windows fix back to trunk
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'charm/repo.go' | |||
2 | --- charm/repo.go 2013-07-09 10:32:23 +0000 | |||
3 | +++ charm/repo.go 2013-10-17 18:24:24 +0000 | |||
4 | @@ -17,6 +17,7 @@ | |||
5 | 17 | "strings" | 17 | "strings" |
6 | 18 | 18 | ||
7 | 19 | "launchpad.net/juju-core/log" | 19 | "launchpad.net/juju-core/log" |
8 | 20 | "launchpad.net/juju-core/utils" | ||
9 | 20 | ) | 21 | ) |
10 | 21 | 22 | ||
11 | 22 | // CacheDir stores the charm cache directory path. | 23 | // CacheDir stores the charm cache directory path. |
12 | @@ -257,7 +258,7 @@ | |||
13 | 257 | os.Remove(dlPath) | 258 | os.Remove(dlPath) |
14 | 258 | return nil, err | 259 | return nil, err |
15 | 259 | } | 260 | } |
17 | 260 | if err := os.Rename(dlPath, path); err != nil { | 261 | if err := utils.ReplaceFile(dlPath, path); err != nil { |
18 | 261 | return nil, err | 262 | return nil, err |
19 | 262 | } | 263 | } |
20 | 263 | } | 264 | } |
21 | 264 | 265 | ||
22 | === modified file 'cmd/plugins/juju-metadata/validateimagemetadata_test.go' | |||
23 | --- cmd/plugins/juju-metadata/validateimagemetadata_test.go 2013-10-17 05:37:00 +0000 | |||
24 | +++ cmd/plugins/juju-metadata/validateimagemetadata_test.go 2013-10-17 18:24:24 +0000 | |||
25 | @@ -19,9 +19,14 @@ | |||
26 | 19 | ) | 19 | ) |
27 | 20 | 20 | ||
28 | 21 | type ValidateImageMetadataSuite struct { | 21 | type ValidateImageMetadataSuite struct { |
29 | 22 | <<<<<<< TREE | ||
30 | 22 | testbase.LoggingSuite | 23 | testbase.LoggingSuite |
31 | 23 | home *coretesting.FakeHome | 24 | home *coretesting.FakeHome |
32 | 24 | metadataDir string | 25 | metadataDir string |
33 | 26 | ======= | ||
34 | 27 | testbase.LoggingSuite | ||
35 | 28 | home *coretesting.FakeHome | ||
36 | 29 | >>>>>>> MERGE-SOURCE | ||
37 | 25 | } | 30 | } |
38 | 26 | 31 | ||
39 | 27 | var _ = gc.Suite(&ValidateImageMetadataSuite{}) | 32 | var _ = gc.Suite(&ValidateImageMetadataSuite{}) |
40 | @@ -89,6 +94,10 @@ | |||
41 | 89 | environments: | 94 | environments: |
42 | 90 | ec2: | 95 | ec2: |
43 | 91 | type: ec2 | 96 | type: ec2 |
44 | 97 | <<<<<<< TREE | ||
45 | 98 | ======= | ||
46 | 99 | control-bucket: foo | ||
47 | 100 | >>>>>>> MERGE-SOURCE | ||
48 | 92 | default-series: precise | 101 | default-series: precise |
49 | 93 | region: us-east-1 | 102 | region: us-east-1 |
50 | 94 | 103 | ||
51 | @@ -102,11 +111,22 @@ | |||
52 | 102 | ` | 111 | ` |
53 | 103 | 112 | ||
54 | 104 | func (s *ValidateImageMetadataSuite) SetUpTest(c *gc.C) { | 113 | func (s *ValidateImageMetadataSuite) SetUpTest(c *gc.C) { |
55 | 114 | <<<<<<< TREE | ||
56 | 105 | s.LoggingSuite.SetUpTest(c) | 115 | s.LoggingSuite.SetUpTest(c) |
57 | 106 | s.metadataDir = c.MkDir() | 116 | s.metadataDir = c.MkDir() |
58 | 117 | ======= | ||
59 | 118 | s.LoggingSuite.SetUpTest(c) | ||
60 | 119 | >>>>>>> MERGE-SOURCE | ||
61 | 107 | s.home = coretesting.MakeFakeHome(c, metadataTestEnvConfig) | 120 | s.home = coretesting.MakeFakeHome(c, metadataTestEnvConfig) |
62 | 121 | <<<<<<< TREE | ||
63 | 108 | s.PatchEnvironment("AWS_ACCESS_KEY_ID", "access") | 122 | s.PatchEnvironment("AWS_ACCESS_KEY_ID", "access") |
64 | 109 | s.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "secret") | 123 | s.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "secret") |
65 | 124 | ======= | ||
66 | 125 | restore := testbase.PatchEnvironment("AWS_ACCESS_KEY_ID", "access") | ||
67 | 126 | s.AddCleanup(func(*gc.C) { restore() }) | ||
68 | 127 | restore = testbase.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "secret") | ||
69 | 128 | s.AddCleanup(func(*gc.C) { restore() }) | ||
70 | 129 | >>>>>>> MERGE-SOURCE | ||
71 | 110 | } | 130 | } |
72 | 111 | 131 | ||
73 | 112 | func (s *ValidateImageMetadataSuite) TearDownTest(c *gc.C) { | 132 | func (s *ValidateImageMetadataSuite) TearDownTest(c *gc.C) { |
74 | @@ -135,6 +155,7 @@ | |||
75 | 135 | c.Check(strippedOut, gc.Matches, `matching image ids for region "us-east-1":.*`) | 155 | c.Check(strippedOut, gc.Matches, `matching image ids for region "us-east-1":.*`) |
76 | 136 | } | 156 | } |
77 | 137 | 157 | ||
78 | 158 | <<<<<<< TREE | ||
79 | 138 | func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataUsingIncompleteEnvironment(c *gc.C) { | 159 | func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataUsingIncompleteEnvironment(c *gc.C) { |
80 | 139 | testbase.PatchEnvironment("AWS_ACCESS_KEY_ID", "") | 160 | testbase.PatchEnvironment("AWS_ACCESS_KEY_ID", "") |
81 | 140 | testbase.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "") | 161 | testbase.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "") |
82 | @@ -151,6 +172,23 @@ | |||
83 | 151 | c.Check(strippedOut, gc.Matches, `error: environment has no access-key or secret-key`) | 172 | c.Check(strippedOut, gc.Matches, `error: environment has no access-key or secret-key`) |
84 | 152 | } | 173 | } |
85 | 153 | 174 | ||
86 | 175 | ======= | ||
87 | 176 | func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataUsingIncompleteEnvironment(c *gc.C) { | ||
88 | 177 | testbase.PatchEnvironment("AWS_ACCESS_KEY_ID", "") | ||
89 | 178 | testbase.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "") | ||
90 | 179 | s.setupEc2LocalMetadata(c, "us-east-1") | ||
91 | 180 | ctx := coretesting.Context(c) | ||
92 | 181 | metadataDir := config.JujuHomePath("") | ||
93 | 182 | code := cmd.Main( | ||
94 | 183 | &ValidateImageMetadataCommand{}, ctx, []string{"-e", "ec2", "-d", metadataDir}, | ||
95 | 184 | ) | ||
96 | 185 | c.Assert(code, gc.Equals, 1) | ||
97 | 186 | errOut := ctx.Stderr.(*bytes.Buffer).String() | ||
98 | 187 | strippedOut := strings.Replace(errOut, "\n", "", -1) | ||
99 | 188 | c.Check(strippedOut, gc.Matches, `error: environment has no access-key or secret-key`) | ||
100 | 189 | } | ||
101 | 190 | |||
102 | 191 | >>>>>>> MERGE-SOURCE | ||
103 | 154 | func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataWithManualParams(c *gc.C) { | 192 | func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataWithManualParams(c *gc.C) { |
104 | 155 | s.setupEc2LocalMetadata(c, "us-west-1") | 193 | s.setupEc2LocalMetadata(c, "us-west-1") |
105 | 156 | ctx := coretesting.Context(c) | 194 | ctx := coretesting.Context(c) |
106 | 157 | 195 | ||
107 | === modified file 'environs/configstore/disk.go' | |||
108 | --- environs/configstore/disk.go 2013-10-02 15:39:37 +0000 | |||
109 | +++ environs/configstore/disk.go 2013-10-17 18:24:24 +0000 | |||
110 | @@ -199,7 +199,7 @@ | |||
111 | 199 | if err != nil { | 199 | if err != nil { |
112 | 200 | return fmt.Errorf("cannot write temporary file: %v", err) | 200 | return fmt.Errorf("cannot write temporary file: %v", err) |
113 | 201 | } | 201 | } |
115 | 202 | if err := os.Rename(tmpFile.Name(), info.path); err != nil { | 202 | if err := utils.ReplaceFile(tmpFile.Name(), info.path); err != nil { |
116 | 203 | os.Remove(tmpFile.Name()) | 203 | os.Remove(tmpFile.Name()) |
117 | 204 | return fmt.Errorf("cannot rename new environment info file: %v", err) | 204 | return fmt.Errorf("cannot rename new environment info file: %v", err) |
118 | 205 | } | 205 | } |
119 | 206 | 206 | ||
120 | === modified file 'environs/filestorage/filestorage.go' | |||
121 | --- environs/filestorage/filestorage.go 2013-09-20 04:41:12 +0000 | |||
122 | +++ environs/filestorage/filestorage.go 2013-10-17 18:24:24 +0000 | |||
123 | @@ -151,7 +151,7 @@ | |||
124 | 151 | os.Remove(file.Name()) | 151 | os.Remove(file.Name()) |
125 | 152 | return err | 152 | return err |
126 | 153 | } | 153 | } |
128 | 154 | return os.Rename(file.Name(), fullpath) | 154 | return utils.ReplaceFile(file.Name(), fullpath) |
129 | 155 | } | 155 | } |
130 | 156 | 156 | ||
131 | 157 | func (f *fileStorageWriter) Remove(name string) error { | 157 | func (f *fileStorageWriter) Remove(name string) error { |
132 | 158 | 158 | ||
133 | === modified file 'environs/imagemetadata/simplestreams.go' | |||
134 | === modified file 'environs/imagemetadata/simplestreams_test.go' | |||
135 | === modified file 'environs/simplestreams/simplestreams.go' | |||
136 | === modified file 'environs/sync/sync.go' | |||
137 | --- environs/sync/sync.go 2013-10-16 05:26:30 +0000 | |||
138 | +++ environs/sync/sync.go 2013-10-17 18:24:24 +0000 | |||
139 | @@ -174,6 +174,16 @@ | |||
140 | 174 | sha256hash.Write(buf.Bytes()) | 174 | sha256hash.Write(buf.Bytes()) |
141 | 175 | tool.SHA256 = fmt.Sprintf("%x", sha256hash.Sum(nil)) | 175 | tool.SHA256 = fmt.Sprintf("%x", sha256hash.Sum(nil)) |
142 | 176 | tool.Size = nBytes | 176 | tool.Size = nBytes |
143 | 177 | |||
144 | 178 | // TODO(wallyworld) - 2013-10-09 bug=1237130 | ||
145 | 179 | // This is a 1.16 only hack to allow upgrades from 1.14 to work. | ||
146 | 180 | // Remove once 1.16 is released. | ||
147 | 181 | legacyBuf := bytes.NewBuffer(buf.Bytes()) | ||
148 | 182 | legacyName := "tools/juju-" + tool.Version.String() + ".tgz" | ||
149 | 183 | err = dest.Put(legacyName, legacyBuf, nBytes) | ||
150 | 184 | if err != nil { | ||
151 | 185 | return fmt.Errorf("writing tools to legacy location: %v", err) | ||
152 | 186 | } | ||
153 | 177 | return dest.Put(toolsName, buf, nBytes) | 187 | return dest.Put(toolsName, buf, nBytes) |
154 | 178 | } | 188 | } |
155 | 179 | 189 | ||
156 | 180 | 190 | ||
157 | === modified file 'environs/sync/sync_test.go' | |||
158 | --- environs/sync/sync_test.go 2013-10-10 11:40:54 +0000 | |||
159 | +++ environs/sync/sync_test.go 2013-10-17 18:24:24 +0000 | |||
160 | @@ -182,11 +182,36 @@ | |||
161 | 182 | s.targetEnv, test.ctx.MajorVersion, test.ctx.MinorVersion, coretools.Filter{}, envtools.DoNotAllowRetry) | 182 | s.targetEnv, test.ctx.MajorVersion, test.ctx.MinorVersion, coretools.Filter{}, envtools.DoNotAllowRetry) |
162 | 183 | c.Assert(err, gc.IsNil) | 183 | c.Assert(err, gc.IsNil) |
163 | 184 | assertToolsList(c, targetTools, test.tools) | 184 | assertToolsList(c, targetTools, test.tools) |
165 | 185 | assertNoUnexpectedTools(c, s.targetEnv.Storage()) | 185 | <<<<<<< TREE |
166 | 186 | assertNoUnexpectedTools(c, s.targetEnv.Storage()) | ||
167 | 187 | ======= | ||
168 | 188 | |||
169 | 189 | // TODO(wallyworld) - 2013-10-09 bug=1237130 | ||
170 | 190 | // This is a 1.16 only hack to allow upgrades from 1.14 to work. | ||
171 | 191 | // Remove once 1.16 is released. | ||
172 | 192 | assertLegacyTools(c, s.targetEnv.Storage(), test.tools) | ||
173 | 193 | |||
174 | 194 | assertNoUnexpectedTools(c, s.targetEnv.Storage()) | ||
175 | 195 | >>>>>>> MERGE-SOURCE | ||
176 | 186 | }() | 196 | }() |
177 | 187 | } | 197 | } |
178 | 188 | } | 198 | } |
179 | 189 | 199 | ||
180 | 200 | func assertLegacyTools(c *gc.C, stor storage.StorageReader, expected []version.Binary) { | ||
181 | 201 | files, err := stor.List("tools/juju-") | ||
182 | 202 | c.Assert(err, gc.IsNil) | ||
183 | 203 | c.Assert(len(files), gc.Equals, len(expected)) | ||
184 | 204 | for _, vers := range expected { | ||
185 | 205 | filename := "tools/juju-" + vers.String() + ".tgz" | ||
186 | 206 | r, err := stor.Get(filename) | ||
187 | 207 | c.Check(err, gc.IsNil) | ||
188 | 208 | defer r.Close() | ||
189 | 209 | data, err := ioutil.ReadAll(r) | ||
190 | 210 | c.Check(err, gc.IsNil) | ||
191 | 211 | c.Check(string(data), gc.Equals, vers.String()) | ||
192 | 212 | } | ||
193 | 213 | } | ||
194 | 214 | |||
195 | 190 | var ( | 215 | var ( |
196 | 191 | v100p64 = version.MustParseBinary("1.0.0-precise-amd64") | 216 | v100p64 = version.MustParseBinary("1.0.0-precise-amd64") |
197 | 192 | v100q64 = version.MustParseBinary("1.0.0-quantal-amd64") | 217 | v100q64 = version.MustParseBinary("1.0.0-quantal-amd64") |
198 | 193 | 218 | ||
199 | === modified file 'environs/tools/simplestreams.go' | |||
200 | === modified file 'environs/tools/simplestreams_test.go' | |||
201 | --- environs/tools/simplestreams_test.go 2013-10-16 05:26:30 +0000 | |||
202 | +++ environs/tools/simplestreams_test.go 2013-10-17 18:24:24 +0000 | |||
203 | @@ -7,8 +7,13 @@ | |||
204 | 7 | "bytes" | 7 | "bytes" |
205 | 8 | "flag" | 8 | "flag" |
206 | 9 | "fmt" | 9 | "fmt" |
207 | 10 | <<<<<<< TREE | ||
208 | 10 | "io" | 11 | "io" |
209 | 11 | "net/http" | 12 | "net/http" |
210 | 13 | ======= | ||
211 | 14 | "net/http" | ||
212 | 15 | "path/filepath" | ||
213 | 16 | >>>>>>> MERGE-SOURCE | ||
214 | 12 | "reflect" | 17 | "reflect" |
215 | 13 | "strings" | 18 | "strings" |
216 | 14 | "testing" | 19 | "testing" |
217 | @@ -477,6 +482,7 @@ | |||
218 | 477 | c.Assert(item, gc.FitsTypeOf, &tools.ToolsMetadata{}) | 482 | c.Assert(item, gc.FitsTypeOf, &tools.ToolsMetadata{}) |
219 | 478 | c.Assert(item.(*tools.ToolsMetadata).Size, gc.Equals, int64(9223372036854775807)) | 483 | c.Assert(item.(*tools.ToolsMetadata).Size, gc.Equals, int64(9223372036854775807)) |
220 | 479 | } | 484 | } |
221 | 485 | <<<<<<< TREE | ||
222 | 480 | 486 | ||
223 | 481 | type metadataHelperSuite struct { | 487 | type metadataHelperSuite struct { |
224 | 482 | testbase.LoggingSuite | 488 | testbase.LoggingSuite |
225 | @@ -795,3 +801,110 @@ | |||
226 | 795 | "format": "products:1.0" | 801 | "format": "products:1.0" |
227 | 796 | } | 802 | } |
228 | 797 | ` | 803 | ` |
229 | 804 | ======= | ||
230 | 805 | |||
231 | 806 | type signedSuite struct { | ||
232 | 807 | origKey string | ||
233 | 808 | } | ||
234 | 809 | |||
235 | 810 | var testRoundTripper *jujutest.ProxyRoundTripper | ||
236 | 811 | |||
237 | 812 | func init() { | ||
238 | 813 | testRoundTripper = &jujutest.ProxyRoundTripper{} | ||
239 | 814 | simplestreams.RegisterProtocol("signedtest", testRoundTripper) | ||
240 | 815 | } | ||
241 | 816 | |||
242 | 817 | func (s *signedSuite) SetUpSuite(c *gc.C) { | ||
243 | 818 | var imageData = map[string]string{ | ||
244 | 819 | "/unsigned/streams/v1/index.json": unsignedIndex, | ||
245 | 820 | "/unsigned/streams/v1/tools_metadata.json": unsignedProduct, | ||
246 | 821 | } | ||
247 | 822 | |||
248 | 823 | // Set up some signed data from the unsigned data. | ||
249 | 824 | // Overwrite the product path to use the sjson suffix. | ||
250 | 825 | rawUnsignedIndex := strings.Replace( | ||
251 | 826 | unsignedIndex, "streams/v1/tools_metadata.json", "streams/v1/tools_metadata.sjson", -1) | ||
252 | 827 | r := bytes.NewReader([]byte(rawUnsignedIndex)) | ||
253 | 828 | signedData, err := simplestreams.Encode( | ||
254 | 829 | r, sstesting.SignedMetadataPrivateKey, sstesting.PrivateKeyPassphrase) | ||
255 | 830 | c.Assert(err, gc.IsNil) | ||
256 | 831 | imageData["/signed/streams/v1/index.sjson"] = string(signedData) | ||
257 | 832 | |||
258 | 833 | // Replace the tools path in the unsigned data with a different one so we can test that the right | ||
259 | 834 | // tools path is used. | ||
260 | 835 | rawUnsignedProduct := strings.Replace( | ||
261 | 836 | unsignedProduct, "juju-1.13.0", "juju-1.13.1", -1) | ||
262 | 837 | r = bytes.NewReader([]byte(rawUnsignedProduct)) | ||
263 | 838 | signedData, err = simplestreams.Encode( | ||
264 | 839 | r, sstesting.SignedMetadataPrivateKey, sstesting.PrivateKeyPassphrase) | ||
265 | 840 | c.Assert(err, gc.IsNil) | ||
266 | 841 | imageData["/signed/streams/v1/tools_metadata.sjson"] = string(signedData) | ||
267 | 842 | testRoundTripper.Sub = jujutest.NewCannedRoundTripper( | ||
268 | 843 | imageData, map[string]int{"signedtest://unauth": http.StatusUnauthorized}) | ||
269 | 844 | s.origKey = tools.SetSigningPublicKey(sstesting.SignedMetadataPublicKey) | ||
270 | 845 | } | ||
271 | 846 | |||
272 | 847 | func (s *signedSuite) TearDownSuite(c *gc.C) { | ||
273 | 848 | testRoundTripper.Sub = nil | ||
274 | 849 | tools.SetSigningPublicKey(s.origKey) | ||
275 | 850 | } | ||
276 | 851 | |||
277 | 852 | func (s *signedSuite) TestSignedToolsMetadata(c *gc.C) { | ||
278 | 853 | signedSource := simplestreams.NewURLDataSource("signedtest://host/signed", simplestreams.VerifySSLHostnames) | ||
279 | 854 | toolsConstraint := tools.NewVersionedToolsConstraint("1.13.0", simplestreams.LookupParams{ | ||
280 | 855 | CloudSpec: simplestreams.CloudSpec{"us-east-1", "https://ec2.us-east-1.amazonaws.com"}, | ||
281 | 856 | Series: []string{"precise"}, | ||
282 | 857 | Arches: []string{"amd64"}, | ||
283 | 858 | }) | ||
284 | 859 | toolsMetadata, err := tools.Fetch( | ||
285 | 860 | []simplestreams.DataSource{signedSource}, simplestreams.DefaultIndexPath, toolsConstraint, true) | ||
286 | 861 | c.Assert(err, gc.IsNil) | ||
287 | 862 | c.Assert(len(toolsMetadata), gc.Equals, 1) | ||
288 | 863 | c.Assert(toolsMetadata[0].Path, gc.Equals, "tools/releases/20130806/juju-1.13.1-precise-amd64.tgz") | ||
289 | 864 | } | ||
290 | 865 | |||
291 | 866 | var unsignedIndex = ` | ||
292 | 867 | { | ||
293 | 868 | "index": { | ||
294 | 869 | "com.ubuntu.juju:released:tools": { | ||
295 | 870 | "updated": "Mon, 05 Aug 2013 11:07:04 +0000", | ||
296 | 871 | "datatype": "content-download", | ||
297 | 872 | "format": "products:1.0", | ||
298 | 873 | "products": [ | ||
299 | 874 | "com.ubuntu.juju:12.04:amd64" | ||
300 | 875 | ], | ||
301 | 876 | "path": "streams/v1/tools_metadata.json" | ||
302 | 877 | } | ||
303 | 878 | }, | ||
304 | 879 | "updated": "Wed, 01 May 2013 13:31:26 +0000", | ||
305 | 880 | "format": "index:1.0" | ||
306 | 881 | } | ||
307 | 882 | ` | ||
308 | 883 | var unsignedProduct = ` | ||
309 | 884 | { | ||
310 | 885 | "updated": "Wed, 01 May 2013 13:31:26 +0000", | ||
311 | 886 | "content_id": "com.ubuntu.cloud:released:aws", | ||
312 | 887 | "datatype": "content-download", | ||
313 | 888 | "products": { | ||
314 | 889 | "com.ubuntu.juju:12.04:amd64": { | ||
315 | 890 | "arch": "amd64", | ||
316 | 891 | "release": "precise", | ||
317 | 892 | "versions": { | ||
318 | 893 | "20130806": { | ||
319 | 894 | "items": { | ||
320 | 895 | "1130preciseamd64": { | ||
321 | 896 | "version": "1.13.0", | ||
322 | 897 | "size": 2973595, | ||
323 | 898 | "path": "tools/releases/20130806/juju-1.13.0-precise-amd64.tgz", | ||
324 | 899 | "ftype": "tar.gz", | ||
325 | 900 | "sha256": "447aeb6a934a5eaec4f703eda4ef2dde" | ||
326 | 901 | } | ||
327 | 902 | } | ||
328 | 903 | } | ||
329 | 904 | } | ||
330 | 905 | } | ||
331 | 906 | }, | ||
332 | 907 | "format": "products:1.0" | ||
333 | 908 | } | ||
334 | 909 | ` | ||
335 | 910 | >>>>>>> MERGE-SOURCE | ||
336 | 798 | 911 | ||
337 | === modified file 'provider/maas/instance_test.go' | |||
338 | --- provider/maas/instance_test.go 2013-10-15 16:16:59 +0000 | |||
339 | +++ provider/maas/instance_test.go 2013-10-17 18:24:24 +0000 | |||
340 | @@ -95,49 +95,97 @@ | |||
341 | 95 | 95 | ||
342 | 96 | addr, err := inst.Addresses() | 96 | addr, err := inst.Addresses() |
343 | 97 | 97 | ||
389 | 98 | c.Assert(err, gc.IsNil) | 98 | <<<<<<< TREE |
390 | 99 | c.Check(addr, gc.DeepEquals, expected) | 99 | c.Assert(err, gc.IsNil) |
391 | 100 | } | 100 | c.Check(addr, gc.DeepEquals, expected) |
392 | 101 | 101 | } | |
393 | 102 | func (s *instanceTest) TestAddressesMissing(c *gc.C) { | 102 | |
394 | 103 | // Older MAAS versions do not have ip_addresses returned, for these | 103 | func (s *instanceTest) TestAddressesMissing(c *gc.C) { |
395 | 104 | // just the DNS name should be returned without error. | 104 | // Older MAAS versions do not have ip_addresses returned, for these |
396 | 105 | jsonValue := `{ | 105 | // just the DNS name should be returned without error. |
397 | 106 | "hostname": "testing.invalid", | 106 | jsonValue := `{ |
398 | 107 | "system_id": "system_id" | 107 | "hostname": "testing.invalid", |
399 | 108 | }` | 108 | "system_id": "system_id" |
400 | 109 | obj := s.testMAASObject.TestServer.NewNode(jsonValue) | 109 | }` |
401 | 110 | inst := maasInstance{&obj, s.makeEnviron()} | 110 | obj := s.testMAASObject.TestServer.NewNode(jsonValue) |
402 | 111 | 111 | inst := maasInstance{&obj, s.makeEnviron()} | |
403 | 112 | addr, err := inst.Addresses() | 112 | |
404 | 113 | c.Assert(err, gc.IsNil) | 113 | addr, err := inst.Addresses() |
405 | 114 | c.Check(addr, gc.DeepEquals, []instance.Address{ | 114 | c.Assert(err, gc.IsNil) |
406 | 115 | {Value: "testing.invalid", Type: instance.HostName, NetworkScope: instance.NetworkPublic}, | 115 | c.Check(addr, gc.DeepEquals, []instance.Address{ |
407 | 116 | }) | 116 | {Value: "testing.invalid", Type: instance.HostName, NetworkScope: instance.NetworkPublic}, |
408 | 117 | } | 117 | }) |
409 | 118 | 118 | } | |
410 | 119 | func (s *instanceTest) TestAddressesInvalid(c *gc.C) { | 119 | |
411 | 120 | jsonValue := `{ | 120 | func (s *instanceTest) TestAddressesInvalid(c *gc.C) { |
412 | 121 | "hostname": "testing.invalid", | 121 | jsonValue := `{ |
413 | 122 | "system_id": "system_id", | 122 | "hostname": "testing.invalid", |
414 | 123 | "ip_addresses": "incompatible" | 123 | "system_id": "system_id", |
415 | 124 | }` | 124 | "ip_addresses": "incompatible" |
416 | 125 | obj := s.testMAASObject.TestServer.NewNode(jsonValue) | 125 | }` |
417 | 126 | inst := maasInstance{&obj, s.makeEnviron()} | 126 | obj := s.testMAASObject.TestServer.NewNode(jsonValue) |
418 | 127 | 127 | inst := maasInstance{&obj, s.makeEnviron()} | |
419 | 128 | _, err := inst.Addresses() | 128 | |
420 | 129 | c.Assert(err, gc.NotNil) | 129 | _, err := inst.Addresses() |
421 | 130 | } | 130 | c.Assert(err, gc.NotNil) |
422 | 131 | 131 | } | |
423 | 132 | func (s *instanceTest) TestAddressesInvalidContents(c *gc.C) { | 132 | |
424 | 133 | jsonValue := `{ | 133 | func (s *instanceTest) TestAddressesInvalidContents(c *gc.C) { |
425 | 134 | "hostname": "testing.invalid", | 134 | jsonValue := `{ |
426 | 135 | "system_id": "system_id", | 135 | "hostname": "testing.invalid", |
427 | 136 | "ip_addresses": [42] | 136 | "system_id": "system_id", |
428 | 137 | }` | 137 | "ip_addresses": [42] |
429 | 138 | obj := s.testMAASObject.TestServer.NewNode(jsonValue) | 138 | }` |
430 | 139 | inst := maasInstance{&obj, s.makeEnviron()} | 139 | obj := s.testMAASObject.TestServer.NewNode(jsonValue) |
431 | 140 | 140 | inst := maasInstance{&obj, s.makeEnviron()} | |
432 | 141 | _, err := inst.Addresses() | 141 | |
433 | 142 | c.Assert(err, gc.NotNil) | 142 | _, err := inst.Addresses() |
434 | 143 | c.Assert(err, gc.NotNil) | ||
435 | 144 | ======= | ||
436 | 145 | c.Assert(err, gc.IsNil) | ||
437 | 146 | c.Check(addr, gc.DeepEquals, expected) | ||
438 | 147 | } | ||
439 | 148 | |||
440 | 149 | func (s *instanceTest) TestAddressesMissing(c *gc.C) { | ||
441 | 150 | // Older MAAS versions do not have ip_addresses returned, for these | ||
442 | 151 | // just the DNS name should be returned without error. | ||
443 | 152 | jsonValue := `{ | ||
444 | 153 | "hostname": "testing.invalid", | ||
445 | 154 | "system_id": "system_id" | ||
446 | 155 | }` | ||
447 | 156 | obj := s.testMAASObject.TestServer.NewNode(jsonValue) | ||
448 | 157 | inst := maasInstance{&obj, s.environ} | ||
449 | 158 | |||
450 | 159 | addr, err := inst.Addresses() | ||
451 | 160 | c.Assert(err, gc.IsNil) | ||
452 | 161 | c.Check(addr, gc.DeepEquals, []instance.Address{ | ||
453 | 162 | {Value: "testing.invalid", Type: instance.HostName, NetworkScope: instance.NetworkPublic}, | ||
454 | 163 | }) | ||
455 | 164 | } | ||
456 | 165 | |||
457 | 166 | func (s *instanceTest) TestAddressesInvalid(c *gc.C) { | ||
458 | 167 | jsonValue := `{ | ||
459 | 168 | "hostname": "testing.invalid", | ||
460 | 169 | "system_id": "system_id", | ||
461 | 170 | "ip_addresses": "incompatible" | ||
462 | 171 | }` | ||
463 | 172 | obj := s.testMAASObject.TestServer.NewNode(jsonValue) | ||
464 | 173 | inst := maasInstance{&obj, s.environ} | ||
465 | 174 | |||
466 | 175 | _, err := inst.Addresses() | ||
467 | 176 | c.Assert(err, gc.NotNil) | ||
468 | 177 | } | ||
469 | 178 | |||
470 | 179 | func (s *instanceTest) TestAddressesInvalidContents(c *gc.C) { | ||
471 | 180 | jsonValue := `{ | ||
472 | 181 | "hostname": "testing.invalid", | ||
473 | 182 | "system_id": "system_id", | ||
474 | 183 | "ip_addresses": [42] | ||
475 | 184 | }` | ||
476 | 185 | obj := s.testMAASObject.TestServer.NewNode(jsonValue) | ||
477 | 186 | inst := maasInstance{&obj, s.environ} | ||
478 | 187 | |||
479 | 188 | _, err := inst.Addresses() | ||
480 | 189 | c.Assert(err, gc.NotNil) | ||
481 | 190 | >>>>>>> MERGE-SOURCE | ||
482 | 143 | } | 191 | } |
483 | 144 | 192 | ||
484 | === modified file 'provider/openstack/provider.go' | |||
485 | === added file 'utils/file_unix.go' | |||
486 | --- utils/file_unix.go 1970-01-01 00:00:00 +0000 | |||
487 | +++ utils/file_unix.go 2013-10-17 18:24:24 +0000 | |||
488 | @@ -0,0 +1,15 @@ | |||
489 | 1 | // Copyright 2013 Canonical Ltd. | ||
490 | 2 | // Licensed under the AGPLv3, see LICENCE file for details. | ||
491 | 3 | // +build !windows | ||
492 | 4 | |||
493 | 5 | package utils | ||
494 | 6 | |||
495 | 7 | import ( | ||
496 | 8 | "os" | ||
497 | 9 | ) | ||
498 | 10 | |||
499 | 11 | // Replace atomically replaces the destination file or directory with the source. | ||
500 | 12 | // The errors that are returned are identical to those returned by os.Rename. | ||
501 | 13 | func ReplaceFile(source, destination string) error { | ||
502 | 14 | return os.Rename(source, destination) | ||
503 | 15 | } | ||
504 | 0 | 16 | ||
505 | === added file 'utils/file_windows.go' | |||
506 | --- utils/file_windows.go 1970-01-01 00:00:00 +0000 | |||
507 | +++ utils/file_windows.go 2013-10-17 18:24:24 +0000 | |||
508 | @@ -0,0 +1,35 @@ | |||
509 | 1 | // Copyright 2013 Canonical Ltd. | ||
510 | 2 | // Licensed under the AGPLv3, see LICENCE file for details. | ||
511 | 3 | |||
512 | 4 | package utils | ||
513 | 5 | |||
514 | 6 | import ( | ||
515 | 7 | "os" | ||
516 | 8 | "syscall" | ||
517 | 9 | ) | ||
518 | 10 | |||
519 | 11 | const ( | ||
520 | 12 | movefile_replace_existing = 0x1 | ||
521 | 13 | movefile_write_through = 0x8 | ||
522 | 14 | ) | ||
523 | 15 | |||
524 | 16 | //sys moveFileEx(lpExistingFileName *uint16, lpNewFileName *uint16, dwFlags uint32) (err error) = MoveFileExW | ||
525 | 17 | |||
526 | 18 | // ReplaceFile atomically replaces the destination file or directory with the source. | ||
527 | 19 | // The errors that are returned are identical to those returned by os.Rename. | ||
528 | 20 | func ReplaceFile(source, destination string) error { | ||
529 | 21 | src, err := syscall.UTF16PtrFromString(source) | ||
530 | 22 | if err != nil { | ||
531 | 23 | return &os.LinkError{"replace", source, destination, err} | ||
532 | 24 | } | ||
533 | 25 | dest, err := syscall.UTF16PtrFromString(destination) | ||
534 | 26 | if err != nil { | ||
535 | 27 | return &os.LinkError{"replace", source, destination, err} | ||
536 | 28 | } | ||
537 | 29 | |||
538 | 30 | // see http://msdn.microsoft.com/en-us/library/windows/desktop/aa365240(v=vs.85).aspx | ||
539 | 31 | if err := moveFileEx(src, dest, movefile_replace_existing|movefile_write_through); err != nil { | ||
540 | 32 | return &os.LinkError{"replace", source, destination, err} | ||
541 | 33 | } | ||
542 | 34 | return nil | ||
543 | 35 | } | ||
544 | 0 | 36 | ||
545 | === modified file 'utils/fslock/fslock.go' | |||
546 | --- utils/fslock/fslock.go 2013-08-02 12:37:43 +0000 | |||
547 | +++ utils/fslock/fslock.go 2013-10-17 18:24:24 +0000 | |||
548 | @@ -113,7 +113,7 @@ | |||
549 | 113 | } | 113 | } |
550 | 114 | } | 114 | } |
551 | 115 | // Now move the temp directory to the lock directory. | 115 | // Now move the temp directory to the lock directory. |
553 | 116 | err = os.Rename(tempDirName, lock.lockDir()) | 116 | err = utils.ReplaceFile(tempDirName, lock.lockDir()) |
554 | 117 | if err != nil { | 117 | if err != nil { |
555 | 118 | // Any error on rename means we failed. | 118 | // Any error on rename means we failed. |
556 | 119 | // Beaten to it, clean up temporary directory. | 119 | // Beaten to it, clean up temporary directory. |
557 | @@ -200,7 +200,7 @@ | |||
558 | 200 | tempLockName := fmt.Sprintf(".%s.%x", lock.name, lock.nonce) | 200 | tempLockName := fmt.Sprintf(".%s.%x", lock.name, lock.nonce) |
559 | 201 | tempDirName := path.Join(lock.parent, tempLockName) | 201 | tempDirName := path.Join(lock.parent, tempLockName) |
560 | 202 | // Now move the lock directory to the temp directory to release the lock. | 202 | // Now move the lock directory to the temp directory to release the lock. |
562 | 203 | if err := os.Rename(lock.lockDir(), tempDirName); err != nil { | 203 | if err := utils.ReplaceFile(lock.lockDir(), tempDirName); err != nil { |
563 | 204 | return err | 204 | return err |
564 | 205 | } | 205 | } |
565 | 206 | // And now cleanup. | 206 | // And now cleanup. |
566 | 207 | 207 | ||
567 | === modified file 'utils/trivial.go' | |||
568 | --- utils/trivial.go 2013-07-09 10:32:23 +0000 | |||
569 | +++ utils/trivial.go 2013-10-17 18:24:24 +0000 | |||
570 | @@ -32,7 +32,7 @@ | |||
571 | 32 | if _, err = f.Write(data); err != nil { | 32 | if _, err = f.Write(data); err != nil { |
572 | 33 | return err | 33 | return err |
573 | 34 | } | 34 | } |
575 | 35 | return os.Rename(prep, path) | 35 | return ReplaceFile(prep, path) |
576 | 36 | } | 36 | } |
577 | 37 | 37 | ||
578 | 38 | // ReadYaml unmarshals the yaml contained in the file at path into obj. See | 38 | // ReadYaml unmarshals the yaml contained in the file at path into obj. See |
579 | 39 | 39 | ||
580 | === added file 'utils/zfile_windows.go' | |||
581 | --- utils/zfile_windows.go 1970-01-01 00:00:00 +0000 | |||
582 | +++ utils/zfile_windows.go 2013-10-17 18:24:24 +0000 | |||
583 | @@ -0,0 +1,25 @@ | |||
584 | 1 | // mksyscall_windows.pl -l32 file_windows.go | ||
585 | 2 | // MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT | ||
586 | 3 | |||
587 | 4 | package utils | ||
588 | 5 | |||
589 | 6 | import "unsafe" | ||
590 | 7 | import "syscall" | ||
591 | 8 | |||
592 | 9 | var ( | ||
593 | 10 | modkernel32 = syscall.NewLazyDLL("kernel32.dll") | ||
594 | 11 | |||
595 | 12 | procMoveFileExW = modkernel32.NewProc("MoveFileExW") | ||
596 | 13 | ) | ||
597 | 14 | |||
598 | 15 | func moveFileEx(lpExistingFileName *uint16, lpNewFileName *uint16, dwFlags uint32) (err error) { | ||
599 | 16 | r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(lpExistingFileName)), uintptr(unsafe.Pointer(lpNewFileName)), uintptr(dwFlags)) | ||
600 | 17 | if r1 == 0 { | ||
601 | 18 | if e1 != 0 { | ||
602 | 19 | err = error(e1) | ||
603 | 20 | } else { | ||
604 | 21 | err = syscall.EINVAL | ||
605 | 22 | } | ||
606 | 23 | } | ||
607 | 24 | return | ||
608 | 25 | } | ||
609 | 0 | 26 | ||
610 | === modified file 'version/version.go' | |||
611 | --- version/version.go 2013-10-10 11:40:54 +0000 | |||
612 | +++ version/version.go 2013-10-17 18:24:24 +0000 | |||
613 | @@ -22,7 +22,11 @@ | |||
614 | 22 | // The presence and format of this constant is very important. | 22 | // The presence and format of this constant is very important. |
615 | 23 | // The debian/rules build recipe uses this value for the version | 23 | // The debian/rules build recipe uses this value for the version |
616 | 24 | // number of the release package. | 24 | // number of the release package. |
617 | 25 | <<<<<<< TREE | ||
618 | 25 | const version = "1.17.0" | 26 | const version = "1.17.0" |
619 | 27 | ======= | ||
620 | 28 | const version = "1.16.0" | ||
621 | 29 | >>>>>>> MERGE-SOURCE | ||
622 | 26 | 30 | ||
623 | 27 | // Current gives the current version of the system. If the file | 31 | // Current gives the current version of the system. If the file |
624 | 28 | // "FORCE-VERSION" is present in the same directory as the running | 32 | // "FORCE-VERSION" is present in the same directory as the running |