<div dir="ltr">Hi Kiko,<div><br></div><div>We discussed this with Raphael and Jason already, and this are the meeting notes:</div><div><br></div><div><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">Notes from this morning's call - please add/correct if I missed something.</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">- Jason described the current design and implementation of the disk</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">erasing feature in a little more detail than previously.</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">- Jason clarified that there is no separate action/api for starting disk</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">erasing - it's done as part of the releasing action, so the user's</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">workflow isn't complicated by the change.</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">- Raphael agreed that erasing is basically a substate of releasing, and</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">that this was ok and that the design and implementation are fine - it's</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">not necessarily a negative thing to introduce more states, but everyone</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">agreed it should be discussed more ahead of time next time.</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">- Jason brought up the possibility of changing 'Failed Disk Erasing' to</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">'Failed Releasing', but Raphael suggested that the failed erasing state</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">is good because it allows people to pin point exactly where the failure was.</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">- Discussed a per node or per release option to override the global</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">default option for disk erasing - Raphael would prefer a per-release</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">option so we don't add additional boolean properties to nodes. Need to</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">decide if we want to allow users to override the admin set global</span><br style="font-family:arial,sans-serif;font-size:12.7272720336914px"><span style="font-family:arial,sans-serif;font-size:12.7272720336914px">default or not.</span><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Sep 29, 2014 at 3:11 PM, Christian Robottom Reis <span dir="ltr"><<a href="mailto:kiko@canonical.com" target="_blank">kiko@canonical.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I made a comment on this MP which I wanted to note more widely:<br>
<br>
    In the future, changes to the state machine require explicit<br>
    discussion and review before we commit to them. The exposure of<br>
    complex state machines often kills good software -- we're not going<br>
    to make that mistake in MAAS.<br>
<br>
I'd like us to have a process where a lightweight discussion and<br>
sign-off happens with the core team on infrastructural changes. We used<br>
to have pre-implementation calls for features in Launchpad that we could<br>
reuse, or perhaps you want to suggest your favorite approach, I'm happy<br>
either way, and I don't want to do any hard enforcement of this at this<br>
time.<br>
<br>
But let's ensure that as new features are mooted and designs started,<br>
that we have clarity on the design and fix it before the code is sealed.<br>
Think about this as you work on new features -- communication is key to<br>
the success of any project assembled by a team, and software even more<br>
so (and Fred Brooks be the man).<br>
<br>
Thanks,<br>
<br>
----- Forwarded message from Jason Hobbs <<a href="mailto:jason.hobbs@canonical.com">jason.hobbs@canonical.com</a>> -----<br>
<br>
Date: Thu, 25 Sep 2014 22:09:23 -0000<br>
From: Jason Hobbs <<a href="mailto:jason.hobbs@canonical.com">jason.hobbs@canonical.com</a>><br>
To: <a href="mailto:mp%2B236039@code.launchpad.net">mp+236039@code.launchpad.net</a><br>
Subject: [Merge] lp:~jason-hobbs/maas/expose-enable-disk-erasing-option into lp:maas<br>
X-Launchpad-Message-Rationale: Reviewer @maas-maintainers<br>
X-Launchpad-Notification-Type: code-review<br>
X-Launchpad-Branch: ~jason-hobbs/maas/expose-enable-disk-erasing-option<br>
X-Launchpad-Project: maas<br>
X-Launchpad-Hash: 3f95510c33553bf1cac8d8113198718fe47c7cfe<br>
X-Spambayes-Classification: ham; 0.00<br>
<br>
Jason Hobbs has proposed merging lp:~jason-hobbs/maas/expose-enable-disk-erasing-option into lp:maas.<br>
<br>
Commit message:<br>
Add a new config option - 'enable_disk_erasing_on_release'.<br>
<br>
Requested reviews:<br>
  MAAS Maintainers (maas-maintainers)<br>
