-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from balena-io/upgrade-script
upgrade: Container upgrades existing data on start
- Loading branch information
Showing
2 changed files
with
122 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
#!/bin/bash | ||
|
||
set -e | ||
|
||
# creates a backup archive of the dir $1... | ||
backup_data () { | ||
gosu postgres tar --exclude backup.tar.gz -zcf /tmp/backup.tar.gz -C "$1" . | ||
mv /tmp/backup.tar.gz "${1}/backup.tar.gz" | ||
} | ||
|
||
# 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 | ||
sed -i 's/$/ '"$1"'/' /etc/apt/sources.list.d/pgdg.list | ||
|
||
apt-get -qq update \ | ||
&& apt-get install -qq -y --no-install-recommends \ | ||
"postgresql-$1" \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
fi | ||
} | ||
|
||
# creates a dir at $1 which is valid for Postgres data to live in... | ||
create_postgres_data_dir () { | ||
echo "=== Creating data dir $1" | ||
mkdir -p "$1" | ||
chmod 700 "$1" | ||
chown -R postgres:postgres "$1" | ||
} | ||
|
||
# echo a message and die... | ||
die_with_message () { | ||
echo "[FATAL] $1" | ||
exit 2 | ||
} | ||
|
||
# check that this is running from within a valid Postgres container environment... | ||
[ ! -z "$PG_MAJOR" ] || die_with_message "Not a compatible Postgres runtime environment" | ||
|
||
# set our target version... | ||
TARGET_VERSION="$PG_MAJOR" | ||
|
||
# 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)" | ||
|
||
# does the data need upgrading... | ||
if [ "$SOURCE_VERSION" -ne "$TARGET_VERSION" ]; then | ||
echo "=== Upgrading data from v${SOURCE_VERSION} to v${TARGET_VERSION}" | ||
|
||
# define our directories... | ||
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 extisting 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 "=== Initialising new data directory ${PGDATANEW}" | ||
rm -rf "${PGDATANEW}" | ||
create_postgres_data_dir "${PGDATANEW}" | ||
gosu postgres initdb -D "$PGDATANEW" -U "$POSTGRES_USER" $POSTGRES_INITDB_ARGS | ||
|
||
echo "=== Beginning pg_upgrade" | ||
cd /tmp | ||
gosu postgres pg_upgrade \ | ||
-U "$POSTGRES_USER" \ | ||
--old-datadir="$PGDATAOLD" \ | ||
--new-datadir="$PGDATANEW" \ | ||
--old-bindir="$PGBINOLD" \ | ||
--new-bindir="$PGBINNEW" \ | ||
--check | ||
|
||
gosu postgres pg_upgrade \ | ||
-U "$POSTGRES_USER" \ | ||
--old-datadir="$PGDATAOLD" \ | ||
--new-datadir="$PGDATANEW" \ | ||
--old-bindir="$PGBINOLD" \ | ||
--new-bindir="$PGBINNEW" | ||
|
||
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 extisting data to directory "${PGDATA}/${TARGET_VERSION}"" | ||
find "$PGDATA" -maxdepth 1 \ | ||
! -path "$PGDATA" \ | ||
| xargs mv -t "${PGDATA}/${TARGET_VERSION}" | ||
fi | ||
fi | ||
|
||
# set our runtime data directory to the versioned one... | ||
export PGDATA="${PGDATA}/${TARGET_VERSION}" | ||
|
||
# run the existing Postgres entrypoint script... | ||
. /docker-entrypoint.sh | ||
_main "$@" |