Merge lp:~vila/uci-engine/makedirs-races into lp:uci-engine

Proposed by Vincent Ladeuil
Status: Merged
Approved by: Evan
Approved revision: 829
Merged at revision: 831
Proposed branch: lp:~vila/uci-engine/makedirs-races
Merge into: lp:uci-engine
Diff against target: 110 lines (+31/-5)
4 files modified
cli/ci_cli/image.py (+10/-2)
lander/lander/__init__.py (+7/-1)
test_runner/tstrun/run_worker.py (+7/-1)
test_runner/tstrun/testbed.py (+7/-1)
To merge this branch: bzr merge lp:~vila/uci-engine/makedirs-races
Reviewer Review Type Date Requested Status
Evan (community) Approve
Paul Larson Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+237260@code.launchpad.net

Commit message

Fix other call sites where creating needed dirs may be racy

Description of the change

Since I had a brief look at where other call sites (including the one I
copied the if path.exists(): makesdirs() ;) I thought it was faster to fix
them to address the second part of the review remark: "I worry it getting
copied elsewhere" ;)

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:829
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/1537/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/uci-engine-ci/1537/rebuild

review: Approve (continuous-integration)
Revision history for this message
Paul Larson (pwlars) wrote :

Looks fine, the only thing I would say is that since this appears to be such a common problem, we should probably just make this a helper function in ci_utils and call it from there. safe_make_dirs() or something.

review: Approve
Revision history for this message
Evan (ev) wrote :

Way to go the extra mile on that previous MP. Agree with Paul that this could probably be a utility function.

review: Approve
Revision history for this message
Ubuntu CI Bot (uci-bot) wrote :

The attempt to merge lp:~vila/uci-engine/makedirs-races into lp:uci-engine failed. Below is the output from the failed tests.

ERROR:root:/var/lib/lxc not mounted.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cli/ci_cli/image.py'
2--- cli/ci_cli/image.py 2014-08-29 18:28:56 +0000
3+++ cli/ci_cli/image.py 2014-10-06 13:12:24 +0000
4@@ -12,6 +12,8 @@
5 #
6 # You should have received a copy of the GNU General Public License along
7 # with this program. If not, see <http://www.gnu.org/licenses/>.
8+
9+import errno
10 import logging
11 import os
12 import requests
13@@ -51,8 +53,14 @@
14 if response.status_code != 200:
15 raise ImageObjectNotFound('Failed to download {}'.format(temp_url))
16 # Create destination path parts if needed.
17- if not os.path.exists(os.path.dirname(dest_path)):
18- os.makedirs(os.path.dirname(dest_path))
19+ base_dir = os.path.dirname(dest_path)
20+ try:
21+ # Try to create needed dirs
22+ os.makedirs(base_dir)
23+ except OSError as e:
24+ # They are already there, no worries
25+ if e.errno != errno.EEXIST:
26+ raise
27 with open(dest_path, 'wb') as fp:
28 for chunk in response.iter_content(chunk_size=4096):
29 # Ignore keep-alives.
30
31=== modified file 'lander/lander/__init__.py'
32--- lander/lander/__init__.py 2014-08-08 21:31:03 +0000
33+++ lander/lander/__init__.py 2014-10-06 13:12:24 +0000
34@@ -13,6 +13,7 @@
35 # You should have received a copy of the GNU Affero General Public License
36 # along with this program. If not, see <http://www.gnu.org/licenses/>.
37
38+import errno
39 import json
40 import logging
41 import os
42@@ -31,8 +32,13 @@
43 if directory is not None:
44 log_dir = os.path.join(log_dir, directory)
45
46- if not os.path.exists(log_dir):
47+ try:
48+ # Try to create needed dirs
49 os.makedirs(log_dir)
50+ except OSError as e:
51+ # They are already there, no worries
52+ if e.errno != errno.EEXIST:
53+ raise
54
55 path = os.path.join(log_dir, filename)
56
57
58=== modified file 'test_runner/tstrun/run_worker.py'
59--- test_runner/tstrun/run_worker.py 2014-10-01 09:27:59 +0000
60+++ test_runner/tstrun/run_worker.py 2014-10-06 13:12:24 +0000
61@@ -16,6 +16,7 @@
62 from __future__ import unicode_literals
63
64
65+import errno
66 import os
67
68
69@@ -127,8 +128,13 @@
70 conf.set('vm.release', series)
71 conf.set('vm.ppas', ','.join(ppa_list))
72 base_dir = conf.get('vm.vms_dir')
73- if not os.path.exists(base_dir):
74+ try:
75+ # Try to create needed dirs
76 os.makedirs(base_dir)
77+ except OSError as e:
78+ # They are already there, no worries
79+ if e.errno != errno.EEXIST:
80+ raise
81 conf.store.save_changes()
82 self.test_bed = testbed.TestBed(conf)
83 except:
84
85=== modified file 'test_runner/tstrun/testbed.py'
86--- test_runner/tstrun/testbed.py 2014-10-03 13:35:36 +0000
87+++ test_runner/tstrun/testbed.py 2014-10-06 13:12:24 +0000
88@@ -15,6 +15,7 @@
89 # along with this program. If not, see <http://www.gnu.org/licenses/>.
90 from __future__ import unicode_literals
91
92+import errno
93 import logging
94 import os
95 import subprocess
96@@ -248,8 +249,13 @@
97 # provide this key.
98 if not os.path.exists(self.test_bed_key_path):
99 base_dir = os.path.dirname(self.test_bed_key_path)
100- if not os.path.exists(base_dir):
101+ try:
102+ # Try to create needed dirs
103 os.makedirs(base_dir)
104+ except OSError as e:
105+ # They are already there, no worries
106+ if e.errno != errno.EEXIST:
107+ raise
108 # First time the test runner instance needs to create a test bed
109 # instance, we need to create the ssh key pair.
110 subprocess.call(

Subscribers

People subscribed via source and target branches