1 use api::debian_service_client::DebianServiceClient; 2 use api::ShutdownQueueOpeningRequest; 3 use std::process::Command; 4 5 use anyhow::anyhow; 6 use clap::Parser; 7 use log::debug; 8 pub mod api { 9 tonic::include_proto!("com.android.virtualization.terminal.proto"); 10 } 11 12 #[derive(Parser)] 13 /// Flags for running command 14 pub struct Args { 15 /// grpc port number 16 #[arg(long)] 17 #[arg(alias = "grpc_port")] 18 grpc_port: String, 19 } 20 21 #[tokio::main] main() -> Result<(), Box<dyn std::error::Error>>22async fn main() -> Result<(), Box<dyn std::error::Error>> { 23 let args = Args::parse(); 24 let gateway_ip_addr = netdev::get_default_gateway()?.ipv4[0]; 25 26 let server_addr = format!("http://{}:{}", gateway_ip_addr.to_string(), args.grpc_port); 27 28 debug!("connect to grpc server {}", server_addr); 29 30 let mut client = DebianServiceClient::connect(server_addr).await.map_err(|e| e.to_string())?; 31 32 let mut res_stream = client 33 .open_shutdown_request_queue(tonic::Request::new(ShutdownQueueOpeningRequest {})) 34 .await? 35 .into_inner(); 36 37 while let Some(_response) = res_stream.message().await? { 38 let status = Command::new("poweroff").status().expect("power off"); 39 if !status.success() { 40 return Err(anyhow!("Failed to power off: {status}").into()); 41 } 42 debug!("poweroff"); 43 break; 44 } 45 Ok(()) 46 } 47