Update backup endpoints

backups-fix
Inex Code 2021-12-02 18:06:23 +03:00
parent c53cab7b88
commit 71fc93914a
3 changed files with 64 additions and 23 deletions

View File

@ -26,6 +26,7 @@ def create_app(test_config=None):
if app.config["AUTH_TOKEN"] is None: if app.config["AUTH_TOKEN"] is None:
raise ValueError("AUTH_TOKEN is not set") raise ValueError("AUTH_TOKEN is not set")
app.config["ENABLE_SWAGGER"] = os.environ.get("ENABLE_SWAGGER", "0") app.config["ENABLE_SWAGGER"] = os.environ.get("ENABLE_SWAGGER", "0")
app.config["B2_BUCKET"] = os.environ.get("B2_BUCKET")
else: else:
app.config.update(test_config) app.config.update(test_config)

View File

@ -1,8 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Backups management module""" """Backups management module"""
import json import json
import os
import subprocess import subprocess
from flask import request from flask import current_app
from flask_restful import Resource, reqparse from flask_restful import Resource, reqparse
from selfprivacy_api.resources.services import api from selfprivacy_api.resources.services import api
@ -28,12 +29,11 @@ class ListAllBackups(Resource):
401: 401:
description: Unauthorized description: Unauthorized
""" """
repository_name = request.headers.get("X-Repository-Name") bucket = current_app.config["B2_BUCKET"]
backup_listing_command = [ backup_listing_command = [
"restic", "restic",
"-r", "-r",
f"rclone:backblaze:{repository_name}:/sfbackup", f"rclone:backblaze:{bucket}/sfbackup",
"snapshots", "snapshots",
"--json", "--json",
] ]
@ -46,7 +46,11 @@ class ListAllBackups(Resource):
) as backup_listing_process_descriptor: ) as backup_listing_process_descriptor:
snapshots_list = backup_listing_process_descriptor.communicate()[0] snapshots_list = backup_listing_process_descriptor.communicate()[0]
return snapshots_list.decode("utf-8") try:
json.loads(snapshots_list.decode("utf-8"))
except ValueError:
return {"error": snapshots_list.decode("utf-8")}, 500
return json.loads(snapshots_list.decode("utf-8"))
class AsyncCreateBackup(Resource): class AsyncCreateBackup(Resource):
@ -68,18 +72,27 @@ class AsyncCreateBackup(Resource):
401: 401:
description: Unauthorized description: Unauthorized
""" """
repository_name = request.headers.get("X-Repository-Name") bucket = current_app.config["B2_BUCKET"]
init_command = [
"restic",
"-r",
f"rclone:backblaze:{bucket}/sfbackup",
"init",
]
backup_command = [ backup_command = [
"restic", "restic",
"-r", "-r",
f"rclone:backblaze:{repository_name}:/sfbackup", f"rclone:backblaze:{bucket}/sfbackup",
"--verbose", "--verbose",
"--json", "--json",
"backup", "backup",
"/var", "/var",
] ]
subprocess.call(init_command)
with open("/tmp/backup.log", "w", encoding="utf-8") as log_file: with open("/tmp/backup.log", "w", encoding="utf-8") as log_file:
subprocess.Popen( subprocess.Popen(
backup_command, shell=False, stdout=log_file, stderr=subprocess.STDOUT backup_command, shell=False, stdout=log_file, stderr=subprocess.STDOUT
@ -112,6 +125,10 @@ class CheckBackupStatus(Resource):
""" """
backup_status_check_command = ["tail", "-1", "/tmp/backup.log"] backup_status_check_command = ["tail", "-1", "/tmp/backup.log"]
# If the log file does not exists
if os.path.exists("/tmp/backup.log") is False:
return {"message_type": "not_started", "message": "Backup not started"}
with subprocess.Popen( with subprocess.Popen(
backup_status_check_command, backup_status_check_command,
shell=False, shell=False,
@ -125,8 +142,8 @@ class CheckBackupStatus(Resource):
try: try:
json.loads(backup_process_status) json.loads(backup_process_status)
except ValueError: except ValueError:
return {"message": backup_process_status} return {"message_type": "error", "message": backup_process_status}
return backup_process_status return json.loads(backup_process_status)
class AsyncRestoreBackup(Resource): class AsyncRestoreBackup(Resource):
@ -140,6 +157,18 @@ class AsyncRestoreBackup(Resource):
- Backups - Backups
security: security:
- bearerAuth: [] - bearerAuth: []
parameters:
- in: body
required: true
name: backup
description: Backup to restore
schema:
type: object
required:
- backupId
properties:
backupId:
type: string
responses: responses:
200: 200:
description: Backup restoration process started description: Backup restoration process started
@ -148,26 +177,32 @@ class AsyncRestoreBackup(Resource):
401: 401:
description: Unauthorized description: Unauthorized
""" """
parser = reqparse.RequestParser()
parser.add_argument("backupId", type=str, required=True)
args = parser.parse_args()
bucket = current_app.config["B2_BUCKET"]
backup_id = args["backupId"]
backup_restoration_command = [ backup_restoration_command = [
"restic", "restic",
"-r", "-r",
"rclone:backblaze:sfbackup", f"rclone:backblaze:{bucket}/sfbackup",
"var", "restore",
backup_id,
"--target",
"/var",
"--json", "--json",
] ]
with open( with open("/tmp/backup.log", "w", encoding="utf-8") as log_file:
"/tmp/backup.log", "w", encoding="utf-8" subprocess.Popen(
) as backup_log_file_descriptor:
with subprocess.Popen(
backup_restoration_command, backup_restoration_command,
shell=False, shell=False,
stdout=subprocess.PIPE, stdout=log_file,
stderr=backup_log_file_descriptor, stderr=subprocess.STDOUT,
) as backup_restoration_process_descriptor: )
backup_restoration_status = "Backup restoration procedure started"
return {"status": 0, "message": backup_restoration_status} return {"status": 0, "message": "Backup restoration procedure started"}
class BackblazeConfig(Resource): class BackblazeConfig(Resource):

View File

@ -314,16 +314,21 @@ class PullRepositoryChanges(Resource):
shell=False, shell=False,
) )
git_pull_process_descriptor.communicate()[0] data = git_pull_process_descriptor.communicate()[0].decode("utf-8")
os.chdir(current_working_directory) os.chdir(current_working_directory)
if git_pull_process_descriptor.returncode == 0: if git_pull_process_descriptor.returncode == 0:
return {"status": 0, "message": "Update completed successfully"} return {
"status": 0,
"message": "Update completed successfully",
"data": data,
}
elif git_pull_process_descriptor.returncode > 0: elif git_pull_process_descriptor.returncode > 0:
return { return {
"status": git_pull_process_descriptor.returncode, "status": git_pull_process_descriptor.returncode,
"message": "Something went wrong", "message": "Something went wrong",
"data": data,
}, 500 }, 500
@ -335,4 +340,4 @@ api.add_resource(UpgradeSystem, "/configuration/upgrade")
api.add_resource(RebootSystem, "/reboot") api.add_resource(RebootSystem, "/reboot")
api.add_resource(SystemVersion, "/version") api.add_resource(SystemVersion, "/version")
api.add_resource(PythonVersion, "/pythonVersion") api.add_resource(PythonVersion, "/pythonVersion")
api.add_resource(PullRepositoryChanges, "/update") api.add_resource(PullRepositoryChanges, "/configuration/pull")