Merge lp:~cjwatson/launchpad/buildmaster-getFile-rename into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 18543
Proposed branch: lp:~cjwatson/launchpad/buildmaster-getFile-rename
Merge into: lp:launchpad
Diff against target: 32 lines (+7/-1)
1 file modified
lib/lp/buildmaster/interactor.py (+7/-1)
To merge this branch: bzr merge lp:~cjwatson/launchpad/buildmaster-getFile-rename
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+336709@code.launchpad.net

Commit message

Write files fetched from builders to a temporary name, and only rename them into place on success.

Description of the change

This is a slightly speculative attempt to fix odd checksum mismatches on files fetched from builders for gcc-7-cross-ports builds: my theory is that a Deferred might be left over from a previous retry iteration and try to write to the same file. At any rate, it should be pretty safe to follow the rename-into-place protocol here.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/buildmaster/interactor.py'
2--- lib/lp/buildmaster/interactor.py 2017-04-27 15:54:54 +0000
3+++ lib/lp/buildmaster/interactor.py 2018-01-26 16:33:33 +0000
4@@ -10,6 +10,8 @@
5
6 from collections import namedtuple
7 import logging
8+import os.path
9+import tempfile
10 from urlparse import urlparse
11
12 import transaction
13@@ -67,7 +69,9 @@
14
15 def dataReceived(self, data):
16 if self.file is None:
17- self.file = open(self.filename, "wb")
18+ self.file = tempfile.NamedTemporaryFile(
19+ mode="wb", prefix=os.path.basename(self.filename) + "_",
20+ dir=os.path.dirname(self.filename), delete=False)
21 try:
22 self.file.write(data)
23 except IOError:
24@@ -82,6 +86,8 @@
25 try:
26 if self.file is not None:
27 self.file.close()
28+ if self.filename is not None and reason.check(ResponseDone):
29+ os.rename(self.file.name, self.filename)
30 except IOError:
31 self.finished.errback()
32 else: