install_config_files()   B
last analyzed

Complexity

Conditions 5

Size

Total Lines 41

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 41
rs 8.0894
cc 5
1
"""
2
Fabfile to setup and deploy gage-web
3
"""
4
from fabric.api import cd, run, local, env, sudo, put, prompt, lcd, prefix
5
from fabric.contrib.console import confirm
6
from fabtools import require
7
import fabtools
8
9
# uses a file called fabhosts where servers can be defined but gitignored
10
# looks like
11
#
12
# from fabric.api import env
13
#
14
# def prod():
15
#   env.user = 'username'
16
#   env.hosts = ['server1', 'server2']
17
#
18
try:
19
    from fabhosts import (prod,   # noqa
20
                          register_deployment,
21
                          WWW_DIR,
22
                          ENV_DIR,
23
                          USER,
24
                          GROUP,
25
                          DB,
26
                          DB_USER,
27
                          DB_PASSWORD,
28
                          GIT_DIR)
29
except ImportError:
30
    pass
31
32
LOCAL_APP_DIR = '.'
33
LOCAL_CONFIG_DIR = LOCAL_APP_DIR + '/server-config'
34
35
36
def apt_upgrade():
37
    """
38
    Run apt-get upgrade
39
    """
40
    require.deb.uptodate_index(max_age={'day': 1})
41
    sudo('apt-get upgrade')
42
43
44
def create_user():
45
    """
46
    Create a gage_www user for running gage-web
47
    """
48
    require.groups.group(GROUP)
49
    require.users.user(USER, group=GROUP, system=True)
50
51
52
def create_www_folder():
53
    """
54
    Folder for gage-web to run from
55
    """
56
    require.directory(WWW_DIR,
57
                      use_sudo=True,
58
                      owner=USER)
59
60
61
def create_venv():
62
    """
63
    Create virutalenv for gage-web
64
    """
65
    require.python.virtualenv(ENV_DIR,
66
                              use_sudo=True)
67
68
69
def install_system_requirements():
70
    """
71
    Install required system packages
72
    """
73
    require.deb.packages(['python',
74
                          'python-dev',
75
                          'python-pip',
76
                          'python-virtualenv',
77
                          'nginx',
78
                          'postgresql-9.4',
79
                          'postgresql-9.4-postgis-2.1',
80
                          'postgresql-server-dev-9.4',
81
                          'libpq-dev',
82
                          'git',
83
                          'gdal-bin',
84
                          'gfortran',
85
                          'python-gdal',
86
                          'python-numpy',
87
                          'python-scipy',
88
                          'python-pandas',
89
                          'libblas-dev',
90
                          'liblapack-dev',
91
                          'libgdal-dev',
92
                          'supervisor',
93
                          'redis-server',
94
                          'libxslt1.dev',
95
                          'libjpeg8-dev',
96
                          'libjpeg-dev',
97
                          'libfreetype6-dev',
98
                          'zlib1g-dev',
99
                          'libpng12-dev'])
100
    sudo('export CPLUS_INCLUDE_PATH=/usr/include/gdal')
101
    sudo('export C_INCLUDE_PATH=/usr/include/gdal')
102
103
104
def create_database():
105
    """
106
    Create database and setup postgis
107
    """
108
    output = sudo('psql -lqt | cut -d \| -f 1', user='postgres')
109
    if DB in output:
110
        print('{DB} database found!'.format(DB=DB))
111
    else:
112
        print('{DB} not found! Creating DB'.format(DB=DB))
113
        # require.postgres.user(DB_USER, password=DB_PASSWORD)
114
        sudo("""psql -c "CREATE USER '{DB_USER}' NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN UNENCRYPTED PASSWORD '{DB_PASSWORD}';""".format(DB_USER=DB_USER, DB_PASSWORD=DB_PASSWORD),
115
             user='postgres')
116
        # require.postgres.database(DB, owner=DB_USER)
117
        sudo('createdb --owner {DB_USER} {DB}'.format(DB_USER=DB_USER, DB=DB),
118
             user='postgres')
119
        sudo('psql -d {DB} -c "CREATE EXTENSION postgis;"'.format(DB=DB),
120
             user='postgres')
121
        sudo('psql -d {DB} -c "CREATE EXTENSION postgis_topology;"'.format(DB=DB),
122
             user='postgres')
123
124
125
def configure_git():
126
    """
127
    1. Setup bare Git Repo
128
    2. Create post-recieve hook
129
    """
130
    require.directory(GIT_DIR, use_sudo=True)
131
    with cd(GIT_DIR):
132
        sudo('mkdir gage-web.git')
133
        with cd('gage-web.git'):
134
            sudo('git init --bare')
135
            with lcd(LOCAL_CONFIG_DIR):
136
                with cd('hooks'):
137
                    put('./post-receive', './', use_sudo=True)
138
                    sudo('chmod +x post-receive')
139
    with lcd(LOCAL_APP_DIR):
140
        local(
141
            'git remote add production {user}@{server}:{GIT_DIR}/gage-web.git'
142
            .format(user=env.user, server=env.host_string, GIT_DIR=GIT_DIR))
143
144
145
def deploy():
146
    """
147
    Push current master to production and restart gunicorn
148
    """
149
    with lcd(LOCAL_APP_DIR):
