Skip to content

Instantly share code, notes, and snippets.

@jvanasco
Last active May 9, 2016 18:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jvanasco/499c47c9962026cb06df15c8dc46fc32 to your computer and use it in GitHub Desktop.
Save jvanasco/499c47c9962026cb06df15c8dc46fc32 to your computer and use it in GitHub Desktop.
Automated (mostly) Trac Installation for Dreamhost

Automated (mostly) Trac Installation

I have a trac instance for each subversion repo on my dreamhost account.

After a few years, I've accumulated many repos. There are too many to maintain by hand, so I've settled on a standardized deployment and use scipts to manage them.

Everything is organized as such:

  • ~/webroot/ main web directory
  • ~/webroot/svn.example.com domain for subversion/trac
  • ~/webroot/svn.example.com/{PROJECT} path for project webroot
  • ~/webroot/svn.example.com/{PROJECT}/svn path configured in control panel as repo url
  • ~/webroot/svn.example.com/{PROJECT}/trac trac url for repo
  • ~/svn/ dreamhosts's subversion directory
  • ~/svn_trac/ where I have trac instances
  • ~/svn_trac/{PROJECT} trac repo shares the same name as subversion repo
  • ~/svn_trac/trac-venv python virtualenv for trac
  • ~/svn_trac/trac-deploy exported trac files
  • ~/svn_trac/trac-MANAGEMENT management tools

trac is installed into a virtualenv that is used by all installations. my scripts deploy htaccess files that use the dreamhost-managed subversion htpasswd files for access; they also use symlinks to share the "static" assets from a single project. Enrolling projects into the system only requires adding a line to a text file.

first we need a virtualenv

cd ~
mkdir svn_trac
cd svn_trac
virtualenv trac-venv

i like to create a quick shellscript

vi go_trac.sh

> source trac-venv/bin/activate

then activate it ourselves

chmod 744 go_trac.sh
source go_trac.sh

we should see the prompt as (trac-venv)[user]$

install trac

make sure pip and easy_install are current

easy_install --upgrade pip
pip install --upgrade --force setuptools

then install trac

pip install trac

we need the subversion bindings...

thankfully these are on the machine already. just copy them to the local env

cd ~/svn_trac/trac-venv/lib/python2.7/site-packages/
cp -R /usr/lib/python2.7/dist-packages/libsvn .
cp -R /usr/lib/python2.7/dist-packages/svn .

we should be good to go...

make sure we're using the right trac-admin

cd ~/svn_trac
which trac-admin

that should show our trac-env version, not the server

if you don't have any projects...

cd ~/svn_trac
trac-admin MyProject initenv

deploy shared files

let's use one project to create the deployment files that all projects can use

we'll overwrite the ENV variables as needed

cd ~/svn_trac
trac-admin MyProject deploy trac-deploy
chmod +x trac-deploy/cgi-bin/trac.fcgi

setup our management

cd ~/svn_trac
mkdir trac-MANAGEMENT

two files go in there:

  • trac_sites.txt a listing of your projects. one per line.
  • deploy.py the script below

to deploy the sites:

cd ~/svn_trac/trac-MANAGEMENT
python deploy.py

what does the deploy script do?

The deploy script manages everything in webroot/svn.example.com

it does the following for PROJECTNAME:

  • creates a project directory ~/webroot/svn.example.com/PROJECTNAME
  • install an htaccess ~/webroot/svn.example.com/PROJECTNAME/.htaccess that references the subversion password file ~/svn/PROJECTNAME.passwd
  • install an index.html that points to /svn and /trac
  • creates a /trac directory
  • installs a /trac/.htaccess file that handles pretty urls and fcgi
  • installs a /trac/index.fcgi file that points to the ~/svn/PROJECTNAME repo, exports your virtualenv's path, and executes the trac invocation script in ~/svn_trac/trac-MANAGEMENT/cgi-bin
  • installs a symlink on /trac/chrome to the ~/svn_trac/trac-deploy/htdocs folder

edits to trac.ini

set the repo

repository_dir = /home/jvanasco/svn/APP


