Mercurial > hg > Members > anatofuz > ie-virsh
view src/main.rs @ 10:188bf8ab3e81
fmt
author | AnaTofuZ <anatofuz@gmail.com> |
---|---|
date | Wed, 28 Oct 2020 18:21:54 +0900 |
parents | b89466455757 |
children | 9fac2c578228 |
line wrap: on
line source
use clap::Clap; use nix; use std::process::Command; #[derive(Clap)] #[clap(version = "1.0", author = "AnaTofuZ <anatofuz@cr.ie.u-ryukyu.ac.jp>")] struct Opts { #[clap(subcommand)] subcmd: SubCommand, } #[derive(Clap)] enum SubCommand { List(List), Undefine(UnDefine), Define(Define), Shutdown(Shutdown), Destroy(Destroy), Console(Console), Start(Start), Ttyconsole(TTyConsole), } /// define (but don't start) a domain from an template XML file #[derive(Clap)] struct Define { name: String, } /// undefine a domain #[derive(Clap)] struct UnDefine { name: String, } /// start a (previously defined) inactive domain #[derive(Clap)] struct Start { name: String, } /// tty console #[derive(Clap)] struct TTyConsole { name_or_id: String, } /// gracefully shutdown a domain #[derive(Clap)] struct Shutdown { name: String, } /// list domains #[derive(Clap)] struct List {} /// destroy (stop) a domain #[derive(Clap)] struct Destroy { name: String, } /// connect to the guest console #[derive(Clap)] struct Console { name_or_id: String, } struct ListDumpMsg { info_msg: String, border_line: String, } struct VM { id: u32, name: String, is_vm_running: bool, } fn main() { let opts: Opts = Opts::parse(); let uid = getuid(); let gid = getgid(); let user_name = getlogin(uid); println!("uid: {} gid: {} name: {}", uid, gid, user_name); match opts.subcmd { SubCommand::List(_) => { set_root_id(); let (ldump_msg, vm_list_strs) = list_command(user_name); println!("{}\n{}", ldump_msg.info_msg, ldump_msg.border_line); for vm_info in vm_list_strs { println!("{}", vm_info); } } SubCommand::Define(name) => {} SubCommand::Shutdown(name) => {} SubCommand::Console(name) => {} SubCommand::Destroy(name_or_id) => {} _ => {} } //set_root_id(); //list_command(user_name); } fn getlogin(uid: u32) -> &'static str { use std::ffi::CStr; let user_passwd = unsafe { nix::libc::getpwuid(uid) }; let c_str = unsafe { CStr::from_ptr((*user_passwd).pw_name) }; return c_str.to_str().unwrap(); } fn getuid() -> u32 { let uid_struct = nix::unistd::getuid(); return uid_struct.into(); } fn getgid() -> u32 { let gid_struct = nix::unistd::getgid(); return gid_struct.into(); } fn list_command(user_name: &'static str) -> (ListDumpMsg, Vec<String>) { let output = Command::new("virsh") .arg("list") .arg("--all") .output() .expect("failed to virsh"); let virsh_list = String::from_utf8_lossy(&output.stdout); let mut virsh_list = virsh_list.split("\n"); let info_msg = virsh_list.next().unwrap(); let border_line = virsh_list.next().unwrap(); let ldump_msg = ListDumpMsg { info_msg: String::from(info_msg), border_line: String::from(border_line), }; return ( ldump_msg, virsh_list .filter(|&x| x.contains(user_name)) .map(|x| x.to_string()) .collect(), ); } fn set_root_id() { let id = 0; match nix::unistd::seteuid(nix::unistd::Uid::from_raw(id)) { Err(err) => panic!("failed seteuid {}", err), Ok(_) => {} } match nix::unistd::setegid(nix::unistd::Gid::from_raw(id)) { Err(err) => panic!("failed setedid{}", err), Ok(_) => {} } match nix::unistd::setuid(nix::unistd::Uid::from_raw(id)) { Err(err) => panic!("failed setuid {}", err), Ok(_) => {} } match nix::unistd::setgid(nix::unistd::Gid::from_raw(id)) { Err(err) => panic!("failed setdid{}", err), Ok(_) => {} } } fn create_new_vm(user_name: &'static str, vm_name: &'static str, debug_kernel: bool) {}