use argh::{ArgsInfo, FromArgValue, FromArgs};
use std::fmt;
#[cfg(not(target_os = "fuchsia"))]
use ffx_core::ffx_command;
#[derive(Copy, Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub enum GuestType {
Debian,
Termina,
Zircon,
}
impl FromArgValue for GuestType {
fn from_arg_value(value: &str) -> Result<Self, String> {
match value {
"debian" => Ok(Self::Debian),
"termina" => Ok(Self::Termina),
"zircon" => Ok(Self::Zircon),
_ => Err(format!(
"Unrecognized guest type \"{}\". Supported guest types are: \
\"debian\", \"termina\", \"zircon\".",
value
)),
}
}
}
impl fmt::Display for GuestType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
GuestType::Debian => write!(f, "debian"),
GuestType::Termina => write!(f, "termina"),
GuestType::Zircon => write!(f, "zircon"),
}
}
}
impl GuestType {
pub fn moniker(&self) -> &str {
match self {
GuestType::Debian => "/core/debian-guest-manager",
GuestType::Termina => "/core/termina-guest-manager",
GuestType::Zircon => "/core/zircon-guest-manager",
}
}
pub fn guest_manager_interface(&self) -> &str {
match *self {
GuestType::Zircon => "fuchsia.virtualization.ZirconGuestManager",
GuestType::Debian => "fuchsia.virtualization.DebianGuestManager",
GuestType::Termina => "fuchsia.virtualization.TerminaGuestManager",
}
}
pub fn gn_target_label(self) -> &'static str {
match self {
GuestType::Zircon => "//src/virtualization/bundles:zircon",
GuestType::Debian => "//src/virtualization/bundles:debian",
GuestType::Termina => "//src/virtualization/bundles:termina",
}
}
pub fn gn_core_shard_label(&self) -> &'static str {
match self {
GuestType::Zircon => "//src/virtualization/bundles:zircon_core_shards",
GuestType::Debian => "//src/virtualization/bundles:debian_core_shards",
GuestType::Termina => "//src/virtualization/bundles:termina_core_shards",
}
}
pub fn package_url(&self) -> &'static str {
match self {
GuestType::Zircon => "fuchsia-pkg://fuchsia.com/zircon_guest#meta/zircon_guest.cm",
GuestType::Debian => "fuchsia-pkg://fuchsia.com/debian_guest#meta/debian_guest.cm",
GuestType::Termina => "fuchsia-pkg://fuchsia.com/termina_guest#meta/termina_guest.cm",
}
}
pub fn all_guests() -> Vec<GuestType> {
vec![GuestType::Debian, GuestType::Termina, GuestType::Zircon]
}
}
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
pub struct GuestOptions {
#[argh(subcommand)]
pub nested: SubCommands,
}
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
pub enum SubCommands {
Attach(crate::attach_args::AttachArgs),
Launch(crate::launch_args::LaunchArgs),
Stop(crate::stop_args::StopArgs),
Balloon(crate::balloon_args::BalloonArgs),
List(crate::list_args::ListArgs),
Socat(crate::socat_args::SocatArgs),
Vsh(VshArgs),
VsockPerf(crate::vsockperf_args::VsockPerfArgs),
Wipe(crate::wipe_args::WipeArgs),
Mem(crate::mem_args::MemArgs),
}
pub mod mem_args {
use super::*;
#[derive(ArgsInfo, FromArgs, Debug, PartialEq)]
#[argh(subcommand, name = "mem")]
#[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
pub struct MemArgs {
#[argh(subcommand)]
pub mem_cmd: MemCommands,
}
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
pub enum MemCommands {
RequestPluggedMem(RequestPluggedMem),
StatsMem(StatsMem),
}
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "request-plugged")]
pub struct RequestPluggedMem {
#[argh(positional)]
pub guest_type: GuestType,
#[argh(positional)]
pub size: u64,
}
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "stats")]
pub struct StatsMem {
#[argh(positional)]
pub guest_type: GuestType,
}
}
pub mod balloon_args {
use super::*;
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "balloon")]
#[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
pub struct BalloonArgs {
#[argh(subcommand)]
pub balloon_cmd: BalloonCommands,
}
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
pub enum BalloonCommands {
Set(BalloonSet),
Stats(BalloonStats),
}
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "set")]
pub struct BalloonSet {
#[argh(positional)]
pub guest_type: GuestType,
#[argh(positional)]
pub num_pages: u32,
}
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "stats")]
pub struct BalloonStats {
#[argh(positional)]
pub guest_type: GuestType,
}
}
pub mod list_args {
use super::*;
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "list")]
#[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
pub struct ListArgs {
#[argh(positional)]
pub guest_type: Option<GuestType>,
}
}
pub mod socat_args {
use super::*;
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "socat")]
#[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
pub struct SocatArgs {
#[argh(subcommand)]
pub socat_cmd: SocatCommands,
}
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand)]
pub enum SocatCommands {
Listen(SocatListen),
Connect(SocatConnect),
}
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "connect")]
pub struct SocatConnect {
#[argh(positional)]
pub guest_type: GuestType,
#[argh(positional)]
pub guest_port: u32,
}
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "listen")]
pub struct SocatListen {
#[argh(positional)]
pub guest_type: GuestType,
#[argh(positional)]
pub host_port: u32,
}
}
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "vsh")]
pub struct VshArgs {
#[argh(option)]
pub port: Option<u32>,
#[argh(switch, short = 'c')]
pub container: bool,
#[argh(positional)]
pub args: Vec<String>,
}
pub mod wipe_args {
use super::*;
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "wipe")]
#[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
pub struct WipeArgs {
#[argh(positional)]
pub guest_type: GuestType,
}
}
pub mod vsockperf_args {
use super::*;
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "vsock-perf")]
#[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
pub struct VsockPerfArgs {
#[argh(positional)]
pub guest_type: GuestType,
}
}
pub mod launch_args {
use super::*;
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "launch")]
#[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
pub struct LaunchArgs {
#[argh(positional)]
pub guest_type: GuestType,
#[argh(option)]
pub cmdline_add: Vec<String>,
#[argh(option)]
pub default_net: Option<bool>,
#[argh(option)]
pub memory: Option<u64>,
#[argh(option)]
pub cpus: Option<u8>,
#[argh(option)]
pub virtio_balloon: Option<bool>,
#[argh(option)]
pub virtio_console: Option<bool>,
#[argh(option)]
pub virtio_gpu: Option<bool>,
#[argh(option)]
pub virtio_rng: Option<bool>,
#[argh(option)]
pub virtio_sound: Option<bool>,
#[argh(option)]
pub virtio_sound_input: Option<bool>,
#[argh(option)]
pub virtio_vsock: Option<bool>,
#[argh(option)]
pub virtio_mem: Option<bool>,
#[argh(option)]
pub virtio_mem_region_size: Option<u64>,
#[argh(option)]
pub virtio_mem_region_alignment: Option<u64>,
#[argh(option)]
pub virtio_mem_block_size: Option<u64>,
#[argh(switch, short = 'd')]
pub detach: bool,
}
}
pub mod stop_args {
use super::*;
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "stop")]
#[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
pub struct StopArgs {
#[argh(positional)]
pub guest_type: GuestType,
#[argh(switch, short = 'f')]
pub force: bool,
}
}
pub mod attach_args {
use super::*;
#[derive(ArgsInfo, FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "attach")]
#[cfg_attr(not(target_os = "fuchsia"), ffx_command())]
pub struct AttachArgs {
#[argh(positional)]
pub guest_type: GuestType,
#[argh(switch)]
pub serial: bool,
}
}