launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #06334
[Merge] lp:~jtv/maas/acquire-node into lp:maas
Jeroen T. Vermeulen has proposed merging lp:~jtv/maas/acquire-node into lp:maas.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~jtv/maas/acquire-node/+merge/92595
This adds an "acquire" operation to the MaaS API, for use by the juju machine provider.
Acquiring a node involves taking it out of the pool of deployable machines, marking it as deployed, and remembering who it was allocated to.
As it turns out (sorry, Julian, I should have listened!) the Node that the handler returns gets handed to the client by reference, not by value. If the value is needed, we'll need to do something there and I'm not sure what. I filed a separate card for that so it can be in a branch of its own.
Jeroen
--
https://code.launchpad.net/~jtv/maas/acquire-node/+merge/92595
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jtv/maas/acquire-node into lp:maas.
=== modified file 'src/maasserver/api.py'
--- src/maasserver/api.py 2012-02-10 16:50:56 +0000
+++ src/maasserver/api.py 2012-02-10 23:05:58 +0000
@@ -18,6 +18,7 @@
from functools import wraps
import types
+import xmlrpclib
from django.core.exceptions import (
PermissionDenied,
@@ -252,6 +253,10 @@
return ('node_handler', (node_system_id, ))
+class NodesNotAvailable(RuntimeError):
+ """Requested node(s) are not available to be acquired."""
+
+
@api_operations
class NodesHandler(BaseHandler):
"""Manage collection of Nodes / Create Nodes."""
@@ -277,6 +282,11 @@
return HttpResponseBadRequest(
form.errors, content_type='application/json')
+ @api_exported('acquire', 'POST')
+ def acquire(self, request):
+ """Acquire an available node for deployment."""
+ raise NodesNotAvailable("Can't acquire node(s).")
+
@classmethod
def resource_uri(cls, *args, **kwargs):
return ('nodes_handler', [])
=== modified file 'src/maasserver/tests/test_api.py'
--- src/maasserver/tests/test_api.py 2012-02-10 17:10:25 +0000
+++ src/maasserver/tests/test_api.py 2012-02-10 23:05:58 +0000
@@ -16,10 +16,12 @@
import time
from django.test.client import Client
+from maasserver.api import NodesNotAvailable
from maasserver.models import (
MACAddress,
Node,
NODE_STATUS,
+ NODE_STATUS_CHOICES_DICT,
)
from maasserver.testing import (
LoggedInTestCase,
@@ -378,6 +380,38 @@
["One or more MAC Addresses is invalid."],
parsed_result['mac_addresses'])
+ def test_POST_acquire_allocates_node(self):
+ # The "acquire" operation allocates a node.
+ available_status = NODE_STATUS.COMMISSIONED
+ acquired_status = NODE_STATUS.DEPLOYED
+ node = factory.make_node(status=available_status, owner=None)
+ response = self.client.post('/api/nodes/', {'op': 'acquire'})
+ parsed_result = json.loads(response.content)
+
+ self.assertEqual(node.system_id, parsed_result['system_id'])
+
+ [node] = list(Node.objects.filter(system_id=node.system_id))
+ self.assertEqual(acquired_status, node.status)
+ self.assertEqual(self.logged_in_user, node.owner)
+
+ def test_POST_acquire_fails_if_no_node_present(self):
+ # If no nodes exist, none can be acquired.
+ response = self.client.post('/api/nodes/', {'op': 'acquire'})
+ # Fails with server error.
+ self.assertEqual(500, response.status_code)
+
+ def test_POST_acquire_does_not_pick_unavailable_node(self):
+ # The "acquire" operation won't pick nodes that aren't available
+ # for acquisition.
+ available_status = NODE_STATUS.COMMISSIONED
+ unavailable_statuses = (
+ set(NODE_STATUS_CHOICES_DICT) - set([available_status]))
+ for status in unavailable_statuses:
+ factory.make_node(status=status)
+ response = self.client.post('/api/nodes/', {'op': 'acquire'})
+ # Fails with server error.
+ self.assertEqual(500, response.status_code)
+
class MACAddressAPITest(APITestCase):