Skip to main content

guest_cli_args/
lib.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use 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    Zircon,
15}
16
17impl FromArgValue for GuestType {
18    fn from_arg_value(value: &str) -> Result<Self, String> {
19        match value {
20            "debian" => Ok(Self::Debian),
21            "zircon" => Ok(Self::Zircon),
22            _ => Err(format!(
23                "Unrecognized guest type \"{}\". Supported guest types are: \
24                \"debian\", \"zircon\".",
25                value
26            )),
27        }
28    }
29}
30
31impl fmt::Display for GuestType {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        match *self {
34            GuestType::Debian => write!(f, "debian"),
35            GuestType::Zircon => write!(f, "zircon"),
36        }
37    }
38}
39
40impl GuestType {
41    pub fn moniker(&self) -> &str {
42        match self {
43            GuestType::Debian => "/core/debian-guest-manager",
44            GuestType::Zircon => "/core/zircon-guest-manager",
45        }
46    }
47
48    pub fn guest_manager_interface(&self) -> &str {
49        match *self {
50            GuestType::Zircon => "fuchsia.virtualization.ZirconGuestManager",
51            GuestType::Debian => "fuchsia.virtualization.DebianGuestManager",
52        }
53    }
54
55    pub fn gn_target_label(self) -> &'static str {
56        match self {
57            GuestType::Zircon => "//src/virtualization/bundles:zircon",
58            GuestType::Debian => "//src/virtualization/bundles:debian",
59        }
60    }
61
62    pub fn gn_core_shard_label(&self) -> &'static str {
63        match self {
64            GuestType::Zircon => "//src/virtualization/bundles:zircon_core_shards",
65            GuestType::Debian => "//src/virtualization/bundles:debian_core_shards",
66        }
67    }
68
69    pub fn package_url(&self) -> &'static str {
70        match self {
71            GuestType::Zircon => "fuchsia-pkg://fuchsia.com/zircon_guest#meta/zircon_guest.cm",
72            GuestType::Debian => "fuchsia-pkg://fuchsia.com/debian_guest#meta/debian_guest.cm",
73        }
74    }
75
76    pub fn all_guests() -> Vec<GuestType> {
77        vec![GuestType::Debian, GuestType::Zircon]
78    }
79}
80
81#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
82/// Top-level command.
83pub struct GuestOptions {
84    #[argh(subcommand)]
85    pub nested: SubCommands,
86}
87
88#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
89#[argh(subcommand)]
90pub enum SubCommands {
91    Attach(crate::attach_args::AttachArgs),
92    Launch(crate::launch_args::LaunchArgs),
93    Stop(crate::stop_args::StopArgs),
94    Balloon(crate::balloon_args::BalloonArgs),
95    List(crate::list_args::ListArgs),
96    Socat(crate::socat_args::SocatArgs),
97    VsockPerf(crate::vsockperf_args::VsockPerfArgs),
98    Mem(crate::mem_args::MemArgs),
99}
100
101pub mod mem_args {
102    use super::*;
103    /// Interact with the guest virtio-mem. Usage: guest mem sub-command [ request-plugged or stats]
104    #[derive(ArgsInfo, FromArgs, Debug, PartialEq)]
105    #[argh(subcommand, name = "mem")]
106    #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
107    pub struct MemArgs {
108        #[argh(subcommand)]
109        pub mem_cmd: MemCommands,
110    }
111    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
112    #[argh(subcommand)]
113    pub enum MemCommands {
114        RequestPluggedMem(RequestPluggedMem),
115        StatsMem(StatsMem),
116    }
117
118    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
119    /// Modify the requested amount of the dynamically plugged memory. Usage: guest mem request-plugged guest-type size
120    #[argh(subcommand, name = "request-plugged")]
121    pub struct RequestPluggedMem {
122        #[argh(positional)]
123        /// type of the guest
124        pub guest_type: GuestType,
125        #[argh(positional)]
126        /// target amount of memory to be dynamically plugged
127        pub size: u64,
128    }
129    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
130    /// See the stats of a guest's virtio-mem. Usage: guest mem stats guest-type
131    #[argh(subcommand, name = "stats")]
132    pub struct StatsMem {
133        #[argh(positional)]
134        /// type of the guest
135        pub guest_type: GuestType,
136    }
137}
138
139pub mod balloon_args {
140    use super::*;
141    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
142    /// Interact with the guest memory balloon. Usage: guest balloon sub-command guest-type ...
143    #[argh(subcommand, name = "balloon")]
144    #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
145    pub struct BalloonArgs {
146        #[argh(subcommand)]
147        pub balloon_cmd: BalloonCommands,
148    }
149
150    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
151    #[argh(subcommand)]
152    pub enum BalloonCommands {
153        Set(BalloonSet),
154        Stats(BalloonStats),
155    }
156
157    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
158    /// Modify the size of a memory balloon. Usage: guest balloon set guest-type num-pages
159    #[argh(subcommand, name = "set")]
160    pub struct BalloonSet {
161        #[argh(positional)]
162        /// type of the guest
163        pub guest_type: GuestType,
164        #[argh(positional)]
165        /// number of pages guest balloon will have after use.
166        pub num_pages: u32,
167    }
168
169    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
170    /// See the stats of a guest's memory balloon. Usage: guest balloon stats guest-type
171    #[argh(subcommand, name = "stats")]
172    pub struct BalloonStats {
173        #[argh(positional)]
174        /// type of the guest
175        pub guest_type: GuestType,
176    }
177}
178
179pub mod list_args {
180    use super::*;
181    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
182    /// List available guest environments.
183    #[argh(subcommand, name = "list")]
184    #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
185    pub struct ListArgs {
186        #[argh(positional)]
187        /// optional guest type to get detailed information about
188        pub guest_type: Option<GuestType>,
189    }
190}
191
192pub mod socat_args {
193    use super::*;
194    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
195    /// Interact with the guest via socat. See the sub-command help for details.
196    #[argh(subcommand, name = "socat")]
197    #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
198    pub struct SocatArgs {
199        #[argh(subcommand)]
200        pub socat_cmd: SocatCommands,
201    }
202
203    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
204    #[argh(subcommand)]
205    pub enum SocatCommands {
206        Listen(SocatListen),
207        Connect(SocatConnect),
208    }
209
210    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
211    /// Create a socat connection on the specified port. Usage: guest socat connect guest-type port
212    #[argh(subcommand, name = "connect")]
213    pub struct SocatConnect {
214        #[argh(positional)]
215        /// type of the guest
216        pub guest_type: GuestType,
217        #[argh(positional)]
218        /// guest port number to attempt to connect to
219        pub guest_port: u32,
220    }
221
222    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
223    /// Listen through socat on the specified port. Usage: guest socat listen guest-type host-port
224    #[argh(subcommand, name = "listen")]
225    pub struct SocatListen {
226        #[argh(positional)]
227        /// type of the guest
228        pub guest_type: GuestType,
229        #[argh(positional)]
230        /// host port number to accept incoming guest connections on
231        pub host_port: u32,
232    }
233}
234
235pub mod vsockperf_args {
236    use super::*;
237    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
238    /// Perform a vsock micro benchmark on the target guest. Only Debian is supported.
239    #[argh(subcommand, name = "vsock-perf")]
240    #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
241    pub struct VsockPerfArgs {
242        #[argh(positional)]
243        /// type of the guest
244        pub guest_type: GuestType,
245    }
246}
247
248pub mod launch_args {
249    use super::*;
250    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
251    /// Launch a guest image. Usage: guest launch guest_type [--cmdline-add <arg>...] [--default-net <bool>] [--memory <memory-size>] [--cpus <num-cpus>] [--virtio-* <bool>]
252    #[argh(subcommand, name = "launch")]
253    #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
254    pub struct LaunchArgs {
255        #[argh(positional)]
256        /// guest type to launch e.g. 'zircon'.
257        pub guest_type: GuestType,
258        /// adds provided strings to the existing kernel command line
259        #[argh(option)]
260        pub cmdline_add: Vec<String>,
261        /// enable a default net device
262        #[argh(option)]
263        pub default_net: Option<bool>,
264        /// allocate 'bytes' of memory for the guest
265        #[argh(option)]
266        pub memory: Option<u64>,
267        /// number of virtual cpus available for the guest
268        #[argh(option)]
269        pub cpus: Option<u8>,
270        /// enable virtio-balloon
271        #[argh(option)]
272        pub virtio_balloon: Option<bool>,
273        /// enable virtio-console
274        #[argh(option)]
275        pub virtio_console: Option<bool>,
276        /// enable virtio-gpu and virtio-input
277        #[argh(option)]
278        pub virtio_gpu: Option<bool>,
279        /// enable virtio-rng
280        #[argh(option)]
281        pub virtio_rng: Option<bool>,
282        /// enable virtio-sound
283        #[argh(option)]
284        pub virtio_sound: Option<bool>,
285        /// enable virtio-sound-input
286        #[argh(option)]
287        pub virtio_sound_input: Option<bool>,
288        /// enable virtio-vsock
289        #[argh(option)]
290        pub virtio_vsock: Option<bool>,
291        /// enable virtio-mem to allow dynamically (un)plug memory to the guest
292        #[argh(option)]
293        pub virtio_mem: Option<bool>,
294        /// virtio-mem pluggable region size
295        #[argh(option)]
296        pub virtio_mem_region_size: Option<u64>,
297        /// virtio-mem pluggable region alignment
298        #[argh(option)]
299        pub virtio_mem_region_alignment: Option<u64>,
300        /// virtio-mem pluggable blocksize
301        #[argh(option)]
302        pub virtio_mem_block_size: Option<u64>,
303        /// detach from a guest allowing it to run in the background
304        #[argh(switch, short = 'd')]
305        pub detach: bool,
306    }
307}
308
309pub mod stop_args {
310    use super::*;
311    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
312    /// Stop a running guest. Usage: guest stop guest_type [-f]
313    #[argh(subcommand, name = "stop")]
314    #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
315    pub struct StopArgs {
316        /// guest type to stop e.g. 'zircon'
317        #[argh(positional)]
318        pub guest_type: GuestType,
319        /// force stop the guest
320        #[argh(switch, short = 'f')]
321        pub force: bool,
322    }
323}
324
325pub mod attach_args {
326    use super::*;
327    #[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
328    /// Attach console and serial to a running guest. Usage: guest attach guest_type
329    #[argh(subcommand, name = "attach")]
330    #[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
331    pub struct AttachArgs {
332        /// guest type to attach to e.g. 'debian'
333        #[argh(positional)]
334        pub guest_type: GuestType,
335        /// attach via serial instead of virtio-console
336        #[argh(switch)]
337        pub serial: bool,
338    }
339}