-
Notifications
You must be signed in to change notification settings - Fork 9
/
fabfile.py
150 lines (117 loc) · 3.75 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
import os
from functools import wraps
from fabric.api import cd, env, run, task
from fabric.network import ssh
ssh.util.log_to_file('paramiko.log')
def _require_db(target):
"""Decorator to enforce env.read_only_db"""
@wraps(target)
def inner(*args, **kwargs):
if env.read_only_db:
raise Exception("This task cannot be performed on an environment with a read-only database.")
return target(*args, **kwargs)
return inner
@task
def alpheus():
"""Select the primary server for future commands."""
env.hosts = ['represent-alpheus.opennorth.ca']
env.user = 'represent'
env.read_only_db = False
_env_init()
@task
def tempeh():
"""Select the secondary server for future commands."""
env.hosts = ['represent-tempeh.opennorth.ca']
env.user = 'represent'
env.read_only_db = True
_env_init()
def _env_init():
env.home_dir = '/home/' + env.user
env.python = os.path.join(env.home_dir, '.pyenv', 'versions', 'represent', 'bin', 'python')
env.base_dir = os.path.join(env.home_dir)
env.django_dir = os.path.join(env.base_dir, 'app')
env.pip = env.python.replace('bin/python', 'bin/pip')
env.data_dir = os.path.join(env.django_dir, 'data')
@task
def deploy(ref='master'):
"""Perform all the steps in a standard deployment"""
pull(ref)
update_requirements()
if not env.read_only_db:
migrate()
update_statics()
restart()
@task
def pull(ref='master'):
"""Update the git repository to the given branch or tag"""
with cd(env.django_dir):
run('git fetch')
run('git fetch --tags')
run('git checkout %s' % ref)
is_tag = (ref == run('git describe --all %s' % ref).strip())
if not is_tag:
run('git pull origin %s' % ref)
@task
def update_requirements():
"""Update dependencies."""
with cd(env.django_dir):
run(env.pip + ' install -r requirements.txt')
@task
@_require_db
def migrate():
"""Update database schema."""
with cd(env.django_dir):
run(env.python + ' manage.py migrate')
@task
def update_statics():
"""Update static files."""
with cd(env.django_dir):
run(env.python + ' manage.py collectstatic --noinput')
@task
def restart():
"""Restart gunicorn."""
with cd(env.base_dir):
run('systemctl restart represent')
@task
@_require_db
def update_boundaries(args=''):
"""Pull data repositories and load shapefiles."""
_recursive_pull(env.data_dir)
with cd(env.django_dir):
run(env.python + ' manage.py loadshapefiles ' + args)
@task
@_require_db
def update_representatives():
"""Update all representatives."""
with cd(env.django_dir):
run(env.python + ' manage.py updaterepresentatives')
@task
@_require_db
def update_concordances(args=''):
"""Pull data repositories and load postcode concordances."""
_recursive_pull(env.data_dir)
with cd(env.django_dir):
run(env.python + ' manage.py loadpostcodeconcordance ' + args)
@task
@_require_db
def update_postcodes(args=''):
"""Pull data repositories and load postcodes."""
_recursive_pull(env.data_dir)
with cd(env.django_dir):
run(env.python + ' manage.py loadpostcodes ' + args)
def _recursive_pull(base_dir):
"""Find and pull all git repositories in a directory tree."""
with cd(base_dir):
dirs = [
d.strip()[:-1] for d in
run('ls -aFL1').split('\n')
if d.strip().endswith('/') and d.strip() not in ('./', '../')
]
if '.git' in dirs:
# This is a git repo, update it
run('pwd')
run('git pull origin master')
else:
# Continue exploring
for dir in dirs:
_recursive_pull(os.path.join(base_dir, dir))