From 93763797b8b0d24e033184e560062d1dbf1112ce Mon Sep 17 00:00:00 2001 From: Christophe de Dinechin Date: Thu, 6 Jul 2023 16:49:39 +0200 Subject: [PATCH] Add -f / --force option to delete There are cases where krunvm fails to delete a VM, e.g. because the corresponding container no longer exists. Add a `--force` (or `-f`) option to the `delete` subcommand that forces deletion of the VM configuration in that case. Fixes: #42 Signed-off-by: Christophe de Dinechin --- src/create.rs | 2 +- src/delete.rs | 5 +++-- src/main.rs | 20 ++++++++++++++------ src/start.rs | 4 ++-- src/utils.rs | 20 ++++++++++++++++---- 5 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/create.rs b/src/create.rs index 8c71a1f..b390d4d 100644 --- a/src/create.rs +++ b/src/create.rs @@ -211,7 +211,7 @@ https://threedots.ovh/blog/2022/06/quick-look-at-rosetta-on-linux/ if force_x86 { _ = fs::create_dir(format!("{}/.rosetta", rootfs)); } - umount_container(cfg, &vmcfg).unwrap(); + umount_container(cfg, &vmcfg, false).unwrap(); cfg.vmconfig_map.insert(name.clone(), vmcfg); confy::store(APP_NAME, cfg).unwrap(); diff --git a/src/delete.rs b/src/delete.rs index 7a79932..cb9c6b8 100644 --- a/src/delete.rs +++ b/src/delete.rs @@ -7,6 +7,7 @@ use super::utils::{remove_container, umount_container}; pub fn delete(cfg: &mut KrunvmConfig, matches: &ArgMatches) { let name = matches.value_of("NAME").unwrap(); + let force = matches.is_present("force"); let vmcfg = match cfg.vmconfig_map.remove(name) { None => { @@ -16,8 +17,8 @@ pub fn delete(cfg: &mut KrunvmConfig, matches: &ArgMatches) { Some(vmcfg) => vmcfg, }; - umount_container(cfg, &vmcfg).unwrap(); - remove_container(cfg, &vmcfg).unwrap(); + umount_container(cfg, &vmcfg, force).unwrap(); + remove_container(cfg, &vmcfg, force).unwrap(); confy::store(APP_NAME, &cfg).unwrap(); } diff --git a/src/main.rs b/src/main.rs index 4fa6a84..d2e5e1b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -247,12 +247,20 @@ fn main() { ), ) .subcommand( - App::new("delete").about("Delete an existing microVM").arg( - Arg::with_name("NAME") - .help("Name of the microVM to be deleted") - .required(true) - .index(1), - ), + App::new("delete") + .about("Delete an existing microVM") + .arg( + Arg::with_name("NAME") + .help("Name of the microVM to be deleted") + .required(true) + .index(1), + ) + .arg( + Arg::with_name("force") + .long("force") + .short("f") + .help("Force deletion even in case of buildah error"), + ), ) .subcommand( App::new("list").about("List microVMs").arg( diff --git a/src/start.rs b/src/start.rs index 4da23ca..1a00f07 100644 --- a/src/start.rs +++ b/src/start.rs @@ -195,7 +195,7 @@ pub fn start(cfg: &KrunvmConfig, matches: &ArgMatches) { Some(vmcfg) => vmcfg, }; - umount_container(cfg, vmcfg).expect("Error unmounting container"); + umount_container(cfg, vmcfg, false).expect("Error unmounting container"); let rootfs = mount_container(cfg, vmcfg).expect("Error mounting container"); let args: Vec = if cmd.is_some() { @@ -213,5 +213,5 @@ pub fn start(cfg: &KrunvmConfig, matches: &ArgMatches) { unsafe { exec_vm(vmcfg, &rootfs, cmd, args) }; - umount_container(cfg, vmcfg).expect("Error unmounting container"); + umount_container(cfg, vmcfg, false).expect("Error unmounting container"); } diff --git a/src/utils.rs b/src/utils.rs index 46bd2e4..e3f7287 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -204,7 +204,11 @@ pub fn mount_container(cfg: &KrunvmConfig, vmcfg: &VmConfig) -> Result Result<(), std::io::Error> { +pub fn umount_container( + cfg: &KrunvmConfig, + vmcfg: &VmConfig, + force: bool, +) -> Result<(), std::io::Error> { let mut args = get_buildah_args(cfg, BuildahCommand::Unmount); args.push(vmcfg.container.clone()); @@ -230,14 +234,20 @@ pub fn umount_container(cfg: &KrunvmConfig, vmcfg: &VmConfig) -> Result<(), std: "buildah returned an error: {}", std::str::from_utf8(&output.stdout).unwrap() ); - std::process::exit(-1); + if !force { + std::process::exit(-1); + } } Ok(()) } #[allow(unused_variables)] -pub fn remove_container(cfg: &KrunvmConfig, vmcfg: &VmConfig) -> Result<(), std::io::Error> { +pub fn remove_container( + cfg: &KrunvmConfig, + vmcfg: &VmConfig, + force: bool, +) -> Result<(), std::io::Error> { let mut args = get_buildah_args(cfg, BuildahCommand::Remove); args.push(vmcfg.container.clone()); @@ -263,7 +273,9 @@ pub fn remove_container(cfg: &KrunvmConfig, vmcfg: &VmConfig) -> Result<(), std: "buildah returned an error: {}", std::str::from_utf8(&output.stdout).unwrap() ); - std::process::exit(-1); + if !force { + std::process::exit(-1); + } } Ok(())