Skip to content

Commit 52d9b23

Browse files
committed
Fix GCS bucket dependency and improve Azure test script
- Fix repo-gcs-bucket to depend directly on repo-type=gcs instead of repo-gcs-key-type This prevents repo-gcs-bucket from being incorrectly required when using other storage types (posix, s3, azure, sftp) - Regenerate parse.auto.c.inc with corrected dependency - Improve Azure blob storage test script: - Add PostgreSQL path detection and config update (matching AMI test) - Add recovery mode detection and automatic promotion - Add repo2 configuration verification - Add archiving check before backups - Improve volume cleanup with force flag
1 parent ed2630b commit 52d9b23

File tree

3 files changed

+213
-7
lines changed

3 files changed

+213
-7
lines changed

src/build/config/config.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2223,7 +2223,9 @@ option:
22232223
group: repo
22242224
command: repo-type
22252225
depend:
2226-
option: repo-gcs-key-type
2226+
option: repo-type
2227+
list:
2228+
- gcs
22272229

22282230
repo-gcs-endpoint:
22292231
section: global

src/config/parse.auto.c.inc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6164,7 +6164,8 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
61646164
( // opt/repo-gcs-bucket
61656165
PARSE_RULE_OPTIONAL_DEPEND // opt/repo-gcs-bucket
61666166
( // opt/repo-gcs-bucket
6167-
PARSE_RULE_VAL_OPT(RepoGcsKeyType), // opt/repo-gcs-bucket
6167+
PARSE_RULE_VAL_OPT(RepoType), // opt/repo-gcs-bucket
6168+
PARSE_RULE_VAL_STRID(Gcs), // opt/repo-gcs-bucket
61686169
), // opt/repo-gcs-bucket
61696170
), // opt/repo-gcs-bucket
61706171
), // opt/repo-gcs-bucket
@@ -6242,7 +6243,8 @@ static const ParseRuleOption parseRuleOption[CFG_OPTION_TOTAL] =
62426243
( // opt/repo-gcs-endpoint
62436244
PARSE_RULE_OPTIONAL_DEPEND // opt/repo-gcs-endpoint
62446245
( // opt/repo-gcs-endpoint
6245-
PARSE_RULE_VAL_OPT(RepoGcsKeyType), // opt/repo-gcs-endpoint
6246+
PARSE_RULE_VAL_OPT(RepoType), // opt/repo-gcs-endpoint
6247+
PARSE_RULE_VAL_STRID(Gcs), // opt/repo-gcs-endpoint
62466248
), // opt/repo-gcs-endpoint
62476249
// opt/repo-gcs-endpoint
62486250
PARSE_RULE_OPTIONAL_DEFAULT // opt/repo-gcs-endpoint
@@ -11732,6 +11734,8 @@ static const uint8_t optionResolveOrder[] =
1173211734
cfgOptRepoBlockSizeSuper, // opt-resolve-order
1173311735
cfgOptRepoBlockSizeSuperFull, // opt-resolve-order
1173411736
cfgOptRepoCipherPass, // opt-resolve-order
11737+
cfgOptRepoGcsBucket, // opt-resolve-order
11738+
cfgOptRepoGcsEndpoint, // opt-resolve-order
1173511739
cfgOptRepoGcsKeyType, // opt-resolve-order
1173611740
cfgOptRepoHost, // opt-resolve-order
1173711741
cfgOptRepoHostConfig, // opt-resolve-order
@@ -11777,8 +11781,6 @@ static const uint8_t optionResolveOrder[] =
1177711781
cfgOptPgHostKeyFile, // opt-resolve-order
1177811782
cfgOptPgHostPort, // opt-resolve-order
1177911783
cfgOptRepoAzureKey, // opt-resolve-order
11780-
cfgOptRepoGcsBucket, // opt-resolve-order
11781-
cfgOptRepoGcsEndpoint, // opt-resolve-order
1178211784
cfgOptRepoGcsKey, // opt-resolve-order
1178311785
cfgOptRepoHostCaFile, // opt-resolve-order
1178411786
cfgOptRepoHostCaPath, // opt-resolve-order

test/azure/azure-pgbackrest.sh

Lines changed: 204 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,9 @@ cleanup_docker() {
195195
docker rm "$CONTAINER" 2>/dev/null || true
196196

197197
echo "Removing volumes..."
198-
docker volume rm pgdata pgrepo 2>/dev/null || true
198+
docker volume rm -f pgdata pgrepo 2>/dev/null || true
199+
# Wait a moment to ensure volumes are fully removed
200+
sleep 1
199201

200202
# Check and free up port 5433 if in use
201203
if lsof -ti:5433 >/dev/null 2>&1; then
@@ -629,6 +631,25 @@ test_azure_blob() {
629631
echo ""
630632
print_success "PostgreSQL is ready (took ${ELAPSED}s)"
631633

634+
# Check if PostgreSQL is in recovery mode and promote if needed
635+
RECOVERY_STATUS=$(docker exec "$CONTAINER" psql -U postgres -d postgres -t -c "SELECT pg_is_in_recovery();" 2>/dev/null | xargs || echo "t")
636+
if [ "$RECOVERY_STATUS" = "t" ]; then
637+
print_warning "PostgreSQL is in recovery mode, promoting..."
638+
docker exec "$CONTAINER" psql -U postgres -d postgres -c "SELECT pg_wal_replay_resume();" >/dev/null 2>&1 || true
639+
sleep 2
640+
# Wait for PostgreSQL to be ready again after promotion
641+
ELAPSED=0
642+
until docker exec "$CONTAINER" pg_isready -U postgres >/dev/null 2>&1; do
643+
if [ $ELAPSED -ge 30 ]; then
644+
print_error "PostgreSQL failed to start after promotion"
645+
return 1
646+
fi
647+
sleep 1
648+
ELAPSED=$((ELAPSED + 1))
649+
done
650+
print_success "PostgreSQL promoted successfully"
651+
fi
652+
632653
# Create test data (this will also download Northwind if needed)
633654
create_test_data "$CONTAINER"
634655

@@ -672,6 +693,170 @@ test_azure_blob() {
672693
# Clean local backups
673694
docker exec "$CONTAINER" rm -rf /var/lib/pgbackrest/archive/* /var/lib/pgbackrest/backup/* 2>/dev/null || true
674695

696+
# Debug: Check PostgreSQL data directory and pgBackRest config
697+
print_header "Debug: Check PostgreSQL Paths"
698+
echo "PGDATA environment:"
699+
docker exec "$CONTAINER" bash -c 'echo "PGDATA=$PGDATA"'
700+
echo ""
701+
echo "PostgreSQL data directory locations:"
702+
docker exec "$CONTAINER" bash -c 'ls -la /var/lib/postgresql/ 2>/dev/null || echo "Cannot list /var/lib/postgresql"'
703+
echo ""
704+
echo "pgBackRest config pg1-path:"
705+
docker exec "$CONTAINER" bash -c 'grep "pg1-path" /etc/pgbackrest/pgbackrest.conf || echo "pg1-path not found in config"'
706+
echo ""
707+
echo "Actual PostgreSQL data directory (from postgres process):"
708+
ACTUAL_DATA_DIR=$(docker exec "$CONTAINER" bash -c 'psql -U postgres -d postgres -t -c "SHOW data_directory;" 2>/dev/null | xargs' || echo "")
709+
if [ -n "$ACTUAL_DATA_DIR" ]; then
710+
echo "Found data directory: $ACTUAL_DATA_DIR"
711+
echo ""
712+
echo "Updating pgBackRest config with correct path..."
713+
# Remove old pg1-path and add new one with correct directory
714+
# Use /tmp for temp file and Python to avoid all permission issues
715+
docker exec -e DATA_DIR="$ACTUAL_DATA_DIR" "$CONTAINER" bash -c "python3 <<'PYEOF'
716+
import sys
717+
import os
718+
719+
data_dir = os.environ['DATA_DIR']
720+
config_file = '/etc/pgbackrest/pgbackrest.conf'
721+
tmp_file = '/tmp/pgbackrest.conf.tmp'
722+
723+
# Read current config
724+
with open(config_file, 'r') as f:
725+
lines = f.readlines()
726+
727+
# Process lines: remove old pg1-path, add new one after [demo]
728+
output = []
729+
in_demo = False
730+
pg1_added = False
731+
732+
for line in lines:
733+
stripped = line.strip()
734+
735+
# Track when we enter [demo] section
736+
if stripped == '[demo]':
737+
in_demo = True
738+
output.append(line)
739+
continue
740+
741+
# Track when we leave [demo] section
742+
if stripped.startswith('[') and stripped != '[demo]':
743+
if in_demo and not pg1_added:
744+
output.append('pg1-path=' + data_dir + '\n')
745+
pg1_added = True
746+
in_demo = False
747+
output.append(line)
748+
continue
749+
750+
# Skip old pg1-path lines
751+
if stripped.startswith('pg1-path='):
752+
continue
753+
754+
# Add pg1-path after [demo] when we hit first empty line or end
755+
if in_demo and not pg1_added and (stripped == '' or lines.index(line) == len(lines) - 1):
756+
output.append('pg1-path=' + data_dir + '\n')
757+
pg1_added = True
758+
759+
output.append(line)
760+
761+
# If [demo] section exists but pg1-path was never added
762+
if in_demo and not pg1_added:
763+
output.append('pg1-path=' + data_dir + '\n')
764+
765+
# If [demo] section doesn't exist, add it
766+
if '[demo]' not in ''.join(output):
767+
output.append('\n[demo]\n')
768+
output.append('pg1-path=' + data_dir + '\n')
769+
770+
# Write to temp file
771+
with open(tmp_file, 'w') as f:
772+
f.writelines(output)
773+
774+
# Copy back and set permissions
775+
import shutil
776+
import pwd
777+
import grp
778+
779+
shutil.copy(tmp_file, config_file)
780+
postgres_uid = pwd.getpwnam('postgres').pw_uid
781+
postgres_gid = grp.getgrnam('postgres').gr_gid
782+
os.chown(config_file, postgres_uid, postgres_gid)
783+
os.chmod(config_file, 0o640)
784+
os.remove(tmp_file)
785+
PYEOF
786+
"
787+
echo "Updated config:"
788+
docker exec "$CONTAINER" bash -c 'grep "pg1-path" /etc/pgbackrest/pgbackrest.conf'
789+
else
790+
print_warning "Could not determine PostgreSQL data directory, using default"
791+
fi
792+
echo ""
793+
794+
# Verify repo2 is configured
795+
print_header "Verify Azure (repo2) Configuration"
796+
if ! docker exec "$CONTAINER" grep -q "repo2-type=azure" /etc/pgbackrest/pgbackrest.conf; then
797+
echo "repo2 not found in config, running configure-azure.sh..."
798+
docker exec "$CONTAINER" bash -lc "/usr/local/bin/configure-azure.sh" || echo "configure-azure.sh returned error, will configure manually"
799+
800+
# Check if it worked
801+
if ! docker exec "$CONTAINER" grep -q "repo2-type=azure" /etc/pgbackrest/pgbackrest.conf; then
802+
echo "configure-azure.sh didn't add repo2, configuring manually..."
803+
docker exec -e AZURE_ACCOUNT="$AZURE_ACCOUNT" -e AZURE_CONTAINER="$AZURE_CONTAINER" -e AZURE_KEY_TYPE="$AZURE_KEY_TYPE" -e AZURE_REPO_PATH="$AZURE_REPO_PATH" "$CONTAINER" bash -c "
804+
AZURE_REPO_PATH=\${AZURE_REPO_PATH:-/demo-repo}
805+
TMP_FILE=/tmp/pgbackrest_repo2.$$
806+
cat /etc/pgbackrest/pgbackrest.conf > \$TMP_FILE
807+
echo '' >> \$TMP_FILE
808+
echo 'repo2-type=azure' >> \$TMP_FILE
809+
echo \"repo2-azure-account=\${AZURE_ACCOUNT}\" >> \$TMP_FILE
810+
echo \"repo2-azure-container=\${AZURE_CONTAINER}\" >> \$TMP_FILE
811+
echo \"repo2-azure-key-type=\${AZURE_KEY_TYPE}\" >> \$TMP_FILE
812+
echo \"repo2-azure-key=\${AZURE_KEY}\" >> \$TMP_FILE
813+
echo \"repo2-path=\${AZURE_REPO_PATH}\" >> \$TMP_FILE
814+
echo 'repo2-retention-full=4' >> \$TMP_FILE
815+
cp \$TMP_FILE /etc/pgbackrest/pgbackrest.conf
816+
chown postgres:postgres /etc/pgbackrest/pgbackrest.conf
817+
chmod 640 /etc/pgbackrest/pgbackrest.conf
818+
rm -f \$TMP_FILE
819+
"
820+
fi
821+
echo "Config after configuration:"
822+
docker exec "$CONTAINER" grep -E "repo2|azure" /etc/pgbackrest/pgbackrest.conf || echo "No repo2 config found"
823+
else
824+
echo "repo2 configuration found:"
825+
docker exec "$CONTAINER" grep -E "repo2|azure" /etc/pgbackrest/pgbackrest.conf
826+
fi
827+
echo ""
828+
829+
# Ensure archiving is enabled before backups
830+
print_header "Ensure PostgreSQL Archiving Enabled"
831+
ARCHIVE_MODE=$(docker exec "$CONTAINER" psql -U postgres -At -c "show archive_mode")
832+
833+
if [ "$ARCHIVE_MODE" != "on" ]; then
834+
echo "archive_mode is currently $ARCHIVE_MODE - enabling..."
835+
docker exec "$CONTAINER" bash -lc '
836+
set -e
837+
PGDATA_DIR=${PGDATA:-/var/lib/postgresql/data}
838+
{
839+
echo ""
840+
echo "# pgBackRest archiving configuration"
841+
echo "archive_mode = on"
842+
echo "archive_command = '\''pgbackrest --stanza=demo archive-push %p'\''"
843+
echo "archive_timeout = 60"
844+
echo "wal_level = replica"
845+
echo "max_wal_senders = 3"
846+
echo "max_replication_slots = 3"
847+
} >> "$PGDATA_DIR/postgresql.conf"
848+
'
849+
850+
docker restart "$CONTAINER" >/dev/null
851+
echo "Waiting for PostgreSQL to restart with archiving enabled..."
852+
until docker exec "$CONTAINER" pg_isready -U postgres >/dev/null 2>&1; do
853+
sleep 1
854+
done
855+
else
856+
echo "archive_mode already enabled"
857+
fi
858+
echo ""
859+
675860
# Create stanza
676861
print_header "Create Stanza (Azure Blob Storage)"
677862
docker exec "$CONTAINER" pgbackrest --stanza=demo stanza-create
@@ -727,10 +912,27 @@ test_azure_blob() {
727912
-v pgrepo:/var/lib/pgbackrest \
728913
"$IMAGE" \
729914
-lc "/usr/local/bin/configure-azure.sh || true; \
915+
if ! grep -q \"repo2-type=azure\" /etc/pgbackrest/pgbackrest.conf; then \
916+
AZURE_REPO_PATH=\${AZURE_REPO_PATH:-/demo-repo}; \
917+
TMP_FILE=/tmp/pgbackrest_repo2.\$\$; \
918+
cat /etc/pgbackrest/pgbackrest.conf > \$TMP_FILE; \
919+
echo '' >> \$TMP_FILE; \
920+
echo 'repo2-type=azure' >> \$TMP_FILE; \
921+
echo \"repo2-azure-account=\${AZURE_ACCOUNT}\" >> \$TMP_FILE; \
922+
echo \"repo2-azure-container=\${AZURE_CONTAINER}\" >> \$TMP_FILE; \
923+
echo \"repo2-azure-key-type=\${AZURE_KEY_TYPE}\" >> \$TMP_FILE; \
924+
echo \"repo2-azure-key=\${AZURE_KEY}\" >> \$TMP_FILE; \
925+
echo \"repo2-path=\${AZURE_REPO_PATH}\" >> \$TMP_FILE; \
926+
echo 'repo2-retention-full=4' >> \$TMP_FILE; \
927+
cp \$TMP_FILE /etc/pgbackrest/pgbackrest.conf; \
928+
chown postgres:postgres /etc/pgbackrest/pgbackrest.conf; \
929+
chmod 640 /etc/pgbackrest/pgbackrest.conf; \
930+
rm -f \$TMP_FILE; \
931+
fi; \
730932
DATA_DIR=\${ACTUAL_DATA_DIR:-/var/lib/postgresql/data}; \
731933
echo \"Restoring to data directory: \$DATA_DIR\"; \
732934
rm -rf \"\$DATA_DIR\"/* && \
733-
pgbackrest --stanza=demo restore --set='$BACKUP_LABEL_AZURE' --type=immediate --pg1-path=\"\$DATA_DIR\""
935+
pgbackrest --repo=2 --stanza=demo restore --set='$BACKUP_LABEL_AZURE' --type=immediate --pg1-path=\"\$DATA_DIR\""
734936

735937
print_success "Restore complete"
736938

0 commit comments

Comments
 (0)