launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #14028
Re: [Merge] lp:~evilnick/maas/1.2-backport-cli-help into lp:maas
It looks like this patch actually generates a lot of conflicts. It seems
that it is because the pagination code didn't land/hasn't been backported
to 1.2.
I think it is intended, though, as it is part of the 12.10 should scale to
~10k node story.
John
=:->
On Nov 6, 2012 6:30 PM, "Nick Veitch" <nick.veitch@xxxxxxxxxxxxx> wrote:
> 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
> You are subscribed to branch 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'
>
>
--
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.
Follow ups
References