[components]
tracopt.versioncontrol.svn.svn_fs.* = enabled

[svn]
branches = trunk,branches/*
tags = tags/*
import os
username = 'johndoe'
svndomain = 'svn.example.com'
www_root = "/home/%(username)s/webroot/%(svndomain)s/" % {'username': username, 'svndomain': svndomain}
trac_root = "/home/%(username)s/svn_trac/" % {'username': username}
svn_root = "/home/%(username)s/svn" % {'username': username}
shared_chrome_dir = "/home/%(username)s/svn_trac/trac-deploy/htdocs" % {'username': username}
sites = [i.strip() for i in open('trac_sites.txt').readlines()]
template_main_htaccess = """
AuthType Basic
AuthUserFile /home/%(username)s/svn/%(site)s.passwd
AuthName "%(site)s"
require valid-user
RewriteEngine On
RewriteCond %%{HTTPS} off
RewriteRule (.*) https://%%{HTTP_HOST}%%{REQUEST_URI}
"""
template_trac_htaccess = """<Files *.cgi>
SetHandler fastcgi-script
</Files>
<Files *.fcgi>
SetHandler fastcgi-script
</Files>
DirectoryIndex index.fcgi
Options ExecCGI FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %%{HTTPS} off
RewriteRule (.*) https://%%{HTTP_HOST}%%{REQUEST_URI}
RewriteCond %%{DOCUMENT_ROOT}%%{REQUEST_FILENAME} !-d
RewriteCond %%{DOCUMENT_ROOT}%%{REQUEST_FILENAME} !-f
RewriteCond $1 !^index.fcgi/(.*)
# Keep the graphics and style sheet the way they are
RewriteCond $1 !^(.*).css$
RewriteCond $1 !^(.*).gif$
RewriteCond $1 !^(.*).jpg$
RewriteCond $1 !^(.*).png$
RewriteRule ^(.*)$ index.fcgi/$1 [L]
</IfModule>
"""
template_main_index = """<ul>
<li><a href="trac/">trac - issue tracker & source code browser</a></li>
<li><a href="svn/">svn - subversion repository</a></li>
</ul>"""
template_trac_index_fcgi = """#!/bin/bash
export TRAC_ENV="/home/%(username)s/svn_trac/%(site)s"
export PYTHONPATH=/home/%(username)s/svn_trac/trac-venv/lib/python2.7/site-packages:$PYTHONPATH
export LD_LIBRARY_PATH=/home/%(username)s/svn_trac/trac-venv/lib
exec /home/%(username)s/svn_trac/trac-deploy/cgi-bin/trac.fcgi
"""
if __name__ == '__main__':
for site in sites:
site_dir = "%s/%s" % (www_root, site)
if not os.path.exists(site_dir):
print "mkdir %s" % site_dir
os.mkdir(site_dir)
site_htaccess = "%s/.htaccess" % site_dir
print "writing %s" % site_htaccess
open(site_htaccess, "w")\
.write(template_main_htaccess % {'site': site, 'username': username})
os.chmod(site_htaccess, 755)
site_index = "%s/index.html" % site_dir
print "writing %s" % site_index
open(site_index, "w")\
.write(template_main_index % {'site': site, 'username': username, })
os.chmod(site_index, 755)
trac_dir = "%s/trac" % site_dir
if not os.path.exists(trac_dir):
print "mkdir %s" % trac_dir
os.mkdir(trac_dir)
trac_htaccess = "%s/.htaccess" % trac_dir
print "writing %s" % trac_htaccess
open(trac_htaccess, "w")\
.write(template_trac_htaccess % {'site': site, 'username': username, })
os.chmod(trac_htaccess, 755)
trac_index = "%s/index.fcgi" % trac_dir
open(trac_index, "w")\
.write(template_trac_index_fcgi % {'site': site, 'username': username, })
os.chmod(trac_index, 755)
trac_chrome = "%s/chrome" % trac_dir
if os.path.exists(trac_chrome):
if os.path.islink(trac_chrome):
os.path.unlink(trac_chrome)
os.symlink(shared_chrome_dir, trac_chrome)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment