6
|
1 use clap::{App, Arg, Clap};
|
1
|
2 use nix;
|
3
|
3 use std::process::Command;
|
1
|
4
|
5
|
5 #[derive(Clap)]
|
7
|
6 #[clap(version = "1.0", author = "AnaTofuZ <anatofuz@cr.ie.u-ryukyu.ac.jp>")]
|
5
|
7 struct Opts {
|
|
8 #[clap(subcommand)]
|
|
9 subcmd: SubCommand,
|
|
10 }
|
|
11
|
|
12 #[derive(Clap)]
|
|
13 enum SubCommand {
|
|
14 define(Define),
|
|
15 shutdown(Shutdown),
|
7
|
16 list(List),
|
5
|
17 }
|
|
18
|
7
|
19 /// define (but don't start) a domain from an template XML file
|
5
|
20 #[derive(Clap)]
|
|
21 struct Define {
|
|
22 name: String,
|
|
23 }
|
|
24
|
7
|
25 /// gracefully shutdown a domain
|
5
|
26 #[derive(Clap)]
|
|
27 struct Shutdown {
|
|
28 name: String,
|
|
29 }
|
|
30
|
7
|
31 /// list domains
|
|
32 #[derive(Clap)]
|
|
33 struct List {}
|
|
34
|
|
35 struct list_dump_msg {
|
|
36 info_msg: String,
|
|
37 border_line: String,
|
|
38 }
|
|
39
|
5
|
40 struct VM {
|
|
41 id: u32,
|
|
42 name: String,
|
|
43 is_vm_running: bool,
|
|
44 }
|
|
45
|
0
|
46 fn main() {
|
7
|
47 let opts: Opts = Opts::parse();
|
|
48
|
4
|
49 let uid = getuid();
|
|
50 let gid = getgid();
|
3
|
51 let user_name = getlogin(uid);
|
|
52 println!("uid: {} gid: {} name: {}", uid, gid, user_name);
|
5
|
53
|
7
|
54 match opts.subcmd {
|
|
55 SubCommand::define(name) => {}
|
|
56 SubCommand::shutdown(name) => {}
|
5
|
57
|
7
|
58 SubCommand::list(list) => {
|
|
59 set_root_id();
|
|
60 let (vm_list, list_dump_msg) = list_command(user_name);
|
|
61 println!("{}\n{}", list_dump_msg.info_msg, list_dump_msg.border_line);
|
|
62 for vm in vm_list.iter() {
|
|
63 println!("{} {}", vm.id, vm.name);
|
|
64 }
|
5
|
65 }
|
|
66 }
|
|
67
|
|
68 //set_root_id();
|
|
69 //list_command(user_name);
|
0
|
70 }
|
1
|
71
|
2
|
72 fn getlogin(uid: u32) -> &'static str {
|
|
73 use std::ffi::CStr;
|
4
|
74 let user_passwd = unsafe { nix::libc::getpwuid(uid) };
|
|
75 let c_str = unsafe { CStr::from_ptr((*user_passwd).pw_name) };
|
1
|
76 return c_str.to_str().unwrap();
|
|
77 }
|
|
78
|
|
79 fn getuid() -> u32 {
|
|
80 let uid_struct = nix::unistd::getuid();
|
3
|
81 return uid_struct.into();
|
1
|
82 }
|
|
83
|
|
84 fn getgid() -> u32 {
|
|
85 let gid_struct = nix::unistd::getgid();
|
3
|
86 return gid_struct.into();
|
|
87 }
|
|
88
|
7
|
89 fn list_command(user_name: &'static str) -> (Vec<VM>, list_dump_msg) {
|
4
|
90 let output = Command::new("virsh")
|
|
91 .arg("list")
|
|
92 .arg("--all")
|
|
93 .output()
|
|
94 .expect("failed to virsh");
|
|
95 let virsh_list = String::from_utf8_lossy(&output.stdout);
|
|
96 let mut virsh_list = virsh_list.split("\n");
|
7
|
97
|
4
|
98 let info_msg = virsh_list.next().unwrap();
|
|
99 let border_line = virsh_list.next().unwrap();
|
7
|
100 let ldump_msg = list_dump_msg {
|
|
101 info_msg: String::from(info_msg),
|
|
102 border_line: String::from(border_line),
|
|
103 };
|
4
|
104
|
5
|
105 let virsh_emit_vm_list = virsh_list.filter(|&x| x.contains(user_name));
|
|
106
|
6
|
107 let mut vm_list: Vec<VM> = Vec::new();
|
4
|
108
|
5
|
109 for emit_vm in virsh_emit_vm_list {
|
|
110 let mut vm_infos = emit_vm.split(" ");
|
|
111 let vm_status = vm_infos.next().unwrap();
|
|
112 let is_vm_running = if vm_status != "-" { true } else { false };
|
|
113 let name = vm_infos.next().unwrap();
|
7
|
114 vm_list.push(VM {
|
6
|
115 id: 0,
|
|
116 is_vm_running: is_vm_running,
|
|
117 name: String::from(name),
|
7
|
118 });
|
4
|
119 }
|
7
|
120 return (vm_list, ldump_msg);
|
1
|
121 }
|
3
|
122
|
4
|
123 fn set_root_id() {
|
3
|
124 let id = 0;
|
|
125 match nix::unistd::seteuid(nix::unistd::Uid::from_raw(id)) {
|
|
126 Err(err) => panic!("failed seteuid {}", err),
|
|
127 Ok(_) => {}
|
|
128 }
|
|
129 match nix::unistd::setegid(nix::unistd::Gid::from_raw(id)) {
|
|
130 Err(err) => panic!("failed setedid{}", err),
|
|
131 Ok(_) => {}
|
|
132 }
|
|
133
|
|
134 match nix::unistd::setuid(nix::unistd::Uid::from_raw(id)) {
|
|
135 Err(err) => panic!("failed setuid {}", err),
|
|
136 Ok(_) => {}
|
|
137 }
|
|
138
|
|
139 match nix::unistd::setgid(nix::unistd::Gid::from_raw(id)) {
|
|
140 Err(err) => panic!("failed setdid{}", err),
|
|
141 Ok(_) => {}
|
|
142 }
|
4
|
143 }
|
5
|
144
|
6
|
145 fn create_new_vm(user_name: &'static str, vm_name: &'static str, debug_kernel: bool) {}
|