83 lines
3.0 KiB
Plaintext
83 lines
3.0 KiB
Plaintext
|
#!/bin/python3
|
||
|
|
||
|
import json
|
||
|
import subprocess
|
||
|
import sys
|
||
|
import os
|
||
|
|
||
|
if len(sys.argv) < 3:
|
||
|
# Check commands arguments.
|
||
|
print("Usage: ")
|
||
|
print("ksrackup {backup_name} init :: Initialize backup repository.")
|
||
|
print("ksrackup {backup_name} backup :: Perform a new backup.")
|
||
|
print("ksrackup {backup_name} prune :: Prune outdated backups.")
|
||
|
print("ksrackup {backup_name} restic :: Execute an arbitrary restic command.")
|
||
|
exit(1)
|
||
|
|
||
|
# Get command parameters.
|
||
|
backup_name = sys.argv[1]
|
||
|
command = sys.argv[2] # The executed command.
|
||
|
|
||
|
# Open and read a backup configuration file.
|
||
|
backup_file = open(backup_name + ".json")
|
||
|
backup_data = json.load(backup_file)
|
||
|
|
||
|
# Setup the restic environment from backup configuration.
|
||
|
restic_environment = {
|
||
|
"RESTIC_REPOSITORY": backup_data["restic"]["repository"],
|
||
|
"RESTIC_PASSWORD": backup_data["restic"]["password"],
|
||
|
"AWS_ACCESS_KEY_ID": backup_data["restic"]["access_key_id"],
|
||
|
"AWS_SECRET_ACCESS_KEY": backup_data["restic"]["secret_access_key"],
|
||
|
}
|
||
|
|
||
|
# Create the backup directory.
|
||
|
os.makedirs(backup_name, exist_ok=True)
|
||
|
# Move to the backup directory.
|
||
|
os.chdir(backup_name)
|
||
|
|
||
|
# Open error log file.
|
||
|
error_log = open("error.log", "a")
|
||
|
|
||
|
# Execute the command.
|
||
|
if command == "init":
|
||
|
# Initialize a backup repository.
|
||
|
subprocess.run(["restic", "init"], env=restic_environment)
|
||
|
elif command == "backup":
|
||
|
|
||
|
# Perform the right backup operations depending on its type.
|
||
|
if backup_data["type"] == "postgresql":
|
||
|
with open("database.sql", "w") as database_sql:
|
||
|
# Dump of the PostgreSQL database.
|
||
|
subprocess.run([
|
||
|
"docker", "exec", backup_data["postgresql"]["container_name"],
|
||
|
"pg_dump", "-U", backup_data["postgresql"]["username"], backup_data["postgresql"]["database"],
|
||
|
], stdout=database_sql, stderr=error_log)
|
||
|
# Save the dump in the restic repository.
|
||
|
subprocess.run(["restic", "backup", "database.sql"], env=restic_environment, stderr=error_log)
|
||
|
elif backup_data["type"] == "mysql":
|
||
|
with open("database.sql", "w") as database_sql:
|
||
|
# Dump of the MySQL database.
|
||
|
subprocess.run([
|
||
|
"docker", "exec", backup_data["mysql"]["container_name"],
|
||
|
"mysqldump", "-u", backup_data["mysql"]["username"], "-p" + backup_data["mysql"]["password"], backup_data["mysql"]["database"],
|
||
|
], stdout=database_sql, stderr=error_log)
|
||
|
# Save the dump in the restic repository.
|
||
|
subprocess.run(["restic", "backup", "database.sql"], env=restic_environment, stderr=error_log)
|
||
|
elif backup_data["type"] == "files":
|
||
|
# Save the files in the restic repository.
|
||
|
subprocess.run(["restic", "backup", backup_data["files"]["path"]], env=restic_environment, stderr=error_log)
|
||
|
|
||
|
elif command == "prune":
|
||
|
# Define backups conservation policy.
|
||
|
prune_params = [
|
||
|
"--keep-within", "28d",
|
||
|
"--keep-within-daily", "4m",
|
||
|
"--keep-within-weekly", "2y",
|
||
|
"--keep-monthly", "100",
|
||
|
]
|
||
|
# Remove outdated backups.
|
||
|
subprocess.run(["restic", "forget", "--prune"] + prune_params, env=restic_environment, stderr=error_log)
|
||
|
elif command == "restic":
|
||
|
# Execute the arbitrary restic command.
|
||
|
subprocess.run(["restic"] + sys.argv[3:], env=restic_environment)
|