Merge lp:~danilo/linaro-license-protection/django-refactor-deployment into lp:~linaro-automation/linaro-license-protection/trunk

Proposed by Данило Шеган
Status: Rejected
Rejected by: Milo Casagrande
Proposed branch: lp:~danilo/linaro-license-protection/django-refactor-deployment
Merge into: lp:~linaro-automation/linaro-license-protection/trunk
Prerequisite: lp:~danilo/linaro-license-protection/django-refactor
Diff against target: 411 lines (+391/-0)
4 files modified
deploy.py (+147/-0)
deployment_templates/linaro-license-protection.apache2.conf (+41/-0)
deployment_templates/settings.py (+167/-0)
deployment_templates/wsgi.py (+36/-0)
To merge this branch: bzr merge lp:~danilo/linaro-license-protection/django-refactor-deployment
Reviewer Review Type Date Requested Status
Данило Шеган (community) Disapprove
Review via email: mp+114409@code.launchpad.net
To post a comment you must log in.
91. By Данило Шеган

Merge latest django-refactor.

Revision history for this message
Данило Шеган (danilo) wrote :

I'd rather see apache conf integrated into the documentation, and everything deployed in a standard django-manner.

review: Disapprove

Unmerged revisions

91. By Данило Шеган

Merge latest django-refactor.

90. By Данило Шеган