<br>
For more details, see:<br>
<a href="https://code.launchpad.net/~jason-hobbs/maas/expose-enable-disk-erasing-option/+merge/236039" target="_blank">https://code.launchpad.net/~jason-hobbs/maas/expose-enable-disk-erasing-option/+merge/236039</a><br>
<br>
You can enable disk erasing on release now via the API, but not via the Web UI.<br>
--<br>
<a href="https://code.launchpad.net/~jason-hobbs/maas/expose-enable-disk-erasing-option/+merge/236039" target="_blank">https://code.launchpad.net/~jason-hobbs/maas/expose-enable-disk-erasing-option/+merge/236039</a><br>
Your team MAAS Maintainers is requested to review the proposed merge of lp:~jason-hobbs/maas/expose-enable-disk-erasing-option into lp:maas.<br>
<br>
=== modified file 'src/maasserver/api/nodes.py'<br>
--- src/maasserver/api/nodes.py 2014-09-22 05:33:12 +0000<br>
+++ src/maasserver/api/nodes.py 2014-09-25 21:59:28 +0000<br>
@@ -324,7 +324,7 @@<br>
             # postcondition is achieved, so call this success.<br>
             pass<br>
         elif node.status in RELEASABLE_STATUSES:<br>
-            node.release()<br>
+            node.release_or_erase()<br>
         else:<br>
             raise NodeStateViolation(<br>
                 "Node cannot be released in its current state ('%s')."<br>
<br>
=== modified file 'src/maasserver/forms.py'<br>
--- src/maasserver/forms.py     2014-09-23 14:16:33 +0000<br>
+++ src/maasserver/forms.py     2014-09-25 21:59:28 +0000<br>
@@ -26,6 +26,7 @@<br>
     "get_node_edit_form",<br>
     "get_node_create_form",<br>
     "list_all_usable_architectures",<br>
+    "DiskErasingOnReleaseForm",<br>
     "MAASAndNetworkForm",<br>
     "MACAddressForm",<br>
     "NetworkConnectMACsForm",<br>
@@ -1085,6 +1086,12 @@<br>
     enable_third_party_drivers = get_config_field('enable_third_party_drivers')<br>
<br>
<br>
+class DiskErasingOnReleaseForm(ConfigForm):<br>
+    """Settings page, Disk Erasing on Release section."""<br>
+    enable_disk_erasing_on_release = get_config_field(<br>
+        'enable_disk_erasing_on_release')<br>
+<br>
+<br>
 class CommissioningForm(ConfigForm):<br>
     """Settings page, Commissioning section."""<br>
     check_compatibility = get_config_field('check_compatibility')<br>
<br>
=== modified file 'src/maasserver/forms_settings.py'<br>
--- src/maasserver/forms_settings.py    2014-09-22 14:47:49 +0000<br>
+++ src/maasserver/forms_settings.py    2014-09-25 21:59:28 +0000<br>
@@ -257,6 +257,15 @@<br>
                 "using KMS activation.)")<br>
         }<br>
     },<br>
+    'enable_disk_erasing_on_release': {<br>
+        'default': False,<br>
+        'form': forms.BooleanField,<br>
+        'form_kwargs': {<br>
+            'required': False,<br>
+            'label': (<br>
+                "Erase nodes' disks prior to releasing.")<br>
+        }<br>
+    },<br>
 }<br>
<br>
<br>
<br>
=== modified file 'src/maasserver/models/config.py'<br>
--- src/maasserver/models/config.py     2014-07-03 07:01:15 +0000<br>
+++ src/maasserver/models/config.py     2014-09-25 21:59:28 +0000<br>
@@ -58,6 +58,7 @@<br>
         'rpc_region_certificate': None,<br>
         # Third Party<br>
         'enable_third_party_drivers': True,<br>
+        'enable_disk_erasing_on_release': False,<br>
         ## /settings<br>
         }<br>
<br>
<br>
=== modified file 'src/maasserver/models/node.py'<br>
--- src/maasserver/models/node.py       2014-09-25 18:08:05 +0000<br>
+++ src/maasserver/models/node.py       2014-09-25 21:59:28 +0000<br>
@@ -1240,6 +1240,17 @@<br>
         self.license_key = ''<br>
         self.save()<br>
<br>
+    def release_or_erase(self):<br>
+        """Either release the node or erase the node then release it, depending<br>
+        on settings."""<br>
+        erase_on_release = Config.objects.get_config(<br>
+            'enable_disk_erasing_on_release')<br>
+        if erase_on_release:<br>
+            self.start_disk_erasing(self.owner)<br>
+            return<br>
+<br>
+        self.release()<br>
+<br>
     def set_netboot(self, on=True):<br>
         """Set netboot on or off."""<br>
         maaslog.debug("%s: Turning on netboot for node", self.hostname)<br>
