To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / deploy / provision.d @ 1613:90bed4e10cc8

1 1577:e38eee2e1d47 Chris
#!/bin/bash
2
3
set -e
4
5 1589:94669513c53c Chris
# Install necessary system packages. This assumes we are deploying on
6
# Ubuntu 16.04.
7
8
# We aim to make all of these provisioning scripts non-destructive if
9
# run more than once. In this case, running the script again will
10
# install any outstanding updates.
11
12 1587:d8949733849d Chris
apt-get update && \
13
    apt-get dist-upgrade -y && \
14
    apt-get install -y \
15
            ack-grep \
16
            apache2 \
17
            apache2-dev \
18
            apt-utils \
19
            build-essential \
20
            cron \
21 1582:f26dc3004b3f Chris
            curl \
22
            doxygen \
23 1587:d8949733849d Chris
            exim4 \
24 1582:f26dc3004b3f Chris
            git \
25 1587:d8949733849d Chris
            graphviz \
26
            imagemagick \
27
            libapache-dbi-perl \
28
            libapache2-mod-perl2 \
29
            libapr1-dev \
30
            libaprutil1-dev \
31
            libauthen-simple-ldap-perl \
32
            libcurl4-openssl-dev \
33
            libdbd-pg-perl \
34
            libpq-dev \
35
            libmagickwand-dev \
36
            libio-socket-ssl-perl \
37
            logrotate \
38 1607:1c904260787b Chris
            lynx \
39 1582:f26dc3004b3f Chris
            mercurial \
40 1600:ed9c467ef922 Chris
            mercurial-git \
41 1589:94669513c53c Chris
            openjdk-9-jdk-headless \
42 1582:f26dc3004b3f Chris
            postgresql \
43 1587:d8949733849d Chris
            rsync \
44
            ruby \
45
            ruby-dev \
46
            sudo
47 1582:f26dc3004b3f Chris
48 1587:d8949733849d Chris
locale-gen en_US.UTF-8
49 1582:f26dc3004b3f Chris
50
51 1577:e38eee2e1d47 Chris
#!/bin/bash
52
53
set -e
54
55 1589:94669513c53c Chris
# Phusion Passenger as application server.
56
# This gets installed through gem, not apt, and we ask for a specific
57
# version (the last in the 4.0.x line).
58 1577:e38eee2e1d47 Chris
59
if [ ! -f /var/lib/gems/2.3.0/gems/passenger-4.0.60/buildout/apache2/mod_passenger.so ]; then
60
    gem install passenger -v 4.0.60 --no-rdoc --no-ri
61
    passenger-install-apache2-module --languages=ruby
62
fi
63
64
#!/bin/bash
65
66
set -e
67
68 1590:c18460da6620 Chris
# The webapp directory is owned and run by the code user, in group
69
# www-data. The repos and other things served directly are the other
70
# way around -- owned by the www-data user, in group code.
71 1589:94669513c53c Chris
72 1590:c18460da6620 Chris
for user in code docgen ; do
73
    if ! grep -q "^$user:" /etc/passwd ; then
74
        groupadd "$user"
75
        useradd -g "$user" -G www-data "$user"
76
    fi
77
done
78 1577:e38eee2e1d47 Chris
79
#!/bin/bash
80
81
set -e
82
83 1589:94669513c53c Chris
# We might be running in one of two ways:
84
#
85
# 1. The code directory is already at /var/www/code, either because a
86
# previous provisioning step has imported it there or because this
87
# script has been run before -- in this situation all we do is
88
# re-check the ownership and permissions. OR
89
#
90
# 2. The code directory has not yet been copied to /var/www/code, in
91
# which case we expect to find it at /code-to-deploy, e.g. as a
92
# Vagrant shared folder, and we copy it over from there. (We don't
93
# deploy directly from shared folders as we might not be able to
94
# manipulate ownership and permissions properly there.)
95
96 1577:e38eee2e1d47 Chris
if [ ! -d /var/www/code ]; then
97 1587:d8949733849d Chris
    if [ ! -d /code-to-deploy ]; then