Re-add deployment scripts.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'deploy.py'
2--- deploy.py 1970-01-01 00:00:00 +0000
3+++ deploy.py 2012-07-11 12:58:19 +0000
4@@ -0,0 +1,147 @@
5+#!/usr/bin/python
6+import os
7+import re
8+from subprocess import check_call, call
9+import sys
10+
11+# This script takes care of downloading the linaro-license-protection code and
12+# installing it onto a server using the configuration dictionary below for
13+# commonly changed settings.
14+
15+config = {
16+ # Where to check the django app out to
17+ "django_root": "/home/dooferlad/linaro-license-protection",
18+
19+ # Used in apache configuration...
20+ "virtual_host_ip_address_and_port": "_default_",
21+ "server_admin_email_address": "admin@linaro.org",
22+
23+ # Base path that will get searched for files to serve
24+ # In theory there can be more than one XSendFilePath in an apache
25+ # config and mod_xsendfile will search all of them. This isn't something
26+ # that has been tested, but in theory will work and should allow serving
27+ # files from an expanding number of mount points as disk space requirements
28+ # grow.
29+ "x_send_file_path": "/home/dooferlad/linaro-license-protection/android",
30+
31+ # Apache config file name
32+ "apache2_site_config":
33+ "/etc/apache2/sites-available/linaro-license-protection",
34+
35+ # Postgresql database name
36+ "database_name": "linaro-license-protection-2",
37+}
38+
39+# Derived variables
40+config["deploy_root"] = os.path.dirname(config["django_root"])
41+config["django_directory_name"] = os.path.basename(config["django_root"])
42+config["a2_site_name"] = os.path.basename(config["apache2_site_config"])
43+
44+def main():
45+ print "Installing Bazaar"
46+ run("sudo apt-get -y install bzr")
47+
48+ print "Fetching linaro-license-protection code from bzr"
49+ if os.path.isdir(config["django_root"]):
50+ os.chdir(config["django_root"])
51+ run("bzr update")
52+ else:
53+ run("bzr branch lp:~linaro-infrastructure/linaro-license-protection/"
54+ "merge-django-into-trunk " + config["django_root"])
55+
56+ print "Installing python modules"
57+ run("sudo apt-get -y install python-django python-django-openid-auth"
58+ " python-mock python-psycopg2 testrepository")
59+
60+ print "Running unit tests (sqlite database)"
61+ os.chdir(config["django_root"])
62+ run("python manage.py test")
63+
64+ print "Installing required apache modules"
65+ run("sudo apt-get -y install apache2 libapache2-mod-xsendfile"
66+ " libapache2-mod-wsgi")
67+
68+ print "Installing database"
69+ run("sudo apt-get -y install postgresql")
70+ run_allow_fail("sudo -u postgres createuser -dSR linaro")
71+ run_allow_fail("sudo -u postgres createdb " + config["database_name"])
72+
73+ print "Creating configuration files..."
74+ generated_apache_config = os.path.join(
75+ config["django_root"], "deployment_templates",
76+ "linaro-license-protection.apache2.conf.gen")
77+
78+ create_config_file(os.path.join(
79+ config["django_root"], "deployment_templates",
80+ "linaro-license-protection.apache2.conf"),
81+ generated_apache_config)
82+
83+ run("sudo mv " + generated_apache_config + " " +
84+ config["apache2_site_config"])
85+
86+ create_config_file(os.path.join(config["django_root"],
87+ "deployment_templates",
88+ "wsgi.py"),
89+ os.path.join(config["django_root"],
90+ "license_protected_downloads",
91+ "wsgi.py"))
92+
93+ create_config_file(os.path.join(config["django_root"],
94+ "deployment_templates",
95+ "settings.py"),
96+ os.path.join(config["django_root"],
97+ "settings.py"))
98+
99+ print "Deploying files to static root for serving"
100+ run("python manage.py collectstatic --noinput")
101+
102+ print "Reloading Apache"
103+ run("sudo service apache2 reload")
104+
105+ print "Set up database"
106+ os.chdir(config["django_root"])
107+ run("python manage.py syncdb --noinput")
108+
109+ print "Running unit tests (django database)"
110+ os.chdir(config["django_root"])
111+ run("python manage.py test")
112+
113+ print "Enabling new site"
114+ run("sudo a2ensite " + config["a2_site_name"])
115+ run("sudo service apache2 reload")
116+
117+ # Note, we don't run these because they have hard links to sites in.
118+ # May be useful during a production deployment though...
119+ if False:
120+ print "Running deployment tests"
121+ os.chdir(config["django_root"])
122+ run("testr run testplans.test_suite")
123+
124+def run(cmd):
125+ print "-" * 80
126+ print cmd
127+ check_call(cmd, shell=True)
128+
129+def run_allow_fail(cmd):
130+ print "-" * 80
131+ print cmd
132+ call(cmd, shell=True)
133+
134+def template_lookup(match):
135+ if match.group(1) in config:
136+ return config[match.group(1)]
137+ else:
138+ print >> sys.stderr, ("Template used undefined variable %s" %
139+ match.group(1))
140+ exit(1)
141+
142+def create_config_file(in_file_name, out_file_name):
143+ print "Processing %s to create %s" % (in_file_name, out_file_name)
144+ with open(in_file_name) as in_file:
145+ with open(out_file_name, "w") as out_file:
146+ for line in in_file:
147+ line = re.sub(r"\{% (\w+) %\}", template_lookup, line)
148+ out_file.write(line)
149+
150+if __name__ == "__main__":
151+ main()
152
153=== added directory 'deployment_templates'
154=== added file 'deployment_templates/linaro-license-protection.apache2.conf'
155--- deployment_templates/linaro-license-protection.apache2.conf 1970-01-01 00:00:00 +0000
156+++ deployment_templates/linaro-license-protection.apache2.conf 2012-07-11 12:58:19 +0000
157@@ -0,0 +1,41 @@
158+NameVirtualHost {% virtual_host_ip_address_and_port %}
159+
160+<VirtualHost {% virtual_host_ip_address_and_port %}>
161+ Alias /static/ {% django_root %}/static/
162+
163+ <Directory {% django_root %}/static>
164+ Order deny,allow
165+ Allow from all
166+ </Directory>
167+
168+ ServerAdmin {% server_admin_email_address %}
169+
170+ XSendFile on
171+ XSendFilePath {% x_send_file_path %}
172+
173+ WSGIScriptAlias / {% django_root %}/license_protected_downloads/wsgi.py
174+ WSGIDaemonProcess linaro-license-protection
175+
176+ <Directory {% django_root %}/license_protected_downloads>
177+ <Files wsgi.py>
178+ Order deny,allow
179+ Allow from all
180+ </Files>
181+ </Directory>
182+
183+ <Directory />
184+ Options FollowSymLinks
185+ AllowOverride None
186+ </Directory>
187+ <Directory />
188+ Options FollowSymLinks
189+ AllowOverride None
190+ </Directory>
191+ <Directory /var/www/>
192+ Options Indexes FollowSymLinks MultiViews
193+ AllowOverride None
194+ Order allow,deny
195+ allow from all
196+ </Directory>
197+
198+</VirtualHost>
199
200=== added file 'deployment_templates/settings.py'
201--- deployment_templates/settings.py 1970-01-01 00:00:00 +0000
202+++ deployment_templates/settings.py 2012-07-11 12:58:19 +0000
203@@ -0,0 +1,167 @@
204+# Django settings for linaro_license_protection_2 project.
205+
206+import os
207+
208+DEBUG = False
209+
210+PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
211+ROOT_DIR = os.path.split(PROJECT_ROOT)[-1]
212+
213+ADMINS = (
214+ ('Linaro Infrastructure', 'infrastructure@linaro.org'),
215+)
216+
217+MANAGERS = ADMINS
218+
219+DATABASES = {
220+ 'default': {
221+ 'ENGINE': 'django.db.backends.postgresql_psycopg2', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
222+ 'NAME': '{% database_name %}', # Or path to database file if using sqlite3.
223+ 'USER': 'linaro', # Not used with sqlite3.
224+ 'PASSWORD': '', # Not used with sqlite3.
225+ 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
226+ 'PORT': '', # Set to empty string for default. Not used with sqlite3.
227+ }
228+}
229+
230+# Local time zone for this installation. Choices can be found here:
231+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
232+# although not all choices may be available on all operating systems.
233+# On Unix systems, a value of None will cause Django to use the same
234+# timezone as the operating system.
235+# If running in a Windows environment this must be set to the same as your
236+# system time zone.
237+TIME_ZONE = 'America/Chicago'
238+
239+# Language code for this installation. All choices can be found here:
240+# http://www.i18nguy.com/unicode/language-identifiers.html
241+LANGUAGE_CODE = 'en-us'
242+
243+SITE_ID = 1
244+
245+# If you set this to False, Django will make some optimizations so as not
246+# to load the internationalization machinery.
247+USE_I18N = True
248+
249+# If you set this to False, Django will not format dates, numbers and
250+# calendars according to the current locale
251+USE_L10N = True
252+
253+# Absolute filesystem path to the directory that will hold user-uploaded files.
254+# Example: "/home/media/media.lawrence.com/media/"
255+MEDIA_ROOT = ''
256+
257+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
258+# trailing slash.
259+# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
260+MEDIA_URL = ''
261+
262+# Absolute path to the directory static files should be collected to.
263+# Don't put anything in this directory yourself; store your static files
264+# in apps' "static/" subdirectories and in STATICFILES_DIRS.
265+# Example: "/home/media/media.lawrence.com/static/"
266+STATIC_ROOT = os.path.join(PROJECT_ROOT, "static")
267+
268+# URL prefix for static files.
269+# Example: "http://media.lawrence.com/static/"
270+STATIC_URL = '/static/'
271+
272+# URL prefix for admin static files -- CSS, JavaScript and images.
273+# Make sure to use a trailing slash.
274+# Examples: "http://foo.com/static/admin/", "/static/admin/".
275+ADMIN_MEDIA_PREFIX = '/static/admin/'
276+
277+# Additional locations of static files
278+STATICFILES_DIRS = (
279+ # Put strings here, like "/home/html/static" or "C:/www/django/static".
280+ # Always use forward slashes, even on Windows.
281+ # Don't forget to use absolute paths, not relative paths.
282+)
283+
284+# List of finder classes that know how to find static files in
285+# various locations.
286+STATICFILES_FINDERS = (
287+ 'django.contrib.staticfiles.finders.FileSystemFinder',
288+ 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
289+# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
290+)
291+
292+# Make this unique, and don't share it with anybody.
293+SECRET_KEY = 'lkye^=q_i(#jies7^cz#anqq(1g0k$luy5^1jr2nk=g#inet(n'
294+
295+# List of callables that know how to import templates from various sources.
296+TEMPLATE_LOADERS = (
297+ 'django.template.loaders.filesystem.Loader',
298+ 'django.template.loaders.app_directories.Loader',
299+# 'django.template.loaders.eggs.Loader',
300+)
301+
302+MIDDLEWARE_CLASSES = (
303+ 'django.middleware.common.CommonMiddleware',
304+ 'django.contrib.sessions.middleware.SessionMiddleware',
305+ 'django.middleware.csrf.CsrfViewMiddleware',
306+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
307+ 'django.contrib.messages.middleware.MessageMiddleware',
308+)
309+
310+ROOT_URLCONF = ROOT_DIR + '.urls'
311+
312+TEMPLATE_DIRS = (os.path.join(PROJECT_ROOT, "templates" ),)
313+
314+INSTALLED_APPS = (
315+ 'django.contrib.auth',
316+ 'django.contrib.contenttypes',
317+ 'django.contrib.sessions',
318+ 'django.contrib.sites',
319+ 'django.contrib.messages',
320+ 'django.contrib.staticfiles',
321+ # Uncomment the next line to enable the admin:
322+ 'django.contrib.admin',
323+ 'django_openid_auth',
324+ # Uncomment the next line to enable admin documentation:
325+ # 'django.contrib.admindocs',
326+ ROOT_DIR + '.license_protected_downloads',
327+)
328+
329+AUTHENTICATION_BACKENDS = (
330+ 'django_openid_auth.auth.OpenIDBackend',
331+ 'django.contrib.auth.backends.ModelBackend',
332+)
333+
334+LOGIN_URL = '/openid/login/'
335+
336+OPENID_CREATE_USERS = True
337+OPENID_SSO_SERVER_URL = 'https://login.launchpad.net/'
338+OPENID_LAUNCHPAD_TEAMS_MAPPING = {
339+ 'linaro': 'linaro',
340+}
341+
342+# A sample logging configuration. The only tangible logging
343+# performed by this configuration is to send an email to
344+# the site admins on every HTTP 500 error.
345+# See http://docs.djangoproject.com/en/dev/topics/logging for
346+# more details on how to customize your logging configuration.
347+LOGGING = {
348+ 'version': 1,
349+ 'disable_existing_loggers': False,
350+ 'handlers': {
351+ 'mail_admins': {
352+ 'level': 'ERROR',
353+ 'class': 'django.utils.log.AdminEmailHandler'
354+ }
355+ },
356+ 'loggers': {
357+ 'django.request': {
358+ 'handlers': ['mail_admins'],
359+ 'level': 'ERROR',
360+ 'propagate': True,
361+ },
362+ }
363+}
364+
365+SERVED_PATHS = ["{% x_send_file_path %}"]
366+
367+TEMPLATE_CONTEXT_PROCESSORS = (
368+ 'django.contrib.messages.context_processors.messages',
369+ 'django.contrib.auth.context_processors.auth',
370+)
371
372=== added file 'deployment_templates/wsgi.py'
373--- deployment_templates/wsgi.py 1970-01-01 00:00:00 +0000
374+++ deployment_templates/wsgi.py 2012-07-11 12:58:19 +0000
375@@ -0,0 +1,36 @@
376+"""
377+WSGI config for license_protected_downloads project.
378+
379+This module contains the WSGI application used by Django's development server
380+and any production WSGI deployments. It should expose a module-level variable
381+named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
382+this application via the ``WSGI_APPLICATION`` setting.
383+
384+Usually you will have the standard Django WSGI application here, but it also
385+might make sense to replace the whole Django WSGI application with a custom one
386+that later delegates to the Django one. For example, you could introduce WSGI
387+middleware here, or combine a Django application with an application of another
388+framework.
389+
390+"""
391+import os, sys
392+sys.path.append("/usr/lib/python2.7/dist-packages")
393+sys.path.append("/usr/lib/pymodules/python2.7")
394+sys.path.append("/usr/lib/python2.7")
395+sys.path.append("{% django_root %}")
396+sys.path.append("{% deploy_root %}")
397+
398+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{% django_directory_name %}.settings")
399+
400+# This application object is used by any WSGI server configured to use this
401+# file. This includes Django's development server, if the WSGI_APPLICATION
402+# setting points here.
403+#from django.core.wsgi import get_wsgi_application
404+#application = get_wsgi_application()
405+
406+import django.core.handlers.wsgi
407+application = django.core.handlers.wsgi.WSGIHandler()
408+
409+# Apply WSGI middleware here.
410+# from helloworld.wsgi import HelloWorldApplication
411+# application = HelloWorldApplication(application)

Subscribers

People subscribed via source and target branches