cubic 0.17.0

Cubic is a lightweight command line manager for virtual machines. It has a simple, daemon-less and rootless design. All Cubic virtual machines run isolated in the user context. Cubic is built on top of QEMU, KVM and cloud-init. Show all supported images: $ cubic images Create a new virtual machine instance: $ cubic create mymachine --image ubuntu:noble List all virtual machine instances: $ cubic instances Start an instance: $ cubic start <instance name> Stop an instance: $ cubic stop <instance name> Open a shell in the instance: $ cubic ssh <machine name> Copy a file from the host to the instance: $ cubic scp <path/to/host/file> <machine>:<path/to/guest/file> Copy a file from the instance to the hots: $ cubic scp <machine>:<path/to/guest/file> <path/to/host/file>
use crate::commands::{
    self, Command, InstanceCloneCommand, InstanceModifyCommand, InstanceRenameCommand,
};
use crate::env::EnvironmentFactory;
use crate::error::Error;
use crate::image::ImageDao;
use crate::instance::InstanceDao;
use crate::view::Console;
use clap::{Parser, Subcommand};

#[derive(Subcommand)]
pub enum Commands {
    Run(commands::InstanceRunCommand),
    #[clap(alias = "add")]
    Create(commands::CreateInstanceCommand),
    #[clap(alias = "ls", alias = "list")]
    Instances(commands::ListInstanceCommand),
    Images(commands::ListImageCommand),
    Ports(commands::ListPortCommand),
    #[clap(alias = "info")]
    Show(commands::ShowCommand),
    #[clap(alias = "config")]
    Modify(InstanceModifyCommand),
    Console(commands::InstanceConsoleCommand),
    Ssh(commands::InstanceSshCommand),
    Scp(commands::InstanceScpCommand),
    Start(commands::InstanceStartCommand),
    Stop(commands::InstanceStopCommand),
    Restart(commands::InstanceRestartCommand),
    Rename(InstanceRenameCommand),
    Clone(InstanceCloneCommand),
    #[clap(alias = "rm", alias = "del")]
    Delete(commands::DeleteInstanceCommand),
    Prune(commands::PruneCommand),

    /// Image subcommands (Deprecated)
    #[command(subcommand, hide = true)]
    Image(commands::ImageCommands),
    /// Network subcommands (Deprecated)
    #[command(subcommand, hide = true)]
    Net(commands::NetworkCommands),
}

#[derive(Parser, Default)]
pub struct GlobalOptions {
    /// Increase logging output
    #[clap(short, long, action, global = true)]
    verbose: bool,
    /// Reduce logging output
    #[clap(short, long, action, global = true)]
    quiet: bool,
}

#[derive(Parser)]
#[command(author, version, about, long_about = None, arg_required_else_help = true)]
pub struct CommandDispatcher {
    #[command(subcommand)]
    pub command: Commands,

    #[clap(flatten)]
    global: GlobalOptions,
}

impl CommandDispatcher {
    pub fn dispatch(self, console: &mut dyn Console) -> Result<(), Error> {
        console.set_verbosity(commands::Verbosity::new(
            self.global.verbose,
            self.global.quiet,
        ));
        let env = EnvironmentFactory::create_env()?;
        let image_dao = ImageDao::new(&env)?;
        let instance_dao = InstanceDao::new(&env)?;

        match &self.command {
            Commands::Run(cmd) => cmd as &dyn Command,
            Commands::Instances(cmd) => cmd,
            Commands::Images(cmd) => cmd,
            Commands::Ports(cmd) => cmd,
            Commands::Create(cmd) => cmd,
            Commands::Modify(cmd) => cmd,
            Commands::Clone(cmd) => cmd,
            Commands::Rename(cmd) => cmd,
            Commands::Show(cmd) => cmd,
            Commands::Start(cmd) => cmd,
            Commands::Stop(cmd) => cmd,
            Commands::Restart(cmd) => cmd,
            Commands::Console(cmd) => cmd,
            Commands::Ssh(cmd) => cmd,
            Commands::Scp(cmd) => cmd,
            Commands::Delete(cmd) => cmd,
            Commands::Image(cmd) => cmd,
            Commands::Prune(cmd) => cmd,
            Commands::Net(cmd) => cmd,
        }
        .run(console, &env, &image_dao, &instance_dao)
    }
}