From 31cb5de4df3b8ff9b61f55e2c23a3ad6a2d303bf Mon Sep 17 00:00:00 2001 From: Matthieu Borgognon Date: Fri, 7 Feb 2025 16:46:06 +0100 Subject: [PATCH] fix(recover mysql): script + accept any separator in container name + make linter happy --- recovery-docker-mysql.sh | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/recovery-docker-mysql.sh b/recovery-docker-mysql.sh index 754c42f..23ac20b 100644 --- a/recovery-docker-mysql.sh +++ b/recovery-docker-mysql.sh @@ -5,13 +5,13 @@ BACKUPDIR="/backup/mysql" # Display a numbered list of containers from the backup directory echo "Available containers:" -CONTAINERS=($(for file in "$BACKUPDIR"/*.sql.gz; do IFS='-' read -r CONTAINER _ <<< "$(basename "$file" .sql.gz)"; echo "$CONTAINER"; done | sort -u)) +mapfile -t CONTAINERS < <(docker ps --format '{{.Names}}:{{.Image}}' | grep 'mysql\|mariadb' | cut -d":" -f1) for ((i=0; i<${#CONTAINERS[@]}; i++)); do echo "$((i+1)). ${CONTAINERS[$i]}" done # Prompt the user to select a container -read -p "Enter the number of the container: " CONTAINER_NUMBER +read -r -p "Enter the number of the container: " CONTAINER_NUMBER if [[ ! $CONTAINER_NUMBER =~ ^[0-9]+$ || $CONTAINER_NUMBER -lt 1 || $CONTAINER_NUMBER -gt ${#CONTAINERS[@]} ]]; then echo "Invalid input. Please enter a valid container number." exit 1 @@ -22,13 +22,18 @@ CONTAINER=${CONTAINERS[$((CONTAINER_NUMBER-1))]} # Display a numbered list of databases for the selected container echo "Available databases in container $CONTAINER:" -DATABASES=($(for file in "$BACKUPDIR"/*.sql.gz; do IFS='-' read -r FILE_CONTAINER FILE_DATABASE _ <<< "$(basename "$file" .sql.gz)"; if [ "$FILE_CONTAINER" == "$CONTAINER" ]; then echo "$FILE_DATABASE"; fi> +mapfile -t DATABASES < <(for file in "$BACKUPDIR"/"$CONTAINER"*sql.gz; do + filename=$(basename "$file" .sql.gz) + db_part=${filename#"$CONTAINER"[^[:alnum:]]} # Remove container prefix and any separator + db_name=${db_part:0:-13} # Remove timestamp and its separator + echo "$db_name" +done | sort -u) for ((i=0; i<${#DATABASES[@]}; i++)); do echo "$((i+1)). ${DATABASES[$i]}" done # Prompt the user to select a database -read -p "Enter the number of the database: " DATABASE_NUMBER +read -r -p "Enter the number of the database: " DATABASE_NUMBER if [[ ! $DATABASE_NUMBER =~ ^[0-9]+$ || $DATABASE_NUMBER -lt 1 || $DATABASE_NUMBER -gt ${#DATABASES[@]} ]]; then echo "Invalid input. Please enter a valid database number." exit 1 @@ -39,7 +44,12 @@ DATABASENAME=${DATABASES[$((DATABASE_NUMBER-1))]} # Display a numbered list of timestamps for the selected container and database echo "Available timestamps for container $CONTAINER and database $DATABASENAME:" -TIMESTAMPS=($(for file in "$BACKUPDIR"/*.sql.gz; do IFS='-' read -r FILE_CONTAINER FILE_DATABASE FILE_TIMESTAMP _ <<< "$(basename "$file" .sql.gz)"; if [ "$FILE_CONTAINER" == "$CONTAINER" ] && [ "$FILE_DAT> +mapfile -t TIMESTAMPS < <(for file in "$BACKUPDIR"/"$CONTAINER"*"$DATABASENAME"*sql.gz; do + filename=$(basename "$file" .sql.gz) + # Extract timestamp (12 digits) from the end of filename + timestamp=${filename:(-12)} + echo "$timestamp" +done | sort -u) for ((i=0; i<${#TIMESTAMPS[@]}; i++)); do # Manually split and format the timestamp as YYYY-MM-DD HH:mm YEAR=${TIMESTAMPS[$i]:0:4} @@ -52,7 +62,7 @@ for ((i=0; i<${#TIMESTAMPS[@]}; i++)); do done # Prompt the user to select a timestamp -read -p "Enter the number of the timestamp: " TIMESTAMP_NUMBER +read -r -p "Enter the number of the timestamp: " TIMESTAMP_NUMBER if [[ ! $TIMESTAMP_NUMBER =~ ^[0-9]+$ || $TIMESTAMP_NUMBER -lt 1 || $TIMESTAMP_NUMBER -gt ${#TIMESTAMPS[@]} ]]; then echo "Invalid input. Please enter a valid timestamp number." exit 1 @@ -65,18 +75,18 @@ TIMESTAMP=${TIMESTAMPS[$((TIMESTAMP_NUMBER-1))]} FILENAME="$CONTAINER-$DATABASENAME-$TIMESTAMP.sql.gz" # Set the MySQL password in the MYSQL_PWD variable -MYSQL_PWD=$(docker exec $CONTAINER env | grep MYSQL_ROOT_PASSWORD | cut -d"=" -f2) +MYSQL_PWD=$(docker exec "$CONTAINER" env | grep MYSQL_ROOT_PASSWORD | cut -d"=" -f2) # Display confirmation prompt -read -p "Confirm recovery of DB $DATABASENAME in Container $CONTAINER from $TIMESTAMP_FORMATTED? (yes/y): " CONFIRMATION -if [[ ! $CONFIRMATION =~ ^[Yy][Ee][Ss]|[Yy]$ ]]; then +read -r -p "Confirm recovery of DB $DATABASENAME in Container $CONTAINER from $TIMESTAMP_FORMATTED? (yes/y): " CONFIRMATION +if [[ ! $CONFIRMATION =~ ^([Yy][Ee][Ss]|[Yy])$ ]]; then echo "Recovery canceled by user." exit 1 fi # Execute the desired command and capture the output -OUTPUT=$(zcat "$BACKUPDIR/$FILENAME" | docker exec -i $CONTAINER /usr/bin/mysql -u root --password=$MYSQL_PWD $DATABASENAME 2>&1) +OUTPUT=$(zcat "$BACKUPDIR/$FILENAME" | docker exec -i "$CONTAINER" /usr/bin/mysql -u root --password="$MYSQL_PWD" "$DATABASENAME" 2>&1) # Display the output echo "Output of MySQL command:" -echo "$OUTPUT" +echo "$OUTPUT" \ No newline at end of file