2 """ Karmaworld Fabric management script
3 Finals Club (c) 2013"""
8 from fabric.api import cd, env, lcd, prefix, run, sudo, task, local, settings
9 from fabric.contrib import files
14 env.proj_repo = 'git@github.com:FinalsClub/karmaworld.git'
15 env.repo_root = '~/karmaworld'
16 env.proj_root = '/var/www/karmaworld'
18 env.code_root = '{0}/{1}-code'.format(env.proj_root, env.branch)
19 env.supervisor_conf = '{0}/confs/{1}/supervisord.conf'.format(env.code_root, env.branch)
21 ######## Define host(s)
24 Connection information for the local machine
26 def _custom_local(command):
27 prefixed_command = '/bin/bash -l -i -c "%s"' % command
28 return local(prefixed_command)
30 # This is required for the same reason as above
31 env.proj_root = '/var/www/karmaworld'
33 env.reqs = 'reqs/dev.txt'
34 env.confs = 'confs/beta'
39 ####### Define production host
43 Connection Information for production machine
47 env.hosts = ['karmanotes.org']
48 env.proj_root = '/var/www/karmaworld'
49 env.reqs = 'reqs/prod.txt'
50 env.confs = 'confs/prod/'
52 env.gunicorn_addr = '127.0.0.1:8000'
54 ####### Define beta host
58 Connection Information for beta machine
62 env.hosts = ['beta.karmanotes.org']
63 env.proj_root = '/var/www/karmaworld'
64 env.reqs = 'reqs/prod.txt'
65 env.confs = 'confs/prod/'
68 ######## Run Commands in Virutal Environment
69 def virtenv_exec(command):
71 Execute command in Virtualenv
74 path = os.path.sep.join( (env.proj_root, env.branch) )
75 with prefix('source {0}/bin/activate'.format(path)):
78 ######## Sync database
84 virtenv_exec('{0}/manage.py syncdb --migrate'.format(env.code_root))
87 ####### Collect Static Files
91 Collect static files (if AWS config. present, push to S3)
94 virtenv_exec('%s/manage.py collectstatic --noinput' % env.proj_root )
96 ####### Run Dev Server
100 Runs the built-in django webserver
103 virtenv_exec('%s/manage.py runserver' % env.proj_root)
105 ####### Create Virtual Environment
107 def make_virtualenv():
109 Create our Virtualenv in env.proj_root
112 path = os.path.sep.join( (env.proj_root, env.branch) )
113 if not files.exists(path):
114 run('virtualenv {0}'.format(path))
115 if not files.exists(env.code_root):
116 run('ln -s {0} {1}'.format(env.repo_root, env.code_root))
119 def start_supervisord():
123 virtenv_exec('supervisord -c {0}'.format(env.supervisor_conf))
127 def stop_supervisord():
131 virtenv_exec('supervisorctl -c {0} shutdown'.format(env.supervisor_conf))
135 def restart_supervisord():
143 def supervisorctl(action, process):
145 Takes as arguments the name of the process as is
146 defined in supervisord.conf and the action that should
147 be performed on it: start|stop|restart.
149 virtenv_exec('supervisorctl -c {0} {1} {2}'.format(env.supervisor_conf, action, process))
155 Starts the celeryd process
157 supervisorctl('start', 'celeryd')
163 Stops the celeryd process
165 supervisorctl('stop', 'celeryd')
169 def restart_celery():
171 Restarts the celeryd process
173 supervisorctl('restart', 'celeryd')
177 def start_gunicorn():
179 Starts the gunicorn process
181 supervisorctl('start', 'gunicorn')
187 Stops the gunicorn process
189 supervisorctl('stop', 'gunicorn')
193 def restart_gunicorn():
195 Restarts the gunicorn process
197 supervisorctl('restart', 'gunicorn')
200 ####### Update Requirements
203 virtenv_exec('pip install -r {0}/reqs/{1}.txt'.format(env.repo_root, env.branch))
205 ####### Pull new code
208 virtenv_exec('cd %s; git pull' % env.proj_root )
212 Create backup using bup
219 Deploy expected files and directories from non-apt system services.
221 ini_parser = ConfigParser.SafeConfigParser()
222 if not ini_parser.read(env.supervisor_conf):
223 raise Exception("Could not parse INI file {0}".format(env.supervisor_conf))
224 for section, option in (('supervisord','logfile'),
225 ('supervisord','pidfile'),
226 ('unix_http_server','file'),
227 ('program:celeryd','stdout_logfile')):
228 filepath = ini_parser.get(section, option)
229 # generate file's directory structure if needed
230 run('mkdir -p {0}'.format(os.path.split(filepath)[0]))
231 # touch a file and change ownership if needed
232 if 'log' in option and not files.exists(filepath):
233 sudo('touch {0}'.format(filepath))
234 sudo('chown {0}:{1} {2}'.format(env.user, env.group, filepath))
239 Ensure secret files exist for syncdb to run.
242 secrets_path = env.code_root + '/karmaworld/secret'
243 secrets_files = ('filepicker.py', 'static_s3.py', 'db_settings.py')
246 for sfile in secrets_files:
247 ffile = os.path.sep.join((secrets_path,sfile))
248 if not files.exists(ffile):
249 errors.append('{0} missing. Please add and try again.'.format(ffile))
251 raise Exception('\n'.join(errors))
256 Sets up and deploys the project for the first time.
269 Deploys the latest changes
275 restart_supervisord()
276 ########## END COMMANDS