selfprivacy-rest-api/selfprivacy_api/resources/services/restic.py

134 lines
3.4 KiB
Python
Raw Normal View History

2021-11-11 18:31:28 +00:00
#!/usr/bin/env python3
2021-11-16 16:14:01 +00:00
"""Backups management module"""
import json
import subprocess
2021-11-11 18:31:28 +00:00
from flask import request
from flask_restful import Resource
from selfprivacy_api.resources.services import api
2021-11-16 16:14:01 +00:00
2021-11-11 18:31:28 +00:00
class ListAllBackups(Resource):
2021-11-16 16:14:01 +00:00
"""List all restic backups"""
2021-11-11 18:31:28 +00:00
def get(self):
2021-11-16 16:14:01 +00:00
"""
Get all restic backups
---
tags:
- Backups
security:
- bearerAuth: []
responses:
200:
description: A list of snapshots
400:
description: Bad request
401:
description: Unauthorized
"""
repository_name = request.headers.get("X-Repository-Name")
backup_listing_command = [
"restic",
"-r",
f"b2:{repository_name}:/sfbackup",
"snapshots",
"--json",
]
with subprocess.Popen(
backup_listing_command,
shell=False,
2021-11-11 18:31:28 +00:00
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
2021-11-16 16:14:01 +00:00
) as backup_listing_process_descriptor:
snapshots_list = backup_listing_process_descriptor.communicate()[0]
2021-11-11 18:31:28 +00:00
2021-11-16 16:14:01 +00:00
return snapshots_list.decode("utf-8")
2021-11-11 18:31:28 +00:00
class AsyncCreateBackup(Resource):
2021-11-16 16:14:01 +00:00
"""Create a new restic backup"""
2021-11-11 18:31:28 +00:00
def put(self):
2021-11-16 16:14:01 +00:00
"""
Initiate a new restic backup
---
tags:
- Backups
security:
- bearerAuth: []
responses:
200:
description: Backup creation has started
400:
description: Bad request
401:
description: Unauthorized
"""
repository_name = request.headers.get("X-Repository-Name")
2021-11-11 18:31:28 +00:00
2021-11-16 16:14:01 +00:00
backup_command = [
"restic",
"-r",
f"b2:{repository_name}:/sfbackup",
"--verbose",
"--json",
"backup",
"/var",
]
with open("/tmp/backup.log", "w", encoding="utf-8") as log_file:
subprocess.Popen(
backup_command, shell=False, stdout=log_file, stderr=subprocess.STDOUT
)
2021-11-11 18:31:28 +00:00
return {
"status": 0,
"message": "Backup creation has started",
}
2021-11-16 16:14:01 +00:00
class CheckBackupStatus(Resource):
2021-11-16 16:14:01 +00:00
"""Check current backup status"""
def get(self):
"""
2021-11-16 16:14:01 +00:00
Get backup status
---
tags:
- Backups
security:
- bearerAuth: []
responses:
200:
description: Backup status
400:
description: Bad request
401:
description: Unauthorized
"""
backup_status_check_command = ["tail", "-1", "/tmp/backup.log"]
2021-11-16 16:14:01 +00:00
with subprocess.Popen(
backup_status_check_command,
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
) as backup_status_check_process_descriptor:
backup_process_status = (
backup_status_check_process_descriptor.communicate()[0].decode("utf-8")
)
try:
2021-11-16 16:14:01 +00:00
json.loads(backup_process_status)
except ValueError:
2021-11-16 16:14:01 +00:00
return {"message": backup_process_status}
return backup_process_status
2021-11-11 18:31:28 +00:00
api.add_resource(ListAllBackups, "/restic/backup/list")
2021-11-16 08:25:44 +00:00
api.add_resource(AsyncCreateBackup, "/restic/backup/create")
api.add_resource(CheckBackupStatus, "/restic/backup/status")