Skip to content

Commit b29683d

Browse files
authored
Add setPermission support (#122)
1 parent e9db611 commit b29683d

File tree

7 files changed

+84
-3
lines changed

7 files changed

+84
-3
lines changed

python/hdfs_native/__init__.py

+7
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,10 @@ def set_owner(
151151
Sets the owner and/or group for the file at `path`
152152
"""
153153
return self.inner.set_owner(path, owner, group)
154+
155+
def set_permission(self, path: str, permission: int) -> None:
156+
"""
157+
Sets the permissions for file at `path` to the octal value `permission`.
158+
For example, to set "rw-r--r--" Unix style permissions, use permission=0o644.
159+
"""
160+
return self.inner.set_permission(path, permission)

python/hdfs_native/_internal.pyi

+1
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@ class RawClient:
6060
owner: Optional[str],
6161
group: Optional[str],
6262
) -> None: ...
63+
def set_permission(self, path: str, permission: int) -> None: ...

python/src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,12 @@ impl RawClient {
262262
) -> PyHdfsResult<()> {
263263
Ok(self.rt.block_on(self.inner.set_owner(path, owner, group))?)
264264
}
265+
266+
pub fn set_permission(&self, path: &str, permission: u32) -> PyHdfsResult<()> {
267+
Ok(self
268+
.rt
269+
.block_on(self.inner.set_permission(path, permission))?)
270+
}
265271
}
266272

267273
/// A Python module implemented in Rust.

python/tests/test_integration.py

+5
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,9 @@ def test_integration(minidfs: str):
8282
assert file_info.owner == "testuser2"
8383
assert file_info.group == "testgroup2"
8484

85+
assert file_info.permission == 0o644
86+
client.set_permission("/testfile", 0o600)
87+
file_info = client.get_file_info("/testfile")
88+
assert file_info.permission == 0o600
89+
8590
client.delete("/testfile", False)

rust/src/client.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ pub struct WriteOptions {
2222
pub block_size: Option<u64>,
2323
/// Replication factor. Default is retrieved from the server.
2424
pub replication: Option<u32>,
25-
/// Unix file permission, defaults to 0o755. This is the raw octal
26-
/// value represented in base 10.
25+
/// Unix file permission, defaults to 0o644, which is "rw-r--r--" as a Unix permission.
26+
/// This is the raw octal value represented in base 10.
2727
pub permission: u32,
2828
/// Whether to overwrite the file, defaults to false. If true and the
2929
/// file does not exist, it will result in an error.
@@ -38,7 +38,7 @@ impl Default for WriteOptions {
3838
Self {
3939
block_size: None,
4040
replication: None,
41-
permission: 0o755,
41+
permission: 0o644,
4242
overwrite: false,
4343
create_parent: true,
4444
}
@@ -445,6 +445,24 @@ impl Client {
445445
.await?;
446446
Ok(())
447447
}
448+
449+
/// Sets permissions for a file. Permission should be an octal number reprenting the Unix style
450+
/// permission.
451+
///
452+
/// For example, to set permissions to rwxr-xr-x:
453+
/// ```rust
454+
/// # async fn func() {
455+
/// # let client = hdfs_native::Client::new("localhost:9000").unwrap();
456+
/// client.set_permission("/path", 0o755).await.unwrap();
457+
/// }
458+
/// ```
459+
pub async fn set_permission(&self, path: &str, permission: u32) -> Result<()> {
460+
let (link, resolved_path) = self.mount_table.resolve(path);
461+
link.protocol
462+
.set_permission(&resolved_path, permission)
463+
.await?;
464+
Ok(())
465+
}
448466
}
449467

450468
impl Default for Client {

rust/src/hdfs/protocol.rs

+22
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,28 @@ impl NamenodeProtocol {
435435
debug!("setOwner response: {:?}", &decoded);
436436
Ok(decoded)
437437
}
438+
439+
pub(crate) async fn set_permission(
440+
&self,
441+
src: &str,
442+
permission: u32,
443+
) -> Result<hdfs::SetPermissionResponseProto> {
444+
let message = hdfs::SetPermissionRequestProto {
445+
src: src.to_string(),
446+
permission: hdfs::FsPermissionProto { perm: permission },
447+
};
448+
449+
debug!("setPermission request: {:?}", &message);
450+
451+
let response = self
452+
.proxy
453+
.call("setPermission", message.encode_length_delimited_to_vec())
454+
.await?;
455+
456+
let decoded = hdfs::SetPermissionResponseProto::decode_length_delimited(response)?;
457+
debug!("setPermission response: {:?}", &decoded);
458+
Ok(decoded)
459+
}
438460
}
439461

440462
impl Drop for NamenodeProtocol {

rust/tests/test_integration.rs

+22
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ mod test {
189189
test_recursive_listing(&client).await?;
190190
test_set_times(&client).await?;
191191
test_set_owner(&client).await?;
192+
test_set_permission(&client).await?;
192193

193194
Ok(())
194195
}
@@ -381,6 +382,27 @@ mod test {
381382
assert_eq!(file_info.owner, "testuser2");
382383
assert_eq!(file_info.group, "testgroup2");
383384

385+
client.delete("/test", false).await?;
386+
387+
Ok(())
388+
}
389+
390+
async fn test_set_permission(client: &Client) -> Result<()> {
391+
client
392+
.create("/test", WriteOptions::default())
393+
.await?
394+
.close()
395+
.await?;
396+
397+
let file_info = client.get_file_info("/test").await?;
398+
assert_eq!(file_info.permission, 0o644);
399+
400+
client.set_permission("/test", 0o600).await?;
401+
let file_info = client.get_file_info("/test").await?;
402+
assert_eq!(file_info.permission, 0o600);
403+
404+
client.delete("/test", false).await?;
405+
384406
Ok(())
385407
}
386408
}

0 commit comments

Comments
 (0)