2 # Copyright (C) The Arvados Authors. All rights reserved.
4 # SPDX-License-Identifier: AGPL-3.0
6 # This code runs after package variable definitions.
10 for DISTRO_FAMILY in $(. /etc/os-release && echo "${ID:-} ${ID_LIKE:-}"); do
11 case "$DISTRO_FAMILY" in
13 RESETUP_CMD="dpkg-reconfigure $PACKAGE_NAME"
16 RESETUP_CMD="dnf reinstall $PACKAGE_NAME"
20 if [ -z "$RESETUP_CMD" ]; then
21 echo "$PACKAGE_NAME postinst skipped: don't recognize the distribution from /etc/os-release" >&2
24 # Default documentation URL. This can be set to a more specific URL.
25 NOT_READY_DOC_URL="https://doc.arvados.org/install/install-api-server.html"
27 report_web_service_warning() {
28 local warning="$1"; shift
33 To override, set the WEB_SERVICE environment variable to the name of the service
34 hosting the Rails server.
36 After you do that, resume $PACKAGE_NAME setup by running:
42 # Usage: run_and_report ACTION_MSG CMD
43 # This is the usual wrapper that prints ACTION_MSG, runs CMD, then writes
44 # a message about whether CMD succeeded or failed. Returns the exit code
46 local action_message="$1"; shift
48 echo -n "$action_message..."
59 for confdir in "$@"; do
60 if [ ! -d "$confdir" ]; then
61 install -d -g "$WWW_OWNER" -m 0750 "$confdir"
67 # Usage: setup_conffile CONFFILE_PATH [SOURCE_PATH]
68 # Both paths are relative to RELEASE_CONFIG_PATH.
69 # This function will try to safely ensure that a symbolic link for
70 # the configuration file points from RELEASE_CONFIG_PATH to CONFIG_PATH.
71 # If SOURCE_PATH is given, this function will try to install that file as
72 # the configuration file in CONFIG_PATH, and return 1 if the file in
73 # CONFIG_PATH is unmodified from the source.
74 local conffile_relpath="$1"; shift
75 local conffile_source="$1"
76 local release_conffile="$RELEASE_CONFIG_PATH/$conffile_relpath"
77 local etc_conffile="$CONFIG_PATH/$(basename "$conffile_relpath")"
79 # Note that -h can return true and -e will return false simultaneously
80 # when the target is a dangling symlink. We're okay with that outcome,
82 if [ ! -h "$release_conffile" ]; then
83 if [ ! -e "$release_conffile" ]; then
84 ln -s "$etc_conffile" "$release_conffile"
85 # If there's a config file in /var/www identical to the one in /etc,
86 # overwrite it with a symlink after porting its permissions.
87 elif cmp --quiet "$release_conffile" "$etc_conffile"; then
88 local ownership="$(stat -c "%u:%g" "$release_conffile")"
89 local owning_group="${ownership#*:}"
90 if [ 0 != "$owning_group" ]; then
91 chgrp "$owning_group" "$CONFIG_PATH" /etc/arvados
93 chown "$ownership" "$etc_conffile"
94 chmod --reference="$release_conffile" "$etc_conffile"
95 ln --force -s "$etc_conffile" "$release_conffile"
99 if [ -n "$conffile_source" ]; then
100 if [ ! -e "$etc_conffile" ]; then
101 install -g "$WWW_OWNER" -m 0640 \
102 "$RELEASE_CONFIG_PATH/$conffile_source" "$etc_conffile"
104 # Even if $etc_conffile already existed, it might be unmodified from
105 # the source. This is especially likely when a user installs, updates
106 # database.yml, then reconfigures before they update application.yml.
107 # Use cmp to be sure whether $etc_conffile is modified.
108 elif cmp --quiet "$RELEASE_CONFIG_PATH/$conffile_source" "$etc_conffile"; then
115 # Prevent PostgreSQL from trying to page output
117 DB_MIGRATE_STATUS=`bin/rake db:migrate:status 2>&1 || true`
118 if echo "$DB_MIGRATE_STATUS" | grep -qF 'Schema migrations table does not exist yet.'; then
119 # The database exists, but the migrations table doesn't.
120 run_and_report "Setting up database" bin/rake db:schema:load db:seed
121 elif echo "$DB_MIGRATE_STATUS" | grep -q '^database: '; then
122 run_and_report "Running db:migrate" bin/rake db:migrate
123 elif echo "$DB_MIGRATE_STATUS" | grep -q 'database .* does not exist'; then
124 run_and_report "Running db:setup" bin/rake db:setup
126 # We don't have enough configuration to even check the database.
131 configure_version() {
132 if [ -n "$WEB_SERVICE" ]; then
134 elif command -v nginx >/dev/null 2>&1; then
137 report_web_service_warning "Web service (nginx) not found"
140 case "$DISTRO_FAMILY" in
141 debian) WWW_OWNER=www-data ;;
142 rhel) WWW_OWNER=nginx ;;
145 # Before we do anything else, make sure some directories and files are in place
146 if [ ! -e $SHARED_PATH/log ]; then mkdir -p $SHARED_PATH/log; fi
147 if [ ! -e $RELEASE_PATH/tmp ]; then mkdir -p $RELEASE_PATH/tmp; fi
148 if [ ! -e $RELEASE_PATH/log ]; then ln -s $SHARED_PATH/log $RELEASE_PATH/log; fi
149 if [ ! -e $SHARED_PATH/log/production.log ]; then touch $SHARED_PATH/log/production.log; fi
152 export RAILS_ENV=production
154 run_and_report "Installing bundler" gem install --conservative --version '~> 2.4.0' bundler
155 local ruby_minor_ver="$(ruby -e 'puts RUBY_VERSION.split(".")[..1].join(".")')"
156 local bundle="$(gem contents --version '~> 2.4.0' bundler | grep -E '/(bin|exe)/bundle$' | tail -n1)"
157 if ! [ -x "$bundle" ]; then
158 # Some distros (at least Ubuntu 24.04) append the Ruby version to the
159 # executable name, but that isn't reflected in the output of
160 # `gem contents`. Check for that version.
161 bundle="$bundle$ruby_minor_ver"
162 if ! [ -x "$bundle" ]; then
163 echo "Error: failed to find \`bundle\` command after installing bundler gem" >&2
168 local bundle_path="$SHARED_PATH/vendor_bundle"
169 run_and_report "Running bundle config set --local path $SHARED_PATH/vendor_bundle" \
170 "$bundle" config set --local path "$bundle_path"
172 # As of April 2024/Bundler 2.4, `bundle install` tends not to install gems
173 # which are already installed system-wide, which causes bundle activation to
174 # fail later. Work around this by installing all gems manually.
175 find vendor/cache -maxdepth 1 -name '*.gem' -print0 \
176 | run_and_report "Installing bundle gems" xargs -0r \
177 gem install --conservative --ignore-dependencies --local --quiet \
178 --install-dir="$bundle_path/ruby/$ruby_minor_ver.0"
179 run_and_report "Running bundle install" "$bundle" install --prefer-local --quiet
180 run_and_report "Verifying bundle is complete" "$bundle" exec true
182 if [ -z "$WWW_OWNER" ]; then
183 NOT_READY_REASON="there is no web service account to own Arvados configuration"
184 NOT_READY_DOC_URL="https://doc.arvados.org/install/nginx.html"
188 Assumption: $WEB_SERVICE is configured to serve Rails from
190 Assumption: $WEB_SERVICE and passenger run as $WWW_OWNER
194 echo -n "Creating symlinks to configuration in $CONFIG_PATH ..."
195 setup_confdirs /etc/arvados "$CONFIG_PATH"
196 setup_conffile environments/production.rb environments/production.rb.example \
198 # Rails 5.2 does not tolerate dangling symlinks in the initializers
199 # directory, and this one can still be there, left over from a previous
200 # version of the API server package.
201 rm -f $RELEASE_PATH/config/initializers/omniauth.rb
204 echo -n "Ensuring directory and file permissions ..."
205 # Ensure correct ownership of a few files
206 chown "$WWW_OWNER:" $RELEASE_PATH/config/environment.rb
207 chown "$WWW_OWNER:" $RELEASE_PATH/config.ru
208 chown "$WWW_OWNER:" $RELEASE_PATH/db/structure.sql
209 chown "$WWW_OWNER:" $RELEASE_PATH/Gemfile.lock
210 chown -R "$WWW_OWNER:" $SHARED_PATH/log
211 chmod 644 $SHARED_PATH/log/*
215 if [ -n "$NOT_READY_REASON" ]; then
217 # warn about config errors (deprecated/removed keys from
218 # previous version, etc)
219 elif ! run_and_report "Checking configuration for completeness" bin/rake config:check; then
220 NOT_READY_REASON="you must add required configuration settings to /etc/arvados/config.yml"
221 NOT_READY_DOC_URL="https://doc.arvados.org/install/install-api-server.html#update-config"
222 elif ! prepare_database; then
223 NOT_READY_REASON="database setup could not be completed"
226 if [ -n "$WWW_OWNER" ]; then
227 chown -R "$WWW_OWNER:" $RELEASE_PATH/tmp
228 chmod -R 2775 $RELEASE_PATH/tmp
231 if [ -z "$NOT_READY_REASON" ] && [ -n "$WEB_SERVICE" ]; then
232 systemctl restart "$WEB_SERVICE"
237 if [ -n "$NOT_READY_REASON" ]; then
239 NOTE: The $PACKAGE_NAME package was not configured completely because
241 Please refer to the documentation for next steps:
244 After you do that, resume $PACKAGE_NAME setup by running: