launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #12379
[Merge] lp:~jameinel/maas/arch_constraint into lp:maas
John A Meinel has proposed merging lp:~jameinel/maas/arch_constraint into lp:maas.
Commit message:
Expose 'arch' as a constraint that can be used to select nodes in get_available_node_for_acquisition.
Requested reviews:
MAAS Maintainers (maas-maintainers)
For more details, see:
https://code.launchpad.net/~jameinel/maas/arch_constraint/+merge/125979
Ignore this branch, it is just one of ~gz's approved branches that needed a trivial merge-conflict fix.
--
https://code.launchpad.net/~jameinel/maas/arch_constraint/+merge/125979
Your team MAAS Maintainers is requested to review the proposed merge of lp:~jameinel/maas/arch_constraint into lp:maas.
=== modified file 'src/maasserver/api.py'
--- src/maasserver/api.py 2012-09-21 16:36:27 +0000
+++ src/maasserver/api.py 2012-09-24 11:28:20 +0000
@@ -645,11 +645,10 @@
: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}
+ supported_constraints = ('name', 'arch')
+ return {constraint: request_params[constraint]
+ for constraint in supported_constraints
+ if constraint in request_params}
@api_operations
=== modified file 'src/maasserver/models/node.py'
--- src/maasserver/models/node.py 2012-09-24 09:00:41 +0000
+++ src/maasserver/models/node.py 2012-09-24 11:28:20 +0000
@@ -253,6 +253,11 @@
if constraints.get('name'):
available_nodes = available_nodes.filter(
hostname=constraints['name'])
+ if constraints.get('arch'):
+ # GZ 2012-09-11: This only supports an exact match on arch type,
+ # using an i386 image on amd64 hardware will wait.
+ 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-21 16:36:27 +0000
+++ src/maasserver/tests/test_api.py 2012-09-24 11:28:20 +0000
@@ -1663,17 +1663,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
@@ -1687,6 +1676,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-09-24 09:00:41 +0000
+++ src/maasserver/tests/test_node.py 2012-09-24 11:28:20 +0000
@@ -20,6 +20,7 @@
ValidationError,
)
from maasserver.enum import (
+ ARCHITECTURE,
DISTRO_SERIES,
NODE_PERMISSION,
NODE_STATUS,
@@ -635,7 +636,8 @@
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_with_name(self):
+ """A single available node can be selected using its hostname"""
user = factory.make_user()
nodes = [self.make_node() for counter in range(3)]
self.assertEqual(
@@ -643,13 +645,32 @@
Node.objects.get_available_node_for_acquisition(
user, {'name': nodes[1].hostname}))
- def test_get_available_node_returns_None_if_name_is_unknown(self):
+ def test_get_available_node_with_unknown_name(self):
+ """None is returned if there is no node with a given name"""
user = factory.make_user()
self.assertEqual(
None,
Node.objects.get_available_node_for_acquisition(
user, {'name': factory.getRandomString()}))
+ def test_get_available_node_with_arch(self):
+ """An available node can be selected of a given architecture"""
+ 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_with_unknown_arch(self):
+ """None is returned if an arch not used by MaaS is given"""
+ 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