X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/8fbe20476e2d10b1fc8dac848b2a0ffdf488a082..e96ae5fb68ffeac2bf8f21cbcce189d92ec3610f:/build/rails-package-scripts/postinst.sh diff --git a/build/rails-package-scripts/postinst.sh b/build/rails-package-scripts/postinst.sh index 17802a7b52..1fa7d5f4d3 100644 --- a/build/rails-package-scripts/postinst.sh +++ b/build/rails-package-scripts/postinst.sh @@ -7,33 +7,22 @@ set -e -DATABASE_READY=1 -APPLICATION_READY=1 - -if [ -s "$HOME/.rvm/scripts/rvm" ] || [ -s "/usr/local/rvm/scripts/rvm" ]; then - COMMAND_PREFIX="/usr/local/rvm/bin/rvm-exec default" -else - COMMAND_PREFIX= +for DISTRO_FAMILY in $(. /etc/os-release && echo "${ID:-} ${ID_LIKE:-}"); do + case "$DISTRO_FAMILY" in + debian) + RESETUP_CMD="dpkg-reconfigure $PACKAGE_NAME" + break ;; + rhel) + RESETUP_CMD="dnf reinstall $PACKAGE_NAME" + break ;; + esac +done +if [ -z "$RESETUP_CMD" ]; then + echo "$PACKAGE_NAME postinst skipped: don't recognize the distribution from /etc/os-release" >&2 + exit 0 fi - -report_not_ready() { - local ready_flag="$1"; shift - local config_file="$1"; shift - if [ "1" != "$ready_flag" ]; then cat >&2 < for more details. - -When $(basename "$config_file") has been modified, -reconfigure or reinstall this package. - -EOF - fi -} +# Default documentation URL. This can be set to a more specific URL. +NOT_READY_DOC_URL="https://doc.arvados.org/install/install-api-server.html" report_web_service_warning() { local warning="$1"; shift @@ -44,10 +33,8 @@ WARNING: $warning. To override, set the WEB_SERVICE environment variable to the name of the service hosting the Rails server. -For Debian-based systems, then reconfigure this package with dpkg-reconfigure. - -For RPM-based systems, then reinstall this package. - +After you do that, resume $PACKAGE_NAME setup by running: + $RESETUP_CMD EOF } @@ -125,23 +112,19 @@ setup_conffile() { } prepare_database() { - DB_MIGRATE_STATUS=`$COMMAND_PREFIX bin/rake db:migrate:status 2>&1 || true` + DB_MIGRATE_STATUS=`bin/rake db:migrate:status 2>&1 || true` if echo "$DB_MIGRATE_STATUS" | grep -qF 'Schema migrations table does not exist yet.'; then # The database exists, but the migrations table doesn't. - run_and_report "Setting up database" $COMMAND_PREFIX bin/rake \ + run_and_report "Setting up database" bin/rake \ "$RAILSPKG_DATABASE_LOAD_TASK" db:seed elif echo "$DB_MIGRATE_STATUS" | grep -q '^database: '; then run_and_report "Running db:migrate" \ - $COMMAND_PREFIX bin/rake db:migrate + bin/rake db:migrate elif echo "$DB_MIGRATE_STATUS" | grep -q 'database .* does not exist'; then - if ! run_and_report "Running db:setup" \ - $COMMAND_PREFIX bin/rake db:setup 2>/dev/null; then - echo "Warning: unable to set up database." >&2 - DATABASE_READY=0 - fi + run_and_report "Running db:setup" bin/rake db:setup else - echo "Warning: Database is not ready to set up. Skipping database setup." >&2 - DATABASE_READY=0 + # We don't have enough configuration to even check the database. + return 1 fi } @@ -163,31 +146,14 @@ configure_version() { "Multiple web services found. Choosing the first one ($WEB_SERVICE)" fi - if [ -e /etc/redhat-release ]; then - # Recognize any service that starts with "nginx"; e.g., nginx16. - if [ "$WEB_SERVICE" != "${WEB_SERVICE#nginx}" ]; then - WWW_OWNER=nginx - else - WWW_OWNER=apache - fi - else - # Assume we're on a Debian-based system for now. - # Both Apache and Nginx run as www-data by default. - WWW_OWNER=www-data - fi - - echo - echo "Assumption: $WEB_SERVICE is configured to serve Rails from" - echo " $RELEASE_PATH" - echo "Assumption: $WEB_SERVICE and passenger run as $WWW_OWNER" - echo - - echo -n "Creating symlinks to configuration in $CONFIG_PATH ..." - setup_confdirs /etc/arvados "$CONFIG_PATH" - setup_conffile environments/production.rb environments/production.rb.example \ - || true - setup_extra_conffiles - echo "... done." + case "$DISTRO_FAMILY" in + debian) WWW_OWNER=www-data ;; + rhel) case "$WEB_SERVICE" in + httpd*) WWW_OWNER=apache ;; + nginx*) WWW_OWNER=nginx ;; + esac + ;; + esac # Before we do anything else, make sure some directories and files are in place if [ ! -e $SHARED_PATH/log ]; then mkdir -p $SHARED_PATH/log; fi @@ -198,76 +164,104 @@ configure_version() { cd "$RELEASE_PATH" export RAILS_ENV=production - if ! $COMMAND_PREFIX bundle --version >/dev/null 2>&1; then - run_and_report "Installing bundler" $COMMAND_PREFIX gem install bundler --version 2.2.19 --no-document + run_and_report "Installing bundler" gem install --conservative --version '~> 2.4.0' bundler + local ruby_minor_ver="$(ruby -e 'puts RUBY_VERSION.split(".")[..1].join(".")')" + local bundle="$(gem contents --version '~> 2.4.0' bundler | grep -E '/(bin|exe)/bundle$' | tail -n1)" + if ! [ -x "$bundle" ]; then + # Some distros (at least Ubuntu 24.04) append the Ruby version to the + # executable name, but that isn't reflected in the output of + # `gem contents`. Check for that version. + bundle="$bundle$ruby_minor_ver" + if ! [ -x "$bundle" ]; then + echo "Error: failed to find \`bundle\` command after installing bundler gem" >&2 + return 1 + fi fi + local bundle_path="$SHARED_PATH/vendor_bundle" run_and_report "Running bundle config set --local path $SHARED_PATH/vendor_bundle" \ - $COMMAND_PREFIX bin/bundle config set --local path $SHARED_PATH/vendor_bundle - - run_and_report "Running bundle install" \ - $COMMAND_PREFIX bin/bundle install --local --quiet + "$bundle" config set --local path "$bundle_path" + + # As of April 2024/Bundler 2.4, `bundle install` tends not to install gems + # which are already installed system-wide, which causes bundle activation to + # fail later. Work around this by installing all gems manually. + find vendor/cache -maxdepth 1 -name '*.gem' -print0 \ + | run_and_report "Installing bundle gems" xargs -0r \ + gem install --conservative --ignore-dependencies --local --quiet \ + --install-dir="$bundle_path/ruby/$ruby_minor_ver.0" + run_and_report "Running bundle install" "$bundle" install --prefer-local --quiet + run_and_report "Verifying bundle is complete" "$bundle" exec true + + if [ -z "$WWW_OWNER" ]; then + NOT_READY_REASON="there is no web service account to own Arvados configuration" + NOT_READY_DOC_URL="https://doc.arvados.org/install/nginx.html" + else + cat </dev/null 2>&1; then - local RUBY_VERSION="$($COMMAND_PREFIX ruby -e 'puts RUBY_VERSION')" - run_and_report "Adding zlib to bundle" \ - $COMMAND_PREFIX gem install \ - --install-dir="$SHARED_PATH/vendor_bundle/ruby/$RUBY_VERSION" \ - vendor/cache/zlib-*.gem - fi +Assumption: $WEB_SERVICE is configured to serve Rails from + $RELEASE_PATH +Assumption: $WEB_SERVICE and passenger run as $WWW_OWNER - echo -n "Ensuring directory and file permissions ..." - # Ensure correct ownership of a few files - chown "$WWW_OWNER:" $RELEASE_PATH/config/environment.rb - chown "$WWW_OWNER:" $RELEASE_PATH/config.ru - chown "$WWW_OWNER:" $RELEASE_PATH/Gemfile.lock - chown -R "$WWW_OWNER:" $RELEASE_PATH/tmp || true - chown -R "$WWW_OWNER:" $SHARED_PATH/log - # Make sure postgres doesn't try to use a pager. - export PAGER= - case "$RAILSPKG_DATABASE_LOAD_TASK" in - # db:structure:load was deprecated in Rails 6.1 and shouldn't be used. - db:schema:load | db:structure:load) - chown "$WWW_OWNER:" $RELEASE_PATH/db/schema.rb || true - chown "$WWW_OWNER:" $RELEASE_PATH/db/structure.sql || true - ;; - esac - chmod 644 $SHARED_PATH/log/* - chmod -R 2775 $RELEASE_PATH/tmp || true - echo "... done." +EOF - if [ -n "$RAILSPKG_DATABASE_LOAD_TASK" ]; then - prepare_database + echo -n "Creating symlinks to configuration in $CONFIG_PATH ..." + setup_confdirs /etc/arvados "$CONFIG_PATH" + setup_conffile environments/production.rb environments/production.rb.example \ + || true + setup_extra_conffiles + echo "... done." + + echo -n "Ensuring directory and file permissions ..." + # Ensure correct ownership of a few files + chown "$WWW_OWNER:" $RELEASE_PATH/config/environment.rb + chown "$WWW_OWNER:" $RELEASE_PATH/config.ru + chown "$WWW_OWNER:" $RELEASE_PATH/Gemfile.lock + chown -R "$WWW_OWNER:" $SHARED_PATH/log + # Make sure postgres doesn't try to use a pager. + export PAGER= + case "$RAILSPKG_DATABASE_LOAD_TASK" in + # db:structure:load was deprecated in Rails 6.1 and shouldn't be used. + db:schema:load | db:structure:load) + chown "$WWW_OWNER:" $RELEASE_PATH/db/schema.rb || true + chown "$WWW_OWNER:" $RELEASE_PATH/db/structure.sql || true + ;; + esac + chmod 644 $SHARED_PATH/log/* + echo "... done." fi - if [ -e /etc/arvados/config.yml ]; then - # warn about config errors (deprecated/removed keys from - # previous version, etc) - run_and_report "Checking configuration for completeness" \ - $COMMAND_PREFIX bin/rake config:check || APPLICATION_READY=0 - else - APPLICATION_READY=0 + if [ -n "$NOT_READY_REASON" ]; then + : + # warn about config errors (deprecated/removed keys from + # previous version, etc) + elif ! run_and_report "Checking configuration for completeness" bin/rake config:check; then + NOT_READY_REASON="you must add required configuration settings to /etc/arvados/config.yml" + NOT_READY_DOC_URL="https://doc.arvados.org/install/install-api-server.html#update-config" + elif [ -z "$RAILSPKG_DATABASE_LOAD_TASK" ]; then + : + elif ! prepare_database; then + NOT_READY_REASON="database setup could not be completed" fi - chown -R "$WWW_OWNER:" $RELEASE_PATH/tmp - - setup_before_nginx_restart + if [ -n "$WWW_OWNER" ]; then + chown -R "$WWW_OWNER:" $RELEASE_PATH/tmp + chmod -R 2775 $RELEASE_PATH/tmp + fi - if [ -n "$SERVICE_MANAGER" ]; then + if [ -z "$NOT_READY_REASON" ] && [ -n "$SERVICE_MANAGER" ]; then service_command "$SERVICE_MANAGER" restart "$WEB_SERVICE" fi } -if [ "$1" = configure ]; then - # This is a debian-based system - configure_version -elif [ "$1" = "0" ] || [ "$1" = "1" ] || [ "$1" = "2" ]; then - # This is an rpm-based system - configure_version -fi +configure_version +if [ -n "$NOT_READY_REASON" ]; then + cat >&2 < -report_not_ready "$APPLICATION_READY" "/etc/arvados/config.yml" +After you do that, resume $PACKAGE_NAME setup by running: + $RESETUP_CMD +EOF +fi