From 973c4eb9cbf1afa159ebdab3d98f62bf67be9c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radoslav=20Bod=C3=B3?= <bodik@cesnet.cz> Date: Thu, 18 Apr 2024 18:33:14 +0200 Subject: [PATCH] rwm: add storage-state command --- rwm.py | 20 ++++++++++++++++++-- tests/test_default.py | 3 +++ tests/test_rwm.py | 13 +++++++++++++ tests/test_storage.py | 21 ++++++++++++++++++++- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/rwm.py b/rwm.py index 892464d..d08c851 100755 --- a/rwm.py +++ b/rwm.py @@ -462,7 +462,7 @@ class StorageManager: return ret - def _bucket_state(self, bucket_name): + def storage_state(self, bucket_name): """dumps current bucket state into dict""" state = { @@ -488,7 +488,7 @@ class StorageManager: # explicit error handling here, it's used during backup process try: - bucket_state = self._bucket_state(bucket_name) + bucket_state = self.storage_state(bucket_name) now = datetime.now().astimezone().isoformat() self.s3.Bucket(bucket_name).upload_fileobj( BytesIO(gzip.compress(json.dumps(bucket_state, cls=RwmJSONEncoder).encode())), @@ -741,6 +741,16 @@ class RWM: return 0 + def storage_state(self, bucket_name) -> int: + """dump storage state in json""" + + print(json.dumps( + self.storage_manager.storage_state(bucket_name), + indent=4, + cls=RwmJSONEncoder + )) + return 0 + def storage_drop_versions(self, bucket_name) -> int: """storage_drop_versions command""" @@ -799,6 +809,9 @@ def parse_arguments(argv): storage_info_cmd_parser = subparsers.add_parser("storage-info", help="show detailed storage info") storage_info_cmd_parser.add_argument("bucket_name", help="bucket name") + storage_state_cmd_parser = subparsers.add_parser("storage-state", help="dump current storage state") + storage_state_cmd_parser.add_argument("bucket_name", help="bucket name") + storage_drop_versions_cmd_parser = subparsers.add_parser( "storage-drop-versions", help="reclaim storage space; drop any old object versions from bucket" @@ -873,6 +886,9 @@ def main(argv=None): # pylint: disable=too-many-branches if args.command == "storage-info": ret = rwmi.storage_info(args.bucket_name) + if args.command == "storage-state": + ret = rwmi.storage_state(args.bucket_name) + if args.command == "storage-drop-versions": ret = rwmi.storage_drop_versions(args.bucket_name) diff --git a/tests/test_default.py b/tests/test_default.py index 7b69848..2271626 100644 --- a/tests/test_default.py +++ b/tests/test_default.py @@ -65,6 +65,9 @@ def test_main(): with patch.object(rwm.RWM, "storage_info", mock_ok): assert _rwm_minconfig(["storage-info", "dummy"]) == 0 + with patch.object(rwm.RWM, "storage_state", mock_ok): + assert _rwm_minconfig(["storage-state", "dummy"]) == 0 + with patch.object(rwm.RWM, "storage_drop_versions", mock_ok): assert _rwm_minconfig(["storage-drop-versions", "bucket"]) == 0 diff --git a/tests/test_rwm.py b/tests/test_rwm.py index 6c22223..3a89a5b 100644 --- a/tests/test_rwm.py +++ b/tests/test_rwm.py @@ -328,6 +328,19 @@ def test_storage_info(tmpworkdir: str, radosuser_admin: rwm.StorageManager): # assert trwm.storage_info("dummy") == 0 +def test_storage_state(tmpworkdir: str, radosuser_admin: rwm.StorageManager): # pylint: disable=unused-argument + """test storage_state""" + + trwm = rwm.RWM({ + "s3_endpoint_url": radosuser_admin.url, + "s3_access_key": radosuser_admin.access_key, + "s3_secret_key": radosuser_admin.secret_key, + }) + + trwm.storage_create("dummy", "dummy") + assert trwm.storage_state("dummy") == 0 + + def test_storage_drop_versions(tmpworkdir: str): # pylint: disable=unused-argument """test storage drop versions""" diff --git a/tests/test_storage.py b/tests/test_storage.py index da90b7f..96b594a 100644 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -178,6 +178,25 @@ def test_storage_info( assert radosuser_admin.storage_info(bucket_name)["delete_markers"] == 1 +def test_storage_state( + tmpworkdir: str, + radosuser_admin: rwm.StorageManager, +): # pylint: disable=unused-argument + """test manager storage state""" + + bucket_name = "rwmbackup-test1" + target_username = "test1" + + bucket = radosuser_admin.storage_create(bucket_name, target_username) + bucket.upload_fileobj(BytesIO(b"dummydata1"), "dummykey") + bucket.upload_fileobj(BytesIO(b"dummydata1"), "dummykey1") + bucket.Object("dummykey1").delete() + + state = radosuser_admin.storage_state(bucket_name) + assert len(state["versions"]) == 2 + assert len(state["delete_markers"]) == 1 + + def test_storage_drop_versions(tmpworkdir: str, radosuser_admin: rwm.StorageManager): # pylint: disable=unused-argument """test manager storage_drop_versions""" @@ -230,7 +249,7 @@ def test_storage_save_state_error_handling(tmpworkdir: str): # pylint: disable= """test storage_save_state error handling""" mock = Mock(side_effect=TypeError("dummy")) - with patch.object(rwm.StorageManager, "_bucket_state", mock): + with patch.object(rwm.StorageManager, "storage_state", mock): assert rwm.StorageManager("http://localhost", "", "").storage_save_state("dummy") == 1 -- GitLab