<br>
=== modified file 'src/maasserver/models/tests/test_node.py'<br>
--- src/maasserver/models/tests/test_node.py    2014-09-25 17:25:08 +0000<br>
+++ src/maasserver/models/tests/test_node.py    2014-09-25 21:59:28 +0000<br>
@@ -80,6 +80,7 @@<br>
 from maastesting.matchers import (<br>
     MockAnyCall,<br>
     MockCalledOnceWith,<br>
+    MockNotCalled,<br>
     )<br>
 from maastesting.testcase import MAASTestCase<br>
 from metadataserver.enum import RESULT_TYPE<br>
@@ -1695,6 +1696,28 @@<br>
         node.set_netboot(False)<br>
         self.assertFalse(node.netboot)<br>
<br>
+    def test_release_or_erase_erases_when_enabled(self):<br>
+        owner = factory.make_User()<br>
+        node = factory.make_Node(status=NODE_STATUS.ALLOCATED, owner=owner)<br>
+        Config.objects.set_config(<br>
+            'enable_disk_erasing_on_release', True)<br>
+        erase_mock = self.patch_autospec(node, 'start_disk_erasing')<br>
+        release_mock = self.patch_autospec(node, 'release')<br>
+        node.release_or_erase()<br>
+        self.assertThat(erase_mock, MockCalledOnceWith(owner))<br>
+        self.assertThat(release_mock, MockNotCalled())<br>
+<br>
+    def test_release_or_erase_releases_when_disabled(self):<br>
+        owner = factory.make_User()<br>
+        node = factory.make_Node(status=NODE_STATUS.ALLOCATED, owner=owner)<br>
+        Config.objects.set_config(<br>
+            'enable_disk_erasing_on_release', False)<br>
+        erase_mock = self.patch_autospec(node, 'start_disk_erasing')<br>
+        release_mock = self.patch_autospec(node, 'release')<br>
+        node.release_or_erase()<br>
+        self.assertThat(release_mock, MockCalledOnceWith())<br>
+        self.assertThat(erase_mock, MockNotCalled())<br>
+<br>
<br>
 class NodeManagerTest_StartNodes(MAASServerTestCase):<br>
<br>
<br>
=== modified file 'src/maasserver/node_action.py'<br>
--- src/maasserver/node_action.py       2014-09-25 17:25:08 +0000<br>
+++ src/maasserver/node_action.py       2014-09-25 21:59:28 +0000<br>
@@ -330,7 +330,7 @@<br>
<br>
     def execute(self, allow_redirect=True):<br>
         """See `NodeAction.execute`."""<br>
-        self.node.release()<br>
+        self.node.release_or_erase()<br>
         return dedent("""\<br>
             This node is no longer allocated to you.<br>
             """)<br>
<br>
<br>
<br>
----- End forwarded message -----<br>
<span class="HOEnZb"><font color="#888888">--<br>
Christian Robottom Reis   | [+1] 612 888 4935    | <a href="http://launchpad.net/~kiko" target="_blank">http://launchpad.net/~kiko</a><br>
Canonical VP Hyperscale   | [+55 16] 9 9112 6430 | <a href="http://async.com.br/~kiko" target="_blank">http://async.com.br/~kiko</a><br>
<br>
--<br>
Mailing list: <a href="https://launchpad.net/~maas-devel" target="_blank">https://launchpad.net/~maas-devel</a><br>
Post to     : <a href="mailto:maas-devel@lists.launchpad.net">maas-devel@lists.launchpad.net</a><br>
Unsubscribe : <a href="https://launchpad.net/~maas-devel" target="_blank">https://launchpad.net/~maas-devel</a><br>
More help   : <a href="https://help.launchpad.net/ListHelp" target="_blank">https://help.launchpad.net/ListHelp</a><br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br><div dir="ltr">Andres Rodriguez<div>Engineering Manager, HWE Team</div><div>Canonical USA, Inc.</div></div>
</div>