Prepare, configure, and manage Firecracker microVMs in seconds!
virtualization linux microvm firecracker
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

add support for internal dns and dynamic ip addresses (dhcp)

+141 -51
+1 -1
Cargo.lock
··· 190 190 191 191 [[package]] 192 192 name = "fireup" 193 - version = "0.3.0" 193 + version = "0.4.0" 194 194 dependencies = [ 195 195 "anyhow", 196 196 "clap",
+6 -3
crates/firecracker-prepare/src/lib.rs
··· 12 12 pub mod rootfs; 13 13 pub mod ssh; 14 14 15 - pub const GUEST_IP: &str = "172.16.0.2"; 15 + const BBRIDGE_IP: &str = "172.16.0.1"; 16 16 17 17 #[derive(Clone, Copy, PartialEq, Serialize, Deserialize, Debug)] 18 18 pub enum Distro { ··· 131 131 "sh", 132 132 &[ 133 133 "-c", 134 - &format!("echo 'nameserver 8.8.8.8' > {}/etc/resolv.conf", minirootfs), 134 + &format!( 135 + "echo 'nameserver {}' >> {}/etc/resolv.conf", 136 + BBRIDGE_IP, minirootfs 137 + ), 135 138 ], 136 139 true, 137 140 )?; ··· 216 219 &minirootfs, 217 220 "sh", 218 221 "-c", 219 - &format!("echo 'auto eth0\niface eth0 inet static\n address {}\n netmask 255.255.255.0\n gateway 172.16.0.1\n' > /etc/network/interfaces", GUEST_IP), 222 + "echo 'auto eth0\niface eth0 inet dhcp' > /etc/network/interfaces", 220 223 ], 221 224 true, 222 225 )?;
+1 -1
crates/firecracker-up/Cargo.toml
··· 1 1 [package] 2 2 name = "fireup" 3 - version = "0.3.0" 3 + version = "0.4.0" 4 4 authors.workspace = true 5 5 edition.workspace = true 6 6 license.workspace = true
+2 -1
crates/firecracker-up/src/cmd/ssh.rs
··· 1 1 use crate::{command::run_command, config::get_config_dir}; 2 2 use anyhow::Error; 3 - use firecracker_vm::constants::GUEST_IP; 4 3 use glob::glob; 4 + 5 + const GUEST_IP: &str = "vm0.firecracker.local"; 5 6 6 7 pub fn ssh() -> Result<(), Error> { 7 8 let app_dir = get_config_dir()?;
+3 -2
crates/firecracker-vm/src/constants.rs
··· 1 1 pub const TAP_DEV: &str = "tap0"; 2 + pub const BRIDGE_DEV: &str = "br0"; 2 3 pub const API_SOCKET: &str = "/tmp/firecracker.sock"; 3 - pub const GUEST_IP: &str = "172.16.0.2"; 4 - pub const TAP_IP: &str = "172.16.0.1"; 4 + pub const BRIDGE_IP: &str = "172.16.0.1"; 5 5 pub const FC_MAC: &str = "06:00:AC:10:00:02"; 6 6 pub const MASK_SHORT: &str = "/30"; 7 + pub const GUEST_IP: &str = "vm0.firecracker.local";
+67
crates/firecracker-vm/src/dnsmasq.rs
··· 1 + use std::process; 2 + 3 + use anyhow::Error; 4 + 5 + use crate::{ 6 + command::run_command, 7 + constants::{BRIDGE_DEV, BRIDGE_IP, FC_MAC}, 8 + }; 9 + 10 + pub const DNSMASQ_CONFIG_PATH: &str = "/etc/dnsmasq.d/firecracker.conf"; 11 + 12 + pub fn setup_dnsmasq() -> Result<(), Error> { 13 + println!("[+] Checking if DNSMasq is installed..."); 14 + if !dnsmasq_is_installed()? { 15 + println!("[✗] DNSMasq is not installed. Please install it first."); 16 + process::exit(1); 17 + } 18 + 19 + if std::path::Path::new(DNSMASQ_CONFIG_PATH).exists() { 20 + println!("[✓] DNSMasq configuration already exists. Skipping setup."); 21 + return Ok(()); 22 + } 23 + println!("[+] Setting up DNSMasq configuration..."); 24 + run_command("mkdir", &["-p", "/etc/dnsmasq.d"], true)?; 25 + 26 + let dnsmasq_config: &str = &format!( 27 + r#" 28 + interface={} 29 + bind-interfaces 30 + domain=firecracker.local 31 + dhcp-option=option:router,{} 32 + dhcp-option=option:dns-server,{} 33 + dhcp-range=172.16.0.2,172.16.0.150,12h 34 + dhcp-host={},vm0 35 + server=8.8.8.8 36 + server=8.8.4.4 37 + server=1.1.1.1 38 + "#, 39 + BRIDGE_DEV, BRIDGE_IP, BRIDGE_IP, FC_MAC 40 + ); 41 + 42 + run_command( 43 + "sh", 44 + &[ 45 + "-c", 46 + &format!("echo '{}' > {}", dnsmasq_config, DNSMASQ_CONFIG_PATH), 47 + ], 48 + true, 49 + )?; 50 + 51 + restart_dnsmasq()?; 52 + 53 + Ok(()) 54 + } 55 + 56 + pub fn restart_dnsmasq() -> Result<(), Error> { 57 + println!("[+] Starting DNSMasq..."); 58 + run_command("systemctl", &["enable", "dnsmasq"], true)?; 59 + run_command("systemctl", &["restart", "dnsmasq"], true)?; 60 + println!("[✓] DNSMasq started successfully."); 61 + Ok(()) 62 + } 63 + 64 + pub fn dnsmasq_is_installed() -> Result<bool, Error> { 65 + let output = run_command("which", &["dnsmasq"], false)?; 66 + Ok(output.status.success()) 67 + }
+2 -2
crates/firecracker-vm/src/firecracker.rs
··· 8 8 9 9 use crate::command::run_command; 10 10 11 - const NIXOS_BOOT_ARGS: &str = "init=/nix/store/pq529c6dd6x5vaxak4vpyxrv17ydvnwr-nixos-system-nixos-firecracker-25.05.802216.55d1f923c480/init root=/dev/vda ro console=ttyS0 reboot=k panic=1"; 11 + const NIXOS_BOOT_ARGS: &str = "init=/nix/store/w1yqjd8sswh8zj9sz2v76dpw3llzkg5k-nixos-system-nixos-firecracker-25.05.802216.55d1f923c480/init root=/dev/vda ro console=ttyS0 reboot=k panic=1 ip=dhcp"; 12 12 13 13 pub fn configure( 14 14 logfile: &str, ··· 61 61 62 62 fn setup_boot_source(kernel: &str, arch: &str, is_nixos: bool, options: &VmOptions) -> Result<()> { 63 63 println!("[+] Setting boot source..."); 64 - let mut boot_args = "console=ttyS0 reboot=k panic=1 pci=off".to_string(); 64 + let mut boot_args = "console=ttyS0 reboot=k panic=1 pci=off ip=dhcp".to_string(); 65 65 if arch == "aarch64" { 66 66 boot_args = format!("keep_bootcon {}", boot_args); 67 67 }
+5 -19
crates/firecracker-vm/src/guest.rs
··· 1 - use crate::command::run_command; 2 - use crate::constants::GUEST_IP; 1 + use crate::{ 2 + command::run_command, 3 + constants::{BRIDGE_IP, GUEST_IP}, 4 + }; 3 5 use anyhow::Result; 4 6 5 7 pub fn configure_guest_network(key_name: &str) -> Result<()> { 6 8 println!("[+] Configuring network in guest..."); 7 - if let Err(err) = run_command( 8 - "ssh", 9 - &[ 10 - "-i", 11 - key_name, 12 - "-o", 13 - "StrictHostKeyChecking=no", 14 - &format!("root@{}", GUEST_IP), 15 - "ip route add default via 172.16.0.1 dev eth0", 16 - ], 17 - false, 18 - ) { 19 - if !err.to_string().contains("RTNETLINK answers: File exists") { 20 - println!("[-] Failed to set default route: {}", err); 21 - } 22 - } 23 9 run_command( 24 10 "ssh", 25 11 &[ ··· 28 14 "-o", 29 15 "StrictHostKeyChecking=no", 30 16 &format!("root@{}", GUEST_IP), 31 - "echo 'nameserver 8.8.8.8' > /etc/resolv.conf", 17 + &format!("echo 'nameserver {}' > /etc/resolv.conf", BRIDGE_IP), 32 18 ], 33 19 false, 34 20 )?;
+2
crates/firecracker-vm/src/lib.rs
··· 8 8 mod command; 9 9 mod config; 10 10 pub mod constants; 11 + mod dnsmasq; 11 12 mod firecracker; 12 13 mod guest; 13 14 mod network; ··· 75 76 let arch = command::run_command("uname", &["-m"], false)?.stdout; 76 77 let arch = String::from_utf8_lossy(&arch).trim().to_string(); 77 78 network::setup_network()?; 79 + 78 80 firecracker::configure(&logfile, &kernel, &rootfs, &arch, &options, distro)?; 79 81 80 82 if distro != Distro::NixOS {
+48 -19
crates/firecracker-vm/src/network.rs
··· 1 - use crate::constants::{MASK_SHORT, TAP_DEV, TAP_IP}; 1 + use crate::{ 2 + constants::{BRIDGE_DEV, BRIDGE_IP, MASK_SHORT, TAP_DEV}, 3 + dnsmasq::setup_dnsmasq, 4 + }; 2 5 use anyhow::{anyhow, Context, Result}; 3 6 use serde_json::Value; 4 7 ··· 10 13 .unwrap_or(false) 11 14 } 12 15 16 + fn check_bridge_exists() -> bool { 17 + run_command("ip", &["link", "show", BRIDGE_DEV], false) 18 + .map(|output| output.status.success()) 19 + .unwrap_or(false) 20 + } 21 + 13 22 pub fn setup_network() -> Result<()> { 14 23 if check_tap_exists() { 24 + run_command("ip", &["addr", "flush", "dev", TAP_DEV], true)?; 25 + } 26 + 27 + if check_tap_exists() && check_bridge_exists() { 15 28 println!("[✓] Network already configured. Skipping setup."); 16 29 return Ok(()); 17 30 } 18 31 19 - println!("[+] Configuring {}...", TAP_DEV); 20 - run_command( 21 - "ip", 22 - &["tuntap", "add", "dev", TAP_DEV, "mode", "tap"], 23 - true, 24 - )?; 25 - run_command( 26 - "ip", 27 - &[ 28 - "addr", 29 - "add", 30 - &format!("{}{}", TAP_IP, MASK_SHORT), 31 - "dev", 32 - TAP_DEV, 33 - ], 34 - true, 35 - )?; 36 - run_command("ip", &["link", "set", "dev", TAP_DEV, "up"], true)?; 32 + if !check_tap_exists() { 33 + println!("[+] Configuring {}...", TAP_DEV); 34 + run_command( 35 + "ip", 36 + &["tuntap", "add", "dev", TAP_DEV, "mode", "tap"], 37 + true, 38 + )?; 39 + run_command("ip", &["link", "set", "dev", TAP_DEV, "up"], true)?; 40 + } 41 + 42 + if !check_bridge_exists() { 43 + println!("[+] Configuring {}...", BRIDGE_DEV); 44 + run_command( 45 + "ip", 46 + &["link", "add", "name", BRIDGE_DEV, "type", "bridge"], 47 + true, 48 + )?; 49 + run_command("ip", &["link", "set", BRIDGE_DEV, "up"], true)?; 50 + run_command("ip", &["link", "set", TAP_DEV, "master", BRIDGE_DEV], true)?; 51 + run_command( 52 + "ip", 53 + &[ 54 + "addr", 55 + "add", 56 + &format!("{}{}", BRIDGE_IP, MASK_SHORT), 57 + "dev", 58 + BRIDGE_DEV, 59 + ], 60 + true, 61 + )?; 62 + } 37 63 38 64 let ip_forward = run_command("cat", &["/proc/sys/net/ipv4/ip_forward"], false)?.stdout; 39 65 if String::from_utf8_lossy(&ip_forward).trim() != "1" { ··· 85 111 } 86 112 87 113 run_command("iptables", &["-P", "FORWARD", "ACCEPT"], true)?; 114 + 115 + setup_dnsmasq()?; 116 + 88 117 Ok(()) 89 118 }
+2 -2
dist/debian/amd64/DEBIAN/control
··· 1 1 Package: fireup 2 - Version: 0.3.0 2 + Version: 0.4.0 3 3 Section: utils 4 4 Priority: optional 5 5 Architecture: amd64 6 6 Maintainer: Tsiry Sandratraina <tsiry.sndr@rocksky.app> 7 7 Description: fireup is a tool designed to simplify the process of setting up and managing Firecracker microVMs. It automates the preparation of the necessary files, including kernel images, root filesystems, and SSH keys, to quickly get you started with Firecracker. 8 - 8 + Depends: dnsmasq, curl, wget 9 9
+2 -1
dist/debian/arm64/DEBIAN/control
··· 1 1 Package: fireup 2 - Version: 0.3.0 2 + Version: 0.4.0 3 3 Section: utils 4 4 Priority: optional 5 5 Architecture: arm64 6 6 Maintainer: Tsiry Sandratraina <tsiry.sndr@rocksky.app> 7 7 Description: fireup is a tool designed to simplify the process of setting up and managing Firecracker microVMs. It automates the preparation of the necessary files, including kernel images, root filesystems, and SSH keys, to quickly get you started with Firecracker. 8 + Depends: dnsmasq, curl, wget