STATIC_URL is missing in context if ALLOWED_HOSTS not set.

Bug #1214982 reported by Ante Karamatić
10
This bug affects 1 person
Affects Status Importance Assigned to Milestone
horizon (Ubuntu)
Fix Released
Critical
Unassigned
Saucy
Fix Released
Critical
Unassigned

Bug Description

Dashboard in Saucy is unusable with Ubuntu theme installed. Traceback of the problem:

Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/django/core/handlers/wsgi.py", line 255, in __call__
    response = self.get_response(request)
  File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py", line 178, in get_response
    response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
  File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py", line 224, in handle_uncaught_exception
    return callback(request, **param_dict)
  File "/usr/lib/python2.7/dist-packages/django/utils/decorators.py", line 91, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/django/views/defaults.py", line 41, in server_error
    return http.HttpResponseServerError(template.render(Context({})))
  File "/usr/lib/python2.7/dist-packages/django/template/base.py", line 140, in render
    return self._render(context)
  File "/usr/lib/python2.7/dist-packages/django/template/base.py", line 134, in _render
    return self.nodelist.render(context)
  File "/usr/lib/python2.7/dist-packages/django/template/base.py", line 830, in render
    bit = self.render_node(node, context)
  File "/usr/lib/python2.7/dist-packages/django/template/base.py", line 844, in render_node
    return node.render(context)
  File "/usr/lib/python2.7/dist-packages/django/template/loader_tags.py", line 124, in render
    return compiled_parent._render(context)
  File "/usr/lib/python2.7/dist-packages/django/template/base.py", line 134, in _render
    return self.nodelist.render(context)
  File "/usr/lib/python2.7/dist-packages/django/template/base.py", line 830, in render
    bit = self.render_node(node, context)
  File "/usr/lib/python2.7/dist-packages/django/template/base.py", line 844, in render_node
    return node.render(context)
  File "/usr/lib/python2.7/dist-packages/django/template/loader_tags.py", line 156, in render
    return self.render_template(self.template, context)
  File "/usr/lib/python2.7/dist-packages/django/template/loader_tags.py", line 138, in render_template
    output = template.render(context)
  File "/usr/lib/python2.7/dist-packages/django/template/base.py", line 140, in render
    return self._render(context)
  File "/usr/lib/python2.7/dist-packages/django/template/base.py", line 134, in _render
    return self.nodelist.render(context)
  File "/usr/lib/python2.7/dist-packages/django/template/base.py", line 830, in render
    bit = self.render_node(node, context)
  File "/usr/lib/python2.7/dist-packages/django/template/base.py", line 844, in render_node
    return node.render(context)
  File "/usr/lib/python2.7/dist-packages/compressor/templatetags/compress.py", line 147, in render
    return self.render_compressed(context, self.kind, self.mode, forced=forced)
  File "/usr/lib/python2.7/dist-packages/compressor/templatetags/compress.py", line 101, in render_compressed
    cache_key, cache_content = self.render_cached(compressor, kind, mode, forced=forced)
  File "/usr/lib/python2.7/dist-packages/compressor/templatetags/compress.py", line 80, in render_cached
    cache_key = get_templatetag_cachekey(compressor, mode, kind)
  File "/usr/lib/python2.7/dist-packages/compressor/cache.py", line 93, in get_templatetag_cachekey
    "templatetag.%s.%s.%s" % (compressor.cachekey, mode, kind))
  File "/usr/lib/python2.7/dist-packages/compressor/utils/decorators.py", line 39, in __get__
    value = obj.__dict__[self.__name__] = self.__get(obj)
  File "/usr/lib/python2.7/dist-packages/compressor/base.py", line 142, in cachekey
    [self.content] + self.mtimes).encode(self.charset), 12)
  File "/usr/lib/python2.7/dist-packages/compressor/utils/decorators.py", line 39, in __get__
    value = obj.__dict__[self.__name__] = self.__get(obj)
  File "/usr/lib/python2.7/dist-packages/compressor/base.py", line 136, in mtimes
    for kind, value, basename, elem in self.split_contents()
  File "/usr/lib/python2.7/dist-packages/compressor/js.py", line 19, in split_contents
    basename = self.get_basename(attribs['src'])
  File "/usr/lib/python2.7/dist-packages/compressor/base.py", line 75, in get_basename
    "compressed" % (url, base_url))
