1use argh::{ArgsInfo, FromArgValue, FromArgs};
6use std::fmt;
7
8#[cfg(not(target_os = "fuchsia"))]
9use ffx_core::ffx_command;
10
11#[derive(Copy, Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
12pub enum GuestType {
13 Debian,
14 Termina,
15 Zircon,
16}
17
18impl FromArgValue for GuestType {
19 fn from_arg_value(value: &str) -> Result<Self, String> {
20 match value {
21 "debian" => Ok(Self::Debian),
22 "termina" => Ok(Self::Termina),
23 "zircon" => Ok(Self::Zircon),
24 _ => Err(format!(
25 "Unrecognized guest type \"{}\". Supported guest types are: \
26 \"debian\", \"termina\", \"zircon\".",
27 value
28 )),
29 }
30 }
31}
32
33impl fmt::Display for GuestType {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 match *self {
36 GuestType::Debian => write!(f, "debian"),
37 GuestType::Termina => write!(f, "termina"),
38 GuestType::Zircon => write!(f, "zircon"),
39 }
40 }
41}
42
43impl GuestType {
44 pub fn moniker(&self) -> &str {
45 match self {
46 GuestType::Debian => "/core/debian-guest-manager",
47 GuestType::Termina => "/core/termina-guest-manager",
48 GuestType::Zircon => "/core/zircon-guest-manager",
49 }
50 }
51
52 pub fn guest_manager_interface(&self) -> &str {
53 match *self {
54 GuestType::Zircon => "fuchsia.virtualization.ZirconGuestManager",
55 GuestType::Debian => "fuchsia.virtualization.DebianGuestManager",
56 GuestType::Termina => "fuchsia.virtualization.TerminaGuestManager",
57 }
58 }
59
60 pub fn gn_target_label(self) -> &'static str {
61 match self {
62 GuestType::Zircon => "//src/virtualization/bundles:zircon",
63 GuestType::Debian => "//src/virtualization/bundles:debian",
64 GuestType::Termina => "//src/virtualization/bundles:termina",
65 }
66 }
67
68 pub fn gn_core_shard_label(&self) -> &'static str {
69 match self {
70 GuestType::Zircon => "//src/virtualization/bundles:zircon_core_shards",
71 GuestType::Debian => "//src/virtualization/bundles:debian_core_shards",
72 GuestType::Termina => "//src/virtualization/bundles:termina_core_shards",
73 }
74 }
75
76 pub fn package_url(&self) -> &'static str {
77 match self {
78 GuestType::Zircon => "fuchsia-pkg://fuchsia.com/zircon_guest#meta/zircon_guest.cm",
79 GuestType::Debian => "fuchsia-pkg://fuchsia.com/debian_guest#meta/debian_guest.cm",
80 GuestType::Termina => "fuchsia-pkg://fuchsia.com/termina_guest#meta/termina_guest.cm",
81 }
82 }
83
84 pub fn all_guests() -> Vec<GuestType> {
85 vec![GuestType::Debian, GuestType::Termina, GuestType::Zircon]
86 }
87}
88
89#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
90pub struct GuestOptions {
92 #[argh(subcommand)]
93 pub nested: SubCommands,
94}
95
96#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
97#[argh(subcommand)]
98pub enum SubCommands {
99 Attach(crate::attach_args::AttachArgs),
100 Launch(crate::launch_args::LaunchArgs),
101 Stop(crate::stop_args::StopArgs),
102 Balloon(crate::balloon_args::BalloonArgs),
103 List(crate::list_args::ListArgs),
104 Socat(crate::socat_args::SocatArgs),
105 Vsh(VshArgs),
106 VsockPerf(crate::vsockperf_args::VsockPerfArgs),
107 Wipe(crate::wipe_args::WipeArgs),
108 Mem(crate::mem_args::MemArgs),
109}
110
111pub mod mem_args {
112 use super::*;
113 #[derive(ArgsInfo, FromArgs, Debug, PartialEq)]
115 #[argh(subcommand, name = "mem")]
116 #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
117 pub struct MemArgs {
118 #[argh(subcommand)]
119 pub mem_cmd: MemCommands,
120 }
121 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
122 #[argh(subcommand)]
123 pub enum MemCommands {
124 RequestPluggedMem(RequestPluggedMem),
125 StatsMem(StatsMem),
126 }
127
128 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
129 #[argh(subcommand, name = "request-plugged")]
131 pub struct RequestPluggedMem {
132 #[argh(positional)]
133 pub guest_type: GuestType,
135 #[argh(positional)]
136 pub size: u64,
138 }
139 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
140 #[argh(subcommand, name = "stats")]
142 pub struct StatsMem {
143 #[argh(positional)]
144 pub guest_type: GuestType,
146 }
147}
148
149pub mod balloon_args {
150 use super::*;
151 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
152 #[argh(subcommand, name = "balloon")]
154 #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
155 pub struct BalloonArgs {
156 #[argh(subcommand)]
157 pub balloon_cmd: BalloonCommands,
158 }
159
160 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
161 #[argh(subcommand)]
162 pub enum BalloonCommands {
163 Set(BalloonSet),
164 Stats(BalloonStats),
165 }
166
167 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
168 #[argh(subcommand, name = "set")]
170 pub struct BalloonSet {
171 #[argh(positional)]
172 pub guest_type: GuestType,
174 #[argh(positional)]
175 pub num_pages: u32,
177 }
178
179 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
180 #[argh(subcommand, name = "stats")]
182 pub struct BalloonStats {
183 #[argh(positional)]
184 pub guest_type: GuestType,
186 }
187}
188
189pub mod list_args {
190 use super::*;
191 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
192 #[argh(subcommand, name = "list")]
194 #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
195 pub struct ListArgs {
196 #[argh(positional)]
197 pub guest_type: Option<GuestType>,
199 }
200}
201
202pub mod socat_args {
203 use super::*;
204 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
205 #[argh(subcommand, name = "socat")]
207 #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
208 pub struct SocatArgs {
209 #[argh(subcommand)]
210 pub socat_cmd: SocatCommands,
211 }
212
213 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
214 #[argh(subcommand)]
215 pub enum SocatCommands {
216 Listen(SocatListen),
217 Connect(SocatConnect),
218 }
219
220 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
221 #[argh(subcommand, name = "connect")]
223 pub struct SocatConnect {
224 #[argh(positional)]
225 pub guest_type: GuestType,
227 #[argh(positional)]
228 pub guest_port: u32,
230 }
231
232 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
233 #[argh(subcommand, name = "listen")]
235 pub struct SocatListen {
236 #[argh(positional)]
237 pub guest_type: GuestType,
239 #[argh(positional)]
240 pub host_port: u32,
242 }
243}
244
245#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
246#[argh(subcommand, name = "vsh")]
248pub struct VshArgs {
249 #[argh(option)]
250 pub port: Option<u32>,
252 #[argh(switch, short = 'c')]
253 pub container: bool,
255 #[argh(positional)]
256 pub args: Vec<String>,
258}
259
260pub mod wipe_args {
261 use super::*;
262 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
263 #[argh(subcommand, name = "wipe")]
265 #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
266 pub struct WipeArgs {
267 #[argh(positional)]
268 pub guest_type: GuestType,
270 }
271}
272
273pub mod vsockperf_args {
274 use super::*;
275 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
276 #[argh(subcommand, name = "vsock-perf")]
278 #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
279 pub struct VsockPerfArgs {
280 #[argh(positional)]
281 pub guest_type: GuestType,
283 }
284}
285
286pub mod launch_args {
287 use super::*;
288 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
289 #[argh(subcommand, name = "launch")]
291 #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
292 pub struct LaunchArgs {
293 #[argh(positional)]
294 pub guest_type: GuestType,
296 #[argh(option)]
298 pub cmdline_add: Vec<String>,
299 #[argh(option)]
301 pub default_net: Option<bool>,
302 #[argh(option)]
304 pub memory: Option<u64>,
305 #[argh(option)]
307 pub cpus: Option<u8>,
308 #[argh(option)]
310 pub virtio_balloon: Option<bool>,
311 #[argh(option)]
313 pub virtio_console: Option<bool>,
314 #[argh(option)]
316 pub virtio_gpu: Option<bool>,
317 #[argh(option)]
319 pub virtio_rng: Option<bool>,
320 #[argh(option)]
322 pub virtio_sound: Option<bool>,
323 #[argh(option)]
325 pub virtio_sound_input: Option<bool>,
326 #[argh(option)]
328 pub virtio_vsock: Option<bool>,
329 #[argh(option)]
331 pub virtio_mem: Option<bool>,
332 #[argh(option)]
334 pub virtio_mem_region_size: Option<u64>,
335 #[argh(option)]
337 pub virtio_mem_region_alignment: Option<u64>,
338 #[argh(option)]
340 pub virtio_mem_block_size: Option<u64>,
341 #[argh(switch, short = 'd')]
343 pub detach: bool,
344 }
345}
346
347pub mod stop_args {
348 use super::*;
349 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
350 #[argh(subcommand, name = "stop")]
352 #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
353 pub struct StopArgs {
354 #[argh(positional)]
356 pub guest_type: GuestType,
357 #[argh(switch, short = 'f')]
359 pub force: bool,
360 }
361}
362
363pub mod attach_args {
364 use super::*;
365 #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
366 #[argh(subcommand, name = "attach")]
368 #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
369 pub struct AttachArgs {
370 #[argh(positional)]
372 pub guest_type: GuestType,
373 #[argh(switch)]
375 pub serial: bool,
376 }
377}