Support delete remote
parent
b3bbf8fcb3
commit
ae04fab683
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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):
|
||||
|
|
|
@ -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
|
|
@ -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))
|
|
@ -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"}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue