Merge lp:~allenap/maas/remove-temp-dir-after-refresh--bug-1587544 into lp:~maas-committers/maas/trunk

Proposed by Gavin Panella
Status: Merged
Approved by: Gavin Panella
Approved revision: no longer in the source branch.
Merged at revision: 5057
Proposed branch: lp:~allenap/maas/remove-temp-dir-after-refresh--bug-1587544
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 126 lines (+58/-16)
2 files modified
src/provisioningserver/refresh/__init__.py (+16/-16)
src/provisioningserver/refresh/tests/test_refresh.py (+42/-0)
To merge this branch: bzr merge lp:~allenap/maas/remove-temp-dir-after-refresh--bug-1587544
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+296122@code.launchpad.net

Commit message

Ensure that the temporary directory created when refreshing a rack or region controller is removed.

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Looks good. Much cleaner and easier to read.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/provisioningserver/refresh/__init__.py'
2--- src/provisioningserver/refresh/__init__.py 2016-03-28 13:54:47 +0000
3+++ src/provisioningserver/refresh/__init__.py 2016-05-31 17:21:35 +0000
4@@ -3,7 +3,6 @@
5
6 """Functionality to refresh rack controller hardware and networking details."""
7 import os
8-import shutil
9 import socket
10 import stat
11 import subprocess
12@@ -107,18 +106,27 @@
13 'token_key': token_key,
14 'token_secret': token_secret,
15 'consumer_secret': '',
16- }
17-
18- tmpdir = tempfile.mkdtemp(prefix='maas-commission-')
19- scripts_to_run = {
20+ }
21+ scripts = {
22 name: config
23 for name, config in NODE_INFO_SCRIPTS.items()
24 if config["run_on_controller"]
25 }
26- total_scripts = len(scripts_to_run)
27+
28+ with tempfile.TemporaryDirectory(prefix='maas-commission-') as tmpdir:
29+ failed_scripts = runscripts(scripts, url, creds, tmpdir=tmpdir)
30+
31+ if len(failed_scripts) == 0:
32+ signal(url, creds, "OK", "Finished refreshing %s" % system_id)
33+ else:
34+ signal(url, creds, "FAILED", "Failed refreshing %s" % system_id)
35+
36+
37+def runscripts(scripts, url, creds, tmpdir):
38+ total_scripts = len(scripts)
39 current_script = 1
40 failed_scripts = []
41- for output_name, config in scripts_to_run.items():
42+ for output_name, config in scripts.items():
43 signal(
44 url, creds, "WORKING", "Starting %s [%d/%d]" %
45 (config['name'], current_script, total_scripts))
46@@ -143,12 +151,4 @@
47 if proc.returncode != 0:
48 failed_scripts.append(config['name'])
49 current_script += 1
50-
51- shutil.rmtree(tmpdir)
52- fail_count = len(failed_scripts)
53- if fail_count == 0:
54- signal(
55- url, creds, "OK", "Finished refreshing %s" % system_id)
56- else:
57- signal(
58- url, creds, "FAILED", "Failed refreshing %s" % system_id)
59+ return failed_scripts
60
61=== modified file 'src/provisioningserver/refresh/tests/test_refresh.py'
62--- src/provisioningserver/refresh/tests/test_refresh.py 2016-03-28 13:54:47 +0000
63+++ src/provisioningserver/refresh/tests/test_refresh.py 2016-05-31 17:21:35 +0000
64@@ -7,9 +7,12 @@
65
66 from collections import OrderedDict
67 import os
68+from pathlib import Path
69 import random
70 import re
71+import tempfile
72 from textwrap import dedent
73+from unittest.mock import sentinel
74
75 from maastesting.factory import factory
76 from maastesting.matchers import (
77@@ -18,6 +21,11 @@
78 )
79 from maastesting.testcase import MAASTestCase
80 from provisioningserver import refresh
81+from testtools.matchers import (
82+ Contains,
83+ DirExists,
84+ Not,
85+)
86
87
88 class TestHelpers(MAASTestCase):
89@@ -266,3 +274,37 @@
90 'FAILED',
91 "Failed refreshing %s" % system_id],
92 signal.call_args_list[2][0])
93+
94+ def test_refresh_clears_up_temporary_directory(self):
95+
96+ ScriptsBroken = factory.make_exception_type()
97+
98+ def find_temporary_directories():
99+ with tempfile.TemporaryDirectory() as tmpdir:
100+ tmpdir = Path(tmpdir).absolute()
101+ return {
102+ entry.path for entry in tmpdir.parent.iterdir()
103+ if entry.is_dir() and entry != tmpdir
104+ }
105+
106+ tmpdirs_during = set()
107+ tmpdir_during = None
108+
109+ def runscripts(*args, tmpdir):
110+ self.assertThat(tmpdir, DirExists())
111+ nonlocal tmpdirs_during, tmpdir_during
112+ tmpdirs_during |= find_temporary_directories()
113+ tmpdir_during = tmpdir
114+ raise ScriptsBroken("Foom")
115+
116+ self.patch(refresh, "runscripts", runscripts)
117+
118+ tmpdirs_before = find_temporary_directories()
119+ self.assertRaises(
120+ ScriptsBroken, refresh.refresh, sentinel.system_id,
121+ sentinel.consumer_key, sentinel.token_key, sentinel.token_secret)
122+ tmpdirs_after = find_temporary_directories()
123+
124+ self.assertThat(tmpdirs_before, Not(Contains(tmpdir_during)))
125+ self.assertThat(tmpdirs_during, Contains(tmpdir_during))
126+ self.assertThat(tmpdirs_after, Not(Contains(tmpdir_during)))