From e91fb1dc99e74daf21a31a8c75157629425e58a8 Mon Sep 17 00:00:00 2001 From: unitexe Date: Sat, 7 Jun 2025 22:30:35 -0500 Subject: Mount & unmount USB devices via gRPC server --- src/main.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) (limited to 'src') 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) -> Vec { .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, + ) -> Result, 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, + ) -> Result, 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] -- cgit v1.2.3