diff options
Diffstat (limited to 'src/cmd/new.rs')
-rw-r--r-- | src/cmd/new.rs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/cmd/new.rs b/src/cmd/new.rs new file mode 100644 index 0000000..9930379 --- /dev/null +++ b/src/cmd/new.rs @@ -0,0 +1,47 @@ +use crate::cloudinit::CloudInitConfig; +use crate::image::VirtualMachineImage; +use crate::install::{virt_install, VirtInstallArgs}; +use crate::spec::Specification; + +use bytesize::GIB; +use log::info; +use std::net::TcpStream; + +const SSH_PORT: i32 = 22; + +pub fn new(spec: &Specification) -> anyhow::Result<()> { + info!("creating new VM {}", spec.name); + + info!("creating cloud-init config"); + let init = CloudInitConfig::from(&spec)?; + + info!( + "creating VM image {} from {}", + spec.image.display(), + spec.base.display() + ); + let image = VirtualMachineImage::new_from_base(&spec.base, &spec.image)?; + + info!("resizing image to {} GiB", spec.image_size_gib); + image.resize(spec.image_size_gib * GIB)?; + + info!("creating VM"); + let mut args = VirtInstallArgs::new(&spec.name, &image, &init); + args.set_memory(spec.memory_mib); + args.set_vcpus(spec.cpus); + virt_install(&args)?; + + info!("waiting for {} to open its SSH port", spec.name); + wait_for_port(&spec.name, SSH_PORT)?; + + Ok(()) +} + +fn wait_for_port(name: &str, port: i32) -> anyhow::Result<()> { + let addr = format!("{}:{}", name, port); + loop { + if TcpStream::connect(&addr).is_ok() { + return Ok(()); + } + } +} |