98 1589:94669513c53c Chris
        echo "ERROR: Expected to find code tree at /var/www/code or /code-to-deploy: is the deployment script being invoked correctly?"
99 1587:d8949733849d Chris
        exit 2
100
    fi
101
    cp -a /code-to-deploy /var/www/code
102 1577:e38eee2e1d47 Chris
fi
103
104 1587:d8949733849d Chris
chown -R code.www-data /var/www/code
105 1605:18643ab36008 Chris
chmod 755 /var/www/code
106 1587:d8949733849d Chris
find /var/www/code -type d -exec chmod g+s \{\} \;
107
108 1577:e38eee2e1d47 Chris
#!/bin/bash
109
110
set -e
111
112 1589:94669513c53c Chris
# In a real deployment, /var/hg is probably mounted from somewhere
113
# else. But in an empty deployment we need to create it, and in both
114
# cases we set up the config files with their current versions here.
115
116 1577:e38eee2e1d47 Chris
if [ ! -f /var/hg/index.cgi ]; then
117
    mkdir -p /var/hg
118
fi
119 1589:94669513c53c Chris
120
cp /var/www/code/deploy/config/index.cgi /var/hg/
121
cp /var/www/code/deploy/config/hgweb.config /var/hg/
122
123
chmod +x /var/hg/index.cgi
124
125 1590:c18460da6620 Chris
chown -R www-data.code /var/hg
126 1589:94669513c53c Chris
find /var/hg -type d -exec chmod g+s \{\} \;
127
128 1577:e38eee2e1d47 Chris
#!/bin/bash
129
130
set -e
131
132 1589:94669513c53c Chris
# Copy across the database config file (the source file has presumably
133
# been generated from a skeleton, earlier in provisioning)
134
135 1593:83412a0a2389 Chris
infile=/var/www/code/deploy/config/database.yml.gen
136 1589:94669513c53c Chris
outfile=/var/www/code/config/database.yml
137 1587:d8949733849d Chris
138 1589:94669513c53c Chris
if [ ! -f "$outfile" ]; then
139
    if [ ! -f "$infile" ]; then
140
        echo "ERROR: Database config file $infile not found - has the database secret been interpolated from $infile.in correctly?"
141
        exit 2
142
    fi
143
    cp "$infile" "$outfile"
144 1577:e38eee2e1d47 Chris
fi
145
146
#!/bin/bash
147
148
set -e
149
150 1589:94669513c53c Chris
# Install Ruby gems for the web app.
151
152
# We aim to make all of these provisioning scripts non-destructive if
153
# run more than once. In this case, running the script again will
154
# install any outstanding updates.
155
156 1577:e38eee2e1d47 Chris
cd /var/www/code
157
gem install bundler
158
bundle install
159
160
#!/bin/bash
161
162
set -e
163
164 1589:94669513c53c Chris
# Create a session token if it hasn't already been created.
165
166 1577:e38eee2e1d47 Chris
cd /var/www/code
167
168 1589:94669513c53c Chris
if [ ! -f config/initializers/secret_token.rb ]; then
169
    bundle exec rake generate_secret_token
170
fi
171
172
173 1577:e38eee2e1d47 Chris
#!/bin/bash
174
175
set -e
176
177 1589:94669513c53c Chris
# Start the database and if a dump file is found, load it. The dump
178
# file is then deleted so that the db won't be overwritten on
179
# subsequent runs. (The original repo contains no dump file, so it
180
# should exist only if you have provided some data to load.)
181
182 1577:e38eee2e1d47 Chris
/etc/init.d/postgresql start
183
184 1611:89d3095ddc70 Chris
dumpdir="/code-to-deploy"
185
if [ ! -d "$dumpdir" ]; then
186
    dumpdir=/var/www/code
