diff --git a/pkgs/firecracker-vm/default.nix b/pkgs/firecracker-vm/default.nix new file mode 100644 index 0000000..edce103 --- /dev/null +++ b/pkgs/firecracker-vm/default.nix @@ -0,0 +1,32 @@ +{ callPackage +, firecracker +, writeShellScriptBin +, writeText +}: + +let + kernel = callPackage ./kernel.nix { }; + rootfs = callPackage ./rootfs.nix { }; + + vmconfig = writeText "vmconfig.json" (builtins.toJSON { + boot-source = { + kernel_image_path = "${kernel}/vmlinux"; + boot_args = "panic=1 console=ttyS0 ro"; + }; + drives = [ + { + drive_id = "rootfs"; + path_on_host = rootfs; + is_root_device = true; + is_read_only = true; + } + ]; + machine-config.vcpu_count = 2; + machine-config.mem_size_mib = 1024; + network-interfaces = [ ]; + }); + +in +writeShellScriptBin "firecracker-vm" '' + ${firecracker}/bin/firecracker --no-api --config-file ${vmconfig} +'' diff --git a/pkgs/firecracker-vm/kernel.nix b/pkgs/firecracker-vm/kernel.nix new file mode 100644 index 0000000..3d77fa8 --- /dev/null +++ b/pkgs/firecracker-vm/kernel.nix @@ -0,0 +1,34 @@ +{ fetchFromGitHub +, linuxManualConfig +, linux_6_1 +, kernel ? linux_6_1 +}: + +let + fcsrc = fetchFromGitHub { + owner = "firecracker-microvm"; + repo = "firecracker"; + rev = "e1c351bdde745d33858e04089eef6e2279b286fd"; + hash = "sha256-LvVqA5jBKWQYeV9OHrrb+1gmAqHxDszeVBhFwweDrmo="; + }; + + shortVer = builtins.head ( + builtins.match + "([0-9]+\.[0-9]+).*" + kernel.version + ); + +in +(linuxManualConfig { + + inherit (kernel) src version; + configfile = + "${fcsrc}/resources/guest_configs/microvm-kernel-ci-x86_64-${shortVer}.config"; + +}).overrideAttrs (o: { + + postInstall = (o.postInstall or "") + '' + cp vmlinux $out/ + ''; + +}) diff --git a/pkgs/firecracker-vm/rootfs.nix b/pkgs/firecracker-vm/rootfs.nix new file mode 100644 index 0000000..81adba8 --- /dev/null +++ b/pkgs/firecracker-vm/rootfs.nix @@ -0,0 +1,29 @@ +{ e2fsprogs +, pkgsStatic +, runCommand +, util-linux +, writeShellScript +}: + +let + init-sh = builtins.toFile "init.sh" '' + #!/bin/sh + mount none -t proc /proc + mount none -t sysfs /sys + mount none -t tmpfs /tmp + mount none -t tmpfs /run + exec sh + ''; + + mkroot = writeShellScript "mkroot" '' + mkdir -p rootfs/{dev,proc,run,sys,tmp} + install -Dm 755 ${init-sh} rootfs/sbin/init + install -Dm 755 ${pkgsStatic.busybox}/bin/busybox rootfs/bin/busybox + chroot rootfs /bin/busybox --install -s /bin + ${e2fsprogs.bin}/bin/mkfs.ext4 -d rootfs $out 32M + ''; + +in +runCommand "rootfs.img" { } '' + ${util-linux}/bin/unshare -r ${mkroot} +''