-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfabfile.py
executable file
·296 lines (241 loc) · 7.67 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
from fabric.api import task, local, env, settings
from fabric.operations import put
import cuisine
from cuisine import run, sudo, package_ensure
import re
import socket
from server.config import get_settings_prod
import paramiko
from fabric.contrib.files import sed, append
PACKAGES_TO_INSTALL = [
'libpq-dev',
'python-dev',
'nginx-extras',
'python-virtualenv',
'supervisor',
'postgresql-9.1',
'fail2ban',
'vim',
'tmux',
]
DD_API_KEY = '1234567890abcd' # Datadog api key.
AWS_HOST = 'api.mobackapp.com' # Amazon EC2 URL.
APP_NAME = 'moback' # Name of the application.
USER_NAME = APP_NAME # Username in which the app should be running.
# Say Hello
@task
def hello_world():
'''Just a test task to test connecitvity'''
run('echo "Hello World"')
# Vagrant
@task
def vagrant():
'''Vagrant!'''
host = '127.0.0.1'
port = '2222'
for line in local('vagrant ssh-config', capture=True).split('\n'):
match = re.search(r'Hostname\s+(\S+)', line)
if match:
host = match.group(1)
continue
match = re.search(r'User\s+(\S+)', line)
if match:
env.user = match.group(1)
continue
match = re.search(r'Port\s+(\S+)', line)
if match:
port = match.group(1)
continue
match = re.search(r'IdentityFile\s(.+)', line)
if match:
env.key_filename = match.group(1)
continue
env.hosts = ['{0}:{1}'.format(host, port)]
@task
def aws():
'''AWS config'''
host = AWS_HOST
port = 22
env.hosts = ['{0}:{1}'.format(host, port)]
env.user = 'ubuntu'
env.key_filename = 'moback.pem'
print 'HOST: ' + AWS_HOST
def update():
"""Update package list"""
with settings(linewise=True, warn_only=True):
sudo('apt-get -y update')
def upgrade():
"""Upgrade packages"""
with settings(linewise=True, warn_only=True):
sudo('aptitude -y upgrade')
def ensure_packages():
for pkg in PACKAGES_TO_INSTALL:
package_ensure(pkg)
def install_datadog():
sudo('DD_API_KEY=%s bash -c "$(curl'
' -L http://dtdg.co/agent-install-ubuntu)"' % (DD_API_KEY, ))
def create_user():
cuisine.user_ensure(
USER_NAME, home='/home/%s' % USER_NAME, shell='/bin/bash')
cuisine.group_user_ensure('www-data', USER_NAME)
def create_virtualenv():
if not cuisine.dir_exists('/home/%s/ENV' % USER_NAME):
sudo('virtualenv -q --distribute '
'/home/%s/ENV' % (
USER_NAME), user=USER_NAME)
def copy_source():
'''archive the git source and copy it'''
local('git archive $(git symbolic-ref HEAD 2>/dev/null)'
' | bzip2 > /tmp/%s.tar.bz2' % APP_NAME)
remote_filename = '/tmp/%s.tar.bz2' % APP_NAME
code_dir = '/home/%s/CODE' % APP_NAME
sudo('rm -rf %s' % code_dir)
if cuisine.file_exists(remote_filename):
sudo('rm %s' % remote_filename)
cuisine.file_upload(
remote_filename, '/tmp/%s.tar.bz2' % APP_NAME)
with cuisine.mode_sudo():
run('mkdir -p %s' % code_dir)
cuisine.file_attribs(remote_filename)
run('tar jxf %s -C %s' % (remote_filename, code_dir))
run('rm %s' % (remote_filename,))
def install_python_reqs():
sudo('. /home/%s/ENV/bin/activate &&'
' pip install -r /home/%s/CODE/requirements.txt'
% (USER_NAME, USER_NAME), user=USER_NAME)
def copy_confs():
nginx_conf_path = '/etc/nginx/sites-available/default'
sprvsr_conf_path = '/etc/supervisor/conf.d/moback.conf'
pghba_path = '/etc/postgresql/9.1/main/pg_hba.conf'
put('confs/nginx_default.conf',
nginx_conf_path, True)
put('confs/supervisord.conf', sprvsr_conf_path,
True, mode=0644)
put('confs/pg_hba.conf', pghba_path, True)
with cuisine.mode_sudo():
cuisine.file_attribs(
nginx_conf_path, owner='root', group='root')
cuisine.file_attribs(
sprvsr_conf_path, owner='root', group='root')
cuisine.file_attribs(
pghba_path, owner='root', group='root')
def setup_db():
cfg = get_settings_prod()
dbname = cfg["db"]["database"]
dbuser = cfg["db"]["username"]
dbpasswd = cfg["db"]["password"]
queries = [
"psql -d postgres -c "
"\"CREATE USER {dbuser} WITH PASSWORD"
" '{dbpasswd}';\"",
"psql -d postgres -c"
" \"GRANT SELECT, INSERT, UPDATE, DELETE ON ALL "
"TABLES IN SCHEMA public TO {dbuser};\"",
"psql -d postgres -c"
" \"GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA"
" public TO {dbuser};\"",
"psql -d postgres -c "
"\"GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public"
" TO {dbuser};\"",
"psql -c \"CREATE DATABASE"
" {dbname} WITH owner={dbuser};\"",
]
for q in queries:
try:
query = q.format(dbuser=dbuser, dbpasswd=dbpasswd, dbname=dbname)
sudo(query, user='postgres')
except:
pass
try:
sudo("psql -d moback -f /home/%s/CODE/extras/schema.sql" % USER_NAME,
user='moback')
except:
pass
def reboot():
sudo("shutdown -r 0")
def is_host_up(host, counter=0):
print('%d : Attempting connection to host: %s' %
(counter, host))
original_timeout = socket.getdefaulttimeout()
socket.setdefaulttimeout(1)
host_up = True
try:
paramiko.Transport((host, 22))
except Exception, e:
host_up = False
print('%s down, %s' % (host, e))
finally:
socket.setdefaulttimeout(original_timeout)
return host_up
def ping_untill_starts():
counter = 0
while not is_host_up(env.host, counter):
counter += 1
@task
def restart_server():
sudo('supervisorctl restart moback')
@task
def deploy_code():
'''Deploy latest commit and restart uwsgi'''
copy_source()
restart_server()
@task
def configure_ebs():
'''configure ebs volume for postgres befor executing this method
sudo su -
yes | mkfs -t ext3 /dev/xvdf
mkdir /data
mount /dev/xvdf /data
'''
with settings(warn_only=True):
with cuisine.mode_sudo():
run('service postgresql stop')
run('rm -rf /data/lost+found')
run('mkdir /data/lib/')
run('mkdir /data/lib/PostgreSQL')
run('mkdir /data/lib/PostgreSQL/9.1')
run('mkdir /data/lib/PostgreSQL/9.1/main')
run('cp -r /var/lib/postgresql/9.1/main /data/lib/PostgreSQL/9.1')
run('chown -R postgres:postgres /data/lib/PostgreSQL')
run('chmod 0700 /data/lib/PostgreSQL/9.1/main')
run('touch /data/moback.log')
run('chmod 777 /data/moback.log')
append(
'/etc/fstab',
'/dev/xvdf /data ext3 defaults 0 0', use_sudo=True)
sed('/etc/postgresql/9.1/main/postgresql.conf',
'/var/lib/postgresql/9.1/main',
'/data/lib/PostgreSQL/9.1/main',
use_sudo=True)
append(
'/etc/postgresql/9.1/main/postgresql.conf',
"listen_addresses = '*'", True)
with settings(warn_only=True):
with cuisine.mode_sudo():
run('service postgresql start')
run('service postgresql reload')
@task
def deploy_full(production='false'):
'''Fresh and full deploy'''
update()
upgrade()
ensure_packages()
install_datadog()
create_user()
create_virtualenv()
copy_source()
install_python_reqs()
copy_confs()
setup_db()
configure_ebs()
restart_server()
reboot()
ping_untill_starts()
@task
def ssh():
'''Open up ssh console'''
try:
if env.host == AWS_HOST:
local('ssh -i moback.pem ubuntu@' + AWS_HOST)
except:
pass