mirror of
https://git.selfprivacy.org/SelfPrivacy/selfprivacy-rest-api.git
synced 2025-01-23 17:26:46 +00:00
Update backup endpoints
This commit is contained in:
parent
c53cab7b88
commit
71fc93914a
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in a new issue