|
4 | 4 | log() { |
5 | 5 | local level="$1" |
6 | 6 | local message="$2" |
7 | | - echo "[$(date '+%Y-%m-%d %H:%M:%S')] ${level}: ${message}" |
| 7 | + echo "[$(date '+%Y-%m-%d %H:%M:%S')] ${level}: ${MYNAME}: ${message}" |
8 | 8 | } |
9 | 9 |
|
10 | 10 | filter_sensitive_values() { |
@@ -55,78 +55,78 @@ error_to_sentry() { |
55 | 55 |
|
56 | 56 | MYNAME="postgresql-backup-restore" |
57 | 57 | STATUS=0 |
58 | | -log "INFO" "${MYNAME}: restore: Started" |
| 58 | +log "INFO" "restore: Started" |
59 | 59 |
|
60 | 60 | # Ensure the database user exists. |
61 | | -log "INFO" "${MYNAME}: checking for DB user ${DB_USER}" |
| 61 | +log "INFO" "checking for DB user ${DB_USER}" |
62 | 62 | result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command='\du' | grep ${DB_USER}) |
63 | 63 | if [ -z "${result}" ]; then |
64 | 64 | result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command="create role ${DB_USER} with login password '${DB_USERPASSWORD}' inherit;") |
65 | 65 | if [ "${result}" != "CREATE ROLE" ]; then |
66 | 66 | error_message="Create role command failed: ${result}" |
67 | | - log "ERROR" "${MYNAME}: FATAL: ${error_message}" |
| 67 | + log "ERROR" "FATAL: ${error_message}" |
68 | 68 | error_to_sentry "${error_message}" "${DB_NAME}" "1" |
69 | 69 | exit 1 |
70 | 70 | fi |
71 | 71 | fi |
72 | 72 |
|
73 | 73 | # Delete database if it exists. |
74 | | -log "INFO" "${MYNAME}: checking for DB ${DB_NAME}" |
| 74 | +log "INFO" "checking for DB ${DB_NAME}" |
75 | 75 | result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --list | grep ${DB_NAME}) |
76 | 76 | if [ -z "${result}" ]; then |
77 | | - log "INFO" "${MYNAME}: INFO: Database \"${DB_NAME}\" on host \"${DB_HOST}\" does not exist." |
| 77 | + log "INFO" "INFO: Database \"${DB_NAME}\" on host \"${DB_HOST}\" does not exist." |
78 | 78 | else |
79 | | - log "INFO" "${MYNAME}: finding current owner of DB ${DB_NAME}" |
| 79 | + log "INFO" "finding current owner of DB ${DB_NAME}" |
80 | 80 | db_owner=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --command='\list' | grep ${DB_NAME} | cut -d '|' -f 2 | sed -e 's/ *//g') |
81 | | - log "INFO" "${MYNAME}: INFO: Database owner is ${db_owner}" |
| 81 | + log "INFO" "INFO: Database owner is ${db_owner}" |
82 | 82 |
|
83 | | - log "INFO" "${MYNAME}: deleting database ${DB_NAME}" |
| 83 | + log "INFO" "deleting database ${DB_NAME}" |
84 | 84 | result=$(psql --host=${DB_HOST} --dbname=postgres --username=${db_owner} --command="DROP DATABASE ${DB_NAME};") |
85 | 85 | if [ "${result}" != "DROP DATABASE" ]; then |
86 | 86 | error_message="Drop database command failed: ${result}" |
87 | | - log "ERROR" "${MYNAME}: FATAL: ${error_message}" |
| 87 | + log "ERROR" "FATAL: ${error_message}" |
88 | 88 | error_to_sentry "${error_message}" "${DB_NAME}" "1" |
89 | 89 | exit 1 |
90 | 90 | fi |
91 | 91 | fi |
92 | 92 |
|
93 | 93 | # Download the backup and checksum files |
94 | | -log "INFO" "${MYNAME}: copying database ${DB_NAME} backup and checksum from ${S3_BUCKET}" |
| 94 | +log "INFO" "copying database ${DB_NAME} backup and checksum from ${S3_BUCKET}" |
95 | 95 | start=$(date +%s) |
96 | 96 |
|
97 | 97 | # maintain backward compatibility with key variables accepted by s3cmd |
98 | 98 | export AWS_ACCESS_KEY_ID="${AWS_ACCESS_KEY_ID:-$AWS_ACCESS_KEY}" |
99 | 99 | export AWS_SECRET_ACCESS_KEY="${AWS_SECRET_ACCESS_KEY:-$AWS_SECRET_KEY}" |
100 | 100 |
|
101 | 101 | # Download database backup |
102 | | -aws s3 cp "${S3_BUCKET}/${DB_NAME}.sql.gz" "/tmp/${DB_NAME}.sql.gz" || STATUS=$? |
| 102 | +aws s3 cp --quiet "${S3_BUCKET}/${DB_NAME}.sql.gz" "/tmp/${DB_NAME}.sql.gz" || STATUS=$? |
103 | 103 | if [ $STATUS -ne 0 ]; then |
104 | | - error_message="${MYNAME}: FATAL: Copy backup of ${DB_NAME} from ${S3_BUCKET} returned non-zero status ($STATUS) in $(expr $(date +%s) - ${start}) seconds." |
| 104 | + error_message="FATAL: Copy backup of ${DB_NAME} from ${S3_BUCKET} returned non-zero status ($STATUS) in $(expr $(date +%s) - ${start}) seconds." |
105 | 105 | log "ERROR" "${error_message}" |
106 | 106 | error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}" |
107 | 107 | exit $STATUS |
108 | 108 | fi |
109 | 109 |
|
110 | 110 | # Download checksum file |
111 | | -aws s3 cp "${S3_BUCKET}/${DB_NAME}.sql.sha256.gz" "/tmp/${DB_NAME}.sql.sha256.gz" || STATUS=$? |
| 111 | +aws s3 cp --quiet "${S3_BUCKET}/${DB_NAME}.sql.sha256.gz" "/tmp/${DB_NAME}.sql.sha256.gz" || STATUS=$? |
112 | 112 | end=$(date +%s) |
113 | 113 | if [ $STATUS -ne 0 ]; then |
114 | | - error_message="${MYNAME}: FATAL: Copy checksum of ${DB_NAME} from ${S3_BUCKET} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds." |
| 114 | + error_message="FATAL: Copy checksum of ${DB_NAME} from ${S3_BUCKET} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds." |
115 | 115 | log "ERROR" "${error_message}" |
116 | 116 | error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}" |
117 | 117 | exit $STATUS |
118 | 118 | else |
119 | | - log "INFO" "${MYNAME}: Copy backup and checksum of ${DB_NAME} from ${S3_BUCKET} completed in $(expr ${end} - ${start}) seconds." |
| 119 | + log "INFO" "Copy backup and checksum of ${DB_NAME} from ${S3_BUCKET} completed in $(expr ${end} - ${start}) seconds." |
120 | 120 | fi |
121 | 121 |
|
122 | 122 | # Decompress both files |
123 | | -log "INFO" "${MYNAME}: decompressing backup and checksum of ${DB_NAME}" |
| 123 | +log "INFO" "decompressing backup and checksum of ${DB_NAME}" |
124 | 124 | start=$(date +%s) |
125 | 125 |
|
126 | 126 | # Decompress backup file |
127 | 127 | gunzip -f /tmp/${DB_NAME}.sql.gz || STATUS=$? |
128 | 128 | if [ $STATUS -ne 0 ]; then |
129 | | - error_message="${MYNAME}: FATAL: Decompressing backup of ${DB_NAME} returned non-zero status ($STATUS) in $(expr $(date +%s) - ${start}) seconds." |
| 129 | + error_message="FATAL: Decompressing backup of ${DB_NAME} returned non-zero status ($STATUS) in $(expr $(date +%s) - ${start}) seconds." |
130 | 130 | log "ERROR" "${error_message}" |
131 | 131 | error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}" |
132 | 132 | exit $STATUS |
|
136 | 136 | gunzip -f /tmp/${DB_NAME}.sql.sha256.gz || STATUS=$? |
137 | 137 | end=$(date +%s) |
138 | 138 | if [ $STATUS -ne 0 ]; then |
139 | | - error_message="${MYNAME}: FATAL: Decompressing checksum of ${DB_NAME} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds." |
| 139 | + error_message="FATAL: Decompressing checksum of ${DB_NAME} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds." |
140 | 140 | log "ERROR" "${error_message}" |
141 | 141 | error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}" |
142 | 142 | exit $STATUS |
143 | 143 | else |
144 | | - log "INFO" "${MYNAME}: Decompressing backup and checksum of ${DB_NAME} completed in $(expr ${end} - ${start}) seconds." |
| 144 | + log "INFO" "Decompressing backup and checksum of ${DB_NAME} completed in $(expr ${end} - ${start}) seconds." |
145 | 145 | fi |
146 | 146 |
|
147 | 147 | # Validate the checksum |
148 | | -log "INFO" "${MYNAME}: Validating backup integrity with checksum" |
| 148 | +log "INFO" "Validating backup integrity with checksum" |
149 | 149 | cd /tmp || { |
150 | | - error_message="${MYNAME}: FATAL: Failed to change directory to /tmp" |
| 150 | + error_message="FATAL: Failed to change directory to /tmp" |
151 | 151 | log "ERROR" "${error_message}" |
152 | 152 | error_to_sentry "${error_message}" "${DB_NAME}" "1" |
153 | 153 | exit 1 |
154 | 154 | } |
155 | 155 |
|
156 | | -sha256sum -c "${DB_NAME}.sql.sha256" || { |
157 | | - error_message="${MYNAME}: FATAL: Checksum validation failed for backup of ${DB_NAME}. The backup may be corrupted or tampered with." |
| 156 | +sha256sum --check --quiet "${DB_NAME}.sql.sha256" || { |
| 157 | + error_message="FATAL: Checksum validation failed for backup of ${DB_NAME}. The backup may be corrupted or tampered with." |
158 | 158 | log "ERROR" "${error_message}" |
159 | 159 | error_to_sentry "${error_message}" "${DB_NAME}" "1" |
160 | 160 | exit 1 |
161 | 161 | } |
162 | | -log "INFO" "${MYNAME}: Checksum validation successful - backup integrity confirmed" |
| 162 | +log "INFO" "Checksum validation successful - backup integrity confirmed" |
163 | 163 |
|
164 | 164 | # Restore the database |
165 | | -log "INFO" "${MYNAME}: restoring ${DB_NAME}" |
| 165 | +log "INFO" "restoring ${DB_NAME}" |
166 | 166 | start=$(date +%s) |
167 | 167 | psql --host=${DB_HOST} --username=${DB_ROOTUSER} --dbname=postgres ${DB_OPTIONS} < /tmp/${DB_NAME}.sql || STATUS=$? |
168 | 168 | end=$(date +%s) |
169 | 169 |
|
170 | 170 | if [ $STATUS -ne 0 ]; then |
171 | | - error_message="${MYNAME}: FATAL: Restore of ${DB_NAME} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds." |
| 171 | + error_message="FATAL: Restore of ${DB_NAME} returned non-zero status ($STATUS) in $(expr ${end} - ${start}) seconds." |
172 | 172 | log "ERROR" "${error_message}" |
173 | 173 | error_to_sentry "${error_message}" "${DB_NAME}" "${STATUS}" |
174 | 174 | exit $STATUS |
175 | 175 | else |
176 | | - log "INFO" "${MYNAME}: Restore of ${DB_NAME} completed in $(expr ${end} - ${start}) seconds." |
| 176 | + log "INFO" "Restore of ${DB_NAME} completed in $(expr ${end} - ${start}) seconds." |
177 | 177 | fi |
178 | 178 |
|
179 | 179 | # Verify database restore success |
180 | | -log "INFO" "${MYNAME}: Verifying database restore success" |
| 180 | +log "INFO" "Verifying database restore success" |
181 | 181 | result=$(psql --host=${DB_HOST} --username=${DB_ROOTUSER} --list | grep ${DB_NAME}) |
182 | 182 | if [ -z "${result}" ]; then |
183 | | - error_message="${MYNAME}: FATAL: Database ${DB_NAME} not found after restore attempt." |
| 183 | + error_message="FATAL: Database ${DB_NAME} not found after restore attempt." |
184 | 184 | log "ERROR" "${error_message}" |
185 | 185 | error_to_sentry "${error_message}" "${DB_NAME}" "1" |
186 | 186 | exit 1 |
187 | 187 | else |
188 | | - log "INFO" "${MYNAME}: Database ${DB_NAME} successfully restored and verified." |
| 188 | + log "INFO" "Database ${DB_NAME} successfully restored and verified." |
189 | 189 | fi |
190 | 190 |
|
191 | 191 | # Clean up temporary files |
192 | 192 | rm -f "/tmp/${DB_NAME}.sql" "/tmp/${DB_NAME}.sql.sha256" |
193 | | -log "INFO" "${MYNAME}: Temporary files cleaned up" |
| 193 | +log "INFO" "Temporary files cleaned up" |
194 | 194 |
|
195 | | -log "INFO" "${MYNAME}: restore: Completed" |
| 195 | +log "INFO" "restore: Completed" |
196 | 196 | exit $STATUS |
0 commit comments