187
fi
188
189
cd "$dumpdir"
190 1577:e38eee2e1d47 Chris
191
if [ -f postgres-dumpall ]; then
192
    chmod ugo+r postgres-dumpall
193
    sudo -u postgres psql -f postgres-dumpall postgres
194 1589:94669513c53c Chris
    rm postgres-dumpall
195 1577:e38eee2e1d47 Chris
fi
196
197
#!/bin/bash
198
199
set -e
200
201 1589:94669513c53c Chris
# Install the Apache mod_perl module used for hg repo access control
202
203 1577:e38eee2e1d47 Chris
if [ ! -f /usr/local/lib/site_perl/Apache/Authn/SoundSoftware.pm ]; then
204
    mkdir -p /usr/local/lib/site_perl/Apache/Authn/
205 1589:94669513c53c Chris
    cp /var/www/code/extra/soundsoftware/SoundSoftware.pm \
206
       /usr/local/lib/site_perl/Apache/Authn/
207 1577:e38eee2e1d47 Chris
fi
208
209
#!/bin/bash
210
211
set -e
212
213 1589:94669513c53c Chris
# Install Apache config files and module loaders
214
215 1577:e38eee2e1d47 Chris
cd /var/www/code
216
217 1602:b22e234c3c7b Chris
codeconf=/var/www/code/deploy/config/code.conf.gen
218
codeconfssl=/var/www/code/deploy/config/code-ssl.conf.gen
219 1606:16325d2ab2dd Chris
staticconf=/var/www/code/deploy/config/soundsoftware-static.conf
220 1587:d8949733849d Chris
221 1602:b22e234c3c7b Chris
if [ ! -f "$codeconf" ]; then
222
    echo "ERROR: Apache config file $codeconf not found - has the database secret been interpolated from its input file correctly?"
223 1587:d8949733849d Chris
    exit 2
224
fi
225
226 1577:e38eee2e1d47 Chris
if [ ! -f /etc/apache2/sites-enabled/10-code.conf ]; then
227
228
    rm -f /etc/apache2/sites-enabled/000-default.conf
229
230 1587:d8949733849d Chris
    cp deploy/config/passenger.conf /etc/apache2/mods-available/
231
    cp deploy/config/passenger.load /etc/apache2/mods-available/
232
    cp deploy/config/perl.conf      /etc/apache2/mods-available/
233 1577:e38eee2e1d47 Chris
234 1608:b8e5e9734526 Chris
    ln -s ../mods-available/passenger.conf   /etc/apache2/mods-enabled/
235
    ln -s ../mods-available/passenger.load   /etc/apache2/mods-enabled/
236
    ln -s ../mods-available/perl.conf        /etc/apache2/mods-enabled/
237
    ln -s ../mods-available/expires.load     /etc/apache2/mods-enabled/
238
    ln -s ../mods-available/rewrite.load     /etc/apache2/mods-enabled/
239
    ln -s ../mods-available/cgi.load         /etc/apache2/mods-enabled/
240
    ln -s ../mods-available/ssl.load         /etc/apache2/mods-enabled/
241
    ln -s ../mods-available/auth_digest.load /etc/apache2/mods-enabled/
242 1577:e38eee2e1d47 Chris
243 1602:b22e234c3c7b Chris
    cp "$codeconf" /etc/apache2/sites-available/code.conf
244
    cp "$codeconfssl" /etc/apache2/sites-available/code-ssl.conf
245 1606:16325d2ab2dd Chris
    cp "$staticconf" /etc/apache2/sites-available/soundsoftware-static.conf
246 1577:e38eee2e1d47 Chris
    ln -s ../sites-available/code.conf /etc/apache2/sites-enabled/10-code.conf
247
248
    apache2ctl configtest
