2 # Copyright (C) The Arvados Authors. All rights reserved.
4 # SPDX-License-Identifier: AGPL-3.0
6 # This code runs after package variable definitions and step2.sh.
14 local ready_flag="$1"; shift
15 local config_file="$1"; shift
16 if [ "1" != "$ready_flag" ]; then cat >&2 <<EOF
20 The $PACKAGE_NAME package was not configured completely because
21 $config_file needs some tweaking.
22 Please refer to the documentation at
23 <$DOC_URL> for more details.
25 When $(basename "$config_file") has been modified,
26 reconfigure or reinstall this package.
32 report_web_service_warning() {
33 local warning="$1"; shift
38 To override, set the WEB_SERVICE environment variable to the name of the service
39 hosting the Rails server.
41 For Debian-based systems, then reconfigure this package with dpkg-reconfigure.
43 For RPM-based systems, then reinstall this package.
49 # Usage: run_and_report ACTION_MSG CMD
50 # This is the usual wrapper that prints ACTION_MSG, runs CMD, then writes
51 # a message about whether CMD succeeded or failed. Returns the exit code
53 local action_message="$1"; shift
55 echo -n "$action_message..."
66 for confdir in "$@"; do
67 if [ ! -d "$confdir" ]; then
68 install -d -g "$WWW_OWNER" -m 0750 "$confdir"
74 # Usage: setup_conffile CONFFILE_PATH [SOURCE_PATH]
75 # Both paths are relative to RELEASE_CONFIG_PATH.
76 # This function will try to safely ensure that a symbolic link for
77 # the configuration file points from RELEASE_CONFIG_PATH to CONFIG_PATH.
78 # If SOURCE_PATH is given, this function will try to install that file as
79 # the configuration file in CONFIG_PATH, and return 1 if the file in
80 # CONFIG_PATH is unmodified from the source.
81 local conffile_relpath="$1"; shift
82 local conffile_source="$1"
83 local release_conffile="$RELEASE_CONFIG_PATH/$conffile_relpath"
84 local etc_conffile="$CONFIG_PATH/$(basename "$conffile_relpath")"
86 # Note that -h can return true and -e will return false simultaneously
87 # when the target is a dangling symlink. We're okay with that outcome,
89 if [ ! -h "$release_conffile" ]; then
90 if [ ! -e "$release_conffile" ]; then
91 ln -s "$etc_conffile" "$release_conffile"
92 # If there's a config file in /var/www identical to the one in /etc,
93 # overwrite it with a symlink after porting its permissions.
94 elif cmp --quiet "$release_conffile" "$etc_conffile"; then
95 local ownership="$(stat -c "%u:%g" "$release_conffile")"
96 local owning_group="${ownership#*:}"
97 if [ 0 != "$owning_group" ]; then
98 chgrp "$owning_group" "$CONFIG_PATH" /etc/arvados
100 chown "$ownership" "$etc_conffile"
101 chmod --reference="$release_conffile" "$etc_conffile"
102 ln --force -s "$etc_conffile" "$release_conffile"
106 if [ -n "$conffile_source" ]; then
107 if [ ! -e "$etc_conffile" ]; then
108 install -g "$WWW_OWNER" -m 0640 \
109 "$RELEASE_CONFIG_PATH/$conffile_source" "$etc_conffile"
111 # Even if $etc_conffile already existed, it might be unmodified from
112 # the source. This is especially likely when a user installs, updates
113 # database.yml, then reconfigures before they update application.yml.
114 # Use cmp to be sure whether $etc_conffile is modified.
115 elif cmp --quiet "$RELEASE_CONFIG_PATH/$conffile_source" "$etc_conffile"; then
122 DB_MIGRATE_STATUS=`bin/rake db:migrate:status 2>&1 || true`
123 if echo "$DB_MIGRATE_STATUS" | grep -qF 'Schema migrations table does not exist yet.'; then
124 # The database exists, but the migrations table doesn't.
125 run_and_report "Setting up database" bin/rake \
126 "$RAILSPKG_DATABASE_LOAD_TASK" db:seed
127 elif echo "$DB_MIGRATE_STATUS" | grep -q '^database: '; then
128 run_and_report "Running db:migrate" \
130 elif echo "$DB_MIGRATE_STATUS" | grep -q 'database .* does not exist'; then
131 if ! run_and_report "Running db:setup" \
132 bin/rake db:setup 2>/dev/null; then
133 echo "Warning: unable to set up database." >&2
137 echo "Warning: Database is not ready to set up. Skipping database setup." >&2
142 configure_version() {
143 if [ -n "$WEB_SERVICE" ]; then
144 SERVICE_MANAGER=$(guess_service_manager)
145 elif WEB_SERVICE=$(list_services_systemd | grep -E '^(nginx|httpd)'); then
146 SERVICE_MANAGER=systemd
147 elif WEB_SERVICE=$(list_services_service \
148 | grep -Eo '\b(nginx|httpd)[^[:space:]]*'); then
149 SERVICE_MANAGER=service
152 if [ -z "$WEB_SERVICE" ]; then
153 report_web_service_warning "Web service (Nginx or Apache) not found"
154 elif [ "$WEB_SERVICE" != "$(echo "$WEB_SERVICE" | head -n 1)" ]; then
155 WEB_SERVICE=$(echo "$WEB_SERVICE" | head -n 1)
156 report_web_service_warning \
157 "Multiple web services found. Choosing the first one ($WEB_SERVICE)"
160 if [ -e /etc/redhat-release ]; then
161 # Recognize any service that starts with "nginx"; e.g., nginx16.
162 if [ "$WEB_SERVICE" != "${WEB_SERVICE#nginx}" ]; then
168 # Assume we're on a Debian-based system for now.
169 # Both Apache and Nginx run as www-data by default.
174 echo "Assumption: $WEB_SERVICE is configured to serve Rails from"
175 echo " $RELEASE_PATH"
176 echo "Assumption: $WEB_SERVICE and passenger run as $WWW_OWNER"
179 echo -n "Creating symlinks to configuration in $CONFIG_PATH ..."
180 setup_confdirs /etc/arvados "$CONFIG_PATH"
181 setup_conffile environments/production.rb environments/production.rb.example \
183 setup_extra_conffiles
186 # Before we do anything else, make sure some directories and files are in place
187 if [ ! -e $SHARED_PATH/log ]; then mkdir -p $SHARED_PATH/log; fi
188 if [ ! -e $RELEASE_PATH/tmp ]; then mkdir -p $RELEASE_PATH/tmp; fi
189 if [ ! -e $RELEASE_PATH/log ]; then ln -s $SHARED_PATH/log $RELEASE_PATH/log; fi
190 if [ ! -e $SHARED_PATH/log/production.log ]; then touch $SHARED_PATH/log/production.log; fi
193 export RAILS_ENV=production
195 run_and_report "Installing bundler" gem install --conservative --version '~> 2.4.0' bundler
196 local bundle="$(gem contents --version '~> 2.4.0' bundler | grep -E '/(bin|exe)/bundle$' | tail -n1)"
197 if ! [ -x "$bundle" ]; then
198 # Some distros (at least Ubuntu 24.04) append the Ruby version to the
199 # executable name, but that isn't reflected in the output of
200 # `gem contents`. Check for that version.
201 bundle="$bundle$(ruby -e 'puts RUBY_VERSION.split(".")[..1].join(".")')"
202 if ! [ -x "$bundle" ]; then
203 echo "Error: failed to find \`bundle\` command after installing bundler gem" >&2
208 local bundle_path="$SHARED_PATH/vendor_bundle"
209 run_and_report "Running bundle config set --local path $SHARED_PATH/vendor_bundle" \
210 "$bundle" config set --local path "$bundle_path"
212 # As of April 2024/Bundler 2.4, `bundle install` tends not to install gems
213 # which are already installed system-wide, which causes bundle activation to
214 # fail later. Work around this by installing all gems manually.
215 find vendor/cache -maxdepth 1 -name '*.gem' -print0 \
216 | run_and_report "Installing bundle gems" xargs -0r \
217 gem install --conservative --ignore-dependencies --local --quiet \
218 --install-dir="$bundle_path/ruby/$(ruby -e 'puts RUBY_VERSION')"
219 run_and_report "Running bundle install" "$bundle" install --prefer-local --quiet
220 run_and_report "Verifying bundle is complete" "$bundle" exec true
222 echo -n "Ensuring directory and file permissions ..."
223 # Ensure correct ownership of a few files
224 chown "$WWW_OWNER:" $RELEASE_PATH/config/environment.rb
225 chown "$WWW_OWNER:" $RELEASE_PATH/config.ru
226 chown "$WWW_OWNER:" $RELEASE_PATH/Gemfile.lock
227 chown -R "$WWW_OWNER:" $RELEASE_PATH/tmp || true
228 chown -R "$WWW_OWNER:" $SHARED_PATH/log
229 # Make sure postgres doesn't try to use a pager.
231 case "$RAILSPKG_DATABASE_LOAD_TASK" in
232 # db:structure:load was deprecated in Rails 6.1 and shouldn't be used.
233 db:schema:load | db:structure:load)
234 chown "$WWW_OWNER:" $RELEASE_PATH/db/schema.rb || true
235 chown "$WWW_OWNER:" $RELEASE_PATH/db/structure.sql || true
238 chmod 644 $SHARED_PATH/log/*
239 chmod -R 2775 $RELEASE_PATH/tmp || true
242 if [ -n "$RAILSPKG_DATABASE_LOAD_TASK" ]; then
246 if [ -e /etc/arvados/config.yml ]; then
247 # warn about config errors (deprecated/removed keys from
248 # previous version, etc)
249 run_and_report "Checking configuration for completeness" \
250 bin/rake config:check || APPLICATION_READY=0
255 chown -R "$WWW_OWNER:" $RELEASE_PATH/tmp
257 if [ -n "$SERVICE_MANAGER" ]; then
258 service_command "$SERVICE_MANAGER" restart "$WEB_SERVICE"
262 if [ "$1" = configure ]; then
263 # This is a debian-based system
265 elif [ "$1" = "0" ] || [ "$1" = "1" ] || [ "$1" = "2" ]; then
266 # This is an rpm-based system
270 report_not_ready "$APPLICATION_READY" "/etc/arvados/config.yml"