#!/bin/bash # command info if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "-help" ]; then echo "config script to install PostgreSQL" echo "bonus.postgresql.sh [on|off]" echo "bonus.postgresql.sh [backup] [database]" echo "bonus.postgresql.sh [restore] [database] [user] [password]" echo "bonus.postgresql.sh [info]" exit 1 fi command=$1 db_name=$2 db_user=$3 db_user_pw=$4 db_backupfile=$5 PG_VERSION=15 echo "# Using the default PostgreSQL version: $PG_VERSION" # switch on if [ "$command" = "1" ] || [ "$command" = "on" ]; then echo "# Install PostgreSQL" if [ ! -f /etc/apt/trusted.gpg.d/postgresql.gpg ]; then curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list sudo apt update fi sudo apt install -y postgresql-$PG_VERSION postgres_datadir="/var/lib/postgresql" # default data dir postgres_confdir="/etc/postgresql" # default conf dir sudo systemctl stop postgresql sudo systemctl stop postgresql@$PG_VERSION-main if [ ! -d /mnt/hdd/app-data/postgresql ]; then echo "# There is no old pg data" # symlink conf dir sudo mkdir -p /mnt/hdd/app-data/postgresql-conf/postgresql sudo chown -R postgres:postgres /mnt/hdd/app-data/postgresql-conf # fix ownership sudo mv $postgres_confdir /etc/postgresql.bak # backup new empty dir sudo rm -rf $postgres_confdir # not a symlink.. delete it silently sudo ln -s /mnt/hdd/app-data/postgresql-conf/postgresql /etc/ # create symlink # symlink data dir sudo mkdir -p /mnt/hdd/app-data/postgresql sudo chown -R postgres:postgres /mnt/hdd/app-data/postgresql # fix ownership sudo mv $postgres_datadir /var/lib/postgresql.bak # backup new empty dir sudo rm -rf $postgres_datadir # not a symlink.. delete it silently sudo ln -s /mnt/hdd/app-data/postgresql /var/lib/ # create symlink echo "# Create PostgreSQL $PG_VERSION data" sudo mkdir -p $postgres_datadir/$PG_VERSION/main sudo chown -R postgres:postgres $postgres_datadir echo "# Create cluster" sudo pg_createcluster $PG_VERSION main sudo pg_ctlcluster $PG_VERSION main start elif [ -d /mnt/hdd/app-data/postgresql/$PG_VERSION/main ]; then echo "# There is old data for $PG_VERSION, restoring ..." if [ -d /mnt/hdd/app-data/postgresql-conf ]; then # symlink conf dir sudo mkdir -p /mnt/hdd/app-data/postgresql-conf/postgresql sudo chown -R postgres:postgres /mnt/hdd/app-data/postgresql-conf # fix ownership sudo mv $postgres_confdir /etc/postgresql.bak # backup new empty dir sudo rm -rf $postgres_confdir # not a symlink.. delete it silently sudo ln -s /mnt/hdd/app-data/postgresql-conf/postgresql /etc/ # create symlink else # generate new cluster and use default config echo "# Create $PG_VERSION config" sudo mkdir -p $postgres_datadir/$PG_VERSION/main sudo chown -R postgres:postgres $postgres_datadir sudo pg_createcluster $PG_VERSION main sudo pg_ctlcluster $PG_VERSION main start echo "Setting default password for postgres user" # start cluster temporarily sudo systemctl start postgresql sudo pg_createcluster $PG_VERSION main sudo pg_ctlcluster $PG_VERSION main start echo "Setting default password for postgres user" sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD 'postgres';" sudo systemctl stop postgresql sudo systemctl stop postgresql@$PG_VERSION-main # move and symlink conf dir sudo mkdir -p /mnt/hdd/app-data/postgresql-conf sudo mv /etc/postgresql /mnt/hdd/app-data/postgresql-conf/ sudo chown -R postgres:postgres /mnt/hdd/app-data/postgresql-conf sudo ln -s /mnt/hdd/app-data/postgresql-conf/postgresql /etc/ # create symlink sudo chown -R postgres:postgres $postgres_confdir fi # symlink data dir sudo mkdir -p /mnt/hdd/app-data/postgresql sudo chown -R postgres:postgres /mnt/hdd/app-data/postgresql # fix ownership sudo mv $postgres_datadir /var/lib/postgresql.bak # backup new empty dir sudo rm -rf $postgres_datadir # not a symlink.. delete it silently sudo ln -s /mnt/hdd/app-data/postgresql /var/lib/ # create symlink sudo chown -R postgres:postgres $postgres_datadir sudo systemctl start postgresql sudo systemctl start postgresql@13-main sudo pg_createcluster $PG_VERSION main sudo pg_ctlcluster $PG_VERSION main start elif [ -d /mnt/hdd/app-data/postgresql/13/main ]; then echo "# There is old data for pg 13, start and upgrade cluster ..." sudo apt install -y postgresql-13 || exit 1 sudo systemctl stop postgresql sudo systemctl stop postgresql@13-main if [ -d /mnt/hdd/app-data/postgresql-conf ]; then # symlink conf dir sudo mkdir -p /mnt/hdd/app-data/postgresql-conf/postgresql sudo chown -R postgres:postgres /mnt/hdd/app-data/postgresql-conf # fix ownership sudo mv $postgres_confdir /etc/postgresql.bak # backup new empty dir sudo rm -rf $postgres_confdir # not a symlink.. delete it silently sudo ln -s /mnt/hdd/app-data/postgresql-conf/postgresql /etc/ # create symlink else # generate new cluster and use default config echo "# Create pg 13 config" sudo mkdir -p $postgres_datadir/13/main sudo chown -R postgres:postgres $postgres_datadir # start cluster temporarily sudo systemctl start postgresql sudo pg_createcluster 13 main sudo pg_ctlcluster 13 main start echo "Setting default password for postgres user" sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD 'postgres';" sudo systemctl stop postgresql sudo systemctl stop postgresql@13-main # move and symlink conf dir sudo mkdir -p /mnt/hdd/app-data/postgresql-conf sudo mv /etc/postgresql /mnt/hdd/app-data/postgresql-conf/ sudo chown -R postgres:postgres /mnt/hdd/app-data/postgresql-conf sudo ln -s /mnt/hdd/app-data/postgresql-conf/postgresql /etc/ # create symlink sudo chown -R postgres:postgres $postgres_confdir fi # symlink data dir sudo mkdir -p /mnt/hdd/app-data/postgresql sudo chown -R postgres:postgres /mnt/hdd/app-data/postgresql # fix ownership sudo mv $postgres_datadir /var/lib/postgresql.bak # backup new empty dir sudo rm -rf $postgres_datadir # not a symlink.. delete it silently sudo ln -s /mnt/hdd/app-data/postgresql /var/lib/ # create symlink sudo chown -R postgres:postgres $postgres_datadir sudo systemctl start postgresql sudo systemctl start postgresql@13-main sudo pg_createcluster 13 main sudo pg_ctlcluster 13 main start if [ -d /mnt/hdd/app-data/postgresql/$PG_VERSION ] || pg_lsclusters | grep -q "$PG_VERSION main"; then echo "# backup /mnt/hdd/app-data/postgresql/$PG_VERSION" now=$(date +"%Y_%m_%d_%H%M%S") sudo mv /mnt/hdd/app-data/postgresql/$PG_VERSION /mnt/hdd/app-data/postgresql/$PG_VERSION-backup-$now echo "# Drop empty pg 15 cluster" sudo pg_dropcluster $PG_VERSION main fi # /usr/bin/pg_upgradecluster [OPTIONS] [] sudo pg_upgradecluster 13 main $postgres_datadir/$PG_VERSION/main || exit 1 sudo chown -R postgres:postgres /mnt/hdd/app-data/postgresql/$PG_VERSION echo "# backup /mnt/hdd/app-data/postgresql/13" now=$(date +"%Y_%m_%d_%H%M%S") sudo mv /mnt/hdd/app-data/postgresql/13 /mnt/hdd/app-data/postgresql/13-backup-$now sudo pg_dropcluster 13 main sudo systemctl disable --now postgresql@13-main sudo apt remove -y postgresql-13 if sudo cat /etc/postgresql/$PG_VERSION/main/postgresql.conf | grep 5433; then echo "# Switch port back to 5432" sudo sed -i 's/port = 5433/port = 5432/' /etc/postgresql/$PG_VERSION/main/postgresql.conf echo "# Restart posgresql.service" sudo systemctl restart postgresql fi fi # start cluster sudo systemctl enable --now postgresql sudo systemctl enable --now postgresql@$PG_VERSION-main # check if PostgreSQL was installed if psql --version; then echo "# wait for the postgresql server to start" count=0 count_max=30 while ! nc -zv '127.0.0.1' 5432 2>/dev/null; do count=$((count + 1)) echo "sleep $count/$count_max" sleep 1 if [ $count = $count_max ]; then sudo systemctl status postgresql echo "FAIL - Was not able to start PostgreSQL service" sudo systemctl status postgresql@$PG_VERSION-main.service exit 1 fi done echo "Setting default password for postgres user" sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD 'postgres';" echo "OK PostgreSQL installed" else echo "FAIL - Was not able to install PostgreSQL" echo "ABORT - PostgreSQL install" exit 1 fi exit 0 fi # switch off if [ "$command" = "0" ] || [ "$command" = "off" ]; then echo "*** REMOVING POSTGRESQL ***" sudo systemctl disable --now postgresql sudo systemctl disable --now postgresql@$PG_VERSION-main sudo systemctl disable --now postgresql@13-main sudo apt remove -y postgresql if dpkg -l | grep -q "postgresql-13"; then sudo apt remove -y postgresql-13 fi echo "# remove symlink /var/lib/postgresql" sudo rm /var/lib/postgresql sudo rm /etc/postgresql exit 0 fi # backup backup_target="/mnt/hdd/app-data/backup/$db_name" backup_file="${db_name}_$(date +%d)-$(date +%m)-$(date +%Y)_$(date +%H)-$(date +%M)_dump" if [ ! -d $backup_target ]; then sudo mkdir -p $backup_target 1>&2 fi # https://www.postgresql.org/docs/current/backup-dump.html if [ "$command" = "backup" ] && [ "$db_name" != "" ]; then echo "*** BACKUP POSTGRESQL $db_name ***" sudo -u postgres pg_dump $db_name >$backup_target/${backup_file}.sql || exit 1 # Delete old backups (keep last 3 backups) sudo chown -R admin:admin $backup_target ls -tp $backup_target/*.sql | grep -v '/$' | tail -n +4 | tr '\n' '\0' | xargs -0 rm -- 2>/dev/null echo "OK - backup finished, file saved as $backup_target/${backup_file}.sql" exit 0 fi # restore if [ "$command" = "restore" ] && [ "$db_name" != "" ] && [ "$db_user" != "" ] && [ "$db_user_pw" != "" ]; then echo "*** RESTORE POSTGRESQL $db_name ***" # find recent backup if [ "$db_backupfile" != "" ]; then backup_file=$db_backupfile else backup_file=$(ls -t $backup_target/*.sql | head -n1) fi if [ ! -e $backup_file ]; then echo "FAIL - sql file to restore not found in ${backup_target}" exit 1 else echo "Start restore from backup ${backup_file}" fi # clean up echo "# Clean up old database" sudo -u postgres psql -c "drop database $db_name;" || exit 1 sudo -u postgres psql -c "drop user $db_user;" # create database and user echo "# Create fresh database" sudo -u postgres psql -c "create database $db_name;" sudo -u postgres psql -c "create user $db_user with encrypted password '$db_user_pw';" sudo -u postgres psql -c "grant all privileges on database $db_name to $db_user;" # restore dump echo "# Import SQL Dump" sudo mkdir -p $backup_target/logs 1>&2 sudo chown -R postgres:postgres $backup_file sudo -u postgres psql $db_name <${backup_file} >$backup_target/logs/sql_import.log || exit 1 echo "$backup_target/sql_import.log written" echo "OK - database $db_name restored from ${backup_file}" exit 0 fi if [ "$command" = "info" ]; then check=$(sudo -u postgres psql -c "show data_directory;" | grep data_directory) if [ "$check" = "" ]; then echo "show data_directory failed, PostgreSQL not installed?!" exit 1 else sudo -u postgres psql -c "show data_directory;" sudo -u postgres psql -c "SELECT datname FROM pg_database;" fi exit 0 fi echo "FAIL - Unknown Parameter $command" exit 1