diff --git a/balena-entrypoint.sh b/balena-entrypoint.sh index 20ccd65..b388984 100755 --- a/balena-entrypoint.sh +++ b/balena-entrypoint.sh @@ -2,14 +2,6 @@ set -e -# copies all the data from $1 to $2 -restore_volume () { - echo "=== Restoring data volume structure" - find "$1" -maxdepth 1 \ - ! -path "$1" \ - | xargs mv -t "$2" -} - # install the old version of Postgres, required when doing an upgrade install_old_version () { if [ ! -d "/usr/lib/postgresql/$1/bin" ]; then @@ -41,37 +33,49 @@ die_with_message () { # set our target version TARGET_VERSION="$PG_MAJOR" +PGDATANEW="${PGDATA}/${TARGET_VERSION}" + +migrate_pgdata_root_if_needed () { + # perform a one-time migration from storing data under $PGDATA root, + # to storing it under $PGDATA/$PG_VERSION + if [ -f "${PGDATA}/PG_VERSION" ]; then + local version="$(cat "${PGDATA}/PG_VERSION")" + if [ ! -d "${PGDATA}/${version}" ]; then + create_postgres_data_dir "${PGDATA}/${version}" + echo "=== Moving existing data to directory "${PGDATA}/${version}"" + find "$PGDATA" -maxdepth 1 \ + ! -path "$PGDATA" \ + ! -path "${PGDATA}/${version}*" \ + | xargs mv -t "${PGDATA}/${version}" + fi + fi +} -# ensure we have a versioned data directory -[ -d "${PGDATA}/${TARGET_VERSION}" ] || create_postgres_data_dir "${PGDATA}/${TARGET_VERSION}" - -# check for Postgres data in the root of the $PGDATA directory -if [ -f "${PGDATA}/PG_VERSION" ]; then - SOURCE_VERSION="$(cat ${PGDATA}/PG_VERSION)" +find_source_version () { + # find our source version by looking for a PG_VERSION file + # in every directory under $PGDATA + for src in $(find "$PGDATA" -maxdepth 2 -type f -name 'PG_VERSION' | sort -rn); do + local version="$(cat "$src")" + if [ "$version" -ne "$TARGET_VERSION" ]; then + SOURCE_VERSION="$version" + PGDATAOLD="$(dirname "$src")" # drop 'PG_VERSION' from path + break + fi + done +} +perform_migration_if_needed () { # does the data need upgrading? - if [ "$SOURCE_VERSION" -ne "$TARGET_VERSION" ]; then + if [ -n "${SOURCE_VERSION}" ]; then echo "=== Upgrading data from v${SOURCE_VERSION} to v${TARGET_VERSION}" - PGDATAOLD="${PGDATA}/${SOURCE_VERSION}" - PGDATANEW="${PGDATA}/${TARGET_VERSION}" PGBINOLD="/usr/lib/postgresql/$SOURCE_VERSION/bin" PGBINNEW="/usr/lib/postgresql/$TARGET_VERSION/bin" echo "=== Installing tools for Postgres v${SOURCE_VERSION}" install_old_version "$SOURCE_VERSION" - echo "=== Moving existing data to ${PGDATAOLD}" - create_postgres_data_dir "${PGDATAOLD}" - find "$PGDATA" -maxdepth 1 \ - ! -path "$PGDATA" \ - ! -path "$PGDATAOLD*" \ - | xargs mv -t "${PGDATAOLD}" - - trap "restore_volume ${PGDATAOLD} ${PGDATA}" ERR - echo "=== Initializing new data directory ${PGDATANEW}" - rm -rf "${PGDATANEW}" create_postgres_data_dir "${PGDATANEW}" gosu postgres initdb -D "$PGDATANEW" -U "$POSTGRES_USER" $POSTGRES_INITDB_ARGS @@ -95,16 +99,21 @@ if [ -f "${PGDATA}/PG_VERSION" ]; then echo "=== Restoring configuration files" cp "${PGDATAOLD}/pg_hba.conf" "${PGDATANEW}/pg_hba.conf" cp "${PGDATAOLD}/pg_ident.conf" "${PGDATANEW}/pg_ident.conf" - else - echo "=== Moving existing data to directory "${PGDATA}/${TARGET_VERSION}"" - find "$PGDATA" -maxdepth 1 \ - ! -path "$PGDATA" \ - | xargs mv -t "${PGDATA}/${TARGET_VERSION}" + + echo "=== Migration succeeded; removing old data directory" + rm -rf "${PGDATAOLD}" fi -fi +} + +migrate_pgdata_root_if_needed +find_source_version +perform_migration_if_needed + +# ensure we have a versioned data directory +[ -d "${PGDATANEW}" ] || create_postgres_data_dir "${PGDATANEW}" # set our runtime data directory to the target version -export PGDATA="${PGDATA}/${TARGET_VERSION}" +export PGDATA="${PGDATANEW}" # run the existing Postgres entrypoint script . /usr/local/bin/docker-entrypoint.sh