From 31c1c161b634a5eb9f8e3b22e9e6bea99fe81f0c Mon Sep 17 00:00:00 2001 From: Praveen Date: Wed, 26 Mar 2025 17:38:23 +0530 Subject: [PATCH 1/4] Added the step to download the hash file and validate and then start the db restore step --- application/restore.sh | 195 +++++++++++++++++++++++++++++++---------- 1 file changed, 147 insertions(+), 48 deletions(-) diff --git a/application/restore.sh b/application/restore.sh index e506608..3fc721d 100755 --- a/application/restore.sh +++ b/application/restore.sh @@ -1,79 +1,178 @@ -#!/usr/bin/env sh +#!/usr/bin/env bash -MYNAME="postgresql-backup-restore" -STATUS=0 +# Initialize logging with timestamp +log() { + local level="$1"; + local message="$2"; + echo "[$(date '+%Y-%m-%d %H:%M:%S')] ${level}: ${message}"; +} -echo "${MYNAME}: restore: Started" +# Sentry reporting with validation and backwards compatibility +error_to_sentry() { + local error_message="$1"; + local db_name="$2"; + local status_code="$3"; + + # Check if SENTRY_DSN is configured - ensures restore continues + if [ -z "${SENTRY_DSN:-}" ]; then + log "DEBUG" "Sentry logging skipped - SENTRY_DSN not configured"; + return 0; + fi + + # Validate SENTRY_DSN format + if ! [[ "${SENTRY_DSN}" =~ ^https://[^@]+@[^/]+/[0-9]+$ ]]; then + log "WARN" "Invalid SENTRY_DSN format - Sentry logging will be skipped"; + return 0; + fi + + # Attempt to send event to Sentry + if sentry-cli send-event \ + --message "${error_message}" \ + --level error \ + --tag "database:${db_name}" \ + --tag "status:${status_code}"; then + log "DEBUG" "Successfully sent error to Sentry - Message: ${error_message}, Database: ${db_name}, Status: ${status_code}"; + else + log "WARN" "Failed to send error to Sentry, but continuing restore process"; + fi + + return 0; +} + +MYNAME="postgresql-backup-restore"; +STATUS=0; +log "INFO" "${MYNAME}: restore: Started"; # Ensure the database user exists. -echo "${MYNAME}: checking for DB user ${DB_USER}" -result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command='\du' | grep ${DB_USER}) +log "INFO" "${MYNAME}: checking for DB user ${DB_USER}"; +result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command='\du' | grep ${DB_USER}); if [ -z "${result}" ]; then - result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command="create role ${DB_USER} with login password '${DB_USERPASSWORD}' inherit;") + result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command="create role ${DB_USER} with login password '${DB_USERPASSWORD}' inherit;"); if [ "${result}" != "CREATE ROLE" ]; then - message="Create role command failed: ${result}" - echo "${MYNAME}: FATAL: ${message}" - exit 1 + error_message="Create role command failed: ${result}"; + log "ERROR" "${MYNAME}: FATAL: ${error_message}"; + error_to_sentry "${error_message}" "${DB_NAME}" "1"; + exit 1; fi fi # Delete database if it exists. -echo "${MYNAME}: checking for DB ${DB_NAME}" -result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --list | grep ${DB_NAME}) +log "INFO" "${MYNAME}: checking for DB ${DB_NAME}"; +result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --list | grep ${DB_NAME}); if [ -z "${result}" ]; then - message="Database "${DB_NAME}" on host "${DB_HOST}" does not exist." - echo "${MYNAME}: INFO: ${message}" + log "INFO" "${MYNAME}: INFO: Database \"${DB_NAME}\" on host \"${DB_HOST}\" does not exist."; else - message="finding current owner of DB ${DB_NAME}" - echo "${MYNAME}: ${message}" - db_owner=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command='\list' | grep ${DB_NAME} | cut -d '|' -f 2 | sed -e 's/ *//g') - message="Database owner is ${db_owner}" - echo "${MYNAME}: INFO: ${message}" - - echo "${MYNAME}: deleting database ${DB_NAME}" - result=$(psql --host=${DB_HOST} --dbname=postgres --username=${db_owner} --command="DROP DATABASE ${DB_NAME};") + log "INFO" "${MYNAME}: finding current owner of DB ${DB_NAME}"; + db_owner=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command='\list' | grep ${DB_NAME} | cut -d '|' -f 2 | sed -e 's/ *//g'); + log "INFO" "${MYNAME}: INFO: Database owner is ${db_owner}"; + + log "INFO" "${MYNAME}: deleting database ${DB_NAME}"; + result=$(psql --host=${DB_HOST} --dbname=postgres --username=${db_owner} --command="DROP DATABASE ${DB_NAME};"); if [ "${result}" != "DROP DATABASE" ]; then - message="Drop database command failed: ${result}" - echo "${MYNAME}: FATAL: ${message}" - exit 1 + error_message="Drop database command failed: ${result}"; + log "ERROR" "${MYNAME}: FATAL: ${error_message}"; + error_to_sentry "${error_message}" "${DB_NAME}" "1"; + exit 1; fi fi -echo "${MYNAME}: copying database ${DB_NAME} backup from ${S3_BUCKET}" -start=$(date +%s) -s3cmd get -f ${S3_BUCKET}/${DB_NAME}.sql.gz /tmp/${DB_NAME}.sql.gz || STATUS=$? -end=$(date +%s) +# Download the backup and checksum files +log "INFO" "${MYNAME}: copying database ${DB_NAME} backup and checksum from ${S3_BUCKET}"; +start=$(date +%s); + +# Download database backup +s3cmd get -f ${S3_BUCKET}/${DB_NAME}.sql.gz /tmp/${DB_NAME}.sql.gz || STATUS=$?; +if [ $STATUS -ne 0 ]; then + error_message="${MYNAME}: FATAL: Copy backup of ${DB_NAME} from ${S3_BUCKET} returned non-zero status ($STATUS) in $(expr $(date +%s) - ${start}) seconds."; + log "ERROR" "${error_message}"; + error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}"; + exit $STATUS; +fi +# Download checksum file +s3cmd get -f ${S3_BUCKET}/${DB_NAME}.sql.sha256.gz /tmp/${DB_NAME}.sql.sha256.gz || STATUS=$?; +end=$(date +%s); if [ $STATUS -ne 0 ]; then - echo "${MYNAME}: FATAL: Copy backup of ${DB_NAME} from ${S3_BUCKET} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds." - exit $STATUS + error_message="${MYNAME}: FATAL: Copy checksum of ${DB_NAME} from ${S3_BUCKET} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds."; + log "ERROR" "${error_message}"; + error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}"; + exit $STATUS; else - echo "${MYNAME}: Copy backup of ${DB_NAME} from ${S3_BUCKET} completed in $(expr ${end} - ${start}) seconds." + log "INFO" "${MYNAME}: Copy backup and checksum of ${DB_NAME} from ${S3_BUCKET} completed in $(expr ${end} - ${start}) seconds."; fi -echo "${MYNAME}: decompressing backup of ${DB_NAME}" -start=$(date +%s) -gunzip -f /tmp/${DB_NAME}.sql.gz || STATUS=$? -end=$(date +%s) +# Decompress both files +log "INFO" "${MYNAME}: decompressing backup and checksum of ${DB_NAME}"; +start=$(date +%s); + +# Decompress backup file +gunzip -f /tmp/${DB_NAME}.sql.gz || STATUS=$?; +if [ $STATUS -ne 0 ]; then + error_message="${MYNAME}: FATAL: Decompressing backup of ${DB_NAME} returned non-zero status ($STATUS) in $(expr $(date +%s) - ${start}) seconds."; + log "ERROR" "${error_message}"; + error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}"; + exit $STATUS; +fi +# Decompress checksum file +gunzip -f /tmp/${DB_NAME}.sql.sha256.gz || STATUS=$?; +end=$(date +%s); if [ $STATUS -ne 0 ]; then - echo "${MYNAME}: FATAL: Decompressing backup of ${DB_NAME} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds." - exit $STATUS + error_message="${MYNAME}: FATAL: Decompressing checksum of ${DB_NAME} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds."; + log "ERROR" "${error_message}"; + error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}"; + exit $STATUS; else - echo "${MYNAME}: Decompressing backup of ${DB_NAME} completed in $(expr ${end} - ${start}) seconds." + log "INFO" "${MYNAME}: Decompressing backup and checksum of ${DB_NAME} completed in $(expr ${end} - ${start}) seconds."; fi -echo "${MYNAME}: restoring ${DB_NAME}" -start=$(date +%s) -psql --host=${DB_HOST} --username=${DB_ROOTUSER} --dbname=postgres ${DB_OPTIONS} < /tmp/${DB_NAME}.sql || STATUS=$? -end=$(date +%s) +# Validate the checksum +log "INFO" "${MYNAME}: Validating backup integrity with checksum"; +cd /tmp || { + error_message="${MYNAME}: FATAL: Failed to change directory to /tmp"; + log "ERROR" "${error_message}"; + error_to_sentry "${error_message}" "${DB_NAME}" "1"; + exit 1; +} + +sha256sum -c "${DB_NAME}.sql.sha256" || { + error_message="${MYNAME}: FATAL: Checksum validation failed for backup of ${DB_NAME}. The backup may be corrupted or tampered with."; + log "ERROR" "${error_message}"; + error_to_sentry "${error_message}" "${DB_NAME}" "1"; + exit 1; +} +log "INFO" "${MYNAME}: Checksum validation successful - backup integrity confirmed"; + +# Restore the database +log "INFO" "${MYNAME}: restoring ${DB_NAME}"; +start=$(date +%s); +psql --host=${DB_HOST} --username=${DB_ROOTUSER} --dbname=postgres ${DB_OPTIONS:-} < /tmp/${DB_NAME}.sql || STATUS=$?; +end=$(date +%s); if [ $STATUS -ne 0 ]; then - echo "${MYNAME}: FATAL: Restore of ${DB_NAME} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds." - exit $STATUS + error_message="${MYNAME}: FATAL: Restore of ${DB_NAME} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds."; + log "ERROR" "${error_message}"; + error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}"; + exit $STATUS; else - echo "${MYNAME}: Restore of ${DB_NAME} completed in $(expr ${end} - ${start}) seconds." + log "INFO" "${MYNAME}: Restore of ${DB_NAME} completed in $(expr ${end} - ${start}) seconds."; fi -echo "${MYNAME}: restore: Completed" -exit $STATUS +# Verify database restore success +log "INFO" "${MYNAME}: Verifying database restore success"; +result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --list | grep ${DB_NAME}); +if [ -z "${result}" ]; then + error_message="${MYNAME}: FATAL: Database ${DB_NAME} not found after restore attempt."; + log "ERROR" "${error_message}"; + error_to_sentry "${error_message}" "${DB_NAME}" "1"; + exit 1; +else + log "INFO" "${MYNAME}: Database ${DB_NAME} successfully restored and verified."; +fi + +# Clean up temporary files +rm -f "/tmp/${DB_NAME}.sql" "/tmp/${DB_NAME}.sql.sha256"; +log "INFO" "${MYNAME}: Temporary files cleaned up"; + +log "INFO" "${MYNAME}: restore: Completed"; +exit $STATUS; \ No newline at end of file From 831e9a02e322f819b14d6214aba62fa5776b3241 Mon Sep 17 00:00:00 2001 From: Praveen Date: Thu, 27 Mar 2025 12:37:38 +0530 Subject: [PATCH 2/4] Added terminating newline --- application/restore.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/restore.sh b/application/restore.sh index 3fc721d..f007499 100755 --- a/application/restore.sh +++ b/application/restore.sh @@ -175,4 +175,4 @@ rm -f "/tmp/${DB_NAME}.sql" "/tmp/${DB_NAME}.sql.sha256"; log "INFO" "${MYNAME}: Temporary files cleaned up"; log "INFO" "${MYNAME}: restore: Completed"; -exit $STATUS; \ No newline at end of file +exit $STATUS; From 892f6b0c398f05ff21d1fdd0fa46bbd16559523c Mon Sep 17 00:00:00 2001 From: Praveen Date: Wed, 2 Apr 2025 11:38:58 +0530 Subject: [PATCH 3/4] changed the shebang to sh and also changed the sentry dsn validate to support sh --- application/restore.sh | 191 +++++++++++++++++++++-------------------- 1 file changed, 96 insertions(+), 95 deletions(-) diff --git a/application/restore.sh b/application/restore.sh index f007499..b220275 100755 --- a/application/restore.sh +++ b/application/restore.sh @@ -1,28 +1,29 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # Initialize logging with timestamp log() { - local level="$1"; - local message="$2"; - echo "[$(date '+%Y-%m-%d %H:%M:%S')] ${level}: ${message}"; + local level="$1" + local message="$2" + echo "[$(date '+%Y-%m-%d %H:%M:%S')] ${level}: ${message}" } # Sentry reporting with validation and backwards compatibility error_to_sentry() { - local error_message="$1"; - local db_name="$2"; - local status_code="$3"; + local error_message="$1" + local db_name="$2" + local status_code="$3" # Check if SENTRY_DSN is configured - ensures restore continues if [ -z "${SENTRY_DSN:-}" ]; then - log "DEBUG" "Sentry logging skipped - SENTRY_DSN not configured"; - return 0; + log "DEBUG" "Sentry logging skipped - SENTRY_DSN not configured" + return 0 fi # Validate SENTRY_DSN format - if ! [[ "${SENTRY_DSN}" =~ ^https://[^@]+@[^/]+/[0-9]+$ ]]; then - log "WARN" "Invalid SENTRY_DSN format - Sentry logging will be skipped"; - return 0; + echo "${SENTRY_DSN}" | grep -E "^https://[^@]+@[^/]+/[0-9]+$" >/dev/null 2>&1 + if [ $? -ne 0 ]; then + log "WARN" "Invalid SENTRY_DSN format - Sentry logging will be skipped" + return 0 fi # Attempt to send event to Sentry @@ -31,148 +32,148 @@ error_to_sentry() { --level error \ --tag "database:${db_name}" \ --tag "status:${status_code}"; then - log "DEBUG" "Successfully sent error to Sentry - Message: ${error_message}, Database: ${db_name}, Status: ${status_code}"; + log "DEBUG" "Successfully sent error to Sentry - Message: ${error_message}, Database: ${db_name}, Status: ${status_code}" else - log "WARN" "Failed to send error to Sentry, but continuing restore process"; + log "WARN" "Failed to send error to Sentry, but continuing restore process" fi - return 0; + return 0 } -MYNAME="postgresql-backup-restore"; -STATUS=0; -log "INFO" "${MYNAME}: restore: Started"; +MYNAME="postgresql-backup-restore" +STATUS=0 +log "INFO" "${MYNAME}: restore: Started" # Ensure the database user exists. -log "INFO" "${MYNAME}: checking for DB user ${DB_USER}"; -result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command='\du' | grep ${DB_USER}); +log "INFO" "${MYNAME}: checking for DB user ${DB_USER}" +result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command='\du' | grep ${DB_USER}) if [ -z "${result}" ]; then - result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command="create role ${DB_USER} with login password '${DB_USERPASSWORD}' inherit;"); + result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command="create role ${DB_USER} with login password '${DB_USERPASSWORD}' inherit;") if [ "${result}" != "CREATE ROLE" ]; then - error_message="Create role command failed: ${result}"; - log "ERROR" "${MYNAME}: FATAL: ${error_message}"; - error_to_sentry "${error_message}" "${DB_NAME}" "1"; - exit 1; + error_message="Create role command failed: ${result}" + log "ERROR" "${MYNAME}: FATAL: ${error_message}" + error_to_sentry "${error_message}" "${DB_NAME}" "1" + exit 1 fi fi # Delete database if it exists. -log "INFO" "${MYNAME}: checking for DB ${DB_NAME}"; -result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --list | grep ${DB_NAME}); +log "INFO" "${MYNAME}: checking for DB ${DB_NAME}" +result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --list | grep ${DB_NAME}) if [ -z "${result}" ]; then - log "INFO" "${MYNAME}: INFO: Database \"${DB_NAME}\" on host \"${DB_HOST}\" does not exist."; + log "INFO" "${MYNAME}: INFO: Database \"${DB_NAME}\" on host \"${DB_HOST}\" does not exist." else - log "INFO" "${MYNAME}: finding current owner of DB ${DB_NAME}"; - db_owner=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command='\list' | grep ${DB_NAME} | cut -d '|' -f 2 | sed -e 's/ *//g'); - log "INFO" "${MYNAME}: INFO: Database owner is ${db_owner}"; + log "INFO" "${MYNAME}: finding current owner of DB ${DB_NAME}" + db_owner=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command='\list' | grep ${DB_NAME} | cut -d '|' -f 2 | sed -e 's/ *//g') + log "INFO" "${MYNAME}: INFO: Database owner is ${db_owner}" - log "INFO" "${MYNAME}: deleting database ${DB_NAME}"; - result=$(psql --host=${DB_HOST} --dbname=postgres --username=${db_owner} --command="DROP DATABASE ${DB_NAME};"); + log "INFO" "${MYNAME}: deleting database ${DB_NAME}" + result=$(psql --host=${DB_HOST} --dbname=postgres --username=${db_owner} --command="DROP DATABASE ${DB_NAME};") if [ "${result}" != "DROP DATABASE" ]; then - error_message="Drop database command failed: ${result}"; - log "ERROR" "${MYNAME}: FATAL: ${error_message}"; - error_to_sentry "${error_message}" "${DB_NAME}" "1"; - exit 1; + error_message="Drop database command failed: ${result}" + log "ERROR" "${MYNAME}: FATAL: ${error_message}" + error_to_sentry "${error_message}" "${DB_NAME}" "1" + exit 1 fi fi # Download the backup and checksum files -log "INFO" "${MYNAME}: copying database ${DB_NAME} backup and checksum from ${S3_BUCKET}"; -start=$(date +%s); +log "INFO" "${MYNAME}: copying database ${DB_NAME} backup and checksum from ${S3_BUCKET}" +start=$(date +%s) # Download database backup -s3cmd get -f ${S3_BUCKET}/${DB_NAME}.sql.gz /tmp/${DB_NAME}.sql.gz || STATUS=$?; +s3cmd get -f ${S3_BUCKET}/${DB_NAME}.sql.gz /tmp/${DB_NAME}.sql.gz || STATUS=$? if [ $STATUS -ne 0 ]; then - error_message="${MYNAME}: FATAL: Copy backup of ${DB_NAME} from ${S3_BUCKET} returned non-zero status ($STATUS) in $(expr $(date +%s) - ${start}) seconds."; - log "ERROR" "${error_message}"; - error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}"; - exit $STATUS; + error_message="${MYNAME}: FATAL: Copy backup of ${DB_NAME} from ${S3_BUCKET} returned non-zero status ($STATUS) in $(expr $(date +%s) - ${start}) seconds." + log "ERROR" "${error_message}" + error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}" + exit $STATUS fi # Download checksum file -s3cmd get -f ${S3_BUCKET}/${DB_NAME}.sql.sha256.gz /tmp/${DB_NAME}.sql.sha256.gz || STATUS=$?; -end=$(date +%s); +s3cmd get -f ${S3_BUCKET}/${DB_NAME}.sql.sha256.gz /tmp/${DB_NAME}.sql.sha256.gz || STATUS=$? +end=$(date +%s) if [ $STATUS -ne 0 ]; then - error_message="${MYNAME}: FATAL: Copy checksum of ${DB_NAME} from ${S3_BUCKET} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds."; - log "ERROR" "${error_message}"; - error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}"; - exit $STATUS; + error_message="${MYNAME}: FATAL: Copy checksum of ${DB_NAME} from ${S3_BUCKET} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds." + log "ERROR" "${error_message}" + error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}" + exit $STATUS else - log "INFO" "${MYNAME}: Copy backup and checksum of ${DB_NAME} from ${S3_BUCKET} completed in $(expr ${end} - ${start}) seconds."; + log "INFO" "${MYNAME}: Copy backup and checksum of ${DB_NAME} from ${S3_BUCKET} completed in $(expr ${end} - ${start}) seconds." fi # Decompress both files -log "INFO" "${MYNAME}: decompressing backup and checksum of ${DB_NAME}"; -start=$(date +%s); +log "INFO" "${MYNAME}: decompressing backup and checksum of ${DB_NAME}" +start=$(date +%s) # Decompress backup file -gunzip -f /tmp/${DB_NAME}.sql.gz || STATUS=$?; +gunzip -f /tmp/${DB_NAME}.sql.gz || STATUS=$? if [ $STATUS -ne 0 ]; then - error_message="${MYNAME}: FATAL: Decompressing backup of ${DB_NAME} returned non-zero status ($STATUS) in $(expr $(date +%s) - ${start}) seconds."; - log "ERROR" "${error_message}"; - error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}"; - exit $STATUS; + error_message="${MYNAME}: FATAL: Decompressing backup of ${DB_NAME} returned non-zero status ($STATUS) in $(expr $(date +%s) - ${start}) seconds." + log "ERROR" "${error_message}" + error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}" + exit $STATUS fi # Decompress checksum file -gunzip -f /tmp/${DB_NAME}.sql.sha256.gz || STATUS=$?; -end=$(date +%s); +gunzip -f /tmp/${DB_NAME}.sql.sha256.gz || STATUS=$? +end=$(date +%s) if [ $STATUS -ne 0 ]; then - error_message="${MYNAME}: FATAL: Decompressing checksum of ${DB_NAME} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds."; - log "ERROR" "${error_message}"; - error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}"; - exit $STATUS; + error_message="${MYNAME}: FATAL: Decompressing checksum of ${DB_NAME} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds." + log "ERROR" "${error_message}" + error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}" + exit $STATUS else - log "INFO" "${MYNAME}: Decompressing backup and checksum of ${DB_NAME} completed in $(expr ${end} - ${start}) seconds."; + log "INFO" "${MYNAME}: Decompressing backup and checksum of ${DB_NAME} completed in $(expr ${end} - ${start}) seconds." fi # Validate the checksum -log "INFO" "${MYNAME}: Validating backup integrity with checksum"; +log "INFO" "${MYNAME}: Validating backup integrity with checksum" cd /tmp || { - error_message="${MYNAME}: FATAL: Failed to change directory to /tmp"; - log "ERROR" "${error_message}"; - error_to_sentry "${error_message}" "${DB_NAME}" "1"; - exit 1; + error_message="${MYNAME}: FATAL: Failed to change directory to /tmp" + log "ERROR" "${error_message}" + error_to_sentry "${error_message}" "${DB_NAME}" "1" + exit 1 } sha256sum -c "${DB_NAME}.sql.sha256" || { - error_message="${MYNAME}: FATAL: Checksum validation failed for backup of ${DB_NAME}. The backup may be corrupted or tampered with."; - log "ERROR" "${error_message}"; - error_to_sentry "${error_message}" "${DB_NAME}" "1"; - exit 1; + error_message="${MYNAME}: FATAL: Checksum validation failed for backup of ${DB_NAME}. The backup may be corrupted or tampered with." + log "ERROR" "${error_message}" + error_to_sentry "${error_message}" "${DB_NAME}" "1" + exit 1 } -log "INFO" "${MYNAME}: Checksum validation successful - backup integrity confirmed"; +log "INFO" "${MYNAME}: Checksum validation successful - backup integrity confirmed" # Restore the database -log "INFO" "${MYNAME}: restoring ${DB_NAME}"; -start=$(date +%s); -psql --host=${DB_HOST} --username=${DB_ROOTUSER} --dbname=postgres ${DB_OPTIONS:-} < /tmp/${DB_NAME}.sql || STATUS=$?; -end=$(date +%s); +log "INFO" "${MYNAME}: restoring ${DB_NAME}" +start=$(date +%s) +psql --host=${DB_HOST} --username=${DB_ROOTUSER} --dbname=postgres ${DB_OPTIONS:-} < /tmp/${DB_NAME}.sql || STATUS=$? +end=$(date +%s) if [ $STATUS -ne 0 ]; then - error_message="${MYNAME}: FATAL: Restore of ${DB_NAME} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds."; - log "ERROR" "${error_message}"; - error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}"; - exit $STATUS; + error_message="${MYNAME}: FATAL: Restore of ${DB_NAME} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds." + log "ERROR" "${error_message}" + error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}" + exit $STATUS else - log "INFO" "${MYNAME}: Restore of ${DB_NAME} completed in $(expr ${end} - ${start}) seconds."; + log "INFO" "${MYNAME}: Restore of ${DB_NAME} completed in $(expr ${end} - ${start}) seconds." fi # Verify database restore success -log "INFO" "${MYNAME}: Verifying database restore success"; -result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --list | grep ${DB_NAME}); +log "INFO" "${MYNAME}: Verifying database restore success" +result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --list | grep ${DB_NAME}) if [ -z "${result}" ]; then - error_message="${MYNAME}: FATAL: Database ${DB_NAME} not found after restore attempt."; - log "ERROR" "${error_message}"; - error_to_sentry "${error_message}" "${DB_NAME}" "1"; - exit 1; + error_message="${MYNAME}: FATAL: Database ${DB_NAME} not found after restore attempt." + log "ERROR" "${error_message}" + error_to_sentry "${error_message}" "${DB_NAME}" "1" + exit 1 else - log "INFO" "${MYNAME}: Database ${DB_NAME} successfully restored and verified."; + log "INFO" "${MYNAME}: Database ${DB_NAME} successfully restored and verified." fi # Clean up temporary files -rm -f "/tmp/${DB_NAME}.sql" "/tmp/${DB_NAME}.sql.sha256"; -log "INFO" "${MYNAME}: Temporary files cleaned up"; +rm -f "/tmp/${DB_NAME}.sql" "/tmp/${DB_NAME}.sql.sha256" +log "INFO" "${MYNAME}: Temporary files cleaned up" -log "INFO" "${MYNAME}: restore: Completed"; -exit $STATUS; +log "INFO" "${MYNAME}: restore: Completed" +exit $STATUS From af32d0bbd7f8b19cbb3d6c2f80e0fd02f05cbae1 Mon Sep 17 00:00:00 2001 From: Praveen Date: Wed, 2 Apr 2025 11:43:17 +0530 Subject: [PATCH 4/4] fix in the db option --- application/restore.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/restore.sh b/application/restore.sh index b220275..90873e2 100755 --- a/application/restore.sh +++ b/application/restore.sh @@ -147,7 +147,7 @@ log "INFO" "${MYNAME}: Checksum validation successful - backup integrity confirm # Restore the database log "INFO" "${MYNAME}: restoring ${DB_NAME}" start=$(date +%s) -psql --host=${DB_HOST} --username=${DB_ROOTUSER} --dbname=postgres ${DB_OPTIONS:-} < /tmp/${DB_NAME}.sql || STATUS=$? +psql --host=${DB_HOST} --username=${DB_ROOTUSER} --dbname=postgres ${DB_OPTIONS} < /tmp/${DB_NAME}.sql || STATUS=$? end=$(date +%s) if [ $STATUS -ne 0 ]; then