Posted By

mandric on 04/11/08


Tagged

Bash script unix linux debian fastcgi trac django fcgi wsgi


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

webology


Bootstrap a Django setup


 / Published in: Bash
 

This is meant to be run as root, so do it at your own risk. It's very raw and needs error checking, but works. I run this script to get new django sites off the ground in a few minutes.

  1. #!/bin/bash
  2. # Create a django skeleton.
  3. # Dir structure looks like:
  4. #~example/
  5. # bin
  6. # sites
  7. # example.com
  8. # |-- lib
  9. # | `-- example
  10. # | |-- media
  11. # | `-- templates
  12. # |-- logs
  13. # |-- public
  14. # | |-- admin_media -> /path/to/django/contrib/admin/media
  15. # | `-- media -> /home/example/sites/example.com/lib/example/media
  16. # |-- static
  17. # |-- trac
  18. # |-- uploads
  19.  
  20.  
  21. if [ -z $1 ] ; then
  22. echo 'Please specify a username.'
  23. exit
  24. fi
  25.  
  26. if [ -z $2 ] ; then
  27. echo 'Please specify a domain name.'
  28. exit
  29. fi
  30.  
  31. USER=$1
  32. PROJECT=$USER
  33. SITE=$2
  34. USER_PASS=`makepasswd --chars=15`
  35. DB_PASS=`makepasswd --chars=25`
  36. SECRET_KEY=`makepasswd --chars=128`
  37. HOME_DIR=/home/$USER
  38. LIB_DIR=$HOME_DIR/sites/$SITE/projects
  39.  
  40. bootstrap_user () {
  41. echo "rand user pass: $USER_PASS"
  42. echo "Creating $USER"
  43. # add unix user
  44. adduser $USER --force-badname
  45.  
  46. mkdir $HOME_DIR/sites/$SITE -p
  47. mkdir $LIB_DIR
  48. mkdir $HOME_DIR/sites/$SITE/logs
  49. mkdir $HOME_DIR/sites/$SITE/public
  50. mkdir $HOME_DIR/sites/$SITE/static
  51. mkdir $HOME_DIR/sites/$SITE/uploads
  52. mkdir $HOME_DIR/bin
  53. }
  54.  
  55.  
  56.  
  57. create_database () {
  58. # Create database
  59. NAME=$PROJECT
  60. USER=$USER
  61. echo "$USER db pass: $DB_PASS"
  62. echo "enter mysql root pass"
  63. mysql -u root -p << EOF
  64. create database $NAME default character set = 'utf8' default collate = 'utf8_general_ci';
  65. GRANT ALL ON ${NAME}.* TO '${NAME}'@'localhost' IDENTIFIED BY '${DB_PASS}';
  66. flush privileges;
  67. EOF
  68. }
  69.  
  70. # Setup Trac
  71. setup_trac() {
  72. mkdir -p $HOME_DIR/sites/$SITE/trac/env
  73. mkdir $HOME_DIR/sites/$SITE/trac/repos
  74. trac-admin $HOME_DIR/sites/$SITE/trac/env initenv
  75. svnadmin create $HOME_DIR/sites/$SITE/trac/repos/
  76.  
  77. cat >>$HOME_DIR/sites/$SITE/public/trac.fcgi <<EOF
  78. #!/usr/bin/python
  79. # -*- coding: utf-8 -*-
  80. #
  81. # Copyright (C) 2003-2004 Edgewall Software
  82. # Copyright (C) 2003-2004 Jonas Borgström <[email protected]>
  83. # All rights reserved.
  84. #
  85. # This software is licensed as described in the file COPYING, which
  86. # you should have received as part of this distribution. The terms
  87. # are also available at http://trac.edgewall.org/wiki/TracLicense.
  88. #
  89. # This software consists of voluntary contributions made by many
  90. # individuals. For the exact contribution history, see the revision
  91. # history and logs, available at http://trac.edgewall.org/log/.
  92. #
  93. # Author: Jonas Borgström <[email protected]>
  94.  
  95. # for andric.us
  96. import os
  97.  
  98. os.environ['TRAC_ENV'] = '${HOME_DIR}/sites/${SITE}/trac/env'
  99.  
  100. try:
  101. from trac.web import fcgi_frontend
  102. fcgi_frontend.run()
  103. except SystemExit:
  104. raise
  105. except Exception, e:
  106. print 'Content-Type: text/plain
  107.  
  108. ',
  109. print 'Oops...'
  110. print
  111. print 'Trac detected an internal error:'
  112. print
  113. print e
  114. print
  115. import traceback
  116. import StringIO
  117. tb = StringIO.StringIO()
  118. traceback.print_exc(file=tb)
  119. print tb.getvalue()
  120. EOF
  121. }
  122.  
  123.  
  124. create_wsgi () {
  125. # Copy .htaccess and dispatch.wsgi into public dir
  126. # This also depends on the proper configuration in apache.
  127. cat >>$HOME_DIR/sites/$SITE/public/dispatch.wsgi <<EOF
  128. #!/usr/bin/python2.5
  129. import sys, os
  130.  
  131. # make stdout go to stderr for wsgi apps
  132. sys.stdout = sys.stderr
  133.  
  134. USERNAME = '$USER'
  135. SITE = '$SITE'
  136. PROJECT = '$USER'
  137.  
  138. # Add a custom Python path.
  139. sys.path.insert(0, "/home/%s/sites/%s/projects" % (USERNAME,SITE) )
  140. os.environ['PYTHON_EGG_CACHE'] = '/home/%s/sites/%s/.python-eggs'
  141. # Import our django handler
  142. import django.core.handlers.wsgi
  143.  
  144. # Set the DJANGO_SETTINGS_MODULE environment variable.
  145. os.environ['DJANGO_SETTINGS_MODULE'] = "%s.settings" % PROJECT
  146. application = django.core.handlers.wsgi.WSGIHandler()
  147. EOF
  148. }
  149.  
  150. create_fcgi () {
  151. # Add .htaccess only under fcgi
  152. cat >>$HOME_DIR/sites/$SITE/public/.htaccess <<EOF
  153. RewriteEngine On
  154. RewriteBase /
  155. #RewriteCond %{REQUEST_FILENAME} !-f
  156. #RewriteCond %{REQUEST_FILENAME} !-d
  157. RewriteRule ^(media/.*)$ - [L]
  158. RewriteRule ^(admin_media/.*)$ - [L]
  159.  
  160. # rewrite trac/ requests so they get served by trac.fcgi
  161. RewriteRule ^(trac\.fcgi/.*)$ - [L]
  162. RewriteRule ^trac/(.*)$ trac.fcgi/\$1 [L]
  163.  
  164. # rewrite everything else to disptach.fcgi
  165. RewriteRule ^(dispatch\.fcgi/.*)$ - [L]
  166. RewriteRule ^(.*)$ dispatch.fcgi/\$1 [QSA,L]
  167. EOF
  168.  
  169. cat >>$HOME_DIR/sites/$SITE/public/dispatch.fcgi <<EOF
  170. #!/usr/bin/python
  171. import sys, os
  172.  
  173. USERNAME = '$USER'
  174. SITE = '$SITE'
  175. PROJECT = '$USER'
  176.  
  177. # Add a custom Python path.
  178. sys.path.insert(0, "/home/%s/sites/%s/apps/%s" % (USERNAME,SITE,PROJECT) )
  179. sys.path.insert(0, "/home/%s/lib/python" % (USERNAME,) )
  180.  
  181. # Switch to the directory of your project.
  182. #os.chdir("/home/%s/dev/" % (USERNAME,) )
  183.  
  184. # Set the DJANGO_SETTINGS_MODULE environment variable.
  185. os.environ['DJANGO_SETTINGS_MODULE'] = "%s.settings" % PROJECT
  186.  
  187. from django.core.servers.fastcgi import runfastcgi
  188. runfastcgi(method="threaded", daemonize="false")
  189. EOF
  190.  
  191. echo "make dispatch.fcgi executable"
  192. chmod +x $HOME_DIR/sites/$SITE/public/dispatch.fcgi
  193. }
  194.  
  195. setup_django () {
  196. # Build django project
  197. cd $LIB_DIR && \
  198. /usr/bin/django-admin.py startproject $PROJECT && \
  199. cd $PROJECT && \
  200. mkdir media && \
  201. mkdir templates
  202.  
  203. # Link in media dirs
  204. cd $HOME_DIR/sites/$SITE/public
  205. ln -s /usr/lib/python2.4/site-packages/django/contrib/admin/media admin_media
  206. ln -s $LIB_DIR/$PROJECT/media .
  207. create_wsgi
  208. #create_fcgi
  209.  
  210. # Add local override trick to settings.py
  211. cat >> $LIB_DIR/$PROJECT/settings.py <<EOF
  212.  
  213. # allow local settings to override
  214. try:
  215. from local_settings import *
  216. except ImportError, exp:
  217. pass
  218.  
  219. EOF
  220.  
  221. echo "Adding overrides to local_settings.py"
  222. cat >> $LIB_DIR/$PROJECT/local_settings.py <<EOF
  223. import os
  224. DATABASE_ENGINE='mysql'
  225. DATABASE_NAME='${PROJECT}'
  226. DATABASE_USER='${USER}'
  227. DATABASE_PASSWORD='${DB_PASS}'
  228. TIME_ZONE = 'America/Chicago'
  229. # Make this unique, and don't share it with anybody.
  230. SECRET_KEY = '${SECRET_KEY}'
  231.  
  232. TEMPLATE_DIRS = (
  233. os.path.join (os.getcwd(), 'templates'),
  234. '$LIB_DIR/$PROJECT/templates',
  235. )
  236.  
  237. MEDIA_ROOT = '$LIB_DIR/$PROJECT/media/'
  238.  
  239. MIDDLEWARE_CLASSES = (
  240. 'django.middleware.common.CommonMiddleware',
  241. 'django.contrib.sessions.middleware.SessionMiddleware',
  242. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  243. 'django.middleware.cache.CacheMiddleware',
  244. 'django.middleware.doc.XViewMiddleware',
  245. 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
  246. )
  247.  
  248. INSTALLED_APPS = (
  249. 'django.contrib.auth',
  250. 'django.contrib.contenttypes',
  251. 'django.contrib.sessions',
  252. 'django.contrib.sites',
  253. 'django.contrib.admin',
  254. 'django.contrib.markup',
  255. 'template_utils',
  256. 'django.contrib.flatpages',
  257. )
  258. ADMIN_MEDIA_PREFIX = '/admin_media/'
  259.  
  260. EOF
  261.  
  262.  
  263. echo "local_settings has a pw in it, so only allow read from owner."
  264. echo "chmod 400 $LIB_DIR/$PROJECT/local_settings.py"
  265. chmod 400 $LIB_DIR/$PROJECT/local_settings.py
  266.  
  267. echo "Configure django apps by hand ..."
  268. echo "$LIB_DIR/$PROJECT/local_settings.py"
  269.  
  270. # Hardening app
  271. cd $HOME_DIR && \
  272. find . -name \*.py -type f -exec chmod -w {} \;
  273. find . -type d -exec chmod -w {} \;
  274.  
  275. }
  276.  
  277. cleanup_perms () {
  278. # Make sure everything in user dir is owned by user
  279. echo "Finalizing some permissions ..."
  280. echo "chown -R $USER $HOME_DIR"
  281. chown -R $USER:$USER $HOME_DIR
  282.  
  283. echo "chmod +w $HOME_DIR"
  284. chmod +w $HOME_DIR
  285.  
  286. # Chown logs dir as root
  287. echo "chown root $HOME_DIR/sites/$SITE/logs"
  288. chown root $HOME_DIR/sites/$SITE/logs
  289.  
  290. echo "chmod +w $HOME_DIR/sites/$SITE/logs"
  291. chmod +w $HOME_DIR/sites/$SITE/logs
  292. }
  293.  
  294. bootstrap_user
  295. create_database
  296. setup_django
  297. #setup_trac
  298. cleanup_perms

Report this snippet  

You need to login to post a comment.