From 2dfcb4e778e189a04c1161fe3f89fc63355f7767 Mon Sep 17 00:00:00 2001 From: Maxim Deb Natkh Date: Thu, 16 Jan 2025 17:26:30 +0100 Subject: [PATCH] [Filestore]: support remove by parentId and name in filestore-client --- cloud/filestore/apps/client/lib/rm.cpp | 20 +++++++++--- .../tests/client/canondata/result.json | 3 ++ .../client/canondata/test.test_rm/results.txt | 32 +++++++++++++++++++ cloud/filestore/tests/client/test.py | 32 +++++++++++++++++++ 4 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 cloud/filestore/tests/client/canondata/test.test_rm/results.txt diff --git a/cloud/filestore/apps/client/lib/rm.cpp b/cloud/filestore/apps/client/lib/rm.cpp index f1d24948290..e804440b969 100644 --- a/cloud/filestore/apps/client/lib/rm.cpp +++ b/cloud/filestore/apps/client/lib/rm.cpp @@ -16,6 +16,7 @@ class TRmCommand final private: TString Path; bool RemoveDir = false; + ui64 NodeId = 0; public: TRmCommand() @@ -25,6 +26,11 @@ class TRmCommand final .RequiredArgument("PATH") .StoreResult(&Path); + Opts.AddLongOption("node") + .DefaultValue(0) + .RequiredArgument("ID") + .StoreResult(&NodeId); + Opts.AddLongOption('r', "recursive") .NoArgument() .SetFlag(&RemoveDir); @@ -35,14 +41,20 @@ class TRmCommand final auto sessionGuard = CreateSession(); auto& session = sessionGuard.AccessSession(); - const auto resolved = ResolvePath(session, Path, false); + // If nodeId is set, treat it as a nodeId and path as a name. Otherwise, + // resolve path to get nodeId and name. + if (!NodeId) { + const auto resolved = ResolvePath(session, Path, false); + Y_ENSURE(resolved.size() >= 2, "can't rm root node"); - Y_ENSURE(resolved.size() >= 2, "can't rm root node"); + NodeId = resolved[resolved.size() - 2].Node.GetId(); + Path = ToString(resolved.back().Name); + } auto request = CreateRequest(); - request->SetNodeId(resolved[resolved.size() - 2].Node.GetId()); - request->SetName(ToString(resolved.back().Name)); + request->SetNodeId(NodeId); + request->SetName(Path); request->SetUnlinkDirectory(RemoveDir); auto response = WaitFor(session.UnlinkNode( diff --git a/cloud/filestore/tests/client/canondata/result.json b/cloud/filestore/tests/client/canondata/result.json index 5b49114cd5d..508ced9dbe1 100644 --- a/cloud/filestore/tests/client/canondata/result.json +++ b/cloud/filestore/tests/client/canondata/result.json @@ -38,6 +38,9 @@ "test.test_resize": { "uri": "file://test.test_resize/results.txt" }, + "test.test_rm": { + "uri": "file://test.test_rm/results.txt" + }, "test.test_stat": { "uri": "file://test.test_stat/results.txt" }, diff --git a/cloud/filestore/tests/client/canondata/test.test_rm/results.txt b/cloud/filestore/tests/client/canondata/test.test_rm/results.txt new file mode 100644 index 00000000000..66f9101472b --- /dev/null +++ b/cloud/filestore/tests/client/canondata/test.test_rm/results.txt @@ -0,0 +1,32 @@ +[ + { + "Type": 1, + "Links": 1, + "Name": "c.txt", + "Mode": 420, + "Id": 4 + }, + { + "Type": 1, + "Links": 1, + "Name": "d.txt", + "Mode": 420, + "Id": 5 + } +][ + { + "Type": 1, + "Links": 1, + "Name": "d.txt", + "Mode": 420, + "Id": 5 + } +][][ + { + "Type": 2, + "Links": 1, + "Name": "b", + "Mode": 511, + "Id": 3 + } +][] \ No newline at end of file diff --git a/cloud/filestore/tests/client/test.py b/cloud/filestore/tests/client/test.py index c51170d3c9b..e09d591965b 100644 --- a/cloud/filestore/tests/client/test.py +++ b/cloud/filestore/tests/client/test.py @@ -293,6 +293,38 @@ def test_diff(): return ret +def test_rm(): + client, results_path = __init_test() + client.create("fs", "test_cloud", "test_folder", BLOCK_SIZE, BLOCKS_COUNT) + + client.mkdir("fs", "/a") + client.mkdir("fs", "/a/b") + client.touch("fs", "/a/b/c.txt") + client.touch("fs", "/a/b/d.txt") + + # remove by path + out = __exec_ls(client, "fs", "/a/b") + out += client.rm("fs", "/a/b/c.txt") + + # remove by parentId + name + out += __exec_ls(client, "fs", "/a/b") + node_id = json.loads(client.stat("fs", "/a/b"))["Id"] + out += client.rm("fs", "d.txt", "--node", str(node_id)) + out += __exec_ls(client, "fs", "/a/b") + + # remove a directory + out += __exec_ls(client, "fs", "/a") + out += client.rm("fs", "/a/b", "-r") + out += __exec_ls(client, "fs", "/a") + + client.destroy("fs") + with open(results_path, "wb") as results_file: + results_file.write(out) + + ret = common.canonical_file(results_path, local=True) + return ret + + def test_write_ls_rm_ls(): client, results_path = __init_test()