From c3a4eeadd9ba07bbc133b9fe50eb941af73d63b5 Mon Sep 17 00:00:00 2001 From: Edi Septriyanto Date: Sat, 8 Apr 2023 23:09:19 +0700 Subject: [PATCH] Add Postgres installer --- .env.dist | 10 +++ install.sh | 74 +++++++++------- lemper.sh | 84 ++++++++++-------- scripts/install_postgres.sh | 172 ++++++++++++++++++++++++++++++++++++ scripts/remove_postgres.sh | 130 +++++++++++++++++++++++++++ shunit2/run_test.sh | 2 +- 6 files changed, 402 insertions(+), 70 deletions(-) create mode 100755 scripts/install_postgres.sh create mode 100755 scripts/remove_postgres.sh diff --git a/.env.dist b/.env.dist index d204228..211679b 100644 --- a/.env.dist +++ b/.env.dist @@ -227,6 +227,16 @@ MARIABACKUP_USER="lemperdb" # Leave it blank for auto generated secure password. MARIABACKUP_PASS="" +[postgres] +INSTALL_POSTGRES=true + +# Postgres version (only type the major version number). +POSTGRES_VERSION="15" + +# Default Postgres system user. +POSTGRES_USER="postgres" +POSTGRES_PGDATA="/var/lib/postgresql/data" + [memcached] INSTALL_MEMCACHED=false diff --git a/install.sh b/install.sh index 5525fea..b1a31cf 100755 --- a/install.sh +++ b/install.sh @@ -75,8 +75,8 @@ fi ### Create default account ### echo "" -USERNAME=${LEMPER_USERNAME:-"lemper"} -create_account "${USERNAME}" +LEMPER_USERNAME=${LEMPER_USERNAME:-"lemper"} +create_account "${LEMPER_USERNAME}" ### Certbot Let's Encrypt SSL installation ### if [ -f ./scripts/install_certbotle.sh ]; then @@ -192,7 +192,7 @@ if [[ "${DRYRUN}" != true ]]; then status -e "\nCongrats, your LEMPer Stack installation has been completed." ### Recap ### - if [[ -n "${PASSWORD}" ]]; then + if [[ -n "${LEMPER_PASSWORD}" ]]; then CREDENTIALS="~~~~~~~~~~~~~~~~~~~~~~~~~o0o~~~~~~~~~~~~~~~~~~~~~~~~~ Default system information: Hostname : ${HOSTNAME} @@ -200,46 +200,26 @@ Default system information: SSH Port : ${SSH_PORT} LEMPer Stack admin account: - Username : ${USERNAME} - Password : ${PASSWORD} + Username : ${LEMPER_USERNAME} + Password : ${LEMPER_PASSWORD} Database administration (Adminer): http://${SERVER_IP}:8082/lcp/dbadmin/ - Database root password: ${MYSQL_ROOT_PASSWORD} + MySQL root password: ${MYSQL_ROOT_PASSWORD} Mariabackup user information: DB Username: ${MARIABACKUP_USER} - DB Password: ${MARIABACKUP_PASS} + DB Password: ${MARIABACKUP_PASS}" -File manager (TinyFileManager): - http://${SERVER_IP}:8082/lcp/filemanager/ - - Use your default LEMPer stack admin account for Filemanager login." - - if [[ "${INSTALL_MAILER}" == true ]]; then + if [[ "${INSTALL_POSTGRES}" == true ]]; then CREDENTIALS="${CREDENTIALS} -Default Mail service: - Maildir : /home/${USERNAME}/Maildir - Sender Domain: ${SENDER_DOMAIN} - Sender IP : ${SERVER_IP} - IMAP Port : 143, 993 (SSL/TLS) - POP3 Port : 110, 995 (SSL/TLS) +PostgreSQL user information: + Default Postgres User: ${POSTGRES_USER} - Domain Key : lemper._domainkey.${SENDER_DOMAIN} - DKIM Key : ${DKIM_KEY} - SPF Record : v=spf1 ip4:${SERVER_IP} include:${SENDER_DOMAIN} mx ~all - - Use your default LEMPer stack admin account for Mail login." - fi - - if [[ "${INSTALL_MEMCACHED}" == true && "${MEMCACHED_SASL}" == true ]]; then - CREDENTIALS="${CREDENTIALS} - -Memcached SASL login: - Username : ${MEMCACHED_USERNAME} - Password : ${MEMCACHED_PASSWORD}" + PostgresSQL DB Username: ${PSQL_USER} + PostgresSQL DB Password: ${PSQL_PASS}" fi if [[ "${INSTALL_MONGODB}" == true ]]; then @@ -257,8 +237,38 @@ Redis required password enabled: Password : ${REDIS_PASSWORD}" fi + if [[ "${INSTALL_MEMCACHED}" == true && "${MEMCACHED_SASL}" == true ]]; then + CREDENTIALS="${CREDENTIALS} + +Memcached SASL login: + Username : ${MEMCACHED_USERNAME} + Password : ${MEMCACHED_PASSWORD}" + fi + + if [[ "${INSTALL_MAILER}" == true ]]; then + CREDENTIALS="${CREDENTIALS} + +Default Mail service: + Maildir : /home/${LEMPER_USERNAME}/Maildir + Sender Domain: ${SENDER_DOMAIN} + Sender IP : ${SERVER_IP} + IMAP Port : 143, 993 (SSL/TLS) + POP3 Port : 110, 995 (SSL/TLS) + + Domain Key : lemper._domainkey.${SENDER_DOMAIN} + DKIM Key : ${DKIM_KEY} + SPF Record : v=spf1 ip4:${SERVER_IP} include:${SENDER_DOMAIN} mx ~all + + Use your default LEMPer stack admin account for Mail login." + fi + CREDENTIALS="${CREDENTIALS} +File manager (TinyFileManager): + http://${SERVER_IP}:8082/lcp/filemanager/ + + Use your default LEMPer stack admin account for Filemanager login. + Please Save the above Credentials & Keep it Secure! ~~~~~~~~~~~~~~~~~~~~~~~~~o0o~~~~~~~~~~~~~~~~~~~~~~~~~" diff --git a/lemper.sh b/lemper.sh index 9bbaefe..c32648e 100755 --- a/lemper.sh +++ b/lemper.sh @@ -71,8 +71,8 @@ function lemper_install() { ### Create default account ### echo "" - USERNAME=${LEMPER_USERNAME:-"lemper"} - create_account "${USERNAME}" + LEMPER_USERNAME=${LEMPER_USERNAME:-"lemper"} + create_account "${LEMPER_USERNAME}" ### Certbot Let's Encrypt SSL installation ### if [ -f ./scripts/install_certbotle.sh ]; then @@ -188,54 +188,34 @@ function lemper_install() { status -e "\nCongrats, your LEMPer Stack installation has been completed." ### Recap ### - if [[ -n "${PASSWORD}" ]]; then + if [[ -n "${LEMPER_PASSWORD}" ]]; then CREDENTIALS="~~~~~~~~~~~~~~~~~~~~~~~~~o0o~~~~~~~~~~~~~~~~~~~~~~~~~ Default System Information: - Hostname : ${HOSTNAME} - Server IP: ${SERVER_IP} - SSH Port : ${SSH_PORT} + Hostname : ${HOSTNAME} + Server IP: ${SERVER_IP} + SSH Port : ${SSH_PORT} LEMPer Stack Admin Account: - Username : ${USERNAME} - Password : ${PASSWORD} + Username : ${LEMPER_USERNAME} + Password : ${LEMPER_PASSWORD} Database Administration (Adminer): - http://${SERVER_IP}:8082/lcp/dbadmin/ + http://${SERVER_IP}:8082/lcp/dbadmin/ - Database root password: ${MYSQL_ROOT_PASSWORD} + MySQL root password: ${MYSQL_ROOT_PASSWORD} -Mariabackup Information: +Mariabackup user information: DB Username: ${MARIABACKUP_USER} - DB Password: ${MARIABACKUP_PASS} + DB Password: ${MARIABACKUP_PASS}" -Simple File Manager (Experimental): - http://${SERVER_IP}:8082/lcp/filemanager/ - - Use your default LEMPer Stack admin account for Filemanager login." - - if [[ "${INSTALL_MAILER}" == true ]]; then + if [[ "${INSTALL_POSTGRES}" == true ]]; then CREDENTIALS="${CREDENTIALS} -Default Mail Service: - Maildir : /home/${USERNAME}/Maildir - Sender Domain: ${SENDER_DOMAIN} - Sender IP : ${SERVER_IP} - IMAP Port : 143, 993 (SSL/TLS) - POP3 Port : 110, 995 (SSL/TLS) +PostgreSQL user information: + Default Postgres User: ${POSTGRES_USER} - Domain Key : lemper._domainkey.${SENDER_DOMAIN} - DKIM Key : ${DKIM_KEY} - SPF Record : v=spf1 ip4:${SERVER_IP} include:${SENDER_DOMAIN} mx ~all - - Use your default LEMPer Stack admin account for Mail login." - fi - - if [[ "${INSTALL_MEMCACHED}" == true && "${MEMCACHED_SASL}" == true ]]; then - CREDENTIALS="${CREDENTIALS} - -Memcached SASL Login: - Username : ${MEMCACHED_USERNAME} - Password : ${MEMCACHED_PASSWORD}" + PostgresSQL DB Username: ${PSQL_USER} + PostgresSQL DB Password: ${PSQL_PASS}" fi if [[ "${INSTALL_MONGODB}" == true ]]; then @@ -253,8 +233,38 @@ Redis required password enabled: Password : ${REDIS_PASSWORD}" fi + if [[ "${INSTALL_MEMCACHED}" == true && "${MEMCACHED_SASL}" == true ]]; then + CREDENTIALS="${CREDENTIALS} + +Memcached SASL Login: + Username : ${MEMCACHED_USERNAME} + Password : ${MEMCACHED_PASSWORD}" + fi + + if [[ "${INSTALL_MAILER}" == true ]]; then + CREDENTIALS="${CREDENTIALS} + +Default Mail Service: + Maildir : /home/${LEMPER_USERNAME}/Maildir + Sender Domain: ${SENDER_DOMAIN} + Sender IP : ${SERVER_IP} + IMAP Port : 143, 993 (SSL/TLS) + POP3 Port : 110, 995 (SSL/TLS) + + Domain Key : lemper._domainkey.${SENDER_DOMAIN} + DKIM Key : ${DKIM_KEY} + SPF Record : v=spf1 ip4:${SERVER_IP} include:${SENDER_DOMAIN} mx ~all + + Use your default LEMPer Stack admin account for Mail login." + fi + CREDENTIALS="${CREDENTIALS} +File manager (TinyFileManager): + http://${SERVER_IP}:8082/lcp/filemanager/ + + Use your default LEMPer stack admin account for Filemanager login. + Please Save the above Credentials & Keep it Secure! ~~~~~~~~~~~~~~~~~~~~~~~~~o0o~~~~~~~~~~~~~~~~~~~~~~~~~" diff --git a/scripts/install_postgres.sh b/scripts/install_postgres.sh new file mode 100755 index 0000000..2e14782 --- /dev/null +++ b/scripts/install_postgres.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env bash + +# PostgreSQL server installer +# Min. Requirement : GNU/Linux Ubuntu 18.04 +# Last Build : 08/04/2023 +# Author : MasEDI.Net (me@masedi.net) +# Since Version : 2.6.6 + +# Include helper functions. +if [[ "$(type -t run)" != "function" ]]; then + BASE_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd ) + # shellcheck disable=SC1091 + . "${BASE_DIR}/utils.sh" + + # Make sure only root can run this installer script. + requires_root "$@" + + # Make sure only supported distribution can run this installer script. + preflight_system_check +fi + +## +# Add PostgreSQL Repository. +## +function add_postgres_repo() { + local POSTGRES_VERSION=${POSTGRES_VERSION:-"15"} + local POSTGRES_REPO_KEY=${POSTGRES_REPO_KEY:-"ACCC4CF8"} + + case ${DISTRIB_NAME} in + debian | ubuntu) + if [[ ! -f "/etc/apt/sources.list.d/postgres-${RELEASE_NAME}.list" ]]; then + echo "Adding PostgreSQL repository key..." + + run bash -c "wget --quiet -O - https://www.postgresql.org/media/keys/${POSTGRES_REPO_KEY}.asc | apt-key add -" + + echo "Adding PostgreSQL repository..." + + run touch "/etc/apt/sources.list.d/postgres-${RELEASE_NAME}.list" + run bash -c "echo 'deb http://apt.postgresql.org/pub/repos/apt ${RELEASE_NAME}-pgdg main' > /etc/apt/sources.list.d/postgres-${RELEASE_NAME}.list" + run apt-get update -q -y + else + info "PostgreSQL ${POSTGRES_VERSION} repository already exists." + fi + ;; + *) + error "Unable to add PostgreSQL repo, unsupported release: ${DISTRIB_NAME^} ${RELEASE_NAME^}." + echo "Sorry your system is not supported yet, installing from source may fix the issue." + exit 1 + ;; + esac +} + +## +# Install Postgres. +## +function init_postgres_install() { + if [[ "${AUTO_INSTALL}" == true ]]; then + if [[ "${INSTALL_POSTGRES}" == true ]]; then + local DO_INSTALL_POSTGRES="y" + else + local DO_INSTALL_POSTGRES="n" + fi + else + while [[ "${DO_INSTALL_POSTGRES}" != y* && "${DO_INSTALL_POSTGRES}" != n* ]]; do + read -rp "Do you want to install PostgreSQL server? [y/n]: " -i y -e DO_INSTALL_POSTGRES + done + fi + + #export POSTGRES_USER=${POSTGRES_USER:-"postgres"} + export POSTGRES_USER="postgres" + export PSQL_USER=${LEMPER_USERNAME:-"lemper"} + export PSQL_PASS=${LEMPER_PASSWORD:-$(openssl rand -base64 64 | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)} + + local POSTGRES_VERSION=${POSTGRES_VERSION:-"15"} + local POSTGRES_TEST_DB="${PSQL_USER}db" + local PGDATA=${POSTGRES_PGDATA:-"/var/lib/postgresql/data"} + local POSTGRES_PKGS=() + + # Do PostgreSQL server installation here... + if [[ ${DO_INSTALL_POSTGRES} == y* || ${DO_INSTALL_POSTGRES} == Y* ]]; then + # Add repository. + add_postgres_repo + + echo "Installing PostgreSQL server..." + + # Default PostgreSQL user + #if [[ -z $(getent passwd "${POSTGRES_USER}") ]]; then + # run groupadd -r "${POSTGRES_USER}" --gid=999 && \ + # run useradd -r -g "${POSTGRES_USER}" --uid=999 --home-dir=/var/lib/postgresql --shell=/bin/bash "${POSTGRES_USER}" && \ + # run mkdir -p /var/lib/postgresql && \ + # run chown -hR "${POSTGRES_USER}":"${POSTGRES_USER}" /var/lib/postgresql + #fi + + # Install Postgres + if [[ "${POSTGRES_VERSION}" == "latest" || "${POSTGRES_VERSION}" == "stable" ]]; then + POSTGRES_PKGS+=("postgresql" "postgresql-client" "postgresql-client-common" "postgresql-common") + else + POSTGRES_PKGS+=("postgresql-${POSTGRES_VERSION}" "postgresql-client-${POSTGRES_VERSION}" \ + "postgresql-client-common" "postgresql-common") + fi + + run apt-get install -q -y "${POSTGRES_PKGS[@]}" + + #run mkdir -p /var/run/postgresql && \ + #run chown -R "${POSTGRES_USER}":"${POSTGRES_USER}" /var/run/postgresql && \ + #run chmod 2777 /var/run/postgresql + #run mkdir -p "${PGDATA}" && \ + #run chown -R "${POSTGRES_USER}":"${POSTGRES_USER}" "${PGDATA}" && \ + #run chmod 777 "${PGDATA}" + + # Configure PostgreSQL installation. + if [[ "${DRYRUN}" == true ]]; then + info "PostgreSQL server installed in dry run mode." + else + if [[ -f "/lib/systemd/system/postgresql@${POSTGRES_VERSION}-main.service" ]]; then + # Trying to reload daemon. + run systemctl daemon-reload + + # Enable PostgreSQL on startup. + run systemctl enable "postgresql@${POSTGRES_VERSION}-main.service" + + # Restart PostgreSQL service daemon. + #run systemctl start "postgresql@${POSTGRES_VERSION}-main.service" + fi + + if [[ $(pgrep -c postgres) -gt 0 || -n $(command -v psql) ]]; then + success "PostgreSQL server installed successfully." + + if [[ -n $(command -v psql) ]]; then + echo "Creating PostgreSQL user '${POSTGRES_USER}' and database '${POSTGRES_TEST_DB}'." + + # Create test role and database. + run sudo -i -u "${POSTGRES_USER}" -- psql -v ON_ERROR_STOP=1 <<-PGSQL + CREATE ROLE ${PSQL_USER} LOGIN PASSWORD '${PSQL_PASS}'; + CREATE DATABASE ${POSTGRES_TEST_DB}; + GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_TEST_DB} TO ${PSQL_USER}; +PGSQL + fi + + # Restart Postgres + run systemctl restart "postgresql@${POSTGRES_VERSION}-main.service" + + if [[ $(pgrep -c postgres) -gt 0 ]]; then + success "PostgreSQL server configured successfully." + elif [[ -n $(command -v postgres) ]]; then + # Server died? try to start it. + run systemctl start "postgresql@${POSTGRES_VERSION}-main.service" + + if [[ $(pgrep -c postgres) -gt 0 ]]; then + success "PostgreSQL server configured successfully." + else + info "Something went wrong with PostgreSQL server installation." + fi + fi + else + info "Something went wrong with PostgreSQL server installation." + fi + fi + else + info "PostgreSQL installation skipped." + fi +} + +echo "[PostgreSQL Installation]" + +# Start running things from a call at the end so if this script is executed +# after a partial download it doesn't do anything. +if [[ -n $(command -v postgres) && "${FORCE_INSTALL}" != true ]]; then + info "PostgreSQL server already exists, installation skipped." +else + init_postgres_install "$@" +fi diff --git a/scripts/remove_postgres.sh b/scripts/remove_postgres.sh new file mode 100755 index 0000000..ee90194 --- /dev/null +++ b/scripts/remove_postgres.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash + +# PostgreSQL server uninstaller +# Min. Requirement : GNU/Linux Ubuntu 18.04 +# Last Build : 08/04/2023 +# Author : MasEDI.Net (me@masedi.net) +# Since Version : 2.6.6 + +# Include helper functions. +if [[ "$(type -t run)" != "function" ]]; then + BASE_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd ) + # shellcheck disable=SC1091 + . "${BASE_DIR}/utils.sh" + + # Make sure only root can run this installer script. + requires_root "$@" + + # Make sure only supported distribution can run this installer script. + preflight_system_check +fi + +function postgres_remove_config() { + local POSTGRES_VERSION=${POSTGRES_VERSION:-"15"} + local PGDATA=${POSTGRES_PGDATA:-"/var/lib/postgresql/data"} + + # Remove PostgreSQL server config files. + echo "Removing PostgreSQL configuration..." + warning "!! This action is not reversible !!" + + if [[ "${AUTO_REMOVE}" == true ]]; then + if [[ "${FORCE_REMOVE}" == true ]]; then + REMOVE_POSTGRES_CONFIG="y" + else + REMOVE_POSTGRES_CONFIG="n" + fi + else + while [[ "${REMOVE_POSTGRES_CONFIG}" != "y" && "${REMOVE_POSTGRES_CONFIG}" != "n" ]]; do + read -rp "Remove PostgreSQL database and configuration files? [y/n]: " -e REMOVE_POSTGRES_CONFIG + done + fi + + if [[ "${REMOVE_POSTGRES_CONFIG}" == y* || "${REMOVE_POSTGRES_CONFIG}" == Y* ]]; then + [ -d /var/lib/postgresql ] && run rm -fr /var/lib/postgresql + [ -d /var/run/postgresql ] && run rm -fr /var/run/postgresql + [ -d "${PGDATA}" ] && run rm -fr "${PGDATA}" + [ -d "/etc/postgresql/${POSTGRES_VERSION}" ] && run rm -fr "/etc/postgresql/${POSTGRES_VERSION}" + + echo "All database and configuration files deleted permanently." + fi +} + +function init_postgres_removal() { + local POSTGRES_VERSION=${POSTGRES_VERSION:-"15"} + local POSTGRES_USER=${POSTGRES_USER:-"postgres"} + local POSTGRES_PKGS=() + + # Stop PostgreSQL mysql server process. + if [[ $(pgrep -c postgres) -gt 0 ]]; then + echo "Stopping postgres..." + run systemctl stop "postgresql@${POSTGRES_VERSION}-main.service" + fi + + #run systemctl disable "postgresql@${POSTGRES_VERSION}-main.service" + + if dpkg-query -l | awk '/postgresql/ { print $2 }' | grep -qwE "^postgresql"; then + echo "Found PostgreSQL ${POSTGRES_VERSION} packages installation, removing..." + + # Installed Postgres packages. + if [[ "${POSTGRES_VERSION}" == "latest" || "${POSTGRES_VERSION}" == "stable" ]]; then + POSTGRES_PKGS+=("postgresql" "postgresql-client" "postgresql-client-common" "postgresql-common") + else + POSTGRES_PKGS+=("postgresql-${POSTGRES_VERSION}" "postgresql-client-${POSTGRES_VERSION}" \ + "postgresql-client-common" "postgresql-common") + fi + + # Remove PostgreSQL server. + run apt-get --purge remove -q -y "${POSTGRES_PKGS[@]}" + + # Remove PostgreSQL default user. + if [[ -n $(getent passwd "${POSTGRES_USER}") ]]; then + run userdel -r "${POSTGRES_USER}" + fi + + if [[ -n $(getent group "${POSTGRES_USER}") ]]; then + run groupdel "${POSTGRES_USER}" + fi + + # Remove config. + postgres_remove_config + + # Remove repository. + if [[ "${FORCE_REMOVE}" == true ]]; then + run rm -f "/etc/apt/sources.list.d/postgres-${RELEASE_NAME}.list" + fi + else + echo "No installed PostgreSQL ${POSTGRES_VERSION} or MySQL packages found." + echo "Possibly installed from source? Remove it manually!" + fi + + # Final test. + if [[ "${DRYRUN}" != true ]]; then + if [[ $(pgrep -c postgres) -eq 0 ]]; then + success "PostgreSQL server removed." + else + info "PostgreSQL server not removed." + fi + else + info "PostgreSQL server removed in dry run mode." + fi +} + +echo "Uninstalling PostgreSQL server..." + +if [[ -n $(command -v psql) ]]; then + if [[ "${AUTO_REMOVE}" == true ]]; then + REMOVE_POSTGRES="y" + else + while [[ "${REMOVE_POSTGRES}" != "y" && "${REMOVE_POSTGRES}" != "n" ]]; do + read -rp "Are you sure to remove PostgreSQL server? [y/n]: " -e REMOVE_POSTGRES + done + fi + + if [[ "${REMOVE_POSTGRES}" == y* || "${REMOVE_POSTGRES}" == Y* ]]; then + init_postgres_removal "$@" + else + echo "Found PostgreSQL server, but not removed." + fi +else + info "Oops, PostgreSQL server installation not found." +fi diff --git a/shunit2/run_test.sh b/shunit2/run_test.sh index fbfd2ff..60708be 100755 --- a/shunit2/run_test.sh +++ b/shunit2/run_test.sh @@ -31,7 +31,7 @@ testEqualityCreateAccount() { create_account_status="" create_account lemper - [[ -n $(getent passwd "${USERNAME}") ]] && create_account_status="success" + [[ -n $(getent passwd "${LEMPER_USERNAME}") ]] && create_account_status="success" assertEquals "success" "${create_account_status}" }