UncompressableFileError: 'horizon/js/horizon.js' isn't accessible via COMPRESS_URL ('/static/') and can't be compressed

It looks like this behavior is caused by python-django-compressor. If one adopts these changes:

https://github.com/ssaboum/django_compressor/commit/d4e38d8c70576f72cff6751cdc84b4b07aeee4a4

the error goes away. Considering these changes haven't been upstreamed in django-compressor, maybe a better approach would be to fix theme for the dashboard.

Related branches

Ante Karamatić (ivoks)
description: updated
Changed in horizon (Ubuntu Saucy):
status: New → Confirmed
Revision history for this message
Adam Gandelman (gandelman-a) wrote :

First, it looks like the traceback in the original report is using a different configuration than the default we ship. We ship with COMPRESS_OFFLINE = True, but by the looks of the traceback it was enabled. Would be interested in the configs used there.

That said, the default saucy package we're shipping atm is definitely broken. The ubuntu theme, however, is not culprit. It is "good" although the theme itself could use a general refresh for Havana.

Installing it currently requires working around Bug #1218535 and Bug #1216019.

After installed and enabled and making the minimal config in /etc/openstack-dashboard/local_settings.py to point to my keystone server, the dashboard is expected to function. However, I get a 500 and compression exception in apache error log:

OfflineGenerationError: You have offline compression enabled but key "3ddd89d27fa2e162d4efd30c103a072b" is missing from offline manifest. You may need to run "python manage.py compress".

This would typically mean the pre-compressed JS and CSS we ship with the package are outdated but in this case django.core.base:BaseHandler is catching and masking a SuspiciousOperation exception (Invalid HTTP_HOST header (you may need to set ALLOWED_HOSTS) and continuing to process the request. As far as I can tell (as a django novice), this is causing templates to later be rendered with empty/incomplete contexts that lack STATIC_URL, and messing with the hashing algorithm used by compressor to map requested URLs to the compressed files, which results in the OfflineGenerationError / key error.

As a work around in the meantime, adding ALLOWED_HOSTS = '*' to /etc/openstack-dashboard/local_settings.py should resolve it.

We either need to find a sane default for ALLOWED_HOSTS or help fix horizon so such errors cause fast failures.

summary: - Ubuntu theme in Havana is broken
+ STATIC_URL is missing in context if ALLOWED_HOSTS not set.
Changed in horizon (Ubuntu Saucy):
status: Confirmed → Triaged
importance: Undecided → High
importance: High → Critical
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package horizon - 1:2013.2~b2-0ubuntu6

---------------
horizon (1:2013.2~b2-0ubuntu6) saucy; urgency=low

  * debian/patches/ubuntu_local_settings.py: Set flexible
    default for ALLOWED_HOSTS that should be changed for production
    deployments (LP: #1214982).
  * Fix (LP: #1216019):
    - debian/openstack-dashboard.{postinst, postrm}: Add/remove horizon
      user. Ensure /etc/openstack-dashbard ownership.
    - debian/openstack-dashboard.conf: Run WSGIDaemonProcess as user
      horizon, set WSGIProcessGroup to horizon.
    - debian/patches/ubuntu_local_settings.py: Generate and load secret
      key from /etc/openstack-dashboard/secret_key.
 -- Adam Gandelman <email address hidden> Fri, 06 Sep 2013 10:33:18 -0700

Changed in horizon (Ubuntu Saucy):
status: Triaged → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.