""" Cal Leeming [Simplicity Media Ltd] - March 2011 cal.leeming [at] simplicitymedialtd.co.uk """ ##################################################### # multihost.py ##################################################### from django.conf import settings from django.utils.cache import patch_vary_headers import socket class MultiHostMiddleware : def process_request ( self , request ): try : host = request . META [ "HTTP_HOST" ] if host [ - 3 :] == ":80" : host = host [: - 3 ] # ignore default port number, if present request . urlconf = settings . HOST_MIDDLEWARE_URLCONF_MAP [ host ] if settings . HOST_MIDDLEWARE_URLCONF_MAP_RESTRICT . has_key ( host ): if not socket . gethostname () in settings . HOST_MIDDLEWARE_URLCONF_MAP_RESTRICT [ host ]: raise Exception , "The requested site is not authorized to be served from this node." except KeyError : pass # use default urlconf (settings.ROOT_URLCONF) def process_response ( self , request , response ): if getattr ( request , "urlconf" , None ): patch_vary_headers ( response , ( 'Host' ,)) return response ##################################################### # settings.py ##################################################### if not os . environ . has_key ( 'DJANGO_ENVIRONMENT' ): raise Exception , "You must provide environ DJANGO_ENVIRONMENT (dev/prod)" # Place environment specific overrides in here if os . environ [ 'DJANGO_ENVIRONMENT' ] == 'dev' : DEBUG = True elif os . environ [ 'DJANGO_ENVIRONMENT' ] == 'prod' : DEBUG = False DATABASES = { 'db1' : { 'ENGINE' : 'django.db.backends.mysql' , 'NAME' : 'db1' , 'USER' : 'db1' , 'PASSWORD' : 'db1' , 'HOST' : 'db1' }, 'db2' : { 'ENGINE' : 'django.db.backends.mysql' , 'NAME' : 'db2' , 'USER' : 'db2' , 'PASSWORD' : 'db2' , 'HOST' : 'db2' }, } """Monkey Patch to allow imports from the webapp dir, and also not have to specify an absolute template location. This lets you specify relative paths to the webapp across multiple nodes.""" import os PROJECT_PATH = os . path . abspath ( os . path . dirname ( __file__ ) + "/" ) . replace ( ' \\ ' , "/" ) TEMPLATE_DIRS = ( PROJECT_PATH + '/templates/' ) """ Determine which default database we should use. Because this webapp runs on multiple servers in different context, we need to override this here """ if socket . gethostname () == 'sws01.internal' : DATABASES [ 'default' ] = DATABASES . get ( 'db1' ) # Cache settings CACHE_BACKEND = 'memcached://cache01.internal:11211/' TMP_DIR = os . path . realpath ( PROJECT_PATH + '/../../tmp' ) elif socket . gethostname () == 'node02.internal' : DATABASES [ 'default' ] = DATABASES . get ( 'db2' ) TMP_DIR = os . path . realpath ( PROJECT_PATH + '/../tmp' ) else : raise Exception , "Unable to determine which node we are" """ Now make sure those paths are OK """ if not os . path . isdir ( TMP_DIR ): raise Exception , "Configured settings.TMP_DIR path does not exist." HOST_MIDDLEWARE_URLCONF_MAP = { # Control Panel "cp.website1.com" : "webapp.sites.website1.urls" , # Status page "cp.website2.com" : "webapp.sites.status2.urls" , # Members area "cp.website3.com" : "webapp.sites.status3.urls" , } # Restrict certain hostnames to only be served from specific nodes HOST_MIDDLEWARE_URLCONF_MAP_RESTRICT = { # Status page "resource.heavy.page.com" : ( "sws01.internal" , ), } MIDDLEWARE_CLASSES = ( 'webapp.multihost.MultiHostMiddleware' , )