To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / deploy / provision.d @ 1598:073a75bf07fb
| 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 | 1582:f26dc3004b3f | Chris | mercurial \ |
| 39 | 1589:94669513c53c | Chris | openjdk-9-jdk-headless \ |
| 40 | 1582:f26dc3004b3f | Chris | postgresql \ |
| 41 | 1587:d8949733849d | Chris | rsync \ |
| 42 | ruby \ |
||
| 43 | ruby-dev \ |
||
| 44 | sudo |
||
| 45 | 1582:f26dc3004b3f | Chris | |
| 46 | 1587:d8949733849d | Chris | locale-gen en_US.UTF-8 |
| 47 | 1582:f26dc3004b3f | Chris | |
| 48 | |||
| 49 | 1577:e38eee2e1d47 | Chris | #!/bin/bash |
| 50 | |||
| 51 | set -e |
||
| 52 | |||
| 53 | 1589:94669513c53c | Chris | # Phusion Passenger as application server. |
| 54 | # This gets installed through gem, not apt, and we ask for a specific |
||
| 55 | # version (the last in the 4.0.x line). |
||
| 56 | 1577:e38eee2e1d47 | Chris | |
| 57 | if [ ! -f /var/lib/gems/2.3.0/gems/passenger-4.0.60/buildout/apache2/mod_passenger.so ]; then |
||
| 58 | gem install passenger -v 4.0.60 --no-rdoc --no-ri |
||
| 59 | passenger-install-apache2-module --languages=ruby |
||
| 60 | fi |
||
| 61 | |||
| 62 | #!/bin/bash |
||
| 63 | |||
| 64 | set -e |
||
| 65 | |||
| 66 | 1590:c18460da6620 | Chris | # The webapp directory is owned and run by the code user, in group |
| 67 | # www-data. The repos and other things served directly are the other |
||
| 68 | # way around -- owned by the www-data user, in group code. |
||
| 69 | 1589:94669513c53c | Chris | |
| 70 | 1590:c18460da6620 | Chris | for user in code docgen ; do |
| 71 | if ! grep -q "^$user:" /etc/passwd ; then |
||
| 72 | groupadd "$user" |
||
| 73 | useradd -g "$user" -G www-data "$user" |
||
| 74 | fi |
||
| 75 | done |
||
| 76 | 1577:e38eee2e1d47 | Chris | |
| 77 | #!/bin/bash |
||
| 78 | |||
| 79 | set -e |
||
| 80 | |||
| 81 | 1589:94669513c53c | Chris | # We might be running in one of two ways: |
| 82 | # |
||
| 83 | # 1. The code directory is already at /var/www/code, either because a |
||
| 84 | # previous provisioning step has imported it there or because this |
||
| 85 | # script has been run before -- in this situation all we do is |
||
| 86 | # re-check the ownership and permissions. OR |
||
| 87 | # |
||
| 88 | # 2. The code directory has not yet been copied to /var/www/code, in |
||
| 89 | # which case we expect to find it at /code-to-deploy, e.g. as a |
||
| 90 | # Vagrant shared folder, and we copy it over from there. (We don't |
||
| 91 | # deploy directly from shared folders as we might not be able to |
||
| 92 | # manipulate ownership and permissions properly there.) |
||
| 93 | |||
| 94 | 1577:e38eee2e1d47 | Chris | if [ ! -d /var/www/code ]; then |
| 95 | 1587:d8949733849d | Chris | if [ ! -d /code-to-deploy ]; then |
| 96 | 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?" |
| 97 | 1587:d8949733849d | Chris | exit 2 |
| 98 | fi |
||
| 99 | cp -a /code-to-deploy /var/www/code |
||
| 100 | 1577:e38eee2e1d47 | Chris | fi |
| 101 | |||
| 102 | 1587:d8949733849d | Chris | chown -R code.www-data /var/www/code |
| 103 | find /var/www/code -type d -exec chmod g+s \{\} \;
|
||
| 104 | |||
| 105 | |||
| 106 | 1577:e38eee2e1d47 | Chris | #!/bin/bash |
| 107 | |||
| 108 | set -e |
||
| 109 | |||
| 110 | 1589:94669513c53c | Chris | # In a real deployment, /var/hg is probably mounted from somewhere |
| 111 | # else. But in an empty deployment we need to create it, and in both |
||
| 112 | # cases we set up the config files with their current versions here. |
||
| 113 | |||
| 114 | 1577:e38eee2e1d47 | Chris | if [ ! -f /var/hg/index.cgi ]; then |
| 115 | mkdir -p /var/hg |
||
| 116 | fi |
||
| 117 | 1589:94669513c53c | Chris | |
| 118 | cp /var/www/code/deploy/config/index.cgi /var/hg/ |
||
| 119 | cp /var/www/code/deploy/config/hgweb.config /var/hg/ |
||
| 120 | |||
| 121 | chmod +x /var/hg/index.cgi |
||
| 122 | |||
| 123 | 1590:c18460da6620 | Chris | chown -R www-data.code /var/hg |
| 124 | 1589:94669513c53c | Chris | find /var/hg -type d -exec chmod g+s \{\} \;
|
| 125 | |||
| 126 | 1577:e38eee2e1d47 | Chris | #!/bin/bash |
| 127 | |||
| 128 | set -e |
||
| 129 | |||
| 130 | 1589:94669513c53c | Chris | # Copy across the database config file (the source file has presumably |
| 131 | # been generated from a skeleton, earlier in provisioning) |
||
| 132 | |||
| 133 | 1593:83412a0a2389 | Chris | infile=/var/www/code/deploy/config/database.yml.gen |
| 134 | 1589:94669513c53c | Chris | outfile=/var/www/code/config/database.yml |
| 135 | 1587:d8949733849d | Chris | |
| 136 | 1589:94669513c53c | Chris | if [ ! -f "$outfile" ]; then |
| 137 | if [ ! -f "$infile" ]; then |
||
| 138 | echo "ERROR: Database config file $infile not found - has the database secret been interpolated from $infile.in correctly?" |
||
| 139 | exit 2 |
||
| 140 | fi |
||
| 141 | cp "$infile" "$outfile" |
||
| 142 | 1577:e38eee2e1d47 | Chris | fi |
| 143 | |||
| 144 | #!/bin/bash |
||
| 145 | |||
| 146 | set -e |
||
| 147 | |||
| 148 | 1589:94669513c53c | Chris | # Install Ruby gems for the web app. |
| 149 | |||
| 150 | # We aim to make all of these provisioning scripts non-destructive if |
||
| 151 | # run more than once. In this case, running the script again will |
||
| 152 | # install any outstanding updates. |
||
| 153 | |||
| 154 | 1577:e38eee2e1d47 | Chris | cd /var/www/code |
| 155 | gem install bundler |
||
| 156 | bundle install |
||
| 157 | |||
| 158 | #!/bin/bash |
||
| 159 | |||
| 160 | set -e |
||
| 161 | |||
| 162 | 1589:94669513c53c | Chris | # Create a session token if it hasn't already been created. |
| 163 | |||
| 164 | 1577:e38eee2e1d47 | Chris | cd /var/www/code |
| 165 | |||
| 166 | 1589:94669513c53c | Chris | if [ ! -f config/initializers/secret_token.rb ]; then |
| 167 | bundle exec rake generate_secret_token |
||
| 168 | fi |
||
| 169 | |||
| 170 | |||
| 171 | 1577:e38eee2e1d47 | Chris | #!/bin/bash |
| 172 | |||
| 173 | set -e |
||
| 174 | |||
| 175 | 1589:94669513c53c | Chris | # Start the database and if a dump file is found, load it. The dump |
| 176 | # file is then deleted so that the db won't be overwritten on |
||
| 177 | # subsequent runs. (The original repo contains no dump file, so it |
||
| 178 | # should exist only if you have provided some data to load.) |
||
| 179 | |||
| 180 | 1577:e38eee2e1d47 | Chris | /etc/init.d/postgresql start |
| 181 | |||
| 182 | cd /var/www/code |
||
| 183 | |||
| 184 | if [ -f postgres-dumpall ]; then |
||
| 185 | chmod ugo+r postgres-dumpall |
||
| 186 | sudo -u postgres psql -f postgres-dumpall postgres |
||
| 187 | 1589:94669513c53c | Chris | rm postgres-dumpall |
| 188 | 1577:e38eee2e1d47 | Chris | fi |
| 189 | |||
| 190 | #!/bin/bash |
||
| 191 | |||
| 192 | set -e |
||
| 193 | |||
| 194 | 1589:94669513c53c | Chris | # Install the Apache mod_perl module used for hg repo access control |
| 195 | |||
| 196 | 1577:e38eee2e1d47 | Chris | if [ ! -f /usr/local/lib/site_perl/Apache/Authn/SoundSoftware.pm ]; then |
| 197 | mkdir -p /usr/local/lib/site_perl/Apache/Authn/ |
||
| 198 | 1589:94669513c53c | Chris | cp /var/www/code/extra/soundsoftware/SoundSoftware.pm \ |
| 199 | /usr/local/lib/site_perl/Apache/Authn/ |
||
| 200 | 1577:e38eee2e1d47 | Chris | fi |
| 201 | |||
| 202 | #!/bin/bash |
||
| 203 | |||
| 204 | set -e |
||
| 205 | |||
| 206 | 1589:94669513c53c | Chris | # Install Apache config files and module loaders |
| 207 | |||
| 208 | 1577:e38eee2e1d47 | Chris | cd /var/www/code |
| 209 | |||
| 210 | 1593:83412a0a2389 | Chris | codeconffile=/var/www/code/deploy/config/code.conf.gen |
| 211 | 1587:d8949733849d | Chris | |
| 212 | if [ ! -f "$codeconffile" ]; then |
||
| 213 | 1593:83412a0a2389 | Chris | echo "ERROR: Apache config file $codeconffile not found - has the database secret been interpolated from its input file correctly?" |
| 214 | 1587:d8949733849d | Chris | exit 2 |
| 215 | fi |
||
| 216 | |||
| 217 | 1577:e38eee2e1d47 | Chris | if [ ! -f /etc/apache2/sites-enabled/10-code.conf ]; then |
| 218 | |||
| 219 | rm -f /etc/apache2/sites-enabled/000-default.conf |
||
| 220 | |||
| 221 | 1587:d8949733849d | Chris | cp deploy/config/passenger.conf /etc/apache2/mods-available/ |
| 222 | cp deploy/config/passenger.load /etc/apache2/mods-available/ |
||
| 223 | cp deploy/config/perl.conf /etc/apache2/mods-available/ |
||
| 224 | 1577:e38eee2e1d47 | Chris | |
| 225 | ln -s ../mods-available/passenger.conf /etc/apache2/mods-enabled/ |
||
| 226 | ln -s ../mods-available/passenger.load /etc/apache2/mods-enabled/ |
||
| 227 | ln -s ../mods-available/perl.conf /etc/apache2/mods-enabled/ |
||
| 228 | ln -s ../mods-available/expires.load /etc/apache2/mods-enabled/ |
||
| 229 | ln -s ../mods-available/rewrite.load /etc/apache2/mods-enabled/ |
||
| 230 | 1578:06ca2df3d7ca | Chris | ln -s ../mods-available/cgi.load /etc/apache2/mods-enabled/ |
| 231 | 1577:e38eee2e1d47 | Chris | |
| 232 | 1587:d8949733849d | Chris | cp "$codeconffile" /etc/apache2/sites-available/code.conf |
| 233 | 1577:e38eee2e1d47 | Chris | ln -s ../sites-available/code.conf /etc/apache2/sites-enabled/10-code.conf |
| 234 | |||
| 235 | apache2ctl configtest |
||
| 236 | |||
| 237 | fi |
||
| 238 | |||
| 239 | 1588:9149f2098413 | Chris | #!/bin/bash |
| 240 | |||
| 241 | set -e |
||
| 242 | |||
| 243 | 1589:94669513c53c | Chris | # In case we are running without a properly mounted /var/hg directory, |
| 244 | # check for the existence of one repo and, if absent, attempt to clone |
||
| 245 | # it so that we have something we can serve for test purposes. |
||
| 246 | |||
| 247 | 1588:9149f2098413 | Chris | if [ ! -d /var/hg/vamp-plugin-sdk ]; then |
| 248 | echo "Cloning vamp-plugin-sdk repo for testing..." |
||
| 249 | cd /var/hg |
||
| 250 | hg clone https://code.soundsoftware.ac.uk/hg/vamp-plugin-sdk |
||
| 251 | 1590:c18460da6620 | Chris | chown -R www-data.code vamp-plugin-sdk |
| 252 | 1588:9149f2098413 | Chris | fi |
| 253 | 1598:073a75bf07fb | Chris | #!/bin/bash |
| 254 | |||
| 255 | set -e |
||
| 256 | |||
| 257 | # Initialise directories used as targets for cron activity (if they |
||
| 258 | # don't already exist) |
||
| 259 | |||
| 260 | # Reminder: the webapp directory is owned and run by the code user, in |
||
| 261 | # group www-data. The repos and other things served directly are |
||
| 262 | # usually the other way around -- owned by the www-data user, in group |
||
| 263 | # code. I don't recall whether there is a good reason for this. |
||
| 264 | |||
| 265 | for dir in \ |
||
| 266 | /var/files/backups \ |
||
| 267 | /var/doc \ |
||
| 268 | /var/files/git-mirror ; do |
||
| 269 | if [ ! -d "$dir" ]; then |
||
| 270 | mkdir -p "$dir" |
||
| 271 | chown -R code.www-data "$dir" |
||
| 272 | chmod g+s "$dir" |
||
| 273 | fi |
||
| 274 | done |
||
| 275 | |||
| 276 | for dir in \ |
||
| 277 | /var/mirror ; do |
||
| 278 | if [ ! -d "$dir" ]; then |
||
| 279 | mkdir -p "$dir" |
||
| 280 | chown -R www-data.code "$dir" |
||
| 281 | chmod g+s "$dir" |
||
| 282 | fi |
||
| 283 | done |
||
| 284 | 1590:c18460da6620 | Chris | #!/bin/bash |
| 285 | |||
| 286 | set -e |
||
| 287 | |||
| 288 | 1596:45b0571b684d | Chris | # Copy docgen scripts, including the generated scripts with |
| 289 | # interpolated API key etc, to the directory they will be run from. |
||
| 290 | |||
| 291 | # These are run from cron jobs to do the (currently daily) update of |
||
| 292 | # extracted documentation from Doxygen, Javadoc, and MATLAB, and to |
||
| 293 | # enable displaying them with the redmine_embedded plugin. (The API |
||
| 294 | # key is needed to automatically switch on the embedded module for a |
||
| 295 | # project the first time its docs are extracted.) |
||
| 296 | 1590:c18460da6620 | Chris | |
| 297 | cd /var/www/code |
||
| 298 | |||
| 299 | mkdir -p docgen |
||
| 300 | |||
| 301 | for file in \ |
||
| 302 | doxysafe.pl \ |
||
| 303 | extract-doxygen.sh \ |
||
| 304 | extract-javadoc.sh \ |
||
| 305 | extract-matlabdocs.sh \ |
||
| 306 | matlab-docs.conf \ |
||
| 307 | matlab-docs-credit.html \ |
||
| 308 | matlab-docs.pl ; do |
||
| 309 | if [ ! -f docgen/"$file" ]; then |
||
| 310 | cp extra/soundsoftware/"$file" docgen/ |
||
| 311 | fi |
||
| 312 | done |
||
| 313 | |||
| 314 | 1593:83412a0a2389 | Chris | for file in \ |
| 315 | extract-docs.sh ; do |
||
| 316 | if [ ! -f docgen/"$file" ]; then |
||
| 317 | cp deploy/config/"$file".gen docgen/"$file" |
||
| 318 | fi |
||
| 319 | done |
||
| 320 | |||
| 321 | 1590:c18460da6620 | Chris | chown code.www-data docgen/* |
| 322 | chmod +x docgen/*.sh |
||
| 323 | |||
| 324 | #!/bin/bash |
||
| 325 | |||
| 326 | set -e |
||
| 327 | |||
| 328 | 1596:45b0571b684d | Chris | # Copy reposman (repository manager) scripts, including the generated |
| 329 | # scripts with interpolated API key etc, to the directory they will be |
||
| 330 | # run from. |
||
| 331 | |||
| 332 | # There are two sets of scripts here: |
||
| 333 | # |
||
| 334 | # 1. The reposman script that plods through all the projects that have |
||
| 335 | # repositories defined, creates those repositories on disc, and |
||
| 336 | # registers their locations with the projects. This happens often, |
||
| 337 | # currently every minute. |
||
| 338 | # |
||
| 339 | # 2. The external repo management script that plods through all the |
||
| 340 | # projects that have external repositories defined, clones or updates |
||
| 341 | # those external repos to their local locations, and if necessary |
||
| 342 | # registers them with the projects. This happens less often, currently |
||
| 343 | # every hour. |
||
| 344 | 1590:c18460da6620 | Chris | |
| 345 | cd /var/www/code |
||
| 346 | |||
| 347 | mkdir -p reposman |
||
| 348 | |||
| 349 | for file in \ |
||
| 350 | convert-external-repos.rb \ |
||
| 351 | reposman-soundsoftware.rb \ |
||
| 352 | run-hginit.sh \ |
||
| 353 | update-external-repo.sh ; do |
||
| 354 | if [ ! -f reposman/"$file" ]; then |
||
| 355 | cp extra/soundsoftware/"$file" reposman/ |
||
| 356 | fi |
||
| 357 | done |
||
| 358 | |||
| 359 | for file in \ |
||
| 360 | run-external.sh \ |
||
| 361 | run-reposman.sh ; do |
||
| 362 | if [ ! -f reposman/"$file" ]; then |
||
| 363 | 1593:83412a0a2389 | Chris | cp deploy/config/"$file".gen reposman/"$file" |
| 364 | 1590:c18460da6620 | Chris | fi |
| 365 | done |
||
| 366 | |||
| 367 | chown code.www-data reposman/* |
||
| 368 | chmod +x reposman/*.sh |
||
| 369 | chmod +x reposman/*.rb |
||
| 370 | |||
| 371 | touch /var/log/reposman.log |
||
| 372 | touch /var/log/external-repos.log |
||
| 373 | chown www-data.code /var/log/reposman.log |
||
| 374 | chown www-data.code /var/log/external-repos.log |
||
| 375 | |||
| 376 | #!/bin/bash |
||
| 377 | |||
| 378 | set -e |
||
| 379 | |||
| 380 | # Copy cron scripts to the appropriate destinations |
||
| 381 | |||
| 382 | cd /var/www/code |
||
| 383 | |||
| 384 | if [ ! -d /etc/cron.minutely ]; then |
||
| 385 | mkdir -p /etc/cron.minutely |
||
| 386 | echo '* * * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.minutely )' >> /etc/crontab |
||
| 387 | fi |
||
| 388 | |||
| 389 | for t in minutely hourly daily monthly; do |
||
| 390 | for s in deploy/config/cron.$t/[0-9]* ; do |
||
| 391 | name=$(basename $s) |
||
| 392 | dest="/etc/cron.$t/$name" |
||
| 393 | if [ ! -f "$dest" ]; then |
||
| 394 | cp "$s" "$dest" |
||
| 395 | chmod +x "$dest" |
||
| 396 | fi |
||
| 397 | done |
||
| 398 | done |
||
| 399 | |||
| 400 | |||
| 401 | |||
| 402 | #!/bin/bash |
||
| 403 | |||
| 404 | cd /var/www/code |
||
| 405 | cp deploy/config/logrotate.conf /etc/logrotate.conf |
||
| 406 | 1581:ae8043b014c7 | Chris | #!/bin/bash |
| 407 | |||
| 408 | set -e |
||
| 409 | |||
| 410 | 1589:94669513c53c | Chris | # Last action: start the webserver |
| 411 | |||
| 412 | 1581:ae8043b014c7 | Chris | apache2ctl restart |