150
        local('git push production master')
151
        sudo('supervisorctl restart gage:*')
152
        register_deployment(LOCAL_APP_DIR)
153
154
155
def install_requirements():
156
    """
157
    Install requirements into virtualenv
158
    """
159
    with fabtools.python.virtualenv(ENV_DIR):
160
        with cd(WWW_DIR):
161
            require.python.requirements('requirements.txt')
162
163
164
def install_config_files():
165
    """
166
    Put config files for gunicorn, supervisord, nginx
167
    """
168
    # host-export
169
    with cd(WWW_DIR + '/server-config'):
170
        require.file('host-export', source=LOCAL_CONFIG_DIR+'/host-export')
171
        sudo('chmod +x host-export')
172
    # gunicorn
173
    with cd('/home/www'):
174
        fabtools.files.upload_template(
175
            LOCAL_CONFIG_DIR + '/gunicorn-start-gage',
176
            '.',
177
            use_sudo=True,
178
            use_jinja=True,
179
            user=USER,
180
            context={
181
                'WWW_DIR': WWW_DIR,
182
                'ENV_DIR': ENV_DIR,
183
                'USER': USER,
184
                'GROUP': GROUP
185
            },
186
            chown=True),
187
        sudo('chmod +x gunicorn-start-gage')
188
    # supervisord
189
    with cd('/etc/supervisor/conf.d/'):
190
        require.file('gage-web.conf',
191
                     source=LOCAL_CONFIG_DIR+'/gage-web.conf',
192
                     use_sudo=True)
193
        require.directory('/home/www/logs/gage-web/')
194
        sudo('supervisorctl reread')
195
        sudo('supervisorctl update')
196
    # nginx
197
    with cd('/etc/nginx/sites-available'):
198
        require.file('gage-web',
199
                     source=LOCAL_CONFIG_DIR+'/gage-web',
200
                     use_sudo=True)
201
        sudo('ln -s /etc/nginx/sites-available/gage-web' +
202
             ' /etc/nginx/sites-enabled/gage-web')
203
        sudo('service nginx configtest')
204
        sudo('service nginx restart')
205
206
207
def upgrade_db_schema():
208
    """
209
    With manage.py setup database
210
    """
211
    with prefix('source {ENV_DIR}/bin/activate'.format(ENV_DIR=ENV_DIR)):
212
        with prefix('source {WWW_DIR}/server-config/host-export'.format(WWW_DIR=WWW_DIR)):
213
            with cd(WWW_DIR):
214
                sudo('python manage.py db upgrade')
215
216
217
def create_roles():
218
    """
219
    Create user and admin roles
220
    """
221
    with prefix('source {ENV_DIR}/bin/activate'.format(ENV_DIR=ENV_DIR)):
222
        with prefix('source {WWW_DIR}/server-config/host-export'.format(WWW_DIR=WWW_DIR)):
223
            with cd(WWW_DIR):
224
                sudo('python manage.py user create_role -n admin -d "Site Administrators"')
225
                sudo('python manage.py user create_role -n user -d Users')
226
227
def setup_celery():
228
    """
229
    Upload configs for celery, make sure redis is running
230
    """
231
    with cd('/home/www'):
232
        fabtools.files.upload_template(
233
            LOCAL_CONFIG_DIR + '/celery-start-gage',
234
            '.',
235
            use_sudo=True,
236
            use_jinja=True,
237
            user=USER,
238
            context={
239
                'WWW_DIR': WWW_DIR,
240
                'ENV_DIR': ENV_DIR,
241
                'USER': USER,
242
                'GROUP': GROUP
243
            },
244
            chown=True),
245
        sudo('chmod +x celery-start-gage')
246
        fabtools.files.upload_template(
247
            LOCAL_CONFIG_DIR + '/celery-start-beat-gage',
248
            '.',
249
            use_sudo=True,
250
            use_jinja=True,
251
            user=USER,
252
            context={
253
                'WWW_DIR': WWW_DIR,
254
                'ENV_DIR': ENV_DIR,
255
                'USER': USER,
256
                'GROUP': GROUP
257
            },
258
            chown=True),
259
        sudo('chmod +x celery-start-beat-gage')
260
        with cd('/etc/supervisor/conf.d/'):
261
            require.file('gage-web.conf',
262
                         source=LOCAL_CONFIG_DIR+'/gage-web.conf',
263
                         use_sudo=True)
264
            require.directory('/home/www/logs/gage-web/')
265
            sudo('supervisorctl reread')
266
            sudo('supervisorctl update')
267
            sudo('supervisorctl restart gage:*')
268
269
270
def gage_restart():
271
    """
272
    Cron script to restart the supervisorctl gage:gage-celery-beat hourly
273
    """
274
    fabtools.cron.add_task('restart-gage-beat', '@hourly', 'root', WWW_DIR+'/server-config/restart-gage.sh')
275
276
277
278
def bootstrap():
279
    """
280
    Setup all the things
281
    """
282
    create_user()
283
    create_www_folder()
284
    create_venv()
285
    install_system_requirements()
286
    # create_database()
287
    # configure_git()
288
    deploy()
289
    install_requirements()
290
    # Install ssl scripts
291
    install_config_files()
292
    upgrade_db_schema()
293
    create_roles()
294