mirror of
https://github.com/kevinveenbirkenbach/docker-volume-backup.git
synced 2024-11-26 02:01:04 +01:00
Compare commits
9 Commits
d537393da8
...
b7dcb17fd5
Author | SHA1 | Date | |
---|---|---|---|
b7dcb17fd5 | |||
7f6f5f6dc8 | |||
75d48fb3e9 | |||
bb3d20c424 | |||
f057104a65 | |||
7fe1886ff9 | |||
35e28f31d2 | |||
15a1f17184 | |||
ace1a70488 |
@ -71,7 +71,11 @@ def get_instance(container):
|
|||||||
|
|
||||||
# This line uses regular expressions to split the 'container' string.
|
# This line uses regular expressions to split the 'container' string.
|
||||||
# 're.split' is a method that divides a string into a list, based on the occurrences of a pattern.
|
# 're.split' is a method that divides a string into a list, based on the occurrences of a pattern.
|
||||||
|
if container in ['central-mariadb', 'central-postgres']:
|
||||||
|
instance_name = container
|
||||||
|
else:
|
||||||
instance_name = re.split("(_|-)(database|db|postgres)", container)[0]
|
instance_name = re.split("(_|-)(database|db|postgres)", container)[0]
|
||||||
|
|
||||||
# The pattern "(_|-)(database|db|postgres)" is explained as follows:
|
# The pattern "(_|-)(database|db|postgres)" is explained as follows:
|
||||||
# - "(_|-)": Matches an underscore '_' or a hyphen '-'.
|
# - "(_|-)": Matches an underscore '_' or a hyphen '-'.
|
||||||
# - "(database|db|postgres)": Matches one of the strings "database", "db", or "postgres".
|
# - "(database|db|postgres)": Matches one of the strings "database", "db", or "postgres".
|
||||||
@ -93,10 +97,6 @@ def backup_database(container, volume_dir, db_type):
|
|||||||
# Filter the DataFrame for the given instance_name
|
# Filter the DataFrame for the given instance_name
|
||||||
database_entries = DATABASES.loc[DATABASES['instance'] == instance_name]
|
database_entries = DATABASES.loc[DATABASES['instance'] == instance_name]
|
||||||
|
|
||||||
# Check if there are more than one entries
|
|
||||||
if len(database_entries) > 1:
|
|
||||||
raise BackupException(f"More than one entry found for instance '{instance_name}'")
|
|
||||||
|
|
||||||
# Check if there is no entry
|
# Check if there is no entry
|
||||||
if database_entries.empty:
|
if database_entries.empty:
|
||||||
raise BackupException(f"No entry found for instance '{instance_name}'")
|
raise BackupException(f"No entry found for instance '{instance_name}'")
|
||||||
@ -133,7 +133,7 @@ def get_last_backup_dir(volume_name, current_backup_dir):
|
|||||||
"""Get the most recent backup directory for the specified volume."""
|
"""Get the most recent backup directory for the specified volume."""
|
||||||
versions = sorted(os.listdir(VERSIONS_DIR), reverse=True)
|
versions = sorted(os.listdir(VERSIONS_DIR), reverse=True)
|
||||||
for version in versions:
|
for version in versions:
|
||||||
backup_dir = os.path.join(VERSIONS_DIR, version, volume_name, "files")
|
backup_dir = os.path.join(VERSIONS_DIR, version, volume_name, "files", "")
|
||||||
# Ignore current backup dir
|
# Ignore current backup dir
|
||||||
if backup_dir != current_backup_dir:
|
if backup_dir != current_backup_dir:
|
||||||
if os.path.isdir(backup_dir):
|
if os.path.isdir(backup_dir):
|
||||||
@ -142,12 +142,17 @@ def get_last_backup_dir(volume_name, current_backup_dir):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def getStoragePath(volume_name):
|
def getStoragePath(volume_name):
|
||||||
return execute_shell_command(f"docker volume inspect --format '{{{{ .Mountpoint }}}}' {volume_name}")[0]
|
path = execute_shell_command(f"docker volume inspect --format '{{{{ .Mountpoint }}}}' {volume_name}")[0]
|
||||||
|
return f"{path}/"
|
||||||
|
|
||||||
|
def getFileRsyncDestinationPath(volume_dir):
|
||||||
|
path = os.path.join(volume_dir, "files")
|
||||||
|
return f"{path}/"
|
||||||
|
|
||||||
def backup_volume(volume_name, volume_dir):
|
def backup_volume(volume_name, volume_dir):
|
||||||
"""Backup files of a volume with incremental backups."""
|
"""Backup files of a volume with incremental backups."""
|
||||||
print(f"Starting backup routine for volume: {volume_name}")
|
print(f"Starting backup routine for volume: {volume_name}")
|
||||||
files_rsync_destination_path = os.path.join(volume_dir, "files")
|
files_rsync_destination_path = getFileRsyncDestinationPath(volume_dir)
|
||||||
pathlib.Path(files_rsync_destination_path).mkdir(parents=True, exist_ok=True)
|
pathlib.Path(files_rsync_destination_path).mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
last_backup_dir = get_last_backup_dir(volume_name, files_rsync_destination_path)
|
last_backup_dir = get_last_backup_dir(volume_name, files_rsync_destination_path)
|
||||||
|
@ -8,13 +8,37 @@ fi
|
|||||||
|
|
||||||
volume_name="$1" # Volume-Name
|
volume_name="$1" # Volume-Name
|
||||||
backup_hash="$2" # Hashed Machine ID
|
backup_hash="$2" # Hashed Machine ID
|
||||||
version="$3" # version to backup
|
version="$3" # version to recover
|
||||||
container="${4:-}" # optional
|
|
||||||
mysql_root_password="${5:-}" # optional
|
# DATABASE PARAMETERS
|
||||||
database="${6:-}" # optional
|
database_type="$4" # Valid values; mariadb, postgress
|
||||||
|
database_container="$5" # optional
|
||||||
|
database_password="$6" # optional
|
||||||
|
database_name="$7" # optional
|
||||||
|
database_user="$database_name"
|
||||||
|
|
||||||
|
|
||||||
backup_folder="Backups/$backup_hash/backup-docker-to-local/$version/$volume_name"
|
backup_folder="Backups/$backup_hash/backup-docker-to-local/$version/$volume_name"
|
||||||
backup_files="/$backup_folder/files"
|
backup_files="/$backup_folder/files"
|
||||||
backup_sql="/$backup_folder/sql/backup.sql"
|
backup_sql="/$backup_folder/sql/$database_name.backup.sql"
|
||||||
|
|
||||||
|
# DATABASE RECOVERY
|
||||||
|
|
||||||
|
if [ -f "$backup_sql" ]; then
|
||||||
|
if [ -n "$database_container" ] && [ -n "$database_password" ] && [ -n "$database_name" ]; then
|
||||||
|
echo "recover mysql dump"
|
||||||
|
cat "$backup_sql" | docker exec -i "$database_container" mariadb -u "$database_user" --password="$database_password" "$database_name"
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "ERROR: Failed to recover mysql dump"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
echo "A database backup exists, but a parameter is missing."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# FILE RECOVERY
|
||||||
|
|
||||||
echo "Inspect volume $volume_name"
|
echo "Inspect volume $volume_name"
|
||||||
docker volume inspect "$volume_name"
|
docker volume inspect "$volume_name"
|
||||||
@ -31,19 +55,6 @@ else
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "$backup_sql" ]; then
|
|
||||||
if [ -n "$container" ] && [ -n "$mysql_root_password" ] && [ -n "$database" ]; then
|
|
||||||
echo "recover mysql dump"
|
|
||||||
cat "$backup_sql" | docker exec -i "$container" mariadb -u root --password="$mysql_root_password" "$database"
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "ERROR: Failed to recover mysql dump"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
echo "A database backup exists, but a parameter is missing. Files will be recovered instead."
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -d "$backup_files" ]; then
|
if [ -d "$backup_files" ]; then
|
||||||
echo "recover files"
|
echo "recover files"
|
||||||
docker run --rm -v "$volume_name:/recover/" -v "$backup_files:/backup/" "kevinveenbirkenbach/alpine-rsync" sh -c "rsync -avv --delete /backup/ /recover/"
|
docker run --rm -v "$volume_name:/recover/" -v "$backup_files:/backup/" "kevinveenbirkenbach/alpine-rsync" sh -c "rsync -avv --delete /backup/ /recover/"
|
||||||
|
Loading…
Reference in New Issue
Block a user