Merge lp:~natefinch/juju-core/fix-win-bootstrap into lp:~go-bot/juju-core/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
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

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 "strings"
6
7 "launchpad.net/juju-core/log"
8+ "launchpad.net/juju-core/utils"
9 )
10
11 // CacheDir stores the charm cache directory path.
12@@ -257,7 +258,7 @@
13 os.Remove(dlPath)
14 return nil, err
15 }
16- if err := os.Rename(dlPath, path); err != nil {
17+ if err := utils.ReplaceFile(dlPath, path); err != nil {
18 return nil, err
19 }
20 }
21
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 )
27
28 type ValidateImageMetadataSuite struct {
29+<<<<<<< TREE
30 testbase.LoggingSuite
31 home *coretesting.FakeHome
32 metadataDir string
33+=======
34+ testbase.LoggingSuite
35+ home *coretesting.FakeHome
36+>>>>>>> MERGE-SOURCE
37 }
38
39 var _ = gc.Suite(&ValidateImageMetadataSuite{})
40@@ -89,6 +94,10 @@
41 environments:
42 ec2:
43 type: ec2
44+<<<<<<< TREE
45+=======
46+ control-bucket: foo
47+>>>>>>> MERGE-SOURCE
48 default-series: precise
49 region: us-east-1
50
51@@ -102,11 +111,22 @@
52 `
53
54 func (s *ValidateImageMetadataSuite) SetUpTest(c *gc.C) {
55+<<<<<<< TREE
56 s.LoggingSuite.SetUpTest(c)
57 s.metadataDir = c.MkDir()
58+=======
59+ s.LoggingSuite.SetUpTest(c)
60+>>>>>>> MERGE-SOURCE
61 s.home = coretesting.MakeFakeHome(c, metadataTestEnvConfig)
62+<<<<<<< TREE
63 s.PatchEnvironment("AWS_ACCESS_KEY_ID", "access")
64 s.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "secret")
65+=======
66+ restore := testbase.PatchEnvironment("AWS_ACCESS_KEY_ID", "access")
67+ s.AddCleanup(func(*gc.C) { restore() })
68+ restore = testbase.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "secret")
69+ s.AddCleanup(func(*gc.C) { restore() })
70+>>>>>>> MERGE-SOURCE
71 }
72
73 func (s *ValidateImageMetadataSuite) TearDownTest(c *gc.C) {
74@@ -135,6 +155,7 @@
75 c.Check(strippedOut, gc.Matches, `matching image ids for region "us-east-1":.*`)
76 }
77
78+<<<<<<< TREE
79 func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataUsingIncompleteEnvironment(c *gc.C) {
80 testbase.PatchEnvironment("AWS_ACCESS_KEY_ID", "")
81 testbase.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "")
82@@ -151,6 +172,23 @@
83 c.Check(strippedOut, gc.Matches, `error: environment has no access-key or secret-key`)
84 }
85
86+=======
87+func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataUsingIncompleteEnvironment(c *gc.C) {
88+ testbase.PatchEnvironment("AWS_ACCESS_KEY_ID", "")
89+ testbase.PatchEnvironment("AWS_SECRET_ACCESS_KEY", "")
90+ s.setupEc2LocalMetadata(c, "us-east-1")
91+ ctx := coretesting.Context(c)
92+ metadataDir := config.JujuHomePath("")
93+ code := cmd.Main(
94+ &ValidateImageMetadataCommand{}, ctx, []string{"-e", "ec2", "-d", metadataDir},
95+ )
96+ c.Assert(code, gc.Equals, 1)
97+ errOut := ctx.Stderr.(*bytes.Buffer).String()
98+ strippedOut := strings.Replace(errOut, "\n", "", -1)
99+ c.Check(strippedOut, gc.Matches, `error: environment has no access-key or secret-key`)
100+}
101+
102+>>>>>>> MERGE-SOURCE
103 func (s *ValidateImageMetadataSuite) TestEc2LocalMetadataWithManualParams(c *gc.C) {
104 s.setupEc2LocalMetadata(c, "us-west-1")
105 ctx := coretesting.Context(c)
106
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 if err != nil {
112 return fmt.Errorf("cannot write temporary file: %v", err)
113 }
114- if err := os.Rename(tmpFile.Name(), info.path); err != nil {
115+ if err := utils.ReplaceFile(tmpFile.Name(), info.path); err != nil {
116 os.Remove(tmpFile.Name())
117 return fmt.Errorf("cannot rename new environment info file: %v", err)
118 }
119
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 os.Remove(file.Name())
125 return err
126 }
127- return os.Rename(file.Name(), fullpath)
128+ return utils.ReplaceFile(file.Name(), fullpath)
129 }
130
131 func (f *fileStorageWriter) Remove(name string) error {
132
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 sha256hash.Write(buf.Bytes())
141 tool.SHA256 = fmt.Sprintf("%x", sha256hash.Sum(nil))
142 tool.Size = nBytes
143+
144+ // TODO(wallyworld) - 2013-10-09 bug=1237130
145+ // This is a 1.16 only hack to allow upgrades from 1.14 to work.
146+ // Remove once 1.16 is released.
147+ legacyBuf := bytes.NewBuffer(buf.Bytes())
148+ legacyName := "tools/juju-" + tool.Version.String() + ".tgz"
149+ err = dest.Put(legacyName, legacyBuf, nBytes)
150+ if err != nil {
151+ return fmt.Errorf("writing tools to legacy location: %v", err)
152+ }
153 return dest.Put(toolsName, buf, nBytes)
154 }
155
156
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 s.targetEnv, test.ctx.MajorVersion, test.ctx.MinorVersion, coretools.Filter{}, envtools.DoNotAllowRetry)
162 c.Assert(err, gc.IsNil)
163 assertToolsList(c, targetTools, test.tools)
164- assertNoUnexpectedTools(c, s.targetEnv.Storage())
165+<<<<<<< TREE
166+ assertNoUnexpectedTools(c, s.targetEnv.Storage())
167+=======
168+
169+ // TODO(wallyworld) - 2013-10-09 bug=1237130
170+ // This is a 1.16 only hack to allow upgrades from 1.14 to work.
171+ // Remove once 1.16 is released.
172+ assertLegacyTools(c, s.targetEnv.Storage(), test.tools)
173+
174+ assertNoUnexpectedTools(c, s.targetEnv.Storage())
175+>>>>>>> MERGE-SOURCE
176 }()
177 }
178 }
179
180+func assertLegacyTools(c *gc.C, stor storage.StorageReader, expected []version.Binary) {
181+ files, err := stor.List("tools/juju-")
182+ c.Assert(err, gc.IsNil)
183+ c.Assert(len(files), gc.Equals, len(expected))
184+ for _, vers := range expected {
185+ filename := "tools/juju-" + vers.String() + ".tgz"
186+ r, err := stor.Get(filename)
187+ c.Check(err, gc.IsNil)
188+ defer r.Close()
189+ data, err := ioutil.ReadAll(r)
190+ c.Check(err, gc.IsNil)
191+ c.Check(string(data), gc.Equals, vers.String())
192+ }
193+}
194+
195 var (
196 v100p64 = version.MustParseBinary("1.0.0-precise-amd64")
197 v100q64 = version.MustParseBinary("1.0.0-quantal-amd64")
198
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 "bytes"
205 "flag"
206 "fmt"
207+<<<<<<< TREE
208 "io"
209 "net/http"
210+=======
211+ "net/http"
212+ "path/filepath"
213+>>>>>>> MERGE-SOURCE
214 "reflect"
215 "strings"
216 "testing"
217@@ -477,6 +482,7 @@
218 c.Assert(item, gc.FitsTypeOf, &tools.ToolsMetadata{})
219 c.Assert(item.(*tools.ToolsMetadata).Size, gc.Equals, int64(9223372036854775807))
220 }
221+<<<<<<< TREE
222
223 type metadataHelperSuite struct {
224 testbase.LoggingSuite
225@@ -795,3 +801,110 @@
226 "format": "products:1.0"
227 }
228 `
229+=======
230+
231+type signedSuite struct {
232+ origKey string
233+}
234+
235+var testRoundTripper *jujutest.ProxyRoundTripper
236+
237+func init() {
238+ testRoundTripper = &jujutest.ProxyRoundTripper{}
239+ simplestreams.RegisterProtocol("signedtest", testRoundTripper)
240+}
241+
242+func (s *signedSuite) SetUpSuite(c *gc.C) {
243+ var imageData = map[string]string{
244+ "/unsigned/streams/v1/index.json": unsignedIndex,
245+ "/unsigned/streams/v1/tools_metadata.json": unsignedProduct,
246+ }
247+
248+ // Set up some signed data from the unsigned data.
249+ // Overwrite the product path to use the sjson suffix.
250+ rawUnsignedIndex := strings.Replace(
251+ unsignedIndex, "streams/v1/tools_metadata.json", "streams/v1/tools_metadata.sjson", -1)
252+ r := bytes.NewReader([]byte(rawUnsignedIndex))
253+ signedData, err := simplestreams.Encode(
254+ r, sstesting.SignedMetadataPrivateKey, sstesting.PrivateKeyPassphrase)
255+ c.Assert(err, gc.IsNil)
256+ imageData["/signed/streams/v1/index.sjson"] = string(signedData)
257+
258+ // Replace the tools path in the unsigned data with a different one so we can test that the right
259+ // tools path is used.
260+ rawUnsignedProduct := strings.Replace(
261+ unsignedProduct, "juju-1.13.0", "juju-1.13.1", -1)
262+ r = bytes.NewReader([]byte(rawUnsignedProduct))
263+ signedData, err = simplestreams.Encode(
264+ r, sstesting.SignedMetadataPrivateKey, sstesting.PrivateKeyPassphrase)
265+ c.Assert(err, gc.IsNil)
266+ imageData["/signed/streams/v1/tools_metadata.sjson"] = string(signedData)
267+ testRoundTripper.Sub = jujutest.NewCannedRoundTripper(
268+ imageData, map[string]int{"signedtest://unauth": http.StatusUnauthorized})
269+ s.origKey = tools.SetSigningPublicKey(sstesting.SignedMetadataPublicKey)
270+}
271+
272+func (s *signedSuite) TearDownSuite(c *gc.C) {
273+ testRoundTripper.Sub = nil
274+ tools.SetSigningPublicKey(s.origKey)
275+}
276+
277+func (s *signedSuite) TestSignedToolsMetadata(c *gc.C) {
278+ signedSource := simplestreams.NewURLDataSource("signedtest://host/signed", simplestreams.VerifySSLHostnames)
279+ toolsConstraint := tools.NewVersionedToolsConstraint("1.13.0", simplestreams.LookupParams{
280+ CloudSpec: simplestreams.CloudSpec{"us-east-1", "https://ec2.us-east-1.amazonaws.com"},
281+ Series: []string{"precise"},
282+ Arches: []string{"amd64"},
283+ })
284+ toolsMetadata, err := tools.Fetch(
285+ []simplestreams.DataSource{signedSource}, simplestreams.DefaultIndexPath, toolsConstraint, true)
286+ c.Assert(err, gc.IsNil)
287+ c.Assert(len(toolsMetadata), gc.Equals, 1)
288+ c.Assert(toolsMetadata[0].Path, gc.Equals, "tools/releases/20130806/juju-1.13.1-precise-amd64.tgz")
289+}
290+
291+var unsignedIndex = `
292+{
293+ "index": {
294+ "com.ubuntu.juju:released:tools": {
295+ "updated": "Mon, 05 Aug 2013 11:07:04 +0000",
296+ "datatype": "content-download",
297+ "format": "products:1.0",
298+ "products": [
299+ "com.ubuntu.juju:12.04:amd64"
300+ ],
301+ "path": "streams/v1/tools_metadata.json"
302+ }
303+ },
304+ "updated": "Wed, 01 May 2013 13:31:26 +0000",
305+ "format": "index:1.0"
306+}
307+`
308+var unsignedProduct = `
309+{
310+ "updated": "Wed, 01 May 2013 13:31:26 +0000",
311+ "content_id": "com.ubuntu.cloud:released:aws",
312+ "datatype": "content-download",
313+ "products": {
314+ "com.ubuntu.juju:12.04:amd64": {
315+ "arch": "amd64",
316+ "release": "precise",
317+ "versions": {
318+ "20130806": {
319+ "items": {
320+ "1130preciseamd64": {
321+ "version": "1.13.0",
322+ "size": 2973595,
323+ "path": "tools/releases/20130806/juju-1.13.0-precise-amd64.tgz",
324+ "ftype": "tar.gz",
325+ "sha256": "447aeb6a934a5eaec4f703eda4ef2dde"
326+ }
327+ }
328+ }
329+ }
330+ }
331+ },
332+ "format": "products:1.0"
333+}
334+`
335+>>>>>>> MERGE-SOURCE
336
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
342 addr, err := inst.Addresses()
343
344- c.Assert(err, gc.IsNil)
345- c.Check(addr, gc.DeepEquals, expected)
346-}
347-
348-func (s *instanceTest) TestAddressesMissing(c *gc.C) {
349- // Older MAAS versions do not have ip_addresses returned, for these
350- // just the DNS name should be returned without error.
351- jsonValue := `{
352- "hostname": "testing.invalid",
353- "system_id": "system_id"
354- }`
355- obj := s.testMAASObject.TestServer.NewNode(jsonValue)
356- inst := maasInstance{&obj, s.makeEnviron()}
357-
358- addr, err := inst.Addresses()
359- c.Assert(err, gc.IsNil)
360- c.Check(addr, gc.DeepEquals, []instance.Address{
361- {Value: "testing.invalid", Type: instance.HostName, NetworkScope: instance.NetworkPublic},
362- })
363-}
364-
365-func (s *instanceTest) TestAddressesInvalid(c *gc.C) {
366- jsonValue := `{
367- "hostname": "testing.invalid",
368- "system_id": "system_id",
369- "ip_addresses": "incompatible"
370- }`
371- obj := s.testMAASObject.TestServer.NewNode(jsonValue)
372- inst := maasInstance{&obj, s.makeEnviron()}
373-
374- _, err := inst.Addresses()
375- c.Assert(err, gc.NotNil)
376-}
377-
378-func (s *instanceTest) TestAddressesInvalidContents(c *gc.C) {
379- jsonValue := `{
380- "hostname": "testing.invalid",
381- "system_id": "system_id",
382- "ip_addresses": [42]
383- }`
384- obj := s.testMAASObject.TestServer.NewNode(jsonValue)
385- inst := maasInstance{&obj, s.makeEnviron()}
386-
387- _, err := inst.Addresses()
388- c.Assert(err, gc.NotNil)
389+<<<<<<< TREE
390+ c.Assert(err, gc.IsNil)
391+ c.Check(addr, gc.DeepEquals, expected)
392+}
393+
394+func (s *instanceTest) TestAddressesMissing(c *gc.C) {
395+ // Older MAAS versions do not have ip_addresses returned, for these
396+ // just the DNS name should be returned without error.
397+ jsonValue := `{
398+ "hostname": "testing.invalid",
399+ "system_id": "system_id"
400+ }`
401+ obj := s.testMAASObject.TestServer.NewNode(jsonValue)
402+ inst := maasInstance{&obj, s.makeEnviron()}
403+
404+ addr, err := inst.Addresses()
405+ c.Assert(err, gc.IsNil)
406+ c.Check(addr, gc.DeepEquals, []instance.Address{
407+ {Value: "testing.invalid", Type: instance.HostName, NetworkScope: instance.NetworkPublic},
408+ })
409+}
410+
411+func (s *instanceTest) TestAddressesInvalid(c *gc.C) {
412+ jsonValue := `{
413+ "hostname": "testing.invalid",
414+ "system_id": "system_id",
415+ "ip_addresses": "incompatible"
416+ }`
417+ obj := s.testMAASObject.TestServer.NewNode(jsonValue)
418+ inst := maasInstance{&obj, s.makeEnviron()}
419+
420+ _, err := inst.Addresses()
421+ c.Assert(err, gc.NotNil)
422+}
423+
424+func (s *instanceTest) TestAddressesInvalidContents(c *gc.C) {
425+ jsonValue := `{
426+ "hostname": "testing.invalid",
427+ "system_id": "system_id",
428+ "ip_addresses": [42]
429+ }`
430+ obj := s.testMAASObject.TestServer.NewNode(jsonValue)
431+ inst := maasInstance{&obj, s.makeEnviron()}
432+
433+ _, err := inst.Addresses()
434+ c.Assert(err, gc.NotNil)
435+=======
436+ c.Assert(err, gc.IsNil)
437+ c.Check(addr, gc.DeepEquals, expected)
438+}
439+
440+func (s *instanceTest) TestAddressesMissing(c *gc.C) {
441+ // Older MAAS versions do not have ip_addresses returned, for these
442+ // just the DNS name should be returned without error.
443+ jsonValue := `{
444+ "hostname": "testing.invalid",
445+ "system_id": "system_id"
446+ }`
447+ obj := s.testMAASObject.TestServer.NewNode(jsonValue)
448+ inst := maasInstance{&obj, s.environ}
449+
450+ addr, err := inst.Addresses()
451+ c.Assert(err, gc.IsNil)
452+ c.Check(addr, gc.DeepEquals, []instance.Address{
453+ {Value: "testing.invalid", Type: instance.HostName, NetworkScope: instance.NetworkPublic},
454+ })
455+}
456+
457+func (s *instanceTest) TestAddressesInvalid(c *gc.C) {
458+ jsonValue := `{
459+ "hostname": "testing.invalid",
460+ "system_id": "system_id",
461+ "ip_addresses": "incompatible"
462+ }`
463+ obj := s.testMAASObject.TestServer.NewNode(jsonValue)
464+ inst := maasInstance{&obj, s.environ}
465+
466+ _, err := inst.Addresses()
467+ c.Assert(err, gc.NotNil)
468+}
469+
470+func (s *instanceTest) TestAddressesInvalidContents(c *gc.C) {
471+ jsonValue := `{
472+ "hostname": "testing.invalid",
473+ "system_id": "system_id",
474+ "ip_addresses": [42]
475+ }`
476+ obj := s.testMAASObject.TestServer.NewNode(jsonValue)
477+ inst := maasInstance{&obj, s.environ}
478+
479+ _, err := inst.Addresses()
480+ c.Assert(err, gc.NotNil)
481+>>>>>>> MERGE-SOURCE
482 }
483
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+// Copyright 2013 Canonical Ltd.
490+// Licensed under the AGPLv3, see LICENCE file for details.
491+// +build !windows
492+
493+package utils
494+
495+import (
496+ "os"
497+)
498+
499+// Replace atomically replaces the destination file or directory with the source.
500+// The errors that are returned are identical to those returned by os.Rename.
501+func ReplaceFile(source, destination string) error {
502+ return os.Rename(source, destination)
503+}
504
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+// Copyright 2013 Canonical Ltd.
510+// Licensed under the AGPLv3, see LICENCE file for details.
511+
512+package utils
513+
514+import (
515+ "os"
516+ "syscall"
517+)
518+
519+const (
520+ movefile_replace_existing = 0x1
521+ movefile_write_through = 0x8
522+)
523+
524+//sys moveFileEx(lpExistingFileName *uint16, lpNewFileName *uint16, dwFlags uint32) (err error) = MoveFileExW
525+
526+// ReplaceFile atomically replaces the destination file or directory with the source.
527+// The errors that are returned are identical to those returned by os.Rename.
528+func ReplaceFile(source, destination string) error {
529+ src, err := syscall.UTF16PtrFromString(source)
530+ if err != nil {
531+ return &os.LinkError{"replace", source, destination, err}
532+ }
533+ dest, err := syscall.UTF16PtrFromString(destination)
534+ if err != nil {
535+ return &os.LinkError{"replace", source, destination, err}
536+ }
537+
538+ // see http://msdn.microsoft.com/en-us/library/windows/desktop/aa365240(v=vs.85).aspx
539+ if err := moveFileEx(src, dest, movefile_replace_existing|movefile_write_through); err != nil {
540+ return &os.LinkError{"replace", source, destination, err}
541+ }
542+ return nil
543+}
544
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 }
550 }
551 // Now move the temp directory to the lock directory.
552- err = os.Rename(tempDirName, lock.lockDir())
553+ err = utils.ReplaceFile(tempDirName, lock.lockDir())
554 if err != nil {
555 // Any error on rename means we failed.
556 // Beaten to it, clean up temporary directory.
557@@ -200,7 +200,7 @@
558 tempLockName := fmt.Sprintf(".%s.%x", lock.name, lock.nonce)
559 tempDirName := path.Join(lock.parent, tempLockName)
560 // Now move the lock directory to the temp directory to release the lock.
561- if err := os.Rename(lock.lockDir(), tempDirName); err != nil {
562+ if err := utils.ReplaceFile(lock.lockDir(), tempDirName); err != nil {
563 return err
564 }
565 // And now cleanup.
566
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 if _, err = f.Write(data); err != nil {
572 return err
573 }
574- return os.Rename(prep, path)
575+ return ReplaceFile(prep, path)
576 }
577
578 // ReadYaml unmarshals the yaml contained in the file at path into obj. See
579
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+// mksyscall_windows.pl -l32 file_windows.go
585+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
586+
587+package utils
588+
589+import "unsafe"
590+import "syscall"
591+
592+var (
593+ modkernel32 = syscall.NewLazyDLL("kernel32.dll")
594+
595+ procMoveFileExW = modkernel32.NewProc("MoveFileExW")
596+)
597+
598+func moveFileEx(lpExistingFileName *uint16, lpNewFileName *uint16, dwFlags uint32) (err error) {
599+ r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(lpExistingFileName)), uintptr(unsafe.Pointer(lpNewFileName)), uintptr(dwFlags))
600+ if r1 == 0 {
601+ if e1 != 0 {
602+ err = error(e1)
603+ } else {
604+ err = syscall.EINVAL
605+ }
606+ }
607+ return
608+}
609
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 // The presence and format of this constant is very important.
615 // The debian/rules build recipe uses this value for the version
616 // number of the release package.
617+<<<<<<< TREE
618 const version = "1.17.0"
619+=======
620+const version = "1.16.0"
621+>>>>>>> MERGE-SOURCE
622
623 // Current gives the current version of the system. If the file
624 // "FORCE-VERSION" is present in the same directory as the running

Subscribers

People subscribed via source and target branches

to status/vote changes: