-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathfabfile.py
More file actions
175 lines (130 loc) · 4.49 KB
/
fabfile.py
File metadata and controls
175 lines (130 loc) · 4.49 KB
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
from __future__ import print_function
import json
from fabric.api import env, task, prefix, run, cd, shell_env, sudo
from fabric.colors import red, yellow, green, blue
import requests
class DeployFailException:
pass
@task
def post_to_slack(message):
requests.post(
'https://hooks.slack.com/services/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',
data={'payload': json.dumps({'text': message})},
)
def configure_env():
env.hosts = env.apps + env.workers
env.forward_agent = True
env.user = 'deploy'
env.bin = '/data/virtualenv/{venv_name}/bin'.format(**env)
env.activate = '{bin}/activate'.format(**env)
env.python = '{bin}/python'.format(**env)
env.pip = '{bin}/pip'.format(**env)
env.dir = '/data/web/{domain}'.format(**env)
@task(alias='prod')
def production():
env.venv_name = 'spendwell'
env.domain = 'spendwell.co'
env.settings = 'spendwell.settings.production'
env.branch = 'master'
env.apps = ['72.51.30.238', '107.6.24.166']
env.workers = ['72.51.29.172']
configure_env()
@task(alias='stag')
def staging(branch='develop'):
env.venv_name = 'spendwell'
env.domain = 'staging.spendwell.co'
env.settings = 'spendwell.settings.staging'
env.branch = branch
env.apps = ['162.248.180.146']
env.workers = ['72.51.29.189']
configure_env()
@task
def pip_requirements():
with prefix('source {activate}'.format(**env)):
with cd(env.dir):
run('{pip} install -U -r requirements.txt'.format(**env))
@task
def migrate():
with prefix('source {activate}'.format(**env)):
with shell_env(DJANGO_SETTINGS_MODULE=env.settings):
with cd(env.dir):
run('./manage.py migrate'.format(**env))
@task
def npm_install():
if env.host in env.workers:
return
with cd(env.dir):
run('npm install')
@task
def npm_build():
if env.host in env.workers:
return
with prefix('source {activate}'.format(**env)):
with shell_env(DJANGO_SETTINGS_MODULE=env.settings):
with cd(env.dir):
run('npm run build-prod')
@task
def collectstatic():
with prefix('source {activate}'.format(**env)):
with shell_env(DJANGO_SETTINGS_MODULE=env.settings):
with cd(env.dir):
run('./manage.py collectstatic --noinput'.format(**env))
@task
def supervisor_status():
if env.host in env.workers:
process_name = 'celery-celeryd'
else:
process_name = 'gunicorn-{domain}'.format(**env)
running = 'RUNNING' in sudo('/usr/bin/supervisorctl status {}'.format(process_name), shell=False)
if running:
print(green('supervisor running'))
else:
print(red('supervisor not running'))
return running
@task
def supervisor_restart():
if env.host in env.workers:
sudo('/usr/bin/supervisorctl restart celery-celeryd', shell=False)
else:
sudo(
'/usr/bin/supervisorctl status gunicorn-{domain} | '
'sed "s/.*[pid ]\([0-9]\+\)\,.*/\\1/" | '
'xargs kill -HUP'.format(**env),
shell=False,
)
return supervisor_status()
@task
def deploy(force=False):
print(yellow('Deploying to'), blue(env.host))
try:
with cd(env.dir):
old_commit = run('git rev-parse HEAD')
run('git fetch')
run('git checkout origin/{branch}'.format(**env))
new_commit = run('git rev-parse HEAD')
changed = run('git --no-pager diff --name-only {} {}'.format(old_commit, new_commit))
if 'requirements.txt' in changed or force:
pip_requirements()
if 'migrations' in changed or force:
migrate()
package_change = 'package.json' in changed
if package_change or force:
npm_install()
client_change = package_change or 'client/' in changed or 'webpack' in changed
if client_change or force:
npm_build()
static_change = client_change or 'static' in changed
if static_change or force:
collectstatic()
if not supervisor_restart():
raise DeployFailException
except Exception as e:
print(red(e.message))
print(red('DEPLOY FAILED'))
post_to_slack('Deploy Failed! `{branch}` to `{domain}`: {}'.format(e.message, **env))
else:
print(green('DEPLOY SUCCEEDED!'))
post_to_slack('Deployed branch `{branch}` to `{domain}`'.format(**env))
@task
def full_deploy():
deploy(force=True)