diff options
Diffstat (limited to 'script')
-rwxr-xr-x | script/install-as-user | 159 | ||||
-rwxr-xr-x | script/make-crontab | 16 | ||||
-rwxr-xr-x | script/rails-post-deploy | 59 | ||||
-rwxr-xr-x | script/site-specific-install.sh | 163 |
4 files changed, 354 insertions, 43 deletions
diff --git a/script/install-as-user b/script/install-as-user new file mode 100755 index 000000000..4fc341fc6 --- /dev/null +++ b/script/install-as-user @@ -0,0 +1,159 @@ +#!/bin/bash + +set -e +set -x + +if [ $# -ne 3 ] +then + cat >&2 <<EOUSAGE +Usage: $0 <UNIX-USER> <HOST> <INSTALLATION-DIRECTORY> +EOUSAGE + exit 1 +fi + +UNIX_USER="$1" +HOST="$2" +DIRECTORY="$3" +DB_NAME="alaveteli" + +# Check that the arguments we've been passed are sensible: + +IP_ADDRESS_FOR_HOST="$(dig +short $HOST)" + +if [ x = x"$IP_ADDRESS_FOR_HOST" ] +then + echo "The hostname $HOST didn't resolve to an IP address" + exit 1 +fi + +if ! id "$UNIX_USER" 2> /dev/null > /dev/null +then + echo "The user '$UNIX_USER' didn't exist." + exit 1 +fi + +if [ "$(whoami)" != "$UNIX_USER" ] +then + echo "This script should be run by the user '$UNIX_USER'." + exit 1 +fi + +REPOSITORY="$DIRECTORY/alaveteli" +LINK_DESTINATION="$HOME/alaveteli" + +ln -sfn "$REPOSITORY" $LINK_DESTINATION +cd "$REPOSITORY" + +BASHRC="$HOME/.bashrc" + +BASHRC_GEM_COMMENT="Set up local gem directory for Alaveteli" +BASHRC_START="# START $BASHRC_GEM_COMMENT" +BASHRC_END="# END $BASHRC_GEM_COMMENT" + +# Remove the old lines we added: +sed -ibackup "/$BASHRC_START/,/$BASHRC_END/d" "$BASHRC" + +# Create a temporary file, so we can prepend the lines we need. They +# need to be prepended since the Ubuntu skeleton .bashrc begins with +# '[ -z "$PS1" ] && return', skipping the rest of the .bashrc for +# non-interactive use, but we need the gem settings when invoking +# commands in the shell non-interactively. +TMP_BASHRC="$(mktemp "$BASHRC.XXXXXXX")" + +cat >>$TMP_BASHRC <<EOBRC +$BASHRC_START +export GEM_HOME="$HOME/gems" +mkdir -p "\$GEM_HOME" +export GEM_PATH= +export PATH="\$GEM_HOME/bin:\$PATH" +$BASHRC_END +EOBRC + +cat "$BASHRC" >> "$TMP_BASHRC" +mv "$TMP_BASHRC" "$BASHRC" + +source "$BASHRC" + +# Speed up the installation of gems: +echo 'gem: --no-ri --no-rdoc' > "$HOME/.gemrc" + +# Write sensible values into the config file: + +function random_alphanumerics() { + < /dev/urandom tr -dc A-Za-z0-9 | head -c$1 +} + +RANDOM_EMAIL_SECRET=$(random_alphanumerics 32) +RANDOM_EMERGENCY_PASSWORD=$(random_alphanumerics 10) +RANDOM_COOKIE_SECRET=$(random_alphanumerics 100) + +if ! [ -f config/general.yml ] +then + sed -r \ + -e "s,^( *DOMAIN:).*,\\1 '$HOST'," \ + -e "s,^( *FORCE_SSL:).*,\\1 false," \ + -e "s,^( *TIME_ZONE:).*,\\1 'Europe/London'," \ + -e "s,^( *BLOG_FEED:).*,\\1 null," \ + -e "s,^( *TWITTER_USERNAME:).*,\\1 null," \ + -e "s,^( *INCLUDE_DEFAULT_LOCALE_IN_URLS:).*,\\1 false," \ + -e "s,^( *INCOMING_EMAIL_DOMAIN:).*,\\1 '$HOST'," \ + -e "s,^( *INCOMING_EMAIL_PREFIX:).*,\\1 'foi+'," \ + -e "s,^( *INCOMING_EMAIL_SECRET:).*,\\1 '$RANDOM_EMAIL_SECRET'," \ + -e "s,^( *ADMIN_USERNAME:).*,\\1 'emergency'," \ + -e "s,^( *ADMIN_PASSWORD:).*,\\1 '$RANDOM_EMERGENCY_PASSWORD'," \ + -e "s,^( *CONTACT_EMAIL:).*,\\1 'postmaster@$HOST'," \ + -e "s,^( *TRACK_SENDER_EMAIL:).*,\\1 'postmaster@$HOST'," \ + -e "s,^( *COOKIE_STORE_SESSION_SECRET:).*,\\1 '$RANDOM_COOKIE_SECRET'," \ + -e "s,^( *FORWARD_NONBOUNCE_RESPONSES_TO:).*,\\1 'user-support@$HOST'," \ + -e "s,^( *HTML_TO_PDF_COMMAND:).*,\\1 '/usr/bin/wkhtmltopdf-static'," \ + -e "s,^( *EXCEPTION_NOTIFICATIONS_FROM:).*,\\1 'do-not-reply-to-this-address@$HOST'," \ + -e "/EXCEPTION_NOTIFICATIONS_TO:/,/^$/c EXCEPTION_NOTIFICATIONS_TO:\n - team@$HOST\n" \ + -e "s,^( *VARNISH_HOST:).*,\\1 null," \ + -e "s,^( *MTA_LOG_PATH:).*,\\1 '/var/log/mail/mail.log-*'," \ + -e "s,^( *MTA_LOG_TYPE:).*,\\1 'postfix'," \ + -e "s,^( *DONATION_URL:).*,\\1 null," \ + -e "s,^( *THEME_BRANCH:).*,\\1 'develop'," \ + -e "s,^( *USE_MAILCATCHER_IN_DEVELOPMENT:).*,\\1 false," \ + config/general.yml-example > config/general.yml +fi + +# add database.yml +sed -r \ + -e "s,^( *database: *)foi_(.*),\\1${DB_NAME}_\\2," \ + -e "s,^( *username: *).*,\\1${UNIX_USER}," \ + -e "s,^( *password: *).*,\\1null," \ + -e "s,^( *host: *).*,\\1/var/run/postgresql/," \ + -e "s,# constraint_disabling: false, constraint_disabling: false," \ + config/database.yml-example > config/database.yml + +for SUFFIX in production test development +do + REAL_DB_NAME="${DB_NAME}_$SUFFIX" + echo Creating the database $REAL_DB_NAME + # Create each database if it doesn't exist: + if ! psql -l | egrep "^ *$REAL_DB_NAME *\|" > /dev/null + then + createdb -T template0 --owner "$UNIX_USER" "$REAL_DB_NAME" + fi +done + +# Bundler isn't packaged on Debian squeeze, so we have to install it +# as a gem: + +which bundle || gem install bundler + +echo Running rails-post-deploy +script/rails-post-deploy + +LOADED_INDICATOR="$HOME/.alaveteli-sample-data-loaded" + +if [ ! -f "$LOADED_INDICATOR" ] +then + echo Running load-sample-data + bundle exec script/load-sample-data + + echo Running rebuild-xapian-index + script/rebuild-xapian-index + + touch "$LOADED_INDICATOR" +fi diff --git a/script/make-crontab b/script/make-crontab deleted file mode 100755 index d214f1485..000000000 --- a/script/make-crontab +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env python -import re - -mailto = "recipient-of-any-errors@localhost" -user = "user-to-run-as" -location = "/path/to/alaveteli" - -template = open("config/crontab-example").read() -template = re.sub(r"MAILTO=.*", "MAILTO=%s" % mailto, template) -template = template.replace("!!(*= $user *)!!", user) -template = re.sub(r"/data/vhost/.*/script", location + "/script", template) - -print template - - - diff --git a/script/rails-post-deploy b/script/rails-post-deploy index de950311c..c09868347 100755 --- a/script/rails-post-deploy +++ b/script/rails-post-deploy @@ -24,27 +24,32 @@ fi # read config file in for later (STAGING_SITE) if [ -e "config/general" ] || [ -e "config/general.yml" ] then - . commonlib/shlib/deployfns - read_conf config/general + . commonlib/shlib/deployfns + read_conf config/general else - OPTION_DOMAIN=127.0.0.1:3000 - OPTION_STAGING_SITE=1 + OPTION_DOMAIN=127.0.0.1:3000 + OPTION_STAGING_SITE=1 fi # create initial log files if [ -e $TOP_DIR/../logs ] then - # mySociety servers have logs dir in level above - rm -f log - ln -s $TOP_DIR/../logs log + # mySociety servers have logs dir in level above + if ! [ -h log ] && [ -d log ] + then + # If log is a directory rather than a symlink, move that + # directory out of the way: + mv log log.original + fi + ln -sfn $TOP_DIR/../logs log else - # otherwise just make the directory - if [ -h log ] - then - # remove any old-style symlink first - rm -f log - fi - mkdir -p log + # otherwise just make the directory + if [ -h log ] + then + # remove any old-style symlink first + rm -f log + fi + mkdir -p log fi cd log @@ -55,18 +60,18 @@ cd .. if [ "$OPTION_STAGING_SITE" = "0" ] then cat <<-END - - ***************************************************************** - WARNING: About to make config/rails_env.rb which, via special - code in config/boot.rb, forces the Rails environment to be - "production". If this is a development system, please edit your - config/general.yml file and set the STAGING_SITE option to 1, - and also delete the generated config/rails_env.rb file. - Alternatively, you can override config/rails_env.rb at any time - with an environment variable. - ***************************************************************** - - END + + ***************************************************************** + WARNING: About to make config/rails_env.rb which, via special + code in config/boot.rb, forces the Rails environment to be + "production". If this is a development system, please edit your + config/general.yml file and set the STAGING_SITE option to 1, + and also delete the generated config/rails_env.rb file. + Alternatively, you can override config/rails_env.rb at any time + with an environment variable. + ***************************************************************** + +END echo "ENV['RAILS_ENV'] ||= 'production'" > config/rails_env.rb fi @@ -81,7 +86,7 @@ then fi if [ "$TRAVIS" = "true" ] then - bundle_install_options="--without development develop --deployment" + bundle_install_options="--without development develop --deployment" fi bundle install $bundle_install_options diff --git a/script/site-specific-install.sh b/script/site-specific-install.sh new file mode 100755 index 000000000..8917fd577 --- /dev/null +++ b/script/site-specific-install.sh @@ -0,0 +1,163 @@ +#!/bin/sh + +# Set IDEAL_VERSION to the commitish we want to check out; typically +# this is the version tag. Since this may not exist before release, +# fall back to the master branch: +VERSIONS="origin/install-script 0.15 origin/master" + +PARENT_SCRIPT_URL=https://github.com/mysociety/commonlib/blob/master/bin/install-site.sh + +misuse() { + echo The variable $1 was not defined, and it should be. + echo This script should not be run directly - instead, please run: + echo $PARENT_SCRIPT_URL + exit 1 +} + +# Strictly speaking we don't need to check all of these, but it might +# catch some errors made when changing install-site.sh + +[ -z "$DIRECTORY" ] && misuse DIRECTORY +[ -z "$UNIX_USER" ] && misuse UNIX_USER +[ -z "$REPOSITORY" ] && misuse REPOSITORY +[ -z "$REPOSITORY_URL" ] && misuse REPOSITORY_URL +[ -z "$BRANCH" ] && misuse BRANCH +[ -z "$SITE" ] && misuse SITE +[ -z "$DEFAULT_SERVER" ] && misuse DEFAULT_SERVER +[ -z "$HOST" ] && misuse HOST +[ -z "$DISTRIBUTION" ] && misuse DISTRIBUTION +[ -z "$VERSIONS" ] && misuse VERSIONS +[ -z "$DEVELOPMENT_INSTALL" ] && misuse DEVELOPMENT_INSTALL +[ -z "$BIN_DIRECTORY" ] && misuse BIN_DIRECTORY + +update_mysociety_apt_sources + +if [ ! "$DEVELOPMENT_INSTALL" = true ]; then + install_nginx + add_website_to_nginx + # Check out the first available requested version: + su -l -c "cd '$REPOSITORY' && (for v in $VERSIONS; do git checkout $v && break; done)" \ + "$UNIX_USER" +fi + +install_postfix + +# Now there's quite a bit of Postfix configuration that we need to +# make sure is present: + +ensure_line_present \ + "^ *alaveteli *unix *" \ + "alaveteli unix - n n - 50 pipe flags=R user=$UNIX_USER argv=$REPOSITORY/script/mailin" \ + /etc/postfix/master.cf 644 + +ensure_line_present \ + "^ *transport_maps *=" \ + "transport_maps = regexp:/etc/postfix/transports" \ + /etc/postfix/main.cf 644 + +ensure_line_present \ + "^ *local_recipient_maps *=" \ + "local_recipient_maps = proxy:unix:passwd.byname regexp:/etc/postfix/recipients" \ + /etc/postfix/main.cf 644 + +ensure_line_present \ + "^ *mydestination *=" \ + "mydestination = $HOST, $(hostname --fqdn), localhost.localdomain, localhost" \ + /etc/postfix/main.cf 644 + +ensure_line_present \ + "^do-not-reply" \ + "do-not-reply-to-this-address: :blackhole:" \ + /etc/aliases 644 + +ensure_line_present \ + "^mail" \ + "mail.* -/var/log/mail/mail.log" \ + /etc/rsyslog.d/50-default.conf 644 + +cat > /etc/postfix/transports <<EOF +/^foi.*/ alaveteli +EOF + +cat > /etc/postfix/recipients <<EOF +/^foi.*/ this-is-ignored +/^postmaster@/ this-is-ignored +/^user-support@/ this-is-ignored +/^team@/ this-is-ignored +EOF + +if ! egrep '^ */var/log/mail/mail.log *{' /etc/logrotate.d/rsyslog +then + cat >> /etc/logrotate.d/rsyslog <<EOF +/var/log/mail/mail.log { + rotate 30 + daily + dateext + missingok + notifempty + compress + delaycompress + sharedscripts + postrotate + reload rsyslog >/dev/null 2>&1 || true + endscript +} +EOF +fi + +/etc/init.d/rsyslog restart + +newaliases +postmap /etc/postfix/transports +postmap /etc/postfix/recipients +postfix reload + +# (end of the Postfix configuration) + +install_website_packages + +# Make the PostgreSQL user a superuser to avoid the irritating error: +# PG::Error: ERROR: permission denied: "RI_ConstraintTrigger_16564" is a system trigger +# This is only needed for loading the sample data, so the superuser +# permissions are dropped below. +add_postgresql_user --superuser + +export DEVELOPMENT_INSTALL +su -l -c "$BIN_DIRECTORY/install-as-user '$UNIX_USER' '$HOST' '$DIRECTORY'" "$UNIX_USER" + +# Now that the install-as-user script has loaded the sample data, we +# no longer need the PostgreSQL user to be a superuser: +echo "ALTER USER \"$UNIX_USER\" WITH NOSUPERUSER;" | su -l -c 'psql' postgres + +if [ ! "$DEVELOPMENT_INSTALL" = true ]; then + install_sysvinit_script +fi + +# Set up root's crontab: + +cd "$REPOSITORY" + +echo -n "Creating /etc/cron.d/alaveteli... " +(su -l -c "cd '$REPOSITORY' && bundle exec rake config_files:convert_crontab DEPLOY_USER='$UNIX_USER' VHOST_DIR='$DIRECTORY' VCSPATH='$SITE' SITE='$SITE' CRONTAB=config/crontab-example" "$UNIX_USER") > /etc/cron.d/alaveteli +# There are some other parts to rewrite, so just do them with sed: +sed -r \ + -e "/foi-purge-varnish/d" \ + -e "s,^(MAILTO=).*,\1root@$HOST," \ + -e "s,run-with-lockfile,$REPOSITORY/commonlib/bin/run-with-lockfile.sh,g" \ + -i /etc/cron.d/alaveteli +echo $DONE_MSG + +echo -n "Creating /etc/init.d/foi-alert-tracks... " +(su -l -c "cd '$REPOSITORY' && bundle exec rake config_files:convert_init_script DEPLOY_USER='$UNIX_USER' VHOST_DIR='$DIRECTORY' SCRIPT_FILE=config/alert-tracks-debian.ugly" "$UNIX_USER") > /etc/init.d/foi-alert-tracks +chmod a+rx /etc/init.d/foi-alert-tracks +echo $DONE_MSG + +if [ $DEFAULT_SERVER = true ] && [ x != x$EC2_HOSTNAME ] +then + # If we're setting up as the default on an EC2 instance, make sure + # that the /etc/rc.local is set up to run the install script again + # to update the hostname: + overwrite_rc_local +fi + +done_msg "Installation complete"; echo |