diff --git a/rwm.py b/rwm.py index 892464dfb31a711e4f04164dfd063c098c353854..d08c851e3da469ad8701ec997283d864b315720b 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 7b69848b9f706cfb24da1789a5e2281a181ff2de..2271626686d1f7fe624ae9c86429d4749a01d4a9 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 6c22223fde51f496bfe27cab6a13d13d95cdb523..3a89a5b3f0bb1d27b561fe64e6d798f53831ff32 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 da90b7f6645de2e0ebafabef5f2509fcda0b8445..96b594a67515e381d3ed15efd47fdf76b37a37d5 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