diff --git a/Dockerfile b/Dockerfile index e9361d4..0941ed3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -93,7 +93,7 @@ RUN cd /tmp && \ conda clean --all -f -y # Install PostgreSQL in a dedicated conda environment. -RUN conda create -c conda-forge -n pgsql postgresql=10 && conda clean --all -f -y +RUN conda create -c conda-forge -n pgsql postgresql=12 && conda clean --all -f -y # Below is a solution to a strange bug with PGSQL=10 # Taken from https://github.com/tethysplatform/tethys/issues/667. @@ -140,5 +140,8 @@ RUN sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /etc/skel/.bashr # Always activate conda. COPY profile.d/activate_conda.sh /etc/profile.d/ +# Add database migration script. +COPY opt/migrate-database.sh /opt/migrate-database.sh + # Use baseimage-docker's init system. CMD ["/sbin/my_init"] diff --git a/opt/migrate-database.sh b/opt/migrate-database.sh new file mode 100755 index 0000000..64c3dcd --- /dev/null +++ b/opt/migrate-database.sh @@ -0,0 +1,59 @@ +#!/bin/bash +set -exuo pipefail + +# This script is intended to be run in a container. Its job is to migrate the PGSQL database to a newer version. + +# The following variables are required: +DB_FOLDER=/home/${SYSTEM_USER}/.postgresql + +OLD_PGSQL_DB_VERSION=`cat ${DB_FOLDER}/PG_VERSION` # The version of the database before the upgrade is taken from the PG_VERSION file. +NEW_PGSQL_DB_VERSION=`conda run -n pgsql psql -V | awk '{ print int( $3 ) }'` # The new version of PGSQL is given by the `psql -V` command installed in the pgsql conda environment. + +TIMESTAMP=$(date +%Y%m%d%H%M%S) +BACKUP_DB_FOLDER=/home/${SYSTEM_USER}/.postgresql-bak-${TIMESTAMP} +OLD_DB_CONDA_ENV_NAME="pgsql-backup-${OLD_PGSQL_DB_VERSION}-${TIMESTAMP}" +DUMP_FILE_NAME="/home/${SYSTEM_USER}/pgsql-dump-${OLD_PGSQL_DB_VERSION}-${TIMESTAMP}.sql" + +# Make sure the new PostgreSQL server is shut down. +conda run -n pgsql pg_ctl -D ${DB_FOLDER} stop || true # Ignore errors, as the database might not be running. + +# Part 1: dump the old database. + +# Make a backup of the database. +mv ${DB_FOLDER} ${BACKUP_DB_FOLDER} + +# Install the old version of PostgreSQL. +conda create -c conda-forge --yes -n ${OLD_DB_CONDA_ENV_NAME} postgresql=${OLD_PGSQL_DB_VERSION} && conda clean --all -f -y + +# Below is a solution to a strange bug with PGSQL=10 +# Taken from https://github.com/tethysplatform/tethys/issues/667. +# This bug is not present for PGSQL=14. So as soon as we migrate, the line below can be removed. +if [ ${OLD_PGSQL_DB_VERSION} -eq 10 ]; then + cp /usr/share/zoneinfo /home/aiida/.conda/envs/${OLD_DB_CONDA_ENV_NAME}/share/ -R +fi + +# Start the old version of PostgreSQL. +conda run -n ${OLD_DB_CONDA_ENV_NAME} pg_ctl -D ${BACKUP_DB_FOLDER} -l ${BACKUP_DB_FOLDER}/logfile start + +# Dump the old database. +conda run -n ${OLD_DB_CONDA_ENV_NAME} pg_dumpall -f ${DUMP_FILE_NAME} + +# Stop the old version of PostgreSQL. +conda run -n ${OLD_DB_CONDA_ENV_NAME} pg_ctl -D ${BACKUP_DB_FOLDER} stop + +# Delete the environment with old version of PostgreSQL. +conda env remove -n ${OLD_DB_CONDA_ENV_NAME} + +# Part 2: restore the old database to the new version. + +# Create a new database. +conda run -n pgsql initdb -D ${DB_FOLDER} + +# Start the new version of PostgreSQL. +conda run -n pgsql pg_ctl -w -D ${DB_FOLDER} -l ${DB_FOLDER}/logfile start + +# Restore the old database. +conda run -n pgsql psql -f ${DUMP_FILE_NAME} postgres + +# Stop the new version of PostgreSQL to return everything to the original state. +conda run -n pgsql pg_ctl -D ${DB_FOLDER} stop diff --git a/opt/start-postgres.sh b/opt/start-postgres.sh index 20ac98e..6bbff92 100755 --- a/opt/start-postgres.sh +++ b/opt/start-postgres.sh @@ -29,6 +29,11 @@ else if ! $running ; then echo "" > /home/${SYSTEM_USER}/.postgresql/logfile # empty log files rm -vf /home/${SYSTEM_USER}/.postgresql/postmaster.pid - ${PSQL_START_CMD} + ${PSQL_START_CMD} || cant_start=true + fi + + if $cant_start; then + echo "Postgresql could not be started. Maybe the database needs to be migrated." + touch /home/$SYSTEM_USER/.PGSQL_MIGRATION_REQUIRED fi fi