pulling in nginx config
[oweals/karmaworld.git] / fabfile.py
1
2 """ Karmaworld Fabric management script
3     Finals Club (c) 2013"""
4
5 import os
6 import ConfigParser
7
8 from fabric.api import cd, env, lcd, prefix, run, sudo, task, local, settings
9 from fabric.contrib import files
10
11 ######### GLOBAL
12 env.user = 'vagrant'
13 env.group = 'vagrant'
14 env.proj_repo = 'git@github.com:FinalsClub/karmaworld.git'
15 env.repo_root = '~/karmaworld'
16 env.proj_root = '/var/www/karmaworld'
17 env.branch = 'prod'
18 env.code_root = env.proj_root
19 env.env_root = env.proj_root
20 env.supervisor_conf = '{0}/confs/{1}/supervisord.conf'.format(env.code_root, env.branch)
21
22 ######## Define host(s)
23 def here():
24     """
25     Connection information for the local machine
26     """
27     def _custom_local(command):
28         prefixed_command = '/bin/bash -l -i -c "%s"' % command
29         return local(prefixed_command)
30
31     # This is required for the same reason as above
32     env.proj_root = '/var/www/karmaworld'
33     env.cd = lcd
34     env.reqs = 'reqs/dev.txt'
35     env.confs = 'confs/beta'
36     env.branch = 'beta'
37
38
39
40 ####### Define production host
41 @task
42 def prod():
43     """
44     Connection Information for production machine
45     """
46
47     env.user = 'djkarma'
48     env.hosts = ['karmanotes.org']
49     env.proj_root = '/var/www/karmaworld'
50     env.reqs = 'reqs/prod.txt'
51     env.confs = 'confs/prod/'
52     env.branch = 'beta'
53     env.gunicorn_addr = '127.0.0.1:8000'
54
55 ####### Define beta host
56 @task
57 def beta():
58     """
59     Connection Information for beta machine
60     """
61
62     env.user = 'djkarma'
63     env.hosts = ['beta.karmanotes.org']
64     env.proj_root = '/var/www/karmaworld'
65     env.reqs = 'reqs/prod.txt'
66     env.confs = 'confs/prod/'
67     env.branch = 'beta'
68
69 ######## Run Commands in Virutal Environment
70 def virtenv_path():
71     """
72     Builds the virtualenv path.
73     """
74     # not much here now, but maybe useful later.
75     return env.env_root
76
77 def virtenv_exec(command):
78     """
79     Execute command in Virtualenv
80     """
81
82     path = virtenv_path()
83     with prefix('source {0}/bin/activate'.format(path)):
84         run(command)
85
86 ######## Sync database
87 @task
88 def syncdb():
89     """
90     Sync Database
91     """
92     virtenv_exec('{0}/manage.py syncdb --migrate'.format(env.code_root))
93
94
95 ####### Collect Static Files
96 @task
97 def collect_static():
98         """
99         Collect static files (if AWS config. present, push to S3)
100         """
101
102         virtenv_exec('%s/manage.py collectstatic --noinput' % env.code_root )   
103
104 ####### Run Dev Server
105 @task
106 def dev_server():
107         """
108         Runs the built-in django webserver
109         """
110
111         virtenv_exec('%s/manage.py runserver' % env.code_root)  
112
113 ####### Create Virtual Environment
114
115 @task
116 def link_code():
117     """
118     Link the karmaworld repo into the appropriate production location
119     """
120     if not files.exists(env.code_root):
121         run('ln -s {0} {1}'.format(env.repo_root, env.code_root))
122
123 @task
124 def make_virtualenv():
125     """
126     Create our Virtualenv
127     """
128     run('virtualenv {0}'.format(virtenv_path()))
129
130 @task
131 def start_supervisord():
132     """
133     Starts supervisord
134     """
135     virtenv_exec('supervisord -c {0}'.format(env.supervisor_conf))
136
137
138 @task
139 def stop_supervisord():
140     """
141     Restarts supervisord
142     """
143     virtenv_exec('supervisorctl -c {0} shutdown'.format(env.supervisor_conf))
144
145
146 @task
147 def restart_supervisord():
148     """
149     Restarts supervisord
150     """
151     stop_supervisord()
152     start_supervisord()
153
154
155 def supervisorctl(action, process):
156     """
157     Takes as arguments the name of the process as is
158     defined in supervisord.conf and the action that should
159     be performed on it: start|stop|restart.
160     """
161     virtenv_exec('supervisorctl -c {0} {1} {2}'.format(env.supervisor_conf, action, process))
162
163
164 @task
165 def start_celeryd():
166     """
167     Starts the celeryd process
168     """
169     supervisorctl('start', 'celeryd')
170
171
172 @task
173 def stop_celeryd():
174     """
175     Stops the celeryd process
176     """
177     supervisorctl('stop', 'celeryd')
178
179
180 @task
181 def restart_celery():
182     """
183     Restarts the celeryd process
184     """
185     supervisorctl('restart', 'celeryd')
186
187
188 @task
189 def start_gunicorn():
190     """
191     Starts the gunicorn process
192     """
193     supervisorctl('start', 'gunicorn')
194
195
196 @task
197 def stop_gunicorn():
198     """
199     Stops the gunicorn process
200     """
201     supervisorctl('stop', 'gunicorn')
202
203
204 @task
205 def restart_gunicorn():
206     """
207     Restarts the gunicorn process
208     """
209     supervisorctl('restart', 'gunicorn')
210
211
212 ####### Update Requirements
213 @task
214 def update_reqs():
215     virtenv_exec('pip install -r {0}/reqs/{1}.txt'.format(env.repo_root, env.branch))
216
217 ####### Pull new code
218 @task
219 def update_code():
220     virtenv_exec('cd %s; git pull' % env.proj_root )
221
222 def backup():
223     """
224     Create backup using bup
225     """
226     pass
227
228 @task
229 def file_setup():
230     """
231     Deploy expected files and directories from non-apt system services.
232     """
233     ini_parser = ConfigParser.SafeConfigParser()
234     if not ini_parser.read(env.supervisor_conf):
235       raise Exception("Could not parse INI file {0}".format(env.supervisor_conf))
236     for section, option in (('supervisord','logfile'),
237                             ('supervisord','pidfile'),
238                             ('unix_http_server','file'),
239                             ('program:celeryd','stdout_logfile')):
240       filepath = ini_parser.get(section, option)
241       # generate file's directory structure if needed
242       run('mkdir -p {0}'.format(os.path.split(filepath)[0]))
243       # touch a file and change ownership if needed
244       if 'log' in option and not files.exists(filepath):
245           sudo('touch {0}'.format(filepath))
246           sudo('chown {0}:{1} {2}'.format(env.user, env.group, filepath))
247
248 @task
249 def check_secrets():
250     """
251     Ensure secret files exist for syncdb to run.
252     """
253
254     secrets_path = env.code_root + '/karmaworld/secret'
255     secrets_files = ('filepicker.py', 'static_s3.py', 'db_settings.py')
256
257     errors = []
258     for sfile in secrets_files:
259         ffile = os.path.sep.join((secrets_path,sfile))
260         if not files.exists(ffile):
261             errors.append('{0} missing. Please add and try again.'.format(ffile))
262     if errors:
263         raise Exception('\n'.join(errors))
264
265 @task
266 def first_deploy():
267     """
268     Sets up and deploys the project for the first time.
269     """
270     link_code()
271     make_virtualenv()
272     file_setup()
273     check_secrets()
274     update_reqs()
275     syncdb()
276     start_supervisord()
277
278
279 @task
280 def deploy():
281     """
282     Deploys the latest changes
283     """
284     update_code()
285     update_reqs()
286     syncdb()
287     collect_static()
288     restart_supervisord()
289 ########## END COMMANDS