Support delete remote

master
Marko Semet 2020-04-16 21:19:21 +02:00
parent b3bbf8fcb3
commit ae04fab683
7 changed files with 107 additions and 7 deletions

View File

@ -17,8 +17,9 @@ def main(args):
parser_remote_add.add_argument("--target", nargs="?", type=str, default=None, help="The target of the remote (required by borgbackup).")
parser_remote_add.add_argument("name", nargs=1, type=str, help="The name of the remote.")
parser_remote_list = sub_parser.add_parser("remote-list", help="List remotes.")
parser_remote_list.add_argument("name", nargs="?", type=str, default=[None], help="Name of the backup to show details.")
parser_remote_list.add_argument("name", nargs="?", type=str, default=None, help="Name of the backup to show details.")
parser_remote_delete = sub_parser.add_parser("remote-delete", help="Delete remote.")
parser_remote_delete.add_argument("name", nargs="+", type=str, help="The name of the remote to remove.")
parser_system_server = sub_parser.add_parser("system-server", help="Run system service (root required).")
parser_system_server.add_argument("--fork", action="store_const", const=True, default=False, help="Makes a deamon through forking.")
@ -62,6 +63,8 @@ def main(args):
client.run_command(client.remote_add_gen(name=result.name[0], rtype=remote_type, info=info))
elif result.action == "remote-list":
client.run_command(client.remote_list_gen(name=result.name))
elif result.action == "remote-delete":
client.run_command(client.remote_delete_gen(result.name))
# Not found action
elif result.action is None:

View File

@ -54,4 +54,26 @@ def remote_list_gen(name:str=None):
max_length = max(map(lambda x: len(x), result["data"][name].keys())) + 1
for iID, i in sorted(result["data"][name].items(), key=lambda x: x[0]):
print("%s:%s%s" % (iID, " " * (max_length - len(iID)), str(i)))
return remote_list
return remote_list
def remote_delete_gen(names:list):
# Check
if isinstance(names, str):
raise TypeError("names have to be a listing type.")
names = list(names)
for i in names:
if not isinstance(i, str):
raise TypeError("names list have to contain string.")
# Procedure
async def remote_delete(con:utils.Connection):
for i in names:
result = await con.call({"operation": "remote-delete", "name": i})
if result["status"] != "success":
if result["status"] == "failed-not-existing":
print("Remote %s doesn't exists." % i)
exit(1)
else:
raise RuntimeError("Wasn't able to delete remote.") # TODO: Show error
return remote_delete

View File

@ -1,4 +1,4 @@
from . import btrfs, mounts
from . import snapshot
from .. import defaults, utils
@ -10,9 +10,20 @@ async def callback_func(data, uid):
if "operation" not in data:
raise ValueError("'operation' isn't set.")
operation = data["operation"]
del data["operation"]
# Run operation
raise NotImplementedError()
if operation == "create_backup":
# Get args
name = data["name"]
del data["name"]
utils.valid_name_check(name)
# Create snapshot
utils.check_empty_data_dict(data)
return await snapshot.create_snapshot(name, uid)
else:
raise NotImplementedError("%s isn't implemented." & repr(operation))
async def run_deamon(path:str=defaults.DEFAULT_PATH, fork:bool=False):

View File

@ -0,0 +1,18 @@
from . import btrfs, mounts
from .. import utils
async def create_snapshot(name:str, user:str):
# Find home path and mount
user_path = await utils.get_user_home(user)
candidates = []
for i in await mounts.list_mounts():
if user_path.startswith(i.target):
candidates.append(i)
candidates = sorted(candidates, key=lambda x: len(x.target))
mount = candidates[-1]
# List subvolumes
subvols = btrfs.list_path_subvolumes(mount, user_path)
print(repr(subvols))
raise

View File

@ -1,3 +1,4 @@
import asyncio
from .. import utils
@ -6,7 +7,9 @@ class Backup():
periode:int
blocked:set
def __init__(self, name:str, periode:int=None, blocked:list=[]):
to_backup:list
def __init__(self, name:str, periode:int=None, blocked:list=[], to_backup:list=[]):
# Check args
utils.valid_name_check(name)
if periode is not None and not isinstance(periode, int):
@ -16,11 +19,18 @@ class Backup():
blocked = set(blocked)
for i in blocked:
utils.valid_name_check(i)
to_backup = set(to_backup)
for i in to_backup:
if not isinstance(i, str):
raise TypeError("to_backup have to be a string.")
if ":" in i:
raise ValueError(": isn't allowed a char.")
# Set values
self.name = name
self.periode = periode
self.blocks = blocked
self.to_backup = to_backup
def get_next_scedule(self, latest, zero):
if self.periode is not None:
@ -35,6 +45,8 @@ class Backup():
result["blocked"] = ",".join(self.blocked)
if self.periode is not None:
result["periode"] = str(self.periode)
if self.to_backup:
result["to_backup"] = ":".join(self.to_backup)
return result
@staticmethod
@ -51,8 +63,16 @@ class Backup():
if "blocked" in config:
blocked = config["blocked"].split(",")
del config["blocked"]
to_backup = []
if "to_backup" in config:
to_backup = config["to_backup"].split(":")
del config["to_backup"]
# Generate backup
utils.check_empty_data_dict(config)
return Backup(name=name, periode=periode, blocked=blocked)
return Backup(name=name, periode=periode, blocked=blocked, to_backup=to_backup)
async def run_backup(self, subvolumes:list):
print("Subvolumes: %s" % repr(subvolumes))

View File

@ -84,4 +84,28 @@ async def remote_list(data:dict):
result[iID] = i.dump_config()
# Return result
return {"status": "success", "data": result}
return {"status": "success", "data": result}
async def remote_delete(data:dict):
# Import config
from . import config
# Check and delete
name = data["name"]
del data["name"]
utils.check_empty_data_dict(data)
async with config.config_lock:
# Check
if name not in config.remotes:
return {"status": "failed-not-existing"}
# TODO: Check if backup still used by backup
# Remove backup
del config.remotes[name]
await config.save_config()
# Return result
return {"status": "success"}

View File

@ -40,6 +40,8 @@ def gen_callback_func(master:BackupManager):
return await remotes.add_remote(data)
elif operation == "remote-list":
return await remotes.remote_list(data)
elif operation == "remote-delete":
return await remotes.remote_delete(data)
else:
raise NotImplementedError("%s isn't a supported operation." % repr(operation))
return callback_func