Prepare, configure, and manage Firecracker microVMs in seconds!
virtualization linux microvm firecracker
at main 70 lines 2.1 kB view raw
1use anyhow::Error; 2use owo_colors::OwoColorize; 3 4use crate::{command::run_command_with_stdout_inherit, ssh::get_private_key_path}; 5 6pub async fn cp(from: &str, to: &str) -> Result<(), Error> { 7 let pool = firecracker_state::create_connection_pool().await?; 8 9 let vm_name = if from.contains(':') { 10 from.split(':').next().unwrap_or("") 11 } else if to.contains(':') { 12 to.split(':').next().unwrap_or("") 13 } else { 14 return Err(anyhow::anyhow!( 15 "Either source or destination must be in the format <vm_name>:<path>" 16 )); 17 }; 18 19 let vm = firecracker_state::repo::virtual_machine::find(&pool, vm_name).await?; 20 21 if vm.is_none() { 22 println!("[-] MicroVM '{}' not found.", vm_name); 23 std::process::exit(1); 24 } 25 26 if !firecracker_process::vm_is_running(vm_name).await? { 27 println!("[-] MicroVM '{}' is not running.", vm_name); 28 let start_cmd = format!("fireup start {}", vm_name); 29 println!(" Start it with {}", start_cmd.cyan()); 30 std::process::exit(1); 31 } 32 33 let guest_ip = format!("{}.firecracker", vm_name); 34 let key_path = get_private_key_path()?; 35 36 let scp_args = if from.contains(':') { 37 let remote_path = format!("root@{}:{}", guest_ip, from.splitn(2, ':').nth(1).unwrap()); 38 vec!["-r", remote_path.as_str(), to] 39 .iter() 40 .map(|s| s.to_string()) 41 .collect::<Vec<String>>() 42 } else { 43 let remote_path = format!("root@{}:{}", guest_ip, to.splitn(2, ':').nth(1).unwrap()); 44 vec!["-r", from, remote_path.as_str()] 45 .iter() 46 .map(|s| s.to_string()) 47 .collect::<Vec<String>>() 48 }; 49 50 run_command_with_stdout_inherit( 51 "scp", 52 &[ 53 "-q", 54 "-i", 55 &key_path, 56 "-o", 57 "StrictHostKeyChecking=no", 58 "-o", 59 "UserKnownHostsFile=/dev/null", 60 ] 61 .iter() 62 .copied() 63 .chain(scp_args.iter().map(|s| s.as_str())) 64 .collect::<Vec<&str>>() 65 .as_slice(), 66 false, 67 )?; 68 69 Ok(()) 70}