Login

pavement file for deploying django projects

Author:
bl4th3rsk1t3
Posted:
May 23, 2009
Language:
Python
Version:
1.0
Score:
1 (after 1 ratings)

This is the pavement file I use to deploy a django site. It's in early stages. Right now it copies everything up to the desired server over scp. But I think I'll change it to rsync in the future.

It requires pavement, and pexpect.

The pavement file takes slight instruction from your settings.py file. For server information, and "lib_apps" to copy into the lib directory.

An example of a settings file that I use with this pavement file: http://gitweb.codeendeavor.com/?p=django_empty.git;a=blob_plain;f=settings.py;h=23bda7d2a1eb2a52ca0859004ecccd206dade4ec;hb=5d672178dab282caeed5ff0de7ed807c72e44f74

Specifically, check out the bottom for two vars: "LIB_APPS" and "DEPLOYMENTS"

A good example of my empty django project is here: http://gitweb.codeendeavor.com/?p=django_empty.git;a=tree;h=5d672178dab282caeed5ff0de7ed807c72e44f74;hb=5d672178dab282caeed5ff0de7ed807c72e44f74

I think the one thing that's missing is a way to re-spawn fcgi processes. Which I'll hopefully get around to adding sometime soon.

Also, I need to do a little work at making sure source control files don't get pushed through scp.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import os,sys,shutil,pexpect
sys.path.insert(0,os.path.abspath("."))
from paver.easy import *
import settings

"""
Pavement file to help with deploying django.
"""

@task
@cmdopts([
	("server=","s","The server to deploy to, this should be a key in the DEPLOYMENTS hash in django settings"),
	("config=","c","The config file to use as the settings.py, (any file in the ./configs/ folder)"),
	("password=","p","The password for the target servers' username, for scp file copying."),
	("quiet","q","Whether or not the scp copy is quiet")
])
def deploy(options):
	"""
	Deploy this project using a deployment option from the settings file.
	Your settings file needs to have a "DEPLOYMENTS" hash available, ex:
	DEPLOYMENTS={
		'slicehost':{
			'ip':'67.23.1.83',
			'user':'admin',
			'dir':'/var/www/vhosts/aaron/cherokee/project/'
		}
	}
	"""
	if not hasattr(options,"server"):
		print "the server parameter is required, run 'paver deploy help'."
		exit()
	if not settings.DEPLOYMENTS.get(options.server):
		print "The server you supplied does not exist in the DEPLOYMENT hash in your settings file."
		print "Not doing anything."
		exit()
	server=settings.DEPLOYMENTS[options.server]
	if not server.get("user",False):
		print "The target server doesn't have a 'user' key."
		print "Not doing anything."
		exit()
	if not server.get("ip",False):
		print "The target server doesn't have an 'ip' key."
		print "Not doing anything."
		exit()
	if not server.get("dir",False):
		print "The target server doesn't have a 'dir' key."
		print "Not doing anything."
		exit()
	if not server.get("password",False) and not hasattr(options,"password"):
		print "The target server doesn't have a 'password' key, and you didn't specify the 'password' switch, I need the password from one or the other."
		print "Not doing anything."
		exit()
	settingfile=os.path.abspath("settings.py")
	tmp_setting=os.path.abspath("settings_tmp.py")
	moved_tmp=False
	if os.path.exists(settingfile):
		moved_tmp=True
		shutil.move(settingfile,tmp_setting)
	preplibapps(options)
	if moved_tmp: shutil.move(tmp_setting,settingfile)
	mvconfig(options)
	if hasattr(options,"quiet"): child=pexpect.spawn('scp -r -q '+os.path.abspath(".")+' '+server.get("user")+"@"+server.get("ip")+":"+server.get("dir"))
	else: child=pexpect.spawn('scp -r '+thispath+' '+server.get("user")+"@"+server.get("ip")+":"+server.get("dir"))
	child.expect('.ssword:*')
	child.sendline(options.password)
	child.interact()

@task
@cmdopts([
	("config=","c","The config file to use as the settings.py, (any file in the ./configs/ folder)")
])
def mvconfig(options):
	"""copy a saved config file from configs/ to settings.py"""
	if not hasattr(options,"config"):
		print "The config parameter is required, run 'paver help deploy'"
		print "Not doing anything."
		exit()
	setting=os.path.abspath("./configs/"+options.config+".py")
	if not os.path.exists(setting):
		print "The file "+setting+" doesn't exist"
		print "Not doing anything."
		exit()
	copyto=os.path.abspath("settings.py")
	print "copying file "+setting+" to "+copyto
	shutil.copy(setting,copyto)

@task
def preplibapps():
	"""
	Move lib apps into libs folder. Your settings file should have a LIB_APPS tuple available. EX:
	--
	LIB_APPS=(
		'dilla',
		'antaresia',
		'debug_toolbar',
	)
	INSTALLED_APPS=(...)
	INSTALLED_APPS+=LIB_APPS
	--
	Every library app needs to be discoverable in your python path.
	"""
	if not hasattr(settings,"LIB_APPS"):
		print "your settings module needs to have a LIB_APPS tuple, it wasn't found."	
		exit()
	lib_apps=settings.LIB_APPS
	paths=sys.path
	found_apps={}
	libappsdir=os.path.abspath("libs")
	if os.path.exists(libappsdir): shutil.rmtree(libappsdir)
	for path in paths:
		for app in lib_apps:
			if found_apps.get(app,None): continue
			apppath=os.path.abspath(path+"/"+(app.replace(".","/"))+"/")
			if os.path.exists(apppath):
				found_apps[app]=True
				shutil.copytree(apppath,("./libs/"+app+"/"))
	for app in lib_apps:
		if not found_apps.get(app,None):
			print "App "+app+" was not found, and cannot be copied into the vedor/apps directory. Make sure it's in your python path."
	os.system("touch ./libs/__init__.py")

@task
@cmdopts([
	("config=","c","The new name of the config file (without .py), which get's stored in configs/")
])
def savesettingsas(options):
	"""Save the current settings.py file as another config file in the configs/ directory."""
	if not hasattr(options,"config"):
		print "The config switch is required, run paver help savesettingsas for more info."
		print "Not doing anything."
		exit()
	setting=os.path.abspath("settings.py")
	dest=os.path.abspath("./configs/"+options.config+".py")
	if not os.path.exists(setting):
		print "settings.py doesn't exist, not doing anything."
		exit()
	shutil.copy(setting,dest)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

vizualbod (on May 30, 2009):

Best way to re-spawn fcgi processes is to use mod_wsgi :) Learned the hard way.

#

Please login first before commenting.