#!/bin/bash
#Nifty: Install pg_basebackup backupscript for PostgreSQL 17 server

POSTGRES_CONF="/data/postgres/17/data/postgresql.conf"
PG_HBA="/data/postgres/17/data/pg_hba.conf"

# Check if binary for cli exists
if [[ ! -x "/usr/bin/psql" ]]; then
	echo "Seems like PostgreSQL is not installed"
	exit 1
fi

# Set postgresql.conf requirements
sed -i 's/#summarize_wal = off/summarize_wal = on/' $POSTGRES_CONF
sed -i 's/archive_mode = true/archive_mode = on/' $POSTGRES_CONF
sed -i "s/archive_command = '\/bin\/true'/archive_command = 'cp %p \/data\/postgres\/17\/wal_archive\/%f'/" $POSTGRES_CONF

# Allowing postgres user from localhost to use replication
echo "Adding line to pg_hba.conf to allow the user to do a backup"
echo "host    replication     postgres             127.0.0.1/32            scram-sha-256" >> $PG_HBA

echo "Reloading service..."
systemctl reload postgresql-17

if [[ ! -d "/scripts" ]];then
	mkdir "/scripts"
	chmod "0700" "/scripts"
fi

cat > /scripts/pg_basebackup.sh <<EOF
PG_BASEBACKUP="/usr/bin/pg_basebackup"
BASE_BACKUPDIR="/data/pgbackup"
PGPASS="/root/.pgpass"
DATE=\$(date +%Y-%m-%d)
LABEL="This backup was created at \$(hostname) on \$DATE"

# Check if binary exists
if [ ! -x "\$PG_BASEBACKUP" ]; then
	exit 1
fi

# Check if .pgpass is present
if [[ -r \$PGPASS ]]; then
       PGUSER="\$(cut -d ":" -f4 \$PGPASS)"
       PGPASSWORD="\$(cut -d ":" -f5 \$PGPASS)"
else
	echo "No user found."
	exit 1
fi

# Make directory for backup if it doesn't exists
if [[ ! -d "\$BASE_BACKUPDIR/\$DATE" ]]; then
	mkdir -p "\$BASE_BACKUPDIR/\$DATE"
	chmod 0700 "\$BASE_BACKUPDIR"
	chmod 0700 "\$BASE_BACKUPDIR/\$DATE"
fi

# Check if wal_level is replica
if ! /usr/bin/psql -qc "SHOW wal_level" | grep -qE "logical|replica"; then
	echo "wal_level is not set to \"logical\" or \"replica\""
	exit 1
fi

# Check if wal_summerize is on
if ! /usr/bin/psql -qc "SHOW summarize_wal" | grep -q "on"; then
        echo "summarize_wal is not enabled"
        exit 1
fi

# Check if archive directory is created and writeable
WAL_ARCHIVE="/data/postgres/17/wal_archive"
if [ ! -d "\$WAL_ARCHIVE" ]; then
	mkdir "\$WAL_ARCHIVE"
	chmod 0700 "\$WAL_ARCHIVE"
fi

WAL_ARCHIVE_OWNER=\$(stat -c "%U" "\$WAL_ARCHIVE")
WAL_ARCHIVE_PERM=\$(stat -c "%a" "\$WAL_ARCHIVE")
if [[ \$WAL_ARCHIVE_OWNER != "postgres" ]]; then
        chown "postgres:" "\$WAL_ARCHIVE"

fi

if [[ \$WAL_ARCHIVE_PERM != "700" ]]; then
	chmod "700" "\$WAL_ARCHIVE"
fi

# Check if archive_mode is on
if ! /usr/bin/psql -qc "SHOW archive_mode" | grep -q "on"; then
	echo "archive_mode is not on"
	exit 1
fi

# Check if archive_command is correctly set
if ! /usr/bin/psql -qc "SHOW archive_command" | grep -q "cp %p /data/postgres/17/wal_archive/%f"; then
	echo "archive_command isn't set correctly"
	exit 1
fi

# Delete yesterdays backup
YESTERDAY=\$(date -d "yesterday" +%Y-%m-%d)
if [ -d "\$BASE_BACKUPDIR/\$YESTERDAY" ]; then
	rm -rf "\$BASE_BACKUPDIR/\$YESTERDAY"
fi

nice -n10 \$PG_BASEBACKUP -D "\$BASE_BACKUPDIR/\$DATE" -Ft -z -l "\$LABEL"
EOF

# Creating cron job
echo "Adding cronjob"
echo "0 2 * * * /bin/bash /scripts/pg_basebackup.sh > /dev/null 2>&1" >> /var/spool/cron/root
echo -e "\n" >> /var/spool/cron/root

echo "###
#
# Install completed.
# Please do a testrun: /bin/bash /scripts/pg_basebackup.sh && ls -la /data/pgbackup
#
###"