Merge lp:~frankban/juju-quickstart/remove-jenv into lp:juju-quickstart
- remove-jenv
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 113 |
Proposed branch: | lp:~frankban/juju-quickstart/remove-jenv |
Merge into: | lp:juju-quickstart |
Diff against target: |
422 lines (+200/-38) 8 files modified
quickstart/cli/params.py (+8/-1) quickstart/cli/views.py (+30/-2) quickstart/manage.py (+1/-0) quickstart/models/jenv.py (+14/-0) quickstart/tests/cli/test_params.py (+9/-2) quickstart/tests/cli/test_views.py (+102/-33) quickstart/tests/models/test_jenv.py (+35/-0) quickstart/tests/test_manage.py (+1/-0) |
To merge this branch: | bzr merge lp:~frankban/juju-quickstart/remove-jenv |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju GUI Hackers | Pending | ||
Review via email: mp+246162@code.launchpad.net |
Commit message
Description of the change
Jenv files removal functionality.
Add the ability to remove jenv files
from the Juju home.
Test: `make check`.
QA:
- `juju bootstrap` an environment;
- create a new user for the environment:
`juju user add myuser --generate -o ~/.juju/
- run quickstart in interactive mode:
`.venv/bin/python juju-quickstart -i`;
- the "myenv" environment should be listed under
"Other active environments": select it;
- ensure the corresponding environment description in
the jenv detail view makes sense;
- click to remove the environment, cancel the removal in the
confirm dialog and ensure the environment is still there;
- click the "remove" button again, confirm the deletion and
ensure that a message is displayed and the environment
file has been deleted. Also quickstart redirects to the
environments index view and "myenv" is no longer there;
- destroy the environment: done, thank you!
Francesco Banconi (frankban) wrote : | # |
Martin Hilton (martin-hilton) wrote : | # |
LGTM No QA yet, will do so shortly
https:/
File quickstart/
https:/
quickstart/
edit/change it.\n'
Isn't edit/change a tautology? Wouldn't "edit it." be enough.
Brad Crittenden (bac) wrote : | # |
The code LGTM but I question the need for the functionality in
quickstart. I don't feel strongly enough to abandon the work but I think
it only marginally improves the user experience at the expense of more
complication. Perhaps I'm missing a use-case that warrants the
function.
https:/
File quickstart/
https:/
quickstart/
Formatting is odd. I'd prefer one per line if you're doing multi-line.
- 115. By Francesco Banconi
-
Fix typo and improve params formatting.
Francesco Banconi (frankban) wrote : | # |
Please take a look.
https:/
File quickstart/
https:/
quickstart/
On 2015/01/12 15:29:32, bac wrote:
> Formatting is odd. I'd prefer one per line if you're doing
multi-line.
Done.
https:/
File quickstart/
https:/
quickstart/
edit/change it.\n'
On 2015/01/12 14:50:22, martin.hilton wrote:
> Isn't edit/change a tautology? Wouldn't "edit it." be enough.
Done.
Martin Hilton (martin-hilton) wrote : | # |
QA OK following instructions.
Francesco Banconi (frankban) wrote : | # |
*** Submitted:
Jenv files removal functionality.
Add the ability to remove jenv files
from the Juju home.
Test: `make check`.
QA:
- `juju bootstrap` an environment;
- create a new user for the environment:
`juju user add myuser --generate -o ~/.juju/
- run quickstart in interactive mode:
`.venv/
- the "myenv" environment should be listed under
"Other active environments": select it;
- ensure the corresponding environment description in
the jenv detail view makes sense;
- click to remove the environment, cancel the removal in the
confirm dialog and ensure the environment is still there;
- click the "remove" button again, confirm the deletion and
ensure that a message is displayed and the environment
file has been deleted. Also quickstart redirects to the
environments index view and "myenv" is no longer there;
- destroy the environment: done, thank you!
R=martin.hilton, bac
CC=
https:/
Francesco Banconi (frankban) wrote : | # |
Thanks for the reviews!
Preview Diff
1 | === modified file 'quickstart/cli/params.py' |
2 | --- quickstart/cli/params.py 2015-01-07 15:17:49 +0000 |
3 | +++ quickstart/cli/params.py 2015-01-12 15:39:31 +0000 |
4 | @@ -30,7 +30,13 @@ |
5 | import copy |
6 | |
7 | |
8 | -_PARAMS = ('env_type_db', 'env_db', 'jenv_db', 'save_callable') |
9 | +_PARAMS = ( |
10 | + 'env_type_db', |
11 | + 'env_db', |
12 | + 'jenv_db', |
13 | + 'save_callable', |
14 | + 'remove_jenv_callable', |
15 | +) |
16 | |
17 | |
18 | class Params(namedtuple('Params', _PARAMS)): |
19 | @@ -48,4 +54,5 @@ |
20 | env_db=copy.deepcopy(self.env_db), |
21 | jenv_db=copy.deepcopy(self.jenv_db), |
22 | save_callable=self.save_callable, |
23 | + remove_jenv_callable=self.remove_jenv_callable, |
24 | ) |
25 | |
26 | === modified file 'quickstart/cli/views.py' |
27 | --- quickstart/cli/views.py 2015-01-08 14:53:06 +0000 |
28 | +++ quickstart/cli/views.py 2015-01-12 15:39:31 +0000 |
29 | @@ -525,16 +525,26 @@ |
30 | urwid.Text([ |
31 | ('highlight', 'Imported active environment.\n'), |
32 | 'This environment is not included in your environments.yaml file.' |
33 | - '\nFor this reason, it is not possible to edit or remove it.\n' |
34 | + '\nFor this reason, it is not possible to edit it.\n' |
35 | 'However, you can use the link below to ', |
36 | ('highlight', 'use Juju Quickstart'), |
37 | - ' with this environment.', |
38 | + ' with this environment or ', |
39 | + ('highlight', 'remove the corresponding jenv file'), |
40 | + '.\n' |
41 | + 'Note that removing the Juju generated environment file does not ' |
42 | + 'destroy the corresponding active environment.' |
43 | ]), |
44 | ]) |
45 | |
46 | + remove_callback = ui.thunk( |
47 | + _remove_jenv, params.jenv_db, env_data, params.remove_jenv_callable, |
48 | + app.set_message, index_view) |
49 | + confirm_removal_callback = ui.thunk( |
50 | + _confirm_removal, app, env_data, remove_callback) |
51 | controls = [ |
52 | ui.MenuButton('back', ui.thunk(index_view)), |
53 | ui.MenuButton('use', ui.thunk(_use, params.env_db, env_data)), |
54 | + ui.MenuButton(('control alert', 'remove'), confirm_removal_callback), |
55 | ] |
56 | widgets.append(ui.create_controls(*controls)) |
57 | listbox = urwid.ListBox(urwid.SimpleFocusListWalker(widgets)) |
58 | @@ -542,6 +552,24 @@ |
59 | app.set_status([' \N{RIGHTWARDS ARROW OVER LEFTWARDS ARROW} navigate ']) |
60 | |
61 | |
62 | +def _remove_jenv( |
63 | + jenv_db, env_data, remove_jenv_callable, set_message, redirect_view): |
64 | + """Remove the jenv file corresonding to the env_data environment. |
65 | + |
66 | + Update the provided jenv_db and return to the given view. |
67 | + Also output a notification using the given set_message callable. |
68 | + """ |
69 | + env_name = env_data['name'] |
70 | + # Remove the jenv file. |
71 | + msg = remove_jenv_callable(env_name) |
72 | + if msg is None: |
73 | + msg = '{} successfully removed'.format(env_name) |
74 | + # Also remove the environments from the jenv database. |
75 | + del jenv_db['environments'][env_name] |
76 | + set_message(msg) |
77 | + redirect_view() |
78 | + |
79 | + |
80 | def env_edit(app, params, env_data): |
81 | """Create or modify a Juju environment. |
82 | |
83 | |
84 | === modified file 'quickstart/manage.py' |
85 | --- quickstart/manage.py 2015-01-07 14:07:22 +0000 |
86 | +++ quickstart/manage.py 2015-01-12 15:39:31 +0000 |
87 | @@ -218,6 +218,7 @@ |
88 | env_db=env_db, |
89 | jenv_db=jenv_db, |
90 | save_callable=_create_save_callable(parser, env_file), |
91 | + remove_jenv_callable=jenv.remove, |
92 | ) |
93 | new_env_db, env_data = views.show(views.env_index, parameters) |
94 | if new_env_db != env_db: |
95 | |
96 | === modified file 'quickstart/models/jenv.py' |
97 | --- quickstart/models/jenv.py 2014-12-17 12:28:36 +0000 |
98 | +++ quickstart/models/jenv.py 2015-01-12 15:39:31 +0000 |
99 | @@ -174,6 +174,20 @@ |
100 | return db |
101 | |
102 | |
103 | +def remove(env_name): |
104 | + """Remove the jenv file corresponding to the given environment name. |
105 | + |
106 | + Return None if the removal was successful, an error message otherwise. |
107 | + """ |
108 | + jenv_path = _get_jenv_path(env_name) |
109 | + try: |
110 | + os.remove(jenv_path) |
111 | + except OSError as err: |
112 | + msg = 'cannot remove the {} environment: {}' |
113 | + return msg.format(env_name, bytes(err).decode('utf-8')) |
114 | + return None |
115 | + |
116 | + |
117 | def validate(data): |
118 | """Validate the given YAML decoded jenv data. |
119 | |
120 | |
121 | === modified file 'quickstart/tests/cli/test_params.py' |
122 | --- quickstart/tests/cli/test_params.py 2015-01-07 14:07:22 +0000 |
123 | +++ quickstart/tests/cli/test_params.py 2015-01-12 15:39:31 +0000 |
124 | @@ -33,21 +33,24 @@ |
125 | self.env_db = helpers.make_env_db() |
126 | self.jenv_db = helpers.make_jenv_db() |
127 | self.save_callable = lambda env_db: None |
128 | + self.remove_jenv_callable = lambda env_db: None |
129 | # Set up a params object used in tests. |
130 | self.params = params.Params( |
131 | env_type_db=self.env_type_db, |
132 | env_db=self.env_db, |
133 | jenv_db=self.jenv_db, |
134 | save_callable=self.save_callable, |
135 | + remove_jenv_callable=self.remove_jenv_callable, |
136 | ) |
137 | |
138 | def test_tuple(self): |
139 | # The params object can be used as a tuple. |
140 | - env_type_db, env_db, jenv_db, save_callable = self.params |
141 | + env_type_db, env_db, jenv_db, save, remove = self.params |
142 | self.assertIs(self.env_type_db, env_type_db) |
143 | self.assertIs(self.env_db, env_db) |
144 | self.assertIs(self.jenv_db, jenv_db) |
145 | - self.assertIs(self.save_callable, save_callable) |
146 | + self.assertIs(self.save_callable, save) |
147 | + self.assertIs(self.remove_jenv_callable, remove) |
148 | |
149 | def test_attributes(self): |
150 | # Parameters can be accessed as attributes. |
151 | @@ -55,6 +58,8 @@ |
152 | self.assertIs(self.env_db, self.params.env_db) |
153 | self.assertIs(self.jenv_db, self.params.jenv_db) |
154 | self.assertIs(self.save_callable, self.params.save_callable) |
155 | + self.assertIs( |
156 | + self.remove_jenv_callable, self.params.remove_jenv_callable) |
157 | |
158 | def test_immutable(self): |
159 | # It is not possible to replace a stored parameter. |
160 | @@ -69,6 +74,8 @@ |
161 | self.assertIs(self.env_db, self.params.env_db) |
162 | self.assertIs(self.jenv_db, self.params.jenv_db) |
163 | self.assertIs(self.save_callable, self.params.save_callable) |
164 | + self.assertIs( |
165 | + self.remove_jenv_callable, self.params.remove_jenv_callable) |
166 | # The new params object stores the same data. |
167 | self.assertEqual(self.params, params) |
168 | # But they do not refer to the same object. |
169 | |
170 | === modified file 'quickstart/tests/cli/test_views.py' |
171 | --- quickstart/tests/cli/test_views.py 2015-01-07 15:36:57 +0000 |
172 | +++ quickstart/tests/cli/test_views.py 2015-01-12 15:39:31 +0000 |
173 | @@ -137,6 +137,7 @@ |
174 | # Set up the base Urwid application. |
175 | self.loop, self.app = base.setup_urwid_app() |
176 | self.save_callable = mock.Mock() |
177 | + self.remove_jenv_callable = mock.Mock(return_value=None) |
178 | |
179 | def get_widgets_in_contents(self, filter_function=None): |
180 | """Return a list of widgets included in the app contents. |
181 | @@ -174,8 +175,45 @@ |
182 | env_db=env_db, |
183 | jenv_db=jenv_db, |
184 | save_callable=self.save_callable, |
185 | + remove_jenv_callable=self.remove_jenv_callable, |
186 | ) |
187 | |
188 | + def click_remove_button(self, env_name): |
189 | + """Click the remove button in an environment detail view. |
190 | + |
191 | + Assume the view was already called. |
192 | + Return the dialog button widgets and the original view contents. |
193 | + """ |
194 | + original_contents = self.app.get_contents() |
195 | + # The "remove" button is the last one. |
196 | + remove_button = self.get_control_buttons()[-1] |
197 | + cli_helpers.emit(remove_button) |
198 | + # The original env detail contents have been replaced. |
199 | + contents = self.app.get_contents() |
200 | + self.assertIsNot(contents, original_contents) |
201 | + # A "remove" confirmation dialog is displayed. |
202 | + title_widget, message_widget, buttons = cli_helpers.inspect_dialog( |
203 | + contents) |
204 | + self.assertEqual( |
205 | + 'Remove the {} environment'.format(env_name), title_widget.text) |
206 | + self.assertEqual('This action cannot be undone!', message_widget.text) |
207 | + return buttons, original_contents |
208 | + |
209 | + def cancel_removal(self, env_name): |
210 | + """Cancel the environment deletion by clicking the "cancel" button.""" |
211 | + buttons, original_contents = self.click_remove_button(env_name) |
212 | + # The "cancel" button is the first one in the dialog. |
213 | + cancel_button = buttons[0] |
214 | + cli_helpers.emit(cancel_button) |
215 | + return original_contents |
216 | + |
217 | + def confirm_removal(self, env_name): |
218 | + """Confirm the environment deletion.""" |
219 | + buttons, _ = self.click_remove_button(env_name) |
220 | + # The "confirm" button is the second one in the dialog. |
221 | + confirm_button = buttons[1] |
222 | + cli_helpers.emit(confirm_button) |
223 | + |
224 | |
225 | class TestEnvIndex(EnvViewTestsMixin, unittest.TestCase): |
226 | |
227 | @@ -622,18 +660,7 @@ |
228 | def test_remove_button(self): |
229 | # A confirmation dialog is displayed if the "remove" button is clicked. |
230 | self.call_view(env_name='ec2-west') |
231 | - original_contents = self.app.get_contents() |
232 | - # The "remove" button is the last one. |
233 | - remove_button = self.get_control_buttons()[-1] |
234 | - cli_helpers.emit(remove_button) |
235 | - # The original env detail contents have been replaced. |
236 | - contents = self.app.get_contents() |
237 | - self.assertIsNot(contents, original_contents) |
238 | - # A "remove" confirmation dialog is displayed. |
239 | - title_widget, message_widget, buttons = cli_helpers.inspect_dialog( |
240 | - contents) |
241 | - self.assertEqual('Remove the ec2-west environment', title_widget.text) |
242 | - self.assertEqual('This action cannot be undone!', message_widget.text) |
243 | + buttons, _ = self.click_remove_button('ec2-west') |
244 | # The dialog includes the "cancel" and "confirm" buttons. |
245 | self.assertEqual(2, len(buttons)) |
246 | captions = map(cli_helpers.get_button_caption, buttons) |
247 | @@ -642,15 +669,7 @@ |
248 | def test_remove_cancelled(self): |
249 | # The "remove" confirmation dialog can be safely dismissed. |
250 | self.call_view(env_name='ec2-west') |
251 | - original_contents = self.app.get_contents() |
252 | - # The "remove" button is the last one. |
253 | - remove_button = self.get_control_buttons()[-1] |
254 | - cli_helpers.emit(remove_button) |
255 | - contents = self.app.get_contents() |
256 | - buttons = cli_helpers.inspect_dialog(contents)[2] |
257 | - # The "cancel" button is the first one in the dialog. |
258 | - cancel_button = buttons[0] |
259 | - cli_helpers.emit(cancel_button) |
260 | + original_contents = self.cancel_removal('ec2-west') |
261 | # The original contents have been restored. |
262 | self.assertIs(original_contents, self.app.get_contents()) |
263 | |
264 | @@ -659,20 +678,17 @@ |
265 | # The current environment is removed if the "remove" button is clicked |
266 | # and then the deletion is confirmed. Subsequently the application |
267 | # switches to the index view. |
268 | - self.call_view(env_name='ec2-west') |
269 | - # The "remove" button is the last one. |
270 | - remove_button = self.get_control_buttons()[-1] |
271 | - cli_helpers.emit(remove_button) |
272 | - contents = self.app.get_contents() |
273 | - buttons = cli_helpers.inspect_dialog(contents)[2] |
274 | - # The "confirm" button is the second one in the dialog. |
275 | - confirm_button = buttons[1] |
276 | - cli_helpers.emit(confirm_button) |
277 | + env_name = 'ec2-west' |
278 | + self.call_view(env_name=env_name) |
279 | + self.confirm_removal(env_name) |
280 | + # A message notifies the environment has been removed. |
281 | + self.assertEqual( |
282 | + '{} successfully removed'.format(env_name), self.app.get_message()) |
283 | # The index view has been called passing the modified env_db in params. |
284 | self.assertTrue(mock_env_index.called) |
285 | params = mock_env_index.call_args[0][1] |
286 | # The new env_db no longer includes the "ec2-west" environment. |
287 | - self.assertNotIn('ec2-west', params.env_db['environments']) |
288 | + self.assertNotIn(env_name, params.env_db['environments']) |
289 | # The new env_db has been saved. |
290 | self.save_callable.assert_called_once_with(params.env_db) |
291 | |
292 | @@ -732,11 +748,11 @@ |
293 | self.assertEqual(expected_text, widget.text) |
294 | |
295 | def test_view_buttons(self): |
296 | - # The "back" and "use" buttons are displayed. |
297 | + # The "back", "use" and "remove" buttons are displayed. |
298 | self.call_view(env_name='ec2-west') |
299 | buttons = self.get_control_buttons() |
300 | captions = map(cli_helpers.get_button_caption, buttons) |
301 | - self.assertEqual(['back', 'use'], captions) |
302 | + self.assertEqual(['back', 'use', 'remove'], captions) |
303 | |
304 | @mock.patch('quickstart.cli.views.env_index') |
305 | def test_back_button(self, mock_env_index): |
306 | @@ -759,6 +775,59 @@ |
307 | self.assertEqual( |
308 | expected_return_value, context_manager.exception.return_value) |
309 | |
310 | + def test_remove_button(self): |
311 | + # A confirmation dialog is displayed if the "remove" button is clicked. |
312 | + self.call_view(env_name='test-jenv') |
313 | + buttons, _ = self.click_remove_button('test-jenv') |
314 | + # The dialog includes the "cancel" and "confirm" buttons. |
315 | + self.assertEqual(2, len(buttons)) |
316 | + captions = map(cli_helpers.get_button_caption, buttons) |
317 | + self.assertEqual(['cancel', 'confirm'], captions) |
318 | + |
319 | + def test_remove_cancelled(self): |
320 | + # The "remove" confirmation dialog can be safely dismissed. |
321 | + self.call_view(env_name='test-jenv') |
322 | + original_contents = self.cancel_removal('test-jenv') |
323 | + # The original contents have been restored. |
324 | + self.assertIs(original_contents, self.app.get_contents()) |
325 | + |
326 | + @mock.patch('quickstart.cli.views.env_index') |
327 | + def test_remove_confirmed(self, mock_env_index): |
328 | + # The jenv file is removed if the "remove" button is clicked and then |
329 | + # then the deletion is confirmed. Subsequently the application switches |
330 | + # to the index view. |
331 | + env_name = 'test-jenv' |
332 | + self.call_view(env_name=env_name) |
333 | + self.confirm_removal(env_name) |
334 | + # A message notifies the environment has been removed. |
335 | + self.assertEqual( |
336 | + '{} successfully removed'.format(env_name), self.app.get_message()) |
337 | + # The index view has been called passing the modified jenv_db params. |
338 | + self.assertTrue(mock_env_index.called) |
339 | + params = mock_env_index.call_args[0][1] |
340 | + # The new jenv_db no longer includes the "test-jenv" environment. |
341 | + self.assertNotIn(env_name, params.jenv_db['environments']) |
342 | + # The corresponding jenv file has been removed. |
343 | + self.remove_jenv_callable.assert_called_once_with(env_name) |
344 | + self.assertEqual( |
345 | + 'test-jenv successfully removed', self.app.get_message()) |
346 | + |
347 | + @mock.patch('quickstart.cli.views.env_index') |
348 | + def test_remove_confirmed_error(self, mock_env_index): |
349 | + # Errors occurred while trying to remove the jenv files are notified. |
350 | + env_name = 'test-jenv' |
351 | + self.call_view(env_name=env_name) |
352 | + # Simulate an error removing the jenv file. |
353 | + self.remove_jenv_callable.return_value = 'bad wolf' |
354 | + self.confirm_removal(env_name) |
355 | + # The error is notified. |
356 | + self.assertEqual('bad wolf'.format(env_name), self.app.get_message()) |
357 | + # The index view has been called passing the original jenv_db params. |
358 | + self.assertTrue(mock_env_index.called) |
359 | + params = mock_env_index.call_args[0][1] |
360 | + # The jenv_db still includes the "test_jenv" environment. |
361 | + self.assertIn(env_name, params.jenv_db['environments']) |
362 | + |
363 | |
364 | class TestEnvEdit(EnvViewTestsMixin, unittest.TestCase): |
365 | |
366 | |
367 | === modified file 'quickstart/tests/models/test_jenv.py' |
368 | --- quickstart/tests/models/test_jenv.py 2014-12-17 11:34:06 +0000 |
369 | +++ quickstart/tests/models/test_jenv.py 2015-01-12 15:39:31 +0000 |
370 | @@ -272,6 +272,41 @@ |
371 | self.assertEqual({'environments': {}}, jenv_db) |
372 | |
373 | |
374 | +class TestRemove(helpers.JenvFileTestsMixin, unittest.TestCase): |
375 | + |
376 | + @classmethod |
377 | + def setUpClass(cls): |
378 | + # Prepare the jenv file contents. |
379 | + cls.contents = yaml.safe_dump(cls.jenv_data) |
380 | + |
381 | + def test_successful_removal(self): |
382 | + # The jenv file is correctly removed. |
383 | + with self.make_jenv('local', self.contents) as path: |
384 | + error = jenv.remove('local') |
385 | + self.assertIsNone(error) |
386 | + self.assertFalse(os.path.exists(path)) |
387 | + |
388 | + def test_error_directory(self): |
389 | + # An error message is returned if the jenv path points to a directory. |
390 | + with self.make_jenv('local', self.contents) as path: |
391 | + dirname = os.path.dirname(path) |
392 | + os.mkdir(os.path.join(dirname, 'ec2.jenv')) |
393 | + error = jenv.remove('ec2') |
394 | + expected_error = ( |
395 | + 'cannot remove the ec2 environment: ' |
396 | + '[Errno 21] Is a directory: ') |
397 | + self.assertIn(expected_error, error) |
398 | + |
399 | + def test_error_not_found(self): |
400 | + # An error is returned if the environment cannot be found. |
401 | + with self.make_jenv('local', self.contents): |
402 | + error = jenv.remove('hp') |
403 | + expected_error = ( |
404 | + 'cannot remove the hp environment: ' |
405 | + '[Errno 2] No such file or directory: ') |
406 | + self.assertIn(expected_error, error) |
407 | + |
408 | + |
409 | class TestValidate( |
410 | helpers.JenvFileTestsMixin, helpers.ValueErrorTestsMixin, |
411 | unittest.TestCase): |
412 | |
413 | === modified file 'quickstart/tests/test_manage.py' |
414 | --- quickstart/tests/test_manage.py 2015-01-07 14:07:22 +0000 |
415 | +++ quickstart/tests/test_manage.py 2015-01-12 15:39:31 +0000 |
416 | @@ -399,6 +399,7 @@ |
417 | env_db=env_db, |
418 | jenv_db=jenv_db, |
419 | save_callable=mock_save_callable(), |
420 | + remove_jenv_callable=jenv.remove, |
421 | ) |
422 | mock_show.assert_called_once_with(views.env_index, expected_params) |
423 |
Reviewers: mp+246162_ code.launchpad. net,
Message:
Please take a look.
Description:
Jenv files removal functionality.
Add the ability to remove jenv files
from the Juju home.
Test: `make check`.
QA: environments/ myenv`; bin/python juju-quickstart -i`;
- `juju bootstrap` an environment;
- create a new user for the environment:
`juju user add myuser --generate -o ~/.juju/
- run quickstart in interactive mode:
`.venv/
- the "myenv" environment should be listed under
"Other active environments": select it;
- ensure the corresponding environment description in
the jenv detail view makes sense;
- click to remove the environment, cancel the removal in the
confirm dialog and ensure the environment is still there;
- click the "remove" button again, confirm the deletion and
ensure that a message is displayed and the environment
file has been deleted. Also quickstart redirects to the
environments index view and "myenv" is no longer there;
- destroy the environment: done, thank you!
https:/ /code.launchpad .net/~frankban/ juju-quickstart /remove- jenv/+merge/ 246162
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/189540043/
Affected files (+200, -38 lines): cli/params. py cli/views. py manage. py models/ jenv.py tests/cli/ test_params. py tests/cli/ test_views. py tests/models/ test_jenv. py tests/test_ manage. py
A [revision details]
M quickstart/
M quickstart/
M quickstart/
M quickstart/
M quickstart/
M quickstart/
M quickstart/
M quickstart/