launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #11811
[Merge] lp:~gz/maas/arch_constraint into lp:maas
Martin Packman has proposed merging lp:~gz/maas/arch_constraint into lp:maas.
Requested reviews:
MAAS Maintainers (maas-maintainers)
For more details, see:
https://code.launchpad.net/~gz/maas/arch_constraint/+merge/123789
Experiment with adding another constraint to MaaS using the existing architecture field stored on Node. This probably isn't much use, especially as it doesn't know you can fulfil a 'i386' request by sticking an i386 image on an amd64 box.
--
https://code.launchpad.net/~gz/maas/arch_constraint/+merge/123789
Your team MAAS Maintainers is requested to review the proposed merge of lp:~gz/maas/arch_constraint into lp:maas.
=== modified file 'src/maasserver/api.py'
--- src/maasserver/api.py 2012-09-10 14:42:52 +0000
+++ src/maasserver/api.py 2012-09-11 16:57:27 +0000
@@ -616,11 +616,12 @@
:return: A mapping of applicable constraint names to their values.
:rtype: :class:`dict`
"""
- name = request_params.get('name', None)
- if name is None:
- return {}
- else:
- return {'name': name}
+ constraints = {}
+ for k in ('name', 'arch'):
+ v = request_params.get(k, None)
+ if v is not None:
+ constraints[k] = v
+ return constraints
@api_operations
=== modified file 'src/maasserver/models/node.py'
--- src/maasserver/models/node.py 2012-08-24 10:45:47 +0000
+++ src/maasserver/models/node.py 2012-09-11 16:57:27 +0000
@@ -249,6 +249,11 @@
if constraints.get('name'):
available_nodes = available_nodes.filter(
hostname=constraints['name'])
+ if constraints.get('arch'):
+ # GZ 2012-09-11: Need more logic here when picking an image works,
+ # as can satisfy i386 with amd64 and so on.
+ available_nodes = available_nodes.filter(
+ architecture=constraints['arch'])
return get_first(available_nodes)
=== modified file 'src/maasserver/tests/test_api.py'
--- src/maasserver/tests/test_api.py 2012-09-10 14:27:00 +0000
+++ src/maasserver/tests/test_api.py 2012-09-11 16:57:27 +0000
@@ -1587,17 +1587,6 @@
self.assertEqual(
node.hostname, json.loads(response.content)['hostname'])
- def test_POST_acquire_constrains_by_name(self):
- # Negative test for name constraint.
- # If a name constraint is given, "acquire" will only consider a
- # node with that name.
- factory.make_node(status=NODE_STATUS.READY, owner=None)
- response = self.client.post(self.get_uri('nodes/'), {
- 'op': 'acquire',
- 'name': factory.getRandomString(),
- })
- self.assertEqual(httplib.CONFLICT, response.status_code)
-
def test_POST_acquire_treats_unknown_name_as_resource_conflict(self):
# A name constraint naming an unknown node produces a resource
# conflict: most likely the node existed but has changed or
@@ -1611,6 +1600,27 @@
})
self.assertEqual(httplib.CONFLICT, response.status_code)
+ def test_POST_acquire_allocates_node_by_arch(self):
+ # Asking for a particular arch acquires a node with that arch.
+ node = factory.make_node(status=NODE_STATUS.READY,
+ architecture=ARCHITECTURE.i386)
+ response = self.client.post(self.get_uri('nodes/'), {
+ 'op': 'acquire',
+ 'arch': 'i386',
+ })
+ self.assertEqual(httplib.OK, response.status_code)
+ response_json = json.loads(response.content)
+ self.assertEqual(node.architecture, response_json['architecture'])
+
+ def test_POST_acquire_treats_unknown_arch_as_resource_conflict(self):
+ # Asking for an unknown arch returns an HTTP conflict
+ factory.make_node(status=NODE_STATUS.READY)
+ response = self.client.post(self.get_uri('nodes/'), {
+ 'op': 'acquire',
+ 'arch': 'sparc',
+ })
+ self.assertEqual(httplib.CONFLICT, response.status_code)
+
def test_POST_acquire_sets_a_token(self):
# "acquire" should set the Token being used in the request on
# the Node that is allocated.
=== modified file 'src/maasserver/tests/test_node.py'
--- src/maasserver/tests/test_node.py 2012-08-24 10:28:29 +0000
+++ src/maasserver/tests/test_node.py 2012-09-11 16:57:27 +0000
@@ -20,6 +20,7 @@
ValidationError,
)
from maasserver.enum import (
+ ARCHITECTURE,
NODE_PERMISSION,
NODE_STATUS,
NODE_STATUS_CHOICES,
@@ -616,7 +617,7 @@
Node.objects.get_available_node_for_acquisition(
user, {'name': node.system_id}))
- def test_get_available_node_constrains_by_name(self):
+ def test_get_available_node_constraints_by_name(self):
user = factory.make_user()
nodes = [self.make_node() for counter in range(3)]
self.assertEqual(
@@ -631,6 +632,22 @@
Node.objects.get_available_node_for_acquisition(
user, {'name': factory.getRandomString()}))
+ def test_get_available_node_constraints_by_arch(self):
+ user = factory.make_user()
+ nodes = [self.make_node(architecture=s)
+ for s in (ARCHITECTURE.amd64, ARCHITECTURE.i386)]
+ available_node = Node.objects.get_available_node_for_acquisition(
+ user, {'arch': "i386"})
+ self.assertEqual(ARCHITECTURE.i386, available_node.architecture)
+ self.assertEqual(nodes[1], available_node)
+
+ def test_get_available_node_returns_None_if_arch_is_unknown(self):
+ user = factory.make_user()
+ self.assertEqual(
+ None,
+ Node.objects.get_available_node_for_acquisition(
+ user, {'arch': "sparc"}))
+
def test_stop_nodes_stops_nodes(self):
# We don't actually want to fire off power events, but we'll go
# through the motions right up to the point where we'd normally