forked from OpenTreeMap/otm-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fabfile.py
296 lines (214 loc) · 7.82 KB
/
fabfile.py
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
""" Fabric script to handle common building tasks """
from fabric.api import cd, run, require, sudo, env, local, settings, abort, get
from fabric.contrib.files import exists as host_exists
from fabric.colors import yellow
from fabric import operations
import os
env.use_ssh_config = True
def _set_default_paths(env):
""" Modify the fabric environment to have default otm paths set """
base_dir = '/usr/local/otm/'
if 'venv_path' not in env:
env.venv_path = os.path.join(base_dir, 'env')
if 'site_path' not in env:
env.site_path = os.path.join(base_dir, 'app', 'opentreemap')
if 'static_path' not in env:
env.static_path = os.path.join(base_dir, 'static')
_set_default_paths(env)
def vagrant():
""" Configure fabric to use vagrant as a host.
Use the current vagrant directory to gather ssh-config settings
for the vagrant VM. Write these settings to the fabric env.
This should prefix any commands to be run in this context.
EX:
fab vagrant <command_name>
"""
vagrant_ssh_config = {}
for l in local('vagrant ssh-config', capture=True).split('\n'):
try:
l = l.strip()
i = l.index(' ')
setting_name = l[:i].strip()
setting_value = l[i+1:].strip()
# Newer versions of vagrant will wrap certain params like
# IdentityFile in quotes, we need to strip them off
if (setting_value[:1] + setting_value[-1]) in ('\'\'', '""'):
setting_value = setting_value[1:-1]
vagrant_ssh_config[setting_name] = setting_value
except Exception, e:
pass
env.key_filename = vagrant_ssh_config['IdentityFile']
env.user = vagrant_ssh_config['User']
env.hosts = [vagrant_ssh_config['HostName']]
env.port = vagrant_ssh_config['Port']
def me():
""" Configure fabric to use localhost as a host.
This should prefix any commands to be run in this context.
EX:
fab me <command_name>
"""
env.hosts = ['localhost']
def _venv_exec(cmd):
require('venv_path')
return '%s/bin/%s' % (env.venv_path, cmd)
def _python(cmd, coverage=False):
require('venv_path')
if coverage:
bin = "coverage run --source='.'"
else:
bin = "python"
return _venv_exec('%s %s' % (bin, cmd))
def _report_coverage():
require('venv_path')
with cd(env.site_path):
run(_venv_exec('coverage report'))
def _fetch_coverage(local_path):
require('venv_path')
with cd("/tmp"):
# Clean up in case something was left over...
sudo('rm -rf htmlcov coverage.tar.gz')
with cd(env.site_path):
run(_venv_exec('coverage html -d /tmp/htmlcov'))
with cd("/tmp"):
run('tar czf coverage.tar.gz htmlcov')
get('/tmp/coverage.tar.gz', local_path)
sudo('rm -rf htmlcov coverage.tar.gz')
def _manage(cmd, coverage=False):
""" Execute 'cmd' as a django management command in the venv """
with cd(env.site_path):
sudo(_python('manage.py %s' % cmd, coverage=coverage))
def _admin(cmd):
""" Execute 'cmd' as a django-admin command in the venv """
sudo(_venv_exec('django-admin.py %s' % cmd))
def _collectstatic():
""" Collect static files. """
require('site_path')
require('venv_path')
with cd(env.site_path):
sudo('rm -rf "%s"' % env.static_path)
_manage('collectstatic --noinput')
def check():
""" Run flake8 (pep8 + pyflakes) and JSHint """
require('site_path')
with settings(warn_only=True):
local('npm install')
jshint = local('grunt --no-color check', capture=True)
print(jshint)
with cd(env.site_path):
flake8 = run(_venv_exec('flake8 --exclude migrations,opentreemap/local_settings.py *'))
if jshint.failed or flake8.failed:
abort('Code linting failed')
def bundle(dev_mode=False, skip_npm=False):
""" Update npm and bundle javascript """
if not skip_npm:
local('npm install')
local('grunt --no-color %s' % ("--dev" if dev_mode else ""))
def static(dev_mode=False):
""" Collect static files and bundle javascript. """
bundle(dev_mode)
_collectstatic()
def syncdb(dev_data=False):
""" Run syncdb and all migrations
Set dev_data to True to load in the development data
"""
require('site_path')
require('venv_path')
_manage('syncdb --noinput')
_manage('migrate --noinput')
if dev_data:
_manage('loaddata development_data.json')
def schemamigration(app_name, flag=' --auto'):
require('site_path')
require('venv_path')
_manage('schemamigration %s %s' % (app_name, flag))
def runserver(bind_to='0.0.0.0',port='12000'):
""" Run a python development server on the host """
require('site_path')
require('venv_path')
_manage('runserver %s:%s' % (bind_to, port))
def test(test_filter="", coverage=None):
""" Run app tests on the server """
require('site_path')
require('venv_path')
_manage('test %s' % test_filter,
coverage=coverage)
if coverage:
_report_coverage()
_fetch_coverage('coverage.tar.gz')
def uitest(test_filter="", coverage=False):
""" Run selenium UI tests """
require('site_path')
require('venv_path')
_manage('test --live-server-tests --liveserver=localhost:9000-9200 %s'
% test_filter,
coverage=coverage)
if coverage:
_report_coverage()
_fetch_coverage('coverage.tar.gz')
def restart_app():
""" Restart the gunicorns running the app """
sudo("service otm-unicorn restart")
def stop_app():
""" Stop the gunicorns running the app """
sudo("service otm-unicorn stop")
def start_app():
""" Start the gunicorns running the app """
sudo("service otm-unicorn start")
def app_status():
""" Query upstart for the status of the otm-unicorn app """
sudo("service otm-unicorn status")
def tiler_restart():
""" Restart the map tile service """
sudo("service tiler restart")
def tiler_stop():
""" Stop the map tile service """
sudo("service tiler stop")
def tiler_start():
""" Start the map tile service """
sudo("service tiler start")
def tiler_status():
""" Query upstart for the status of the map tile service """
sudo("service tiler status")
def _get_app_path(app):
if app is None:
raise Exception('app cannot be None')
require('site_path')
require('venv_path')
app_path = os.path.join(env.site_path, app)
if not host_exists(app_path):
raise Exception('The app path %s is not accessible' % app_path)
return app_path
###########
# i18n
#
I18N_APPS = ['treemap', 'ecobenefits']
def make_messages(locale=None):
for app in I18N_APPS:
make_messages_for_app(app, locale)
def make_messages_for_app(app, locale=None):
app_path = _get_app_path(app)
with cd(app_path):
print(yellow("Making messages in %s" % app_path))
if locale:
_admin('makemessages --locale %s' % locale)
_admin('makemessages -d djangojs --locale %s' % locale)
else:
_admin('makemessages --all')
_admin('makemessages -d djangojs --all')
def compile_messages():
for app in I18N_APPS:
compile_messages_for_app(app)
def compile_messages_for_app(app):
app_path = _get_app_path(app)
with cd(app_path):
_admin('compilemessages')
def django_shell():
""" Opens a python shell that connects to the django application """
operations.open_shell(command=_manage("shell"))
def dbshell():
""" Opens a psql shell that connects to the application database """
operations.open_shell(command=_manage("dbshell"))
def venv_shell():
""" Opens a bash shell with the application virtualenv activated """
operations.open_shell(command="cd %s && source %s/bin/activate" %
(env.site_path, env.venv_path))