8014, 8059: Unify Rails package building.
[arvados.git] / jenkins / rails-package-scripts / postinst.sh
1 #!/bin/sh
2 # This code runs after package variable definitions and step2.sh.
3
4 set -e
5
6 DATABASE_READY=1
7 APPLICATION_READY=1
8
9 if [ -s "$HOME/.rvm/scripts/rvm" ] || [ -s "/usr/local/rvm/scripts/rvm" ]; then
10     COMMAND_PREFIX="/usr/local/rvm/bin/rvm-exec default"
11 else
12     COMMAND_PREFIX=
13 fi
14
15 report_not_ready() {
16     local ready_flag="$1"; shift
17     local config_file="$1"; shift
18     if [ "1" != "$ready_flag" ]; then cat >&2 <<EOF
19
20 PLEASE NOTE:
21
22 The $PACKAGE_NAME package was not configured completely because
23 $config_file needs some tweaking.
24 Please refer to the documentation at
25 <$DOC_URL> for more details.
26
27 When $(basename "$config_file") has been modified,
28 reconfigure or reinstall this package.
29
30 EOF
31     fi
32 }
33
34 report_web_service_warning() {
35     local warning="$1"; shift
36     cat >&2 <<EOF
37
38 WARNING: $warning.
39
40 To override, set the WEB_SERVICE environment variable to the name of the service
41 hosting the Rails server.
42
43 For Debian-based systems, then reconfigure this package with dpkg-reconfigure.
44
45 For RPM-based systems, then reinstall this package.
46
47 EOF
48 }
49
50 run_and_report() {
51     # Usage: run_and_report ACTION_MSG CMD
52     # This is the usual wrapper that prints ACTION_MSG, runs CMD, then writes
53     # a message about whether CMD succeeded or failed.  Returns the exit code
54     # of CMD.
55     local action_message="$1"; shift
56     local retcode=0
57     echo -n "$action_message..."
58     if "$@"; then
59         echo " done."
60     else
61         retcode=$?
62         echo " failed."
63     fi
64     return $retcode
65 }
66
67 setup_conffile() {
68     # Usage: setup_conffile CONFFILE_PATH [SOURCE_PATH]
69     # Both paths are relative to RELEASE_CONFIG_PATH.
70     # This function will try to safely ensure that a symbolic link for
71     # the configuration file points from RELEASE_CONFIG_PATH to CONFIG_PATH.
72     # If SOURCE_PATH is given, this function will try to install that file as
73     # the configuration file in CONFIG_PATH, and return 1 if the file in
74     # CONFIG_PATH is unmodified from the source.
75     local conffile_relpath="$1"; shift
76     local conffile_source="$1"
77     local release_conffile="$RELEASE_CONFIG_PATH/$conffile_relpath"
78     local etc_conffile="$CONFIG_PATH/$(basename "$conffile_relpath")"
79
80     # Note that -h can return true and -e will return false simultaneously
81     # when the target is a dangling symlink.  We're okay with that outcome,
82     # so check -h first.
83     if [ ! -h "$release_conffile" ]; then
84         if [ ! -e "$release_conffile" ]; then
85             ln -s "$etc_conffile" "$release_conffile"
86         # If there's a config file in /var/www identical to the one in /etc,
87         # overwrite it with a symlink.
88         elif cmp --quiet "$release_conffile" "$etc_conffile"; then
89             ln --force -s "$etc_conffile" "$release_conffile"
90         fi
91     fi
92
93     if [ -n "$conffile_source" ]; then
94         cp --no-clobber "$RELEASE_CONFIG_PATH/$conffile_source" "$etc_conffile"
95         # Even if $etc_conffile already existed, it might be unmodified from
96         # the source.  This is especially likely when a user installs, updates
97         # database.yml, then reconfigures before they update application.yml.
98         # Use cmp to be sure whether $etc_conffile is modified.
99         if cmp --quiet "$RELEASE_CONFIG_PATH/$conffile_source" "$etc_conffile"; then
100             return 1
101         fi
102     fi
103 }
104
105 prepare_database() {
106   DB_MIGRATE_STATUS=`$COMMAND_PREFIX bundle exec rake db:migrate:status 2>&1 || true`
107   if echo $DB_MIGRATE_STATUS | grep -qF 'Schema migrations table does not exist yet.'; then
108       # The database exists, but the migrations table doesn't.
109       run_and_report "Setting up database" $COMMAND_PREFIX bundle exec \
110                      rake "$RAILSPKG_DATABASE_LOAD_TASK" db:seed
111   elif echo $DB_MIGRATE_STATUS | grep -q '^database: '; then
112       run_and_report "Running db:migrate" \
113                      $COMMAND_PREFIX bundle exec rake db:migrate
114   elif echo $DB_MIGRATE_STATUS | grep -q 'database .* does not exist'; then
115       if ! run_and_report "Running db:setup" \
116            $COMMAND_PREFIX bundle exec rake db:setup 2>/dev/null; then
117           echo "Warning: unable to set up database." >&2
118           DATABASE_READY=0
119       fi
120   else
121     echo "Warning: Database is not ready to set up. Skipping database setup." >&2
122     DATABASE_READY=0
123   fi
124 }
125
126 configure_version() {
127   WEB_SERVICE=${WEB_SERVICE:-$(service --status-all 2>/dev/null \
128       | grep -Eo '\bnginx|httpd[^[:space:]]*' || true)}
129   if [ -z "$WEB_SERVICE" ]; then
130     report_web_service_warning "Web service (Nginx or Apache) not found"
131   elif [ "$WEB_SERVICE" != "$(echo "$WEB_SERVICE" | head -n 1)" ]; then
132     WEB_SERVICE=$(echo "$WEB_SERVICE" | head -n 1)
133     report_web_service_warning \
134         "Multiple web services found.  Choosing the first one ($WEB_SERVICE)"
135   fi
136
137   if [ -e /etc/redhat-release ]; then
138       # Recognize any service that starts with "nginx"; e.g., nginx16.
139       if [ "$WEB_SERVICE" != "${WEB_SERVICE#nginx}" ]; then
140         WWW_OWNER=nginx:nginx
141       else
142         WWW_OWNER=apache:apache
143       fi
144   else
145       # Assume we're on a Debian-based system for now.
146       # Both Apache and Nginx run as www-data by default.
147       WWW_OWNER=www-data:www-data
148   fi
149
150   echo
151   echo "Assumption: $WEB_SERVICE is configured to serve Rails from"
152   echo "            $RELEASE_PATH"
153   echo "Assumption: $WEB_SERVICE and passenger run as $WWW_OWNER"
154   echo
155
156   echo -n "Creating symlinks to configuration in $CONFIG_PATH ..."
157   mkdir -p $CONFIG_PATH
158   setup_conffile environments/production.rb environments/production.rb.example \
159       || true
160   setup_conffile application.yml application.yml.example || APPLICATION_READY=0
161   if [ -n "$RAILSPKG_DATABASE_LOAD_TASK" ]; then
162       setup_conffile database.yml database.yml.example || DATABASE_READY=0
163   fi
164   setup_extra_conffiles
165   echo "... done."
166
167   # Before we do anything else, make sure some directories and files are in place
168   if [ ! -e $SHARED_PATH/log ]; then mkdir -p $SHARED_PATH/log; fi
169   if [ ! -e $RELEASE_PATH/tmp ]; then mkdir -p $RELEASE_PATH/tmp; fi
170   if [ ! -e $RELEASE_PATH/log ]; then ln -s $SHARED_PATH/log $RELEASE_PATH/log; fi
171   if [ ! -e $SHARED_PATH/log/production.log ]; then touch $SHARED_PATH/log/production.log; fi
172
173   cd "$RELEASE_PATH"
174   export RAILS_ENV=production
175
176   if ! $COMMAND_PREFIX bundle --version >/dev/null; then
177       run_and_report "Installing bundle" $COMMAND_PREFIX gem install bundle
178   fi
179
180   run_and_report "Running bundle install" \
181       $COMMAND_PREFIX bundle install --path $SHARED_PATH/vendor_bundle --quiet
182
183   echo -n "Ensuring directory and file permissions ..."
184   # Ensure correct ownership of a few files
185   chown "$WWW_OWNER" $RELEASE_PATH/config/environment.rb
186   chown "$WWW_OWNER" $RELEASE_PATH/config.ru
187   chown "$WWW_OWNER" $RELEASE_PATH/Gemfile.lock
188   chown -R "$WWW_OWNER" $RELEASE_PATH/tmp
189   chown -R "$WWW_OWNER" $SHARED_PATH/log
190   case "$RAILSPKG_DATABASE_LOAD_TASK" in
191       db:schema:load) chown "$WWW_OWNER" $RELEASE_PATH/db/schema.rb ;;
192       db:structure:load) chown "$WWW_OWNER" $RELEASE_PATH/db/structure.sql ;;
193   esac
194   chmod 644 $SHARED_PATH/log/*
195   chmod -R 2775 $RELEASE_PATH/tmp
196   echo "... done."
197
198   if [ -n "$RAILSPKG_DATABASE_LOAD_TASK" ]; then
199       chown "$WWW_OWNER" $RELEASE_PATH/config/database.yml
200       prepare_database
201   fi
202
203   if [ 11 = "$RAILSPKG_SUPPORTS_CONFIG_CHECK$APPLICATION_READY" ]; then
204       run_and_report "Checking application.yml for completeness" \
205           $COMMAND_PREFIX bundle exec rake config:check || APPLICATION_READY=0
206   fi
207
208   # precompile assets; thankfully this does not take long
209   if [ "$APPLICATION_READY" = "1" ]; then
210       run_and_report "Precompiling assets" \
211           $COMMAND_PREFIX bundle exec rake assets:precompile -q -s 2>/dev/null \
212           || APPLICATION_READY=0
213   else
214       echo "Precompiling assets... skipped."
215   fi
216   chown -R "$WWW_OWNER" $RELEASE_PATH/tmp
217
218   if [ ! -z "$WEB_SERVICE" ]; then
219       service "$WEB_SERVICE" restart
220   fi
221 }
222
223 if [ "$1" = configure ]; then
224   # This is a debian-based system
225   configure_version
226 elif [ "$1" = "0" ] || [ "$1" = "1" ] || [ "$1" = "2" ]; then
227   # This is an rpm-based system
228   configure_version
229 fi
230
231 report_not_ready "$DATABASE_READY" "$CONFIG_PATH/database.yml"
232 report_not_ready "$APPLICATION_READY" "$CONFIG_PATH/application.yml"