From 9278606870107ccbc7cfe88bb1c4ab3e1f7f466b Mon Sep 17 00:00:00 2001 From: Marko Semet Date: Thu, 16 Apr 2020 18:27:41 +0200 Subject: [PATCH] Add remote list --- home_backup/__main__.py | 11 +++++++---- home_backup/client.py | 24 +++++++++++++++++++++++- home_backup/user_service/remotes.py | 22 ++++++++++++++++++---- home_backup/user_service/rpc.py | 2 ++ home_backup/utils.py | 7 ++++++- 5 files changed, 56 insertions(+), 10 deletions(-) diff --git a/home_backup/__main__.py b/home_backup/__main__.py index cfe46cf..c1f3672 100644 --- a/home_backup/__main__.py +++ b/home_backup/__main__.py @@ -13,10 +13,11 @@ def main(args): sub_parser = parser.add_subparsers(dest="action") parser_remote_add = sub_parser.add_parser("remote-add", help="Add remote for backups.") - parser_remote_add.add_argument("--type", nargs=1, type=str, default=["borgbackup"], help="The remote type.\nDefault: borgbackup") - parser_remote_add.add_argument("--target", nargs=1, type=str, default=None, help="The target of the remote (required by borgbackup).") + parser_remote_add.add_argument("--type", nargs="?", type=str, default="borgbackup", help="The remote type.\nDefault: borgbackup") + 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_delete = sub_parser.add_parser("remote-delete", help="Delete remote.") parser_system_server = sub_parser.add_parser("system-server", help="Run system service (root required).") @@ -44,7 +45,7 @@ def main(args): # Client actions if result.action == "remote-add": # Check remote type - remote_type = result.type[0] + remote_type = result.type if remote_type not in ("borgbackup",): raise ValueError("Unknown backup type %s." % repr(remote_type)) @@ -53,12 +54,14 @@ def main(args): if remote_type == "borgbackup": if result.target is None: raise ValueError("Target isn't set.") - info["target"] = result.target[0] + info["target"] = result.target else: raise NotImplementedError("Type %s isn't supported well." % remote_type) # Add remote 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)) # Not found action elif result.action is None: diff --git a/home_backup/client.py b/home_backup/client.py index 31a1f1c..2ecff9c 100644 --- a/home_backup/client.py +++ b/home_backup/client.py @@ -32,4 +32,26 @@ def remote_add_gen(name:str, rtype:str, info): exit(1) else: raise RuntimeError("Wasn't able to add remote.") # TODO: Show error - return remote_add \ No newline at end of file + return remote_add + + +def remote_list_gen(name:str=None): + async def remote_list(con:utils.Connection): + # Get remotes + result = await con.call({"operation": "remote-list"}) + if result["status"] != "success": + raise RuntimeError("Wasn't able to get remotes list.") # TODO: Show error + + # Output remotes + if name is None: + for i in result["data"].keys(): + print(i) + else: + if name not in result["data"]: + print("Can't find remote %s." % name) + exit(1) + else: + 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 \ No newline at end of file diff --git a/home_backup/user_service/remotes.py b/home_backup/user_service/remotes.py index 1934d94..16706d6 100644 --- a/home_backup/user_service/remotes.py +++ b/home_backup/user_service/remotes.py @@ -54,9 +54,7 @@ async def add_remote(data:dict): info["type"] = rtype del data["info"] - for i in data.keys(): - raise ValueError("%s is an unknown option." % repr(i)) - + utils.check_empty_data_dict(data) rem = Remote.load_remote(name, info) # Set data @@ -70,4 +68,20 @@ async def add_remote(data:dict): await config.save_config() # Return success - return {"status": "success"} \ No newline at end of file + return {"status": "success"} + + +async def remote_list(data:dict): + # Import config + from . import config + + # Generate result + utils.check_empty_data_dict(data) + + result = {} + async with config.config_lock: + for iID, i in config.remotes.items(): + result[iID] = i.dump_config() + + # Return result + return {"status": "success", "data": result} \ No newline at end of file diff --git a/home_backup/user_service/rpc.py b/home_backup/user_service/rpc.py index b19508f..cc0915f 100644 --- a/home_backup/user_service/rpc.py +++ b/home_backup/user_service/rpc.py @@ -38,6 +38,8 @@ def gen_callback_func(master:BackupManager): # Run operation if operation == "remote-add": return await remotes.add_remote(data) + elif operation == "remote-list": + return await remotes.remote_list(data) else: raise NotImplementedError("%s isn't a supported operation." % repr(operation)) return callback_func diff --git a/home_backup/utils.py b/home_backup/utils.py index f02faf5..b8072af 100644 --- a/home_backup/utils.py +++ b/home_backup/utils.py @@ -95,4 +95,9 @@ def valid_name_check(name:str): if not isinstance(name, str): raise TypeError("name has to be a string.") for i in filter(lambda x: not("a" <= x <= "z" or "A" <= x <= "Z" or "0" <= x <= "9" or x in ("_", "-")), name): - raise ValueError("names can't contain %s." % repr(i)) \ No newline at end of file + raise ValueError("names can't contain %s." % repr(i)) + + +def check_empty_data_dict(data:dict): + for i in data.keys(): + raise ValueError("%s is an unknown option." % repr(i)) \ No newline at end of file