249
250
fi
251
252 1588:9149f2098413 Chris
#!/bin/bash
253
254
set -e
255
256 1589:94669513c53c Chris
# In case we are running without a properly mounted /var/hg directory,
257
# check for the existence of one repo and, if absent, attempt to clone
258
# it so that we have something we can serve for test purposes.
259
260 1588:9149f2098413 Chris
if [ ! -d /var/hg/vamp-plugin-sdk ]; then
261
    echo "Cloning vamp-plugin-sdk repo for testing..."
262
    cd /var/hg
263
    hg clone https://code.soundsoftware.ac.uk/hg/vamp-plugin-sdk
264 1590:c18460da6620 Chris
    chown -R www-data.code vamp-plugin-sdk
265 1588:9149f2098413 Chris
fi
266 1598:073a75bf07fb Chris
#!/bin/bash
267
268
set -e
269
270
# Initialise directories used as targets for cron activity (if they
271
# don't already exist)
272
273
# Reminder: the webapp directory is owned and run by the code user, in
274
# group www-data. The repos and other things served directly are
275
# usually the other way around -- owned by the www-data user, in group
276
# code. I don't recall whether there is a good reason for this.
277
278
for dir in \
279
    /var/files/backups \
280
    /var/doc \
281 1613:90bed4e10cc8 Chris
    /var/files/code \
282 1598:073a75bf07fb Chris
    /var/files/git-mirror ; do
283
    if [ ! -d "$dir" ]; then
284
        mkdir -p "$dir"
285
        chown -R code.www-data "$dir"
286
        chmod g+s "$dir"
287
    fi
288
done
289
290
for dir in \
291
    /var/mirror ; do
292
    if [ ! -d "$dir" ]; then
293
        mkdir -p "$dir"
294
        chown -R www-data.code "$dir"
295
        chmod g+s "$dir"
296
    fi
297
done
298 1613:90bed4e10cc8 Chris
299
if [ ! -e /var/www/code/files ]; then
300
    ln -s /var/files/code /var/www/code/files
301
fi
302 1590:c18460da6620 Chris
#!/bin/bash
303
304
set -e
305
306 1596:45b0571b684d Chris
# Copy docgen scripts, including the generated scripts with
307
# interpolated API key etc, to the directory they will be run from.
308
309
# These are run from cron jobs to do the (currently daily) update of
310
# extracted documentation from Doxygen, Javadoc, and MATLAB, and to
311
# enable displaying them with the redmine_embedded plugin. (The API
312
# key is needed to automatically switch on the embedded module for a
313
# project the first time its docs are extracted.)
314 1590:c18460da6620 Chris
315
cd /var/www/code
316
317
mkdir -p docgen
318
319
for file in \
320
    doxysafe.pl \
321
    extract-doxygen.sh \
322
    extract-javadoc.sh \
323
    extract-matlabdocs.sh \
324
    matlab-docs.conf \
325
    matlab-docs-credit.html \
326
    matlab-docs.pl ; do
327
    if [ ! -f docgen/"$file" ]; then
328
        cp extra/soundsoftware/"$file" docgen/
329
    fi
330
done
331
332 1593:83412a0a2389 Chris
for file in \
333
    extract-docs.sh ; do
334
    if [ ! -f docgen/"$file" ]; then
335
        cp deploy/config/"$file".gen docgen/"$file"
336
    fi
