launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #14027
[Merge] lp:~evilnick/maas/1.2-backport-cli-help into lp:maas
Nick Veitch has proposed merging lp:~evilnick/maas/1.2-backport-cli-help into lp:maas.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #1070522 in MAAS: "maas-cli nodes new incomplete documentation"
https://bugs.launchpad.net/maas/+bug/1070522
For more details, see:
https://code.launchpad.net/~evilnick/maas/1.2-backport-cli-help/+merge/133071
backport of help added to maas-cli command for nodes new
--
https://code.launchpad.net/~evilnick/maas/1.2-backport-cli-help/+merge/133071
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~evilnick/maas/1.2-backport-cli-help into lp:maas.
=== modified file 'etc/celeryconfig_common.py'
=== modified file 'src/maasserver/api.py'
--- src/maasserver/api.py 2012-11-01 11:45:29 +0000
+++ src/maasserver/api.py 2012-11-06 14:29:21 +0000
@@ -745,6 +745,16 @@
When a node has been added to MAAS by an admin MAAS user, it is
ready for allocation to services running on the MAAS.
+ The minimum data required is:
+ architecture=<arch string> (e.g "i386/generic")
+ mac_address=<value>
+
+ :param architecture: A string containing the architecture type of
+ the node.
+ :param mac_address: The MAC address of the node.
+ :param hostname: A hostname. If not given, one will be generated.
+ :param powertype: A power management type, if applicable (e.g.
+ "virsh", "ipmi").
"""
node = create_node(request)
if request.user.is_superuser:
=== modified file 'src/maasserver/forms.py'
=== modified file 'src/maasserver/templates/maasserver/node_list.html'
--- src/maasserver/templates/maasserver/node_list.html 2012-10-24 12:51:10 +0000
+++ src/maasserver/templates/maasserver/node_list.html 2012-11-06 14:29:21 +0000
@@ -38,8 +38,13 @@
{% if input_query_error %}
<p class="form-errors">{{input_query_error}}</p>
{% endif %}
+<<<<<<< TREE
{% include "maasserver/nodes_listing.html" with sorting="true" %}
{% include "maasserver/pagination.html" %}
+=======
+ {% include "maasserver/nodes_listing.html" %}
+ {% include "maasserver/pagination.html" %}
+>>>>>>> MERGE-SOURCE
<a id="addnode" href="#" class="button right space-top">+ Add node</a>
<div class="clear"></div>
<a class="right space-top" href="{% url "enlist-preseed-view" %}">View enlistment preseed</a>
=== modified file 'src/maasserver/tests/test_api.py'
--- src/maasserver/tests/test_api.py 2012-11-02 09:22:01 +0000
+++ src/maasserver/tests/test_api.py 2012-11-06 14:29:21 +0000
@@ -4256,6 +4256,7 @@
(response.status_code, response.content))
def test_report_boot_images_warns_if_no_images_found(self):
+<<<<<<< TREE
nodegroup = NodeGroup.objects.ensure_master()
factory.make_node_group() # Second nodegroup with no images.
recorder = self.patch(api, 'register_persistent_error')
@@ -4299,6 +4300,50 @@
response = self.report_images(nodegroup, [image], client=client)
self.assertEqual(httplib.OK, response.status_code)
self.assertEqual(0, recorder.call_count)
+=======
+ nodegroup = NodeGroup.objects.ensure_master()
+ factory.make_node_group() # Second nodegroup with no images.
+ recorder = self.patch(api, 'register_persistent_error')
+ client = make_worker_client(nodegroup)
+ response = self.report_images(nodegroup, [], client=client)
+ self.assertEqual(
+ (httplib.OK, "OK"),
+ (response.status_code, response.content))
+
+ self.assertIn(
+ COMPONENT.IMPORT_PXE_FILES,
+ [args[0][0] for args in recorder.call_args_list])
+ # Check that the persistent error message contains a link to the
+ # clusters listing.
+ self.assertIn(
+ "/settings/#accepted-clusters", recorder.call_args_list[0][0][1])
+
+ def test_report_boot_images_warns_if_any_nodegroup_has_no_images(self):
+ nodegroup = NodeGroup.objects.ensure_master()
+ # Second nodegroup with no images.
+ factory.make_node_group(status=NODEGROUP_STATUS.ACCEPTED)
+ recorder = self.patch(api, 'register_persistent_error')
+ client = make_worker_client(nodegroup)
+ image = make_boot_image_params()
+ response = self.report_images(nodegroup, [image], client=client)
+ self.assertEqual(
+ (httplib.OK, "OK"),
+ (response.status_code, response.content))
+
+ self.assertIn(
+ COMPONENT.IMPORT_PXE_FILES,
+ [args[0][0] for args in recorder.call_args_list])
+
+ def test_report_boot_images_ignores_non_accepted_groups(self):
+ nodegroup = factory.make_node_group(status=NODEGROUP_STATUS.ACCEPTED)
+ factory.make_node_group(status=NODEGROUP_STATUS.PENDING)
+ factory.make_node_group(status=NODEGROUP_STATUS.REJECTED)
+ recorder = self.patch(api, 'register_persistent_error')
+ client = make_worker_client(nodegroup)
+ image = make_boot_image_params()
+ response = self.report_images(nodegroup, [image], client=client)
+ self.assertEqual(0, recorder.call_count)
+>>>>>>> MERGE-SOURCE
def test_report_boot_images_removes_warning_if_images_found(self):
self.patch(api, 'register_persistent_error')
=== modified file 'src/maasserver/tests/test_views_nodes.py'
--- src/maasserver/tests/test_views_nodes.py 2012-10-24 15:16:51 +0000
+++ src/maasserver/tests/test_views_nodes.py 2012-11-06 14:29:21 +0000
@@ -532,6 +532,7 @@
"//div[@id='nodes']/table//td/a/@href")
self.assertEqual([node2_link], node_links)
+<<<<<<< TREE
def test_node_list_paginates(self):
"""Node listing is split across multiple pages with links"""
# Set a very small page size to save creating lots of nodes
@@ -591,6 +592,65 @@
[(a.text.lower(), a.get("href"))
for a in document.xpath("//div[@class='pagination']//a")])
+=======
+ def test_node_list_paginates(self):
+ """Node listing is split across multiple pages with links"""
+ # Set a very small page size to save creating lots of nodes
+ page_size = 2
+ self.patch(nodes_views.NodeListView, 'paginate_by', page_size)
+ nodes = [factory.make_node(created="2012-10-12 12:00:%02d" % i)
+ for i in range(page_size * 2 + 1)]
+ # Order node links with newest first as the view is expected to
+ node_links = [reverse('node-view', args=[node.system_id])
+ for node in reversed(nodes)]
+ expr_node_links = XPath("//div[@id='nodes']/table//a/@href")
+ expr_page_anchors = XPath("//div[@class='pagination']//a")
+ # Fetch first page, should link newest two nodes and page 2
+ response = self.client.get(reverse('node-list'))
+ page1 = fromstring(response.content)
+ self.assertEqual(node_links[:page_size], expr_node_links(page1))
+ self.assertEqual([("next", "?page=2"), ("last", "?page=3")],
+ [(a.text.lower(), a.get("href"))
+ for a in expr_page_anchors(page1)])
+ # Fetch second page, should link next nodes and adjacent pages
+ response = self.client.get(reverse('node-list'), {"page": 2})
+ page2 = fromstring(response.content)
+ self.assertEqual(node_links[page_size:page_size * 2],
+ expr_node_links(page2))
+ self.assertEqual([("first", "."), ("previous", "."),
+ ("next", "?page=3"), ("last", "?page=3")],
+ [(a.text.lower(), a.get("href"))
+ for a in expr_page_anchors(page2)])
+ # Fetch third page, should link oldest node and node list page
+ response = self.client.get(reverse('node-list'), {"page": 3})
+ page3 = fromstring(response.content)
+ self.assertEqual(node_links[page_size * 2:], expr_node_links(page3))
+ self.assertEqual([("first", "."), ("previous", "?page=2")],
+ [(a.text.lower(), a.get("href"))
+ for a in expr_page_anchors(page3)])
+
+ def test_node_list_query_paginates(self):
+ """Node list query subset is split across multiple pages with links"""
+ # Set a very small page size to save creating lots of nodes
+ self.patch(nodes_views.NodeListView, 'paginate_by', 2)
+ nodes = [factory.make_node(created="2012-10-12 12:00:%02d" % i)
+ for i in range(10)]
+ tag = factory.make_tag("odd")
+ for node in nodes[::2]:
+ node.tags = [tag]
+ last_node_link = reverse('node-view', args=[nodes[0].system_id])
+ response = self.client.get(reverse('node-list'),
+ {"query": "maas-tags=odd", "page": 3})
+ document = fromstring(response.content)
+ self.assertIn("5 matching nodes", document.xpath("string(//h1)"))
+ self.assertEqual([last_node_link],
+ document.xpath("//div[@id='nodes']/table//a/@href"))
+ self.assertEqual([("first", "?query=maas-tags%3Dodd"),
+ ("previous", "?query=maas-tags%3Dodd&page=2")],
+ [(a.text.lower(), a.get("href"))
+ for a in document.xpath("//div[@class='pagination']//a")])
+
+>>>>>>> MERGE-SOURCE
class NodePreseedViewTest(LoggedInTestCase):
=== modified file 'src/maasserver/views/nodes.py'
=== modified file 'src/provisioningserver/boot_images.py'
--- src/provisioningserver/boot_images.py 2012-10-25 07:27:24 +0000
+++ src/provisioningserver/boot_images.py 2012-11-06 14:29:21 +0000
@@ -32,10 +32,14 @@
)
from provisioningserver.config import Config
from provisioningserver.pxe import tftppath
+<<<<<<< TREE
from provisioningserver.start_cluster_controller import get_cluster_uuid
task_logger = get_task_logger(name=__name__)
+=======
+from provisioningserver.start_cluster_controller import get_cluster_uuid
+>>>>>>> MERGE-SOURCE
def get_cached_knowledge():
=== modified file 'src/provisioningserver/dns/config.py'
=== modified file 'src/provisioningserver/dns/tests/test_config.py'
Follow ups