use crate::actions::CreateInstanceAction;
use crate::commands::{
Command,
image::{fetch_image, fetch_image_info},
};
use crate::env::Environment;
use crate::error::Error;
use crate::fs::FS;
use crate::image::{ImageName, ImageStore};
use crate::instance::{Instance, InstanceName, InstanceStore, PortForward};
use crate::model::DataSize;
use crate::ssh_cmd::PortChecker;
use crate::view::Console;
use crate::view::SpinnerView;
use clap::Parser;
pub const DEFAULT_CPU_COUNT: u16 = 4;
pub const DEFAULT_MEM_SIZE: &str = "4G";
pub const DEFAULT_DISK_SIZE: &str = "100G";
#[derive(Parser)]
pub struct CreateInstanceCommand {
pub instance_name: InstanceName,
#[clap(short, long)]
image: ImageName,
#[clap(short, long, default_value = "cubic")]
user: String,
#[clap(short, long, default_value_t = DEFAULT_CPU_COUNT)]
cpus: u16,
#[clap(short, long, default_value = DEFAULT_MEM_SIZE)]
mem: DataSize,
#[clap(short, long, default_value = DEFAULT_DISK_SIZE)]
disk: DataSize,
#[clap(short, long)]
port: Vec<PortForward>,
}
impl Command for CreateInstanceCommand {
fn run(
&self,
_console: &mut dyn Console,
env: &Environment,
image_store: &dyn ImageStore,
instance_store: &dyn InstanceStore,
) -> Result<(), Error> {
if instance_store.exists(self.instance_name.as_str()) {
return Result::Err(Error::InstanceAlreadyExists(self.instance_name.to_string()));
}
let image = &fetch_image_info(env, &self.image)?;
fetch_image(env, image_store, image)?;
let mut create_spinner = SpinnerView::new("Creating virtual machine instance".to_string());
let instance = Instance {
name: self.instance_name.to_string(),
arch: image.arch,
user: self.user.to_string(),
cpus: self.cpus,
mem: self.mem.clone(),
disk_capacity: self.disk.clone(),
ssh_port: PortChecker::new().get_new_port(),
hostfwd: self.port.clone(),
..Instance::default()
};
CreateInstanceAction::new().run(env, &FS::new(), instance_store, image, instance)?;
create_spinner.stop();
Result::Ok(())
}
}