From 004cc13999fe4cae36ae3fe3b63ce55e1d54708b Mon Sep 17 00:00:00 2001 From: Matej Hrica Date: Wed, 8 Nov 2023 11:42:06 +0100 Subject: [PATCH] Add support for starting VMs with passt network This required adding another field to the config. This is done by migrating the old config to a newer version. We are backwards compatible on configuration but not forwards compatible (older versions of krunvm will not be able to use the config from this version) If we want forward compatibility, I feel like we need to ditch the confy crate. Signed-off-by: Matej Hrica --- Cargo.lock | 58 +++++++++++++++- Cargo.toml | 1 + src/bindings.rs | 1 + src/commands/changevm.rs | 14 +++- src/commands/config.rs | 17 ++++- src/commands/create.rs | 12 +++- src/commands/delete.rs | 5 +- src/commands/list.rs | 3 +- src/commands/start.rs | 97 +++++++++++++++++++++++++-- src/config/migrate.rs | 138 +++++++++++++++++++++++++++++++++++++++ src/config/mod.rs | 20 ++++++ src/config/v1.rs | 37 +++++++++++ src/config/v2.rs | 98 +++++++++++++++++++++++++++ src/main.rs | 42 ++---------- src/utils.rs | 3 +- 15 files changed, 488 insertions(+), 58 deletions(-) create mode 100644 src/config/migrate.rs create mode 100644 src/config/mod.rs create mode 100644 src/config/v1.rs create mode 100644 src/config/v2.rs diff --git a/Cargo.lock b/Cargo.lock index 8933ac6..50ff01a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,7 +206,18 @@ checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -223,6 +234,7 @@ dependencies = [ "confy", "libc", "nix", + "rand", "serde", "serde_derive", "text_io", @@ -261,6 +273,12 @@ dependencies = [ "memoffset", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro2" version = "1.0.69" @@ -279,6 +297,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.10", +] + [[package]] name = "redox_syscall" version = "0.1.57" @@ -291,7 +339,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" dependencies = [ - "getrandom", + "getrandom 0.1.16", "redox_syscall", "rust-argon2", ] @@ -392,6 +440,12 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index dec77b6..0ec5d84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,4 @@ serde = "1.0.120" serde_derive = "1.0.120" text_io = "0.1.8" nix = {version = "0.27.1", features = ["socket", "fs"]} +rand="0.8.5" diff --git a/src/bindings.rs b/src/bindings.rs index 41dc52c..b8676e3 100644 --- a/src/bindings.rs +++ b/src/bindings.rs @@ -13,6 +13,7 @@ extern "C" { pub fn krun_set_mapped_volumes(ctx: u32, mapped_volumes: *const *const c_char) -> i32; pub fn krun_set_port_map(ctx: u32, port_map: *const *const c_char) -> i32; pub fn krun_set_workdir(ctx: u32, workdir_path: *const c_char) -> i32; + pub fn krun_set_passt_fd(ctx: u32, fd: c_int) -> i32; pub fn krun_set_exec( ctx: u32, exec_path: *const c_char, diff --git a/src/commands/changevm.rs b/src/commands/changevm.rs index 5cd365b..25d4880 100644 --- a/src/commands/changevm.rs +++ b/src/commands/changevm.rs @@ -4,12 +4,12 @@ use clap::Args; use std::collections::HashMap; +use crate::config::{KrunvmConfig, NetworkMode}; use crate::utils::{path_pairs_to_hash_map, port_pairs_to_hash_map, PathPair, PortPair}; -use crate::{KrunvmConfig, APP_NAME}; use super::list::printvm; -/// Change the configuration of a microVM +/// Change the config of a microVM #[derive(Args, Debug)] pub struct ChangeVmCmd { /// Name of the VM to be modified @@ -46,6 +46,9 @@ pub struct ChangeVmCmd { /// Port(s) in format "host_port:guest_port" to be exposed to the host #[arg(long = "port")] ports: Vec, + + #[arg(long)] + network_mode: Option, } impl ChangeVmCmd { @@ -130,12 +133,17 @@ impl ChangeVmCmd { cfg_changed = true; } + if let Some(network_mode) = self.network_mode { + vmcfg.network_mode = network_mode; + cfg_changed = true; + } + println!(); printvm(vmcfg); println!(); if cfg_changed { - confy::store(APP_NAME, &cfg).unwrap(); + crate::config::save(cfg).unwrap(); } } } diff --git a/src/commands/config.rs b/src/commands/config.rs index ab09d34..eabea49 100644 --- a/src/commands/config.rs +++ b/src/commands/config.rs @@ -1,7 +1,7 @@ // Copyright 2021 Red Hat, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::{KrunvmConfig, APP_NAME}; +use crate::config::{KrunvmConfig, NetworkMode}; use clap::Args; /// Configure global values @@ -18,6 +18,10 @@ pub struct ConfigCmd { /// DNS server to use in the microVM #[arg(long)] dns: Option, + + /// Default network mode to use + #[arg(long)] + network_mode: Option, } impl ConfigCmd { @@ -47,11 +51,18 @@ impl ConfigCmd { cfg_changed = true; } + if let Some(network_mode) = self.network_mode { + if network_mode != cfg.default_network_mode { + cfg.default_network_mode = network_mode; + cfg_changed = true; + } + } + if cfg_changed { - confy::store(APP_NAME, &cfg).unwrap(); + crate::config::save(cfg).unwrap(); } - println!("Global configuration:"); + println!("Global config:"); println!( "Default number of CPUs for newly created VMs: {}", cfg.default_cpus diff --git a/src/commands/create.rs b/src/commands/create.rs index 4040983..7ad04aa 100644 --- a/src/commands/create.rs +++ b/src/commands/create.rs @@ -1,6 +1,8 @@ // Copyright 2021 Red Hat, Inc. // SPDX-License-Identifier: Apache-2.0 +use crate::config::{KrunvmConfig, NetworkMode, VmConfig}; +use crate::APP_NAME; use clap::Args; use std::fs; use std::io::Write; @@ -12,8 +14,6 @@ use crate::utils::{ get_buildah_args, mount_container, path_pairs_to_hash_map, port_pairs_to_hash_map, umount_container, BuildahCommand, PathPair, PortPair, }; -use crate::{KrunvmConfig, VmConfig, APP_NAME}; - #[cfg(target_os = "macos")] const KRUNVM_ROSETTA_FILE: &str = ".krunvm-rosetta"; @@ -51,6 +51,10 @@ pub struct CreateCmd { #[arg(long = "port")] ports: Vec, + /// Network mode to use + #[arg(long)] + network_mode: Option, + /// Create a x86_64 microVM even on an Aarch64 host #[arg(short, long)] #[cfg(target_os = "macos")] @@ -68,6 +72,9 @@ impl CreateCmd { let mapped_ports = port_pairs_to_hash_map(self.ports); let image = self.image; let name = self.name; + let network_mode = self + .network_mode + .unwrap_or_else(|| cfg.default_network_mode.clone()); if let Some(ref name) = name { if cfg.vmconfig_map.contains_key(name) { @@ -160,6 +167,7 @@ https://threedots.ovh/blog/2022/06/quick-look-at-rosetta-on-linux/ workdir: workdir.to_string(), mapped_volumes, mapped_ports, + network_mode, }; let rootfs = mount_container(cfg, &vmcfg).unwrap(); diff --git a/src/commands/delete.rs b/src/commands/delete.rs index 2f4c54a..d027a92 100644 --- a/src/commands/delete.rs +++ b/src/commands/delete.rs @@ -1,7 +1,8 @@ // Copyright 2021 Red Hat, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::{KrunvmConfig, APP_NAME}; +use crate::config; +use crate::config::KrunvmConfig; use clap::Args; use crate::utils::{remove_container, umount_container}; @@ -26,6 +27,6 @@ impl DeleteCmd { umount_container(cfg, &vmcfg).unwrap(); remove_container(cfg, &vmcfg).unwrap(); - confy::store(APP_NAME, &cfg).unwrap(); + config::save(cfg).unwrap() } } diff --git a/src/commands/list.rs b/src/commands/list.rs index 791943c..7ca03cf 100644 --- a/src/commands/list.rs +++ b/src/commands/list.rs @@ -1,7 +1,7 @@ // Copyright 2021 Red Hat, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::{KrunvmConfig, VmConfig}; +use crate::config::{KrunvmConfig, VmConfig}; use clap::Args; /// List microVMs @@ -33,6 +33,7 @@ pub fn printvm(vm: &VmConfig) { println!(" DNS server: {}", vm.dns); println!(" Buildah container: {}", vm.container); println!(" Workdir: {}", vm.workdir); + println!(" Network mode: {:?}", vm.network_mode); println!(" Mapped volumes: {:?}", vm.mapped_volumes); println!(" Mapped ports: {:?}", vm.mapped_ports); } diff --git a/src/commands/start.rs b/src/commands/start.rs index 2d67423..c441a43 100644 --- a/src/commands/start.rs +++ b/src/commands/start.rs @@ -2,18 +2,31 @@ // SPDX-License-Identifier: Apache-2.0 use clap::Args; -use libc::c_char; +use libc::{c_char, c_int}; +use nix::errno::Errno; +use nix::sys::socket::{connect, socket, AddressFamily, SockFlag, SockType, UnixAddr}; +use nix::unistd::unlink; +use rand::distributions::{Alphanumeric, DistString}; use std::ffi::CString; + use std::fs::File; +use std::io::{stderr, Write}; #[cfg(target_os = "linux")] use std::io::{Error, ErrorKind}; + +use std::os::fd::OwnedFd; use std::os::unix::io::AsRawFd; + #[cfg(target_os = "macos")] use std::path::Path; +use std::thread; +use std::time::Duration; + use crate::bindings; +use crate::bindings::krun_set_passt_fd; +use crate::config::{KrunvmConfig, NetworkMode, VmConfig}; use crate::utils::{mount_container, umount_container}; -use crate::{KrunvmConfig, VmConfig}; #[derive(Args, Debug)] /// Start an existing microVM @@ -36,6 +49,59 @@ pub struct StartCmd { mem: Option, // TODO: implement or remove this } +fn start_passt() -> Result { + let path = format!( + "/tmp/krunvm-passt-{}.socket", + Alphanumeric.sample_string(&mut rand::thread_rng(), 32) + ); + + //TODO: port forwarding + // passt will fork itself and run in the background + match std::process::Command::new("passt") + .arg("--one-off") + .arg("--socket") + .arg(&path) + .output() + { + Ok(output) if output.status.success() => (), + Ok(output) => { + eprintln!("Failed to start passt: {}", output.status); + eprintln!("Passt stderr follows:"); + eprintln!("---"); + stderr().lock().write_all(&output.stderr).unwrap(); + eprintln!("---"); + return Err(()); + } + Err(e) => { + eprintln!("Failed to start passt: {e}"); + return Err(()); + } + } + + let sock_path = UnixAddr::new(path.as_str()).expect("Failed to create UnixAddr"); + let fd = socket( + AddressFamily::Unix, + SockType::Stream, + SockFlag::empty(), + None, + ) + .expect("Failed to create socket fd"); + + loop { + match connect(fd.as_raw_fd(), &sock_path) { + Ok(()) => { + let _ = unlink(path.as_str()); + return Ok(fd); + } + Err(Errno::ECONNREFUSED) => thread::sleep(Duration::from_millis(10)), + Err(e) => { + eprintln!("Failed to connect to passt socket: {e}"); + return Err(()); + } + } + } +} + impl StartCmd { pub fn run(self, cfg: &KrunvmConfig) { let vmcfg = match cfg.vmconfig_map.get(&self.name) { @@ -152,10 +218,29 @@ unsafe fn exec_vm(vmcfg: &VmConfig, rootfs: &str, cmd: Option<&str>, args: Vec { + let ret = bindings::krun_set_port_map(ctx, ps.as_ptr()); + if ret < 0 { + println!("Error setting VM port map"); + std::process::exit(-1); + } + } + NetworkMode::Passt => { + let Ok(passt_fd) = start_passt() else { + std::process::exit(-1); + }; + let ret = krun_set_passt_fd(ctx, passt_fd.as_raw_fd() as c_int); + if ret < 0 { + let errno = Errno::from_i32(-ret); + if errno == Errno::ENOTSUP { + println!("Failed to set passt fd: your libkrun build does not support virtio-net/passt mode."); + } else { + println!("Failed to set passt fd: {}", errno); + } + std::process::exit(-1); + } + } } if !vmcfg.workdir.is_empty() { diff --git a/src/config/migrate.rs b/src/config/migrate.rs new file mode 100644 index 0000000..91a5956 --- /dev/null +++ b/src/config/migrate.rs @@ -0,0 +1,138 @@ +use crate::config::{v1, v2}; +use confy::ConfyError; + +pub fn migrate_and_load_impl( + load_v2: impl FnOnce() -> Result, + load_v1: impl FnOnce() -> Result, + save_v2: impl FnOnce(&v2::KrunvmConfig) -> Result<(), ()>, +) -> Result { + fn check_version(got: u8, expected: u8) -> Result<(), ()> { + if expected != got { + eprintln!( + "Invalid config version number {} expected {}", + got, expected + ); + Err(()) + } else { + Ok(()) + } + } + + let v2_load_err = match load_v2() { + Ok(conf) => { + check_version(conf.version, 2)?; + return Ok(conf); + } + Err(e) => e, + }; + + let v1_load_err = match load_v1() { + Ok(cfg) => { + check_version(cfg.version, 1)?; + let v2_config = cfg.into(); + save_v2(&v2_config)?; + return Ok(v2_config); + } + Err(e) => e, + }; + + eprintln!("Failed to load config: "); + eprintln!("Tried to load as as v2 config, got error: {v2_load_err}"); + eprintln!("Tried to load as as v1 config, got error: {v1_load_err}"); + Err(()) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::config::NetworkMode; + use std::collections::HashMap; + + #[test] + fn load_without_migrate() { + let cfg = v2::KrunvmConfig { + default_dns: "8.8.8.8".into(), + ..v2::KrunvmConfig::default() + }; + + let returned_cfg = migrate_and_load_impl( + || Ok(cfg.clone()), + || panic!("Loading v1 should not be attempted"), + |_| panic!("Migration should not occur"), + ) + .unwrap(); + assert_eq!(returned_cfg, cfg); + } + + #[test] + fn load_migrating_to_v2() { + let v1_vms = [( + "fedora".to_string(), + v1::VmConfig { + name: "fedora".to_string(), + mapped_ports: Default::default(), + cpus: 2, + dns: "1.1.1.1".to_string(), + mapped_volumes: Default::default(), + workdir: "/".to_string(), + container: "fedora".to_string(), + mem: 8192, + }, + )]; + + let v1_cfg = v1::KrunvmConfig { + default_dns: "8.8.8.8".into(), + vmconfig_map: HashMap::from(v1_vms), + ..v1::KrunvmConfig::default() + }; + + let result_v2_vms = [( + "fedora".to_string(), + v2::VmConfig { + name: "fedora".to_string(), + mapped_ports: Default::default(), + cpus: 2, + dns: "1.1.1.1".to_string(), + mapped_volumes: Default::default(), + workdir: "/".to_string(), + container: "fedora".to_string(), + mem: 8192, + network_mode: NetworkMode::Tsi, + }, + )]; + + let result_v2_cfg = v2::KrunvmConfig { + default_dns: "8.8.8.8".into(), + vmconfig_map: HashMap::from(result_v2_vms), + default_network_mode: NetworkMode::Tsi, + ..v2::KrunvmConfig::default() + }; + + let mut load_v2_called = false; + let mut load_v1_called = false; + let mut save_called = false; + + let returned_cfg = migrate_and_load_impl( + || { + load_v2_called = true; + Err(ConfyError::BadConfigDirectoryStr) + }, + || { + load_v1_called = true; + Ok(v1_cfg) + }, + |migrated| { + save_called = true; + assert_eq!(migrated, &result_v2_cfg); + Ok(()) + }, + ) + .unwrap(); + + assert!(save_called, "Save must be called"); + assert!(load_v2_called, "Load v2 must be called"); + assert!(save_called, "Load v1 must be called"); + + assert_eq!(returned_cfg, result_v2_cfg); + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs new file mode 100644 index 0000000..f50873c --- /dev/null +++ b/src/config/mod.rs @@ -0,0 +1,20 @@ +mod migrate; +mod v1; +mod v2; + +use crate::APP_NAME; + +use crate::config::migrate::migrate_and_load_impl; +pub use v2::{KrunvmConfig, NetworkMode, VmConfig}; + +pub fn save(cfg: &KrunvmConfig) -> Result<(), ()> { + confy::store(APP_NAME, cfg).map_err(|e| eprintln!("Failed to load config: {e}")) +} + +pub fn load() -> Result { + migrate_and_load_impl( + || confy::load::(APP_NAME), + || confy::load::(APP_NAME), + save, + ) +} diff --git a/src/config/v1.rs b/src/config/v1.rs new file mode 100644 index 0000000..877f034 --- /dev/null +++ b/src/config/v1.rs @@ -0,0 +1,37 @@ +use serde_derive::{Deserialize, Serialize}; +use std::collections::HashMap; + +#[derive(Debug, Serialize, Deserialize)] +pub struct KrunvmConfig { + pub version: u8, + pub default_cpus: u32, + pub default_mem: u32, + pub default_dns: String, + pub storage_volume: String, + pub vmconfig_map: HashMap, +} + +impl Default for KrunvmConfig { + fn default() -> KrunvmConfig { + KrunvmConfig { + version: 1, + default_cpus: 2, + default_mem: 1024, + default_dns: "1.1.1.1".to_string(), + storage_volume: String::new(), + vmconfig_map: HashMap::new(), + } + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct VmConfig { + pub name: String, + pub cpus: u32, + pub mem: u32, + pub container: String, + pub workdir: String, + pub dns: String, + pub mapped_volumes: HashMap, + pub mapped_ports: HashMap, +} diff --git a/src/config/v2.rs b/src/config/v2.rs new file mode 100644 index 0000000..c48e3d7 --- /dev/null +++ b/src/config/v2.rs @@ -0,0 +1,98 @@ +use crate::config::v1; + +use serde_derive::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::str::FromStr; + +#[derive(Clone, Serialize, Deserialize, Debug, Default, Eq, PartialEq)] +pub enum NetworkMode { + #[default] + Tsi, + Passt, +} + +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] +pub struct KrunvmConfig { + pub version: u8, + pub default_cpus: u32, + pub default_mem: u32, + pub default_dns: String, + pub default_network_mode: NetworkMode, + pub storage_volume: String, + pub vmconfig_map: HashMap, +} + +impl Default for KrunvmConfig { + fn default() -> KrunvmConfig { + KrunvmConfig { + version: 2, + default_cpus: 2, + default_mem: 1024, + default_dns: "1.1.1.1".to_string(), + default_network_mode: NetworkMode::default(), + storage_volume: String::new(), + vmconfig_map: HashMap::new(), + } + } +} + +impl From for KrunvmConfig { + fn from(old: v1::KrunvmConfig) -> Self { + KrunvmConfig { + version: 2, + default_cpus: old.default_cpus, + default_mem: old.default_mem, + default_dns: old.default_dns, + default_network_mode: NetworkMode::default(), + storage_volume: old.storage_volume, + vmconfig_map: old + .vmconfig_map + .into_iter() + .map(|(key, value)| (key, value.into())) + .collect(), + } + } +} + +#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] +pub struct VmConfig { + pub name: String, + pub cpus: u32, + pub mem: u32, + pub container: String, + pub workdir: String, + pub dns: String, + pub network_mode: NetworkMode, + pub mapped_volumes: HashMap, + pub mapped_ports: HashMap, +} + +impl From for VmConfig { + fn from(old: v1::VmConfig) -> Self { + VmConfig { + name: old.name, + cpus: old.cpus, + mem: old.mem, + container: old.container, + workdir: old.workdir, + dns: old.dns, + mapped_volumes: old.mapped_volumes, + mapped_ports: old.mapped_ports, + network_mode: NetworkMode::default(), + } + } +} + +impl FromStr for NetworkMode { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + if s.eq_ignore_ascii_case("tsi") { + Ok(NetworkMode::Tsi) + } else if s.eq_ignore_ascii_case("passt") { + Ok(NetworkMode::Passt) + } else { + Err("Invalid network mode") + } + } +} diff --git a/src/main.rs b/src/main.rs index 0531136..c35d619 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,60 +1,26 @@ // Copyright 2021 Red Hat, Inc. // SPDX-License-Identifier: Apache-2.0 -use std::collections::HashMap; #[cfg(target_os = "macos")] use std::fs::File; #[cfg(target_os = "macos")] use std::io::{self, Read, Write}; use crate::commands::{ChangeVmCmd, ConfigCmd, CreateCmd, DeleteCmd, ListCmd, StartCmd}; +#[cfg(target_os = "macos")] +use crate::config::KrunvmConfig; use clap::{Parser, Subcommand}; -use serde_derive::{Deserialize, Serialize}; #[cfg(target_os = "macos")] use text_io::read; #[allow(unused)] mod bindings; mod commands; +mod config; mod utils; const APP_NAME: &str = "krunvm"; -#[derive(Default, Debug, Serialize, Deserialize)] -pub struct VmConfig { - name: String, - cpus: u32, - mem: u32, - container: String, - workdir: String, - dns: String, - mapped_volumes: HashMap, - mapped_ports: HashMap, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct KrunvmConfig { - version: u8, - default_cpus: u32, - default_mem: u32, - default_dns: String, - storage_volume: String, - vmconfig_map: HashMap, -} - -impl Default for KrunvmConfig { - fn default() -> KrunvmConfig { - KrunvmConfig { - version: 1, - default_cpus: 2, - default_mem: 1024, - default_dns: "1.1.1.1".to_string(), - storage_volume: String::new(), - vmconfig_map: HashMap::new(), - } - } -} - #[cfg(target_os = "macos")] fn check_case_sensitivity(volume: &str) -> Result { let first_path = format!("{}/krunvm_test", volume); @@ -167,7 +133,7 @@ enum Command { } fn main() { - let mut cfg: KrunvmConfig = confy::load(APP_NAME).unwrap(); + let mut cfg = config::load().unwrap(); let cli_args = Cli::parse(); #[cfg(target_os = "macos")] diff --git a/src/utils.rs b/src/utils.rs index 8b3d5b2..003f621 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,12 +1,13 @@ // Copyright 2021 Red Hat, Inc. // SPDX-License-Identifier: Apache-2.0 +use crate::APP_NAME; use std::collections::HashMap; use std::path::Path; use std::process::Command; use std::str::FromStr; -use crate::{KrunvmConfig, VmConfig, APP_NAME}; +use crate::config::{KrunvmConfig, VmConfig}; pub enum BuildahCommand { From,