launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #06673
[Merge] lp:~rvb/maas/maas-longpoll-js into lp:maas
Raphaël Badin has proposed merging lp:~rvb/maas/maas-longpoll-js into lp:maas with lp:~rvb/maas/maas-longpoll-threaded-server as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~rvb/maas/maas-longpoll-js/+merge/97204
Longpoll js.
--
https://code.launchpad.net/~rvb/maas/maas-longpoll-js/+merge/97204
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~rvb/maas/maas-longpoll-js into lp:maas.
=== modified file 'src/maas/demo.py'
--- src/maas/demo.py 2012-03-13 17:44:20 +0000
+++ src/maas/demo.py 2012-03-13 17:44:21 +0000
@@ -16,12 +16,19 @@
from maas.settings import *
from maas.development import *
+
MEDIA_ROOT = os.path.join(os.getcwd(), "media/demo")
MIDDLEWARE_CLASSES += (
'debug_toolbar.middleware.DebugToolbarMiddleware',
)
+LONGPOLL_SERVER_URL = "http://localhost:4545/"
+
+# Disable longpoll by default for now. Set it back to 'longpoll/' to
+# enable it.
+LONGPOLL_URL = None
+
# This should match the setting in Makefile:pserv.pid.
PSERV_URL = "http://localhost:8001/api"
=== modified file 'src/maas/settings.py'
--- src/maas/settings.py 2012-03-13 17:44:20 +0000
+++ src/maas/settings.py 2012-03-13 17:44:21 +0000
@@ -43,10 +43,19 @@
LOGIN_REDIRECT_URL = '/'
LOGIN_URL = '/accounts/login/'
+# The location of the Longpoll server. If LONGPOLL_SERVER_URL is
+# None, the web app won't act as a proxy to the Longpoll server.
+LONGPOLL_SERVER_URL = None
+
+# The relative path where a proxy to the Longpoll server can be
+# reached. Longpolling will be disabled in the UI if this is None.
+LONGPOLL_URL = 'longpoll/'
+
if FORCE_SCRIPT_NAME is not None:
LOGOUT_URL = FORCE_SCRIPT_NAME + LOGOUT_URL
LOGIN_REDIRECT_URL = FORCE_SCRIPT_NAME + LOGIN_REDIRECT_URL
LOGIN_URL = FORCE_SCRIPT_NAME + LOGIN_URL
+ LONGPOLL_URL = FORCE_SCRIPT_NAME + LONGPOLL_URL
# ADMIN_MEDIA_PREFIX will be deprecated in Django 1.4.
# Admin's media will be served using staticfiles instead.
ADMIN_MEDIA_PREFIX = FORCE_SCRIPT_NAME
@@ -55,7 +64,6 @@
METADATA_URL_REGEXP = '^/metadata/'
YUI_COMBO_URL = "combo/"
-
# We handle exceptions ourselves (in
# maasserver.middleware.APIErrorsMiddleware)
PISTON_DISPLAY_ERRORS = False
=== modified file 'src/maasserver/management/commands/createadmin.py'
--- src/maasserver/management/commands/createadmin.py 2012-03-08 11:37:50 +0000
+++ src/maasserver/management/commands/createadmin.py 2012-03-13 17:44:21 +0000
@@ -12,9 +12,13 @@
__all__ = []
+from optparse import make_option
+
from django.contrib.auth.models import User
-from optparse import make_option
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import (
+ BaseCommand,
+ CommandError,
+ )
from django.db import DEFAULT_DB_ALIAS
=== modified file 'src/maasserver/messages.py'
--- src/maasserver/messages.py 2012-03-13 17:44:20 +0000
+++ src/maasserver/messages.py 2012-03-13 17:44:21 +0000
@@ -12,7 +12,7 @@
__all__ = [
"MaaSMessenger",
"MessengerBase",
- "messaging",
+ "get_messaging",
]
@@ -120,8 +120,10 @@
instance.__class__.__name__, event_name)
-if settings.RABBITMQ_PUBLISH:
- messaging = RabbitMessaging(MODEL_EXCHANGE_NAME)
- MaaSMessenger(Node, messaging.getExchange()).register()
-else:
- messaging = None
+def get_messaging():
+ if settings.RABBITMQ_PUBLISH:
+ messaging = RabbitMessaging(MODEL_EXCHANGE_NAME)
+ MaaSMessenger(Node, messaging.getExchange()).register()
+ return messaging
+ else:
+ return None
=== modified file 'src/maasserver/templates/maasserver/js-conf.html'
--- src/maasserver/templates/maasserver/js-conf.html 2012-03-07 16:37:05 +0000
+++ src/maasserver/templates/maasserver/js-conf.html 2012-03-13 17:44:21 +0000
@@ -28,3 +28,4 @@
<script type="text/javascript" src="{{ STATIC_URL }}js/prefs.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/utils.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/node_views.js"></script>
+
=== modified file 'src/maasserver/tests/test_views.py'
--- src/maasserver/tests/test_views.py 2012-03-13 05:34:38 +0000
+++ src/maasserver/tests/test_views.py 2012-03-13 17:44:21 +0000
@@ -17,6 +17,7 @@
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from lxml.html import fromstring
+from maasserver.views import get_longpoll_context
from maasserver.models import (
Config,
NODE_AFTER_COMMISSIONING_ACTION,
@@ -28,6 +29,7 @@
LoggedInTestCase,
TestCase,
)
+from django.conf import settings
def get_prefixed_form_data(prefix, data):
@@ -107,6 +109,31 @@
self.assertEqual("Invalid file type requested.", response.content)
+class TestUtilities(TestCase):
+
+ def patch_settings(self, name, value):
+ old_value = getattr(settings, name)
+ setattr(settings, name, value)
+ self.addCleanup(setattr, settings, name, old_value)
+
+ def test_get_longpoll_context_empty_if_rabbitmq_publish_is_none(self):
+ self.patch_settings('RABBITMQ_PUBLISH', None)
+ self.assertEqual({}, get_longpoll_context())
+
+ def test_get_longpoll_context_empty_if_longpoll_url_is_None(self):
+ self.patch_settings('LONGPOLL_URL', None)
+ self.assertEqual({}, get_longpoll_context())
+
+ def test_get_longpoll_context(self):
+ longpoll = factory.getRandomString()
+ self.patch_settings('LONGPOLL_URL', longpoll)
+ self.patch_settings('RABBITMQ_PUBLISH', True)
+ context = get_longpoll_context()
+ self.assertItemsEqual(
+ ['LONGPOLL_URL', 'longpoll_queue'], list(context))
+ self.assertEqual(longpoll, context['LONGPOLL_URL'])
+
+
class UserPrefsViewTest(LoggedInTestCase):
def test_prefs_GET_profile(self):
=== modified file 'src/maasserver/urls.py'
--- src/maasserver/urls.py 2012-03-08 15:53:39 +0000
+++ src/maasserver/urls.py 2012-03-13 17:44:21 +0000
@@ -36,6 +36,7 @@
logout,
NodeListView,
NodesCreateView,
+ proxy_to,
settings,
settings_add_archive,
userprefsview,
@@ -76,6 +77,13 @@
r'^nodes/create/$', NodesCreateView.as_view(), name='node-create'),
)
+if django_settings.LONGPOLL_SERVER_URL is not None:
+ urlpatterns += patterns('maasserver.views',
+ url(
+ r'^%s$' % re.escape(django_settings.LONGPOLL_URL), proxy_to,
+ name='proxy'),
+ )
+
# URLs for admin users.
urlpatterns += patterns('maasserver.views',
adminurl(r'^settings/$', settings, name='settings'),
=== modified file 'src/maasserver/views.py'
--- src/maasserver/views.py 2012-03-08 22:31:14 +0000
+++ src/maasserver/views.py 2012-03-13 17:44:21 +0000
@@ -15,12 +15,15 @@
"NodesCreateView",
]
+import mimetypes
import os
+import urllib2
from convoy.combo import (
combine_files,
parse_qs,
)
+from django.conf import settings as django_settings
from django.contrib import messages
from django.contrib.auth.forms import PasswordChangeForm as PasswordForm
from django.contrib.auth.models import User
@@ -54,6 +57,7 @@
ProfileForm,
UbuntuForm,
)
+from maasserver.messages import get_messaging
from maasserver.models import (
Node,
SSHKeys,
@@ -66,6 +70,17 @@
return dj_logout(request, next_page=reverse('login'))
+def get_longpoll_context():
+ messaging = get_messaging()
+ if messaging is not None and django_settings.LONGPOLL_URL is not None:
+ return {
+ 'longpoll_queue': messaging.getQueue().name,
+ 'LONGPOLL_URL': django_settings.LONGPOLL_URL,
+ }
+ else:
+ return {}
+
+
class NodeListView(ListView):
context_object_name = "node_list"
@@ -73,6 +88,11 @@
def get_queryset(self):
return Node.objects.get_visible_nodes(user=self.request.user)
+ def get_context_data(self, **kwargs):
+ context = super(NodeListView, self).get_context_data(**kwargs)
+ context.update(get_longpoll_context())
+ return context
+
class NodesCreateView(CreateView):
@@ -221,6 +241,19 @@
return reverse('settings')
+def proxy_to(request):
+ url = django_settings.LONGPOLL_SERVER_URL
+ assert url is not None, (
+ "LONGPOLL_SERVER_URL should point to a Longpoll server.")
+ if 'QUERY_STRING' in request.META:
+ url += '?' + request.META['QUERY_STRING']
+ proxied_request = urllib2.urlopen(url)
+ status_code = proxied_request.code
+ mimetype = proxied_request.headers.typeheader or mimetypes.guess_type(url)
+ content = proxied_request.read()
+ return HttpResponse(content, status=status_code, mimetype=mimetype)
+
+
def settings(request):
user_list = UserProfile.objects.all_users().order_by('username')
# Process the MaaS & network form.
=== modified file 'vdenv/api-list.py'
--- vdenv/api-list.py 2012-03-09 22:07:14 +0000
+++ vdenv/api-list.py 2012-03-13 17:44:21 +0000
@@ -11,8 +11,9 @@
__metaclass__ = type
+import sys
import xmlrpclib
-import sys
+
host = "192.168.123.2"
user = "cobbler"
=== modified file 'vdenv/setup.py'
--- vdenv/setup.py 2012-03-09 22:05:55 +0000
+++ vdenv/setup.py 2012-03-13 17:44:21 +0000
@@ -11,14 +11,16 @@
__metaclass__ = type
-import yaml
import os
import re
+import subprocess
import sys
+import xmlrpclib
+
+from Cheetah.Template import Template
import libvirt
-from Cheetah.Template import Template
-import subprocess
-import xmlrpclib
+import yaml
+
NODES_RANGE = range(1,4)
Follow ups