Skip to content

Commit c740242

Browse files
authored
Add setOwner support (#117)
1 parent 1540abb commit c740242

File tree

7 files changed

+106
-3
lines changed

7 files changed

+106
-3
lines changed

python/python/hdfs_native/__init__.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import io
2-
from typing import Iterator
2+
from typing import Iterator, Optional
33
from typing_extensions import Buffer
44

55
from ._internal import *
@@ -113,3 +113,9 @@ def set_times(self, path: str, mtime: int, atime: int) -> None:
113113
Changes the modification time and access time of the file at `path` to `mtime` and `atime`, respectively.
114114
"""
115115
return self.inner.set_times(path, mtime, atime)
116+
117+
def set_owner(self, path: str, owner: Optional[str] = None, group: Optional[str] = None) -> None:
118+
"""
119+
Sets the owner and/or group for the file at `path`
120+
"""
121+
return self.inner.set_owner(path, owner, group)

python/python/hdfs_native/_internal.pyi

+3-1
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,6 @@ class RawClient:
5555

5656
def delete(self, path: str, recursive: bool) -> bool: ...
5757

58-
def set_times(self, path: str, mtime: int, atime: int) -> None: ...
58+
def set_times(self, path: str, mtime: int, atime: int) -> None: ...
59+
60+
def set_owner(self, path: str, owner: Optional[str], group: Optional[str]) -> None: ...

python/src/lib.rs

+9
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,15 @@ impl RawClient {
243243
pub fn set_times(&self, path: &str, mtime: u64, atime: u64) -> PyHdfsResult<()> {
244244
Ok(self.rt.block_on(self.inner.set_times(path, mtime, atime))?)
245245
}
246+
247+
pub fn set_owner(
248+
&self,
249+
path: &str,
250+
owner: Option<&str>,
251+
group: Option<&str>,
252+
) -> PyHdfsResult<()> {
253+
Ok(self.rt.block_on(self.inner.set_owner(path, owner, group))?)
254+
}
246255
}
247256

248257
/// A Python module implemented in Rust.

python/tests/test_integration.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,20 @@ def test_integration(minidfs: str):
5959
assert file_info.modification_time == mtime
6060
assert file_info.access_time == atime
6161

62-
client.delete("/testfile", False)
6362

63+
client.set_owner("/testfile", "testuser", "testgroup")
64+
file_info = client.get_file_info("/testfile")
65+
assert file_info.owner == "testuser"
66+
assert file_info.group == "testgroup"
67+
68+
client.set_owner("/testfile", owner="testuser2")
69+
file_info = client.get_file_info("/testfile")
70+
assert file_info.owner == "testuser2"
71+
assert file_info.group == "testgroup"
72+
73+
client.set_owner("/testfile", group="testgroup2")
74+
file_info = client.get_file_info("/testfile")
75+
assert file_info.owner == "testuser2"
76+
assert file_info.group == "testgroup2"
77+
78+
client.delete("/testfile", False)

rust/src/client.rs

+14
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,20 @@ impl Client {
431431
.await?;
432432
Ok(())
433433
}
434+
435+
/// Optionally sets the owner and group for a file.
436+
pub async fn set_owner(
437+
&self,
438+
path: &str,
439+
owner: Option<&str>,
440+
group: Option<&str>,
441+
) -> Result<()> {
442+
let (link, resolved_path) = self.mount_table.resolve(path);
443+
link.protocol
444+
.set_owner(&resolved_path, owner, group)
445+
.await?;
446+
Ok(())
447+
}
434448
}
435449

436450
impl Default for Client {

rust/src/hdfs/protocol.rs

+24
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,30 @@ impl NamenodeProtocol {
411411
debug!("setTimes response: {:?}", &decoded);
412412
Ok(decoded)
413413
}
414+
415+
pub(crate) async fn set_owner(
416+
&self,
417+
src: &str,
418+
owner: Option<&str>,
419+
group: Option<&str>,
420+
) -> Result<hdfs::SetOwnerResponseProto> {
421+
let message = hdfs::SetOwnerRequestProto {
422+
src: src.to_string(),
423+
username: owner.map(str::to_string),
424+
groupname: group.map(str::to_string),
425+
};
426+
427+
debug!("setOwner request: {:?}", &message);
428+
429+
let response = self
430+
.proxy
431+
.call("setOwner", message.encode_length_delimited_to_vec())
432+
.await?;
433+
434+
let decoded = hdfs::SetOwnerResponseProto::decode_length_delimited(response)?;
435+
debug!("setOwner response: {:?}", &decoded);
436+
Ok(decoded)
437+
}
414438
}
415439

416440
impl Drop for NamenodeProtocol {

rust/tests/test_integration.rs

+33
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ mod test {
188188
// We use writing to create files, so do this after
189189
test_recursive_listing(&client).await?;
190190
test_set_times(&client).await?;
191+
test_set_owner(&client).await?;
191192

192193
Ok(())
193194
}
@@ -348,6 +349,38 @@ mod test {
348349
assert_eq!(file_info.modification_time, mtime);
349350
assert_eq!(file_info.access_time, atime);
350351

352+
client.delete("/test", false).await?;
353+
354+
Ok(())
355+
}
356+
357+
async fn test_set_owner(client: &Client) -> Result<()> {
358+
client
359+
.create("/test", WriteOptions::default())
360+
.await?
361+
.close()
362+
.await?;
363+
364+
client
365+
.set_owner("/test", Some("testuser"), Some("testgroup"))
366+
.await?;
367+
let file_info = client.get_file_info("/test").await?;
368+
369+
assert_eq!(file_info.owner, "testuser");
370+
assert_eq!(file_info.group, "testgroup");
371+
372+
client.set_owner("/test", Some("testuser2"), None).await?;
373+
let file_info = client.get_file_info("/test").await?;
374+
375+
assert_eq!(file_info.owner, "testuser2");
376+
assert_eq!(file_info.group, "testgroup");
377+
378+
client.set_owner("/test", None, Some("testgroup2")).await?;
379+
let file_info = client.get_file_info("/test").await?;
380+
381+
assert_eq!(file_info.owner, "testuser2");
382+
assert_eq!(file_info.group, "testgroup2");
383+
351384
Ok(())
352385
}
353386
}

0 commit comments

Comments
 (0)