You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
215 lines
5.5 KiB
215 lines
5.5 KiB
#!/bin/bash
|
|
|
|
confirm() {
|
|
read -p "$1 ([y]es or [N]o): "
|
|
case $(echo $REPLY | tr '[A-Z]' '[a-z]') in
|
|
y | yes) echo "yes" ;;
|
|
*) echo "no" ;;
|
|
esac
|
|
}
|
|
|
|
synopsis() {
|
|
echo "usage: "
|
|
printf "\t list | console | connections\n"
|
|
printf "\t ---------------------------\n"
|
|
printf "\t use <DB_NAME>\n"
|
|
printf "\t lookup <DB_NAME> <TERM>\n"
|
|
printf "\t create <DB_NAME> [PASSWORD]\n"
|
|
printf "\t ---------------------------\n"
|
|
printf "\t backup <DB_NAME> [FOLDER]\n"
|
|
printf "\t restore <DB_NAME> <FILE> [--yes]\n"
|
|
printf "\t ---------------------------\n"
|
|
printf "\t rename <DB_NAME> <NEW_NAME>\n"
|
|
if [[ "$TARGET" != 'prod' ]]; then
|
|
printf "\t drop <DB_NAME> # unless PROD!\n"
|
|
fi
|
|
}
|
|
|
|
list() {
|
|
lxc exec ct1 -- su - postgres -c "psql -Atc \"SELECT datname FROM pg_database WHERE datistemplate=false AND datname<>'postgres';\""
|
|
}
|
|
|
|
console() {
|
|
if [[ -z $1 ]]; then
|
|
lxc exec ct1 -- su - postgres
|
|
else
|
|
lxc exec ct1 -- su - postgres -c "$1"
|
|
fi
|
|
}
|
|
|
|
connections() {
|
|
PROCESSES=$(console "psql -c \"select pid as process_id, usename as username, datname as database_name, client_addr as client_address, application_name, backend_start, state, state_change from pg_stat_activity WHERE datname<>'postgres' ORDER BY datname, usename;\"")
|
|
printf "$PROCESSES\n"
|
|
}
|
|
|
|
use() {
|
|
echo >&2 "about to connect to <${DB_NAME}> ..."
|
|
if [[ -z $1 ]]; then
|
|
lxc exec ct1 -- su - postgres -c "psql $DB_NAME"
|
|
else
|
|
local sql="psql -A -t $DB_NAME -c \\\"$1;\\\""
|
|
local command="su - postgres -c \"$sql\""
|
|
lxc exec ct1 -- sh -c "$command"
|
|
fi
|
|
}
|
|
|
|
create() {
|
|
echo >&2 "about to create to <${DB_NAME}> ..."
|
|
source /opt/miaou-bash/lib/functions.sh
|
|
local DBs=($(list))
|
|
if ! $(containsElement DBs $DB_NAME); then
|
|
local SQL="CREATE USER \\\\\\\"$DB_NAME\\\\\\\" WITH PASSWORD '$DB_PASSWORD'"
|
|
local command="su - postgres sh -c \"psql -c \\\"$SQL\\\"\" && su - postgres sh -c \"createdb -O $DB_NAME $DB_NAME\" && echo CREATE DB"
|
|
# echo $command
|
|
lxc exec ct1 -- sh -c "$command"
|
|
else
|
|
echo $DB_NAME already exists!
|
|
fi
|
|
|
|
}
|
|
|
|
lookup() {
|
|
if [[ ${#TERM} -ge 4 ]]; then
|
|
echo >&2 "about to lookup term <${TERM}> over all tables of database <$DB_NAME> ..."
|
|
local command="pg_dump --data-only --inserts $DB_NAME 2>/dev/null | grep --color \"$TERM\""
|
|
lxc exec ct1 -- su - postgres -c "$command"
|
|
else
|
|
echo "term <$TERM> should contain 4 chars minimum!" && exit 2
|
|
fi
|
|
}
|
|
|
|
backup() {
|
|
if [[ ! -d "$FOLDER" ]]; then
|
|
echo "error: Folder required!"
|
|
file $FOLDER
|
|
exit 2
|
|
fi
|
|
DATE=$(date '+%F')
|
|
ARCHIVE="$FOLDER"/$DB_NAME-$DATE.postgres.gz
|
|
|
|
if [[ -f $ARCHIVE ]]; then
|
|
VERSION_CONTROL=numbered mv -b $ARCHIVE "$FOLDER"/$DB_NAME-$DATE-daily.postgres.gz
|
|
fi
|
|
|
|
echo "backup $DB_NAME $FOLDER"
|
|
PGPASSWORD=$DB_NAME pg_dump -U $DB_NAME $DB_NAME -h ct1.lxd | gzip >"$ARCHIVE"
|
|
echo "archive file created: $ARCHIVE"
|
|
}
|
|
|
|
restore() {
|
|
echo "restore $DB_NAME $FILE"
|
|
if [[ ! -f "$FILE" ]]; then
|
|
echo "error: Backup file (*.postgres.gz) required!"
|
|
file $FILE
|
|
exit 2
|
|
fi
|
|
PROCESSES=$(console "psql -c \"select pid as process_id, usename as username, datname as database_name, client_addr as client_address, application_name, backend_start, state, state_change from pg_stat_activity WHERE datname='$DB_NAME';\"")
|
|
PROCESS_COUNT=$(echo "$PROCESSES" | wc -l)
|
|
if [[ $PROCESS_COUNT -gt 3 ]]; then
|
|
echo "FAILURE: There are some connections to database, please consider stopping bound services"
|
|
echo
|
|
printf "$PROCESSES\n"
|
|
exit 2
|
|
fi
|
|
|
|
if [[ $YES == "true" || "yes" == $(confirm "RESTORATION will drop DATABASE, please acknowledge with care!!!") ]]; then
|
|
FOLDER="$HOME/RECOVERY_POSTGRES"
|
|
mkdir -p "$FOLDER"
|
|
backup
|
|
echo "backup successful, now drop and restore"
|
|
lxc exec ct1 -- su - postgres -c "dropdb $DB_NAME && createdb -O $DB_NAME $DB_NAME"
|
|
gunzip -c "$FILE" | grep -v "^CREATE DATABASE" | PGPASSWORD=$DB_NAME PGOPTIONS='--client-min-messages=warning' psql -X -q -1 -v ON_ERROR_STOP=1 --pset pager=off -U $DB_NAME -h ct1.lxd $DB_NAME 2>&1 >/dev/null
|
|
else
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
rename() {
|
|
echo "rename <$DB_NAME> to <$DB_NEW_NAME>"
|
|
mapfile -t LIST <<<"$(list)"
|
|
found=false
|
|
for db in "${LIST[@]}"; do
|
|
[[ "$db" == "$DB_NEW_NAME" ]] && echoerr "destination database <$DB_NEW_NAME> already exists! Please provide another name." && exit 11
|
|
[[ "$db" == "$DB_NAME" ]] && found=true
|
|
done
|
|
$found || (echoerr "source database <$DB_NAME> not found!" && exit 12)
|
|
|
|
console "psql -c \"ALTER DATABASE \\\"$DB_NAME\\\" RENAME TO \\\"$DB_NEW_NAME\\\" \""
|
|
console "psql -c \"ALTER USER \\\"$DB_NAME\\\" RENAME TO \\\"$DB_NEW_NAME\\\" \""
|
|
console "psql -c \"ALTER USER \\\"$DB_NEW_NAME\\\" PASSWORD '$DB_NEW_NAME' \""
|
|
}
|
|
|
|
drop() {
|
|
console "dropdb $DB_NAME"
|
|
console "dropuser $DB_NAME"
|
|
echo "$DB_NAME dropped!"
|
|
}
|
|
|
|
# MAIN
|
|
. "$MIAOU_BASEDIR/lib/init.sh"
|
|
TARGET=$(grep -Es "^target:" /etc/miaou/defaults.yaml | cut -d ' ' -f2)
|
|
|
|
[[ $# -lt 1 ]] && synopsis && exit 1
|
|
ACTION=$1
|
|
|
|
case $ACTION in
|
|
console)
|
|
shift
|
|
TAIL="$@"
|
|
console "$TAIL"
|
|
;;
|
|
list)
|
|
list
|
|
;;
|
|
connections)
|
|
connections
|
|
;;
|
|
use)
|
|
[[ $# -lt 2 ]] && synopsis && exit 1
|
|
DB_NAME=$2
|
|
shift 2
|
|
TAIL="$@"
|
|
use "$TAIL"
|
|
;;
|
|
create)
|
|
[[ $# -lt 2 ]] && synopsis && exit 1
|
|
DB_NAME=$2
|
|
DB_PASSWORD=${3:-$DB_NAME}
|
|
create
|
|
;;
|
|
lookup)
|
|
[[ $# -lt 3 ]] && synopsis && exit 1
|
|
DB_NAME=$2
|
|
TERM=$3
|
|
lookup
|
|
;;
|
|
backup)
|
|
[[ $# -lt 2 ]] && synopsis && exit 1
|
|
DB_NAME=$2
|
|
FOLDER=${3:-.}
|
|
backup
|
|
;;
|
|
restore)
|
|
[[ $# -lt 3 ]] && synopsis && exit 1
|
|
DB_NAME=$2
|
|
FILE=$3
|
|
YES=true
|
|
restore
|
|
;;
|
|
rename)
|
|
[[ $# -lt 3 ]] && synopsis && exit 1
|
|
DB_NAME=$2
|
|
DB_NEW_NAME=$3
|
|
rename
|
|
;;
|
|
drop)
|
|
[[ $# -lt 2 ]] && synopsis && exit 1
|
|
[[ "$TARGET" = 'prod' ]] && synopsis && exit 2
|
|
DB_NAME=$2
|
|
drop
|
|
;;
|
|
*)
|
|
synopsis
|
|
exit 1
|
|
;;
|
|
esac
|