John A Meinel has proposed merging 
lp:~jameinel/maas/manually-trigger-tag-rebuild into lp:maas.

Commit message:
Add a way to manually trigger a tag rebuilding, rather than having to delete 
and re-add a tag, or change its definition. tags/tag-name/?op=rebuild

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~jameinel/maas/manually-trigger-tag-rebuild/+merge/127928

This is meant as a recovery mechanism.

We are going to start by trusting that the rabbit queues get tags rebuilt 
properly. The alternative is building a lot of additional queue infrastructure 
in the local db.

The idea here is that if something does go wrong (a worker is started but 
doesn't have credentials yet, etc), we at least have a manual relief valve to 
poke at. (Note they could already do this by deleting/recreating the tag, or by 
changing the definition slightly.)

This also gives us a way to load test easily.
-- 
https://code.launchpad.net/~jameinel/maas/manually-trigger-tag-rebuild/+merge/127928
Your team Launchpad code reviewers is requested to review the proposed merge of 
lp:~jameinel/maas/manually-trigger-tag-rebuild into lp:maas.
=== modified file 'src/maasserver/api.py'
--- src/maasserver/api.py	2012-10-03 12:02:59 +0000
+++ src/maasserver/api.py	2012-10-04 05:17:22 +0000
@@ -1371,6 +1371,14 @@
         return nodes
 
     @operation(idempotent=False)
+    def rebuild(self, request, name):
+        """Trigger rebuilding the tag <=> node mapping."""
+        tag = Tag.objects.get_tag_or_404(name=name, user=request.user,
+                                         to_edit=True)
+        tag.populate_nodes()
+        return {'rebuilding': tag.name}
+
+    @operation(idempotent=False)
     def update_nodes(self, request, name):
         """Add or remove nodes being associated with this tag.
 

=== modified file 'src/maasserver/tests/test_api.py'
--- src/maasserver/tests/test_api.py	2012-10-03 14:24:37 +0000
+++ src/maasserver/tests/test_api.py	2012-10-04 05:17:22 +0000
@@ -2584,6 +2584,36 @@
         self.assertEqual({'added': 0, 'removed': 0}, parsed_result)
         self.assertItemsEqual([], tag.node_set.all())
 
+    def test_POST_rebuild_rebuilds_node_mapping(self):
+        tag = factory.make_tag(definition='/foo/bar')
+        # Only one node matches the tag definition, rebuilding should notice
+        node_matching = factory.make_node()
+        node_matching.set_hardware_details('<foo><bar /></foo>')
+        node_bogus = factory.make_node()
+        node_bogus.set_hardware_details('<foo />')
+        node_matching.tags.add(tag)
+        node_bogus.tags.add(tag)
+        self.assertItemsEqual(
+            [node_matching, node_bogus], tag.node_set.all())
+        self.become_admin()
+        response = self.client.post(self.get_tag_uri(tag), {'op': 'rebuild'})
+        self.assertEqual(httplib.OK, response.status_code)
+        parsed_result = json.loads(response.content)
+        self.assertEqual({'rebuilding': tag.name}, parsed_result)
+        self.assertItemsEqual([node_matching], tag.node_set.all())
+
+    def test_POST_rebuild_unknown_404(self):
+        self.become_admin()
+        response = self.client.post(
+            self.get_uri('tags/unknown-tag/'), {'op': 'rebuild'})
+        self.assertEqual(httplib.NOT_FOUND, response.status_code)
+
+    def test_POST_rebuild_refuses_user(self):
+        tag = factory.make_tag(definition='/foo/bar')
+        response = self.client.post(
+            self.get_tag_uri(tag), {'op': 'rebuild'})
+        self.assertEqual(httplib.FORBIDDEN, response.status_code)
+
 
 class TestTagsAPI(APITestCase):
 

_______________________________________________
Mailing list: https://launchpad.net/~launchpad-reviewers
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~launchpad-reviewers
More help   : https://help.launchpad.net/ListHelp

Reply via email to