diff options
| author | unitexe <unitexe70@gmail.com> | 2025-06-07 22:30:35 -0500 |
|---|---|---|
| committer | unitexe <unitexe70@gmail.com> | 2025-06-07 22:30:35 -0500 |
| commit | e91fb1dc99e74daf21a31a8c75157629425e58a8 (patch) | |
| tree | 1c0eddcb5a20710188b8bf4aa6a8c15ed9e77f23 | |
| parent | 1ad4faefea45f1d3bfe4475dbcf1497a507c99bc (diff) | |
Mount & unmount USB devices via gRPC server
| -rw-r--r-- | proto/ormos.proto | 21 | ||||
| -rw-r--r-- | src/main.rs | 99 |
2 files changed, 119 insertions, 1 deletions
diff --git a/proto/ormos.proto b/proto/ormos.proto index 5d20c4d..340dcf5 100644 --- a/proto/ormos.proto +++ b/proto/ormos.proto @@ -4,6 +4,18 @@ package unit.containers.v0; service Ormos { rpc ListUsbDevices (ListUsbDevicesRequest) returns (ListUsbDevicesResponse) {} + rpc MountUsbDevice (MountUsbDeviceRequest) returns (MountUsbDeviceResponse) {} + rpc UnmountUsbDevice (UnmountUsbDeviceRequest) returns (UnmountUsbDeviceResponse) {} +} + +message MountUsbDeviceRequest { + string device_path = 1; + string mount_point = 2; +} + +message MountUsbDeviceResponse { + bool is_success = 1; + string error_message = 2; } message ListUsbDevicesRequest {} @@ -12,6 +24,15 @@ message ListUsbDevicesResponse { repeated UsbDevice devices = 1; } +message UnmountUsbDeviceRequest { + string mount_point = 1; +} + +message UnmountUsbDeviceResponse { + bool is_success = 1; + string error_message = 2; +} + message UsbDevice { string device_path = 1; bool is_mounted = 2; diff --git a/src/main.rs b/src/main.rs index 787e798..d0bff1c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,9 @@ use tonic::{transport::Server, Request, Response, Status}; use skopos::ormos_server::{Ormos, OrmosServer}; -use skopos::{ListUsbDevicesRequest, ListUsbDevicesResponse, UsbDevice}; +use skopos::{ListUsbDevicesRequest, ListUsbDevicesResponse, UsbDevice, MountUsbDeviceRequest, MountUsbDeviceResponse, UnmountUsbDeviceRequest, UnmountUsbDeviceResponse}; use std::io; use std::fs; +use std::process::Command; pub mod skopos { tonic::include_proto!("unit.containers.v0"); @@ -94,6 +95,43 @@ fn create_usb_devices(device_paths: Vec<String>) -> Vec<UsbDevice> { .collect() } +fn mount_usb_device(device_path: &str, mount_point: &str) -> Result<(), io::Error> { + if let Some(parent) = std::path::Path::new(mount_point).parent() { + fs::create_dir_all(parent)?; + } + fs::create_dir_all(mount_point)?; + + let output = Command::new("mount") + .arg(device_path) + .arg(mount_point) + .output()?; + + if output.status.success() { + println!("Successfully mounted {} to {}", device_path, mount_point); + Ok(()) + } else { + let error_msg = String::from_utf8_lossy(&output.stderr); + eprintln!("Mount failed: {}", error_msg); + Err(io::Error::new(io::ErrorKind::Other, error_msg.to_string())) + } +} + +fn unmount_usb_device(mount_point: &str) -> Result<(), io::Error> { + let output = Command::new("umount") + .arg(mount_point) + .output()?; + + if output.status.success() { + println!("Successfully unmounted {}", mount_point); + Ok(()) + } + else { + let error_msg = String::from_utf8_lossy(&output.stderr); + eprintln!("Unmount failed: {}", error_msg); + Err(io::Error::new(io::ErrorKind::Other, error_msg.to_string())) + } +} + #[tonic::async_trait] impl Ormos for MyOrmos { async fn list_usb_devices( @@ -111,6 +149,65 @@ impl Ormos for MyOrmos { Ok(Response::new(response)) } + + async fn mount_usb_device( + &self, + request: Request<MountUsbDeviceRequest>, + ) -> Result<Response<MountUsbDeviceResponse>, Status> { + let req = request.into_inner(); + let device_path = req.device_path; + let mount_point = if req.mount_point.is_empty() { + "/mnt/usb".to_string() // Default mount point + } else { + req.mount_point + }; + + match mount_usb_device(&device_path, &mount_point) { + Ok(()) => { + let response = MountUsbDeviceResponse { + is_success: true, + error_message: String::new(), + }; + Ok(Response::new(response)) + } + Err(e) => { + let response = MountUsbDeviceResponse { + is_success: false, + error_message: e.to_string(), + }; + Ok(Response::new(response)) + } + } + } + + async fn unmount_usb_device( + &self, + request: Request<UnmountUsbDeviceRequest>, + ) -> Result<Response<UnmountUsbDeviceResponse>, Status> { + let req = request.into_inner(); + let mount_point = if req.mount_point.is_empty() { + "/mnt/usb".to_string() // Default mount point + } else { + req.mount_point + }; + + match unmount_usb_device(&mount_point) { + Ok(()) => { + let response = UnmountUsbDeviceResponse { + is_success: true, + error_message: String::new(), + }; + Ok(Response::new(response)) + } + Err(e) => { + let response = UnmountUsbDeviceResponse { + is_success: false, + error_message: e.to_string(), + }; + Ok(Response::new(response)) + } + } + } } #[tokio::main] |