337
done
338
339 1590:c18460da6620 Chris
chown code.www-data docgen/*
340
chmod +x docgen/*.sh
341
342
#!/bin/bash
343
344
set -e
345
346 1596:45b0571b684d Chris
# Copy reposman (repository manager) scripts, including the generated
347
# scripts with interpolated API key etc, to the directory they will be
348
# run from.
349
350
# There are two sets of scripts here:
351
#
352
# 1. The reposman script that plods through all the projects that have
353
# repositories defined, creates those repositories on disc, and
354
# registers their locations with the projects. This happens often,
355
# currently every minute.
356
#
357
# 2. The external repo management script that plods through all the
358
# projects that have external repositories defined, clones or updates
359
# those external repos to their local locations, and if necessary
360
# registers them with the projects. This happens less often, currently
361
# every hour.
362 1590:c18460da6620 Chris
363
cd /var/www/code
364
365
mkdir -p reposman
366
367
for file in \
368
    convert-external-repos.rb \
369
    reposman-soundsoftware.rb \
370
    run-hginit.sh \
371
    update-external-repo.sh ; do
372
    if [ ! -f reposman/"$file" ]; then
373
        cp extra/soundsoftware/"$file" reposman/
374
    fi
375
done
376
377
for file in \
378
    run-external.sh \
379
    run-reposman.sh ; do
380
    if [ ! -f reposman/"$file" ]; then
381 1593:83412a0a2389 Chris
        cp deploy/config/"$file".gen reposman/"$file"
382 1590:c18460da6620 Chris
    fi
383
done
384
385
chown code.www-data reposman/*
386
chmod +x reposman/*.sh
387
chmod +x reposman/*.rb
388
389
touch /var/log/reposman.log
390
touch /var/log/external-repos.log
391
chown www-data.code /var/log/reposman.log
392
chown www-data.code /var/log/external-repos.log
393
394
#!/bin/bash
395
396
set -e
397
398
# Copy cron scripts to the appropriate destinations
399
400
cd /var/www/code
401
402
if [ ! -d /etc/cron.minutely ]; then
403
    mkdir -p /etc/cron.minutely
404
    echo '*  *    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.minutely )' >> /etc/crontab
405
fi
406
407
for t in minutely hourly daily monthly; do
408
    for s in deploy/config/cron.$t/[0-9]* ; do
409
        name=$(basename $s)
410
        dest="/etc/cron.$t/$name"
411
        if [ ! -f "$dest" ]; then
412
            cp "$s" "$dest"
413
            chmod +x "$dest"
414
        fi
415
    done
416
done
417
418
419
420
#!/bin/bash
421
422
cd /var/www/code
423
cp deploy/config/logrotate.conf /etc/logrotate.conf
424 1601:07deb8466f65 Chris
#!/bin/bash
425
426
set -e
427
428
# Print reminders of the things that we haven't covered in the deploy
429
# scripts
430
431
cat <<EOF
432
433
*** APACHE SSL CONFIGURATION
434
435
    The provisioning scripts set up a simple HTTP site only. Refer to
436 1606:16325d2ab2dd Chris
    code-ssl.conf for an example HTTPS configuration (you will of
437
    course need to provide the key/cert files).
438
439 1607:1c904260787b Chris
*** CRON SCRIPTS
440
441
    A number of cron scripts have been installed. It might be no bad
442
    thing to prime and test them by running them all once now. Some of
443
    the services tested by the smoke test script (below) may depend on
444
    their having run. Use deploy/any/run-cron-scripts.sh for this.
445
446 1606:16325d2ab2dd Chris
*** SMOKE TEST
447
448
    There is a smoke test script in the deploy/test directory. That
449
    is, a quick automated acceptance test that checks that basic
450
    services are returning successful HTTP codes. Consider running it
451
    against this server from another host, i.e. not just localhost.
452 1601:07deb8466f65 Chris
453
*** EMAIL
454
455
    Outgoing email is required for notifications, but has not been
456 1608:b8e5e9734526 Chris
    configured as part of this provisioning setup. You'll need to set
457
    up the server's outgoing mail support and also edit the application
458
    email settings in config/configuration.yml.
459 1601:07deb8466f65 Chris
460
*** STATIC FRONT PAGE
461
462
    We have set up only the code/repository site -- if you want a
463
    separate front page, remember to configure that!
464
465
EOF
466 1581:ae8043b014c7 Chris
#!/bin/bash
467
468
set -e
469
470 1601:07deb8466f65 Chris
# Last action: check & start the webserver
471
472
apache2ctl configtest
473 1589:94669513c53c Chris
474 1581:ae8043b014c7 Chris
apache2ctl restart