From 20de399301d1a2880d7afd1574a98f0502018256 Mon Sep 17 00:00:00 2001 From: Sylvain Reynaud Date: Tue, 21 Feb 2023 19:37:12 +0100 Subject: [PATCH 1/2] chore: Add README and getting-started material Signed-off-by: Sylvain Reynaud --- Dev.Dockerfile | 7 +++++ LICENSE | 23 ++++++++++++++++ README.md | 75 +++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 Dev.Dockerfile create mode 100644 LICENSE diff --git a/Dev.Dockerfile b/Dev.Dockerfile new file mode 100644 index 0000000..b3901df --- /dev/null +++ b/Dev.Dockerfile @@ -0,0 +1,7 @@ +FROM rust:1.66 as builder +USER root +WORKDIR /build +RUN apt update -y && apt install -y protobuf-compiler +CMD ["cargo", "build"] + +# docker run -v $(pwd):/build $IMAGE_NAME \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dcf3e29 --- /dev/null +++ b/LICENSE @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) 2023 Polytech Montpellier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +This license is valid for a year and could change next year. \ No newline at end of file diff --git a/README.md b/README.md index 7d11a03..9ad11e8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,76 @@ # Firepilot - Pilot Firecracker binary through Rust -WIP +Firepilot is a **rust crate** to pilot Firecracker. It is a wrapper around Firecracker binary and provides a Rust SDK for interact with the Firecracker API. + +There are some Firecracker features that are not yet supported. If you need one of them, please open an issue. + +This crate is inspired by [firecracker-go-sdk](https://github.com/firecracker-microvm/firecracker-go-sdk) a Go SDK for Firecracker. + +## Getting started + +Add the following to your `Cargo.toml`: + +```toml +[dependencies] +firepilot = { git = "https://github.com/polyxia-org/firepilot.git", branch = "main" } +``` + +Download the Firecracker binary : https://github.com/firecracker-microvm/firecracker/releases/latest + +The following examples show how to use the crate: + +### Run a VM + +`rootfs.ext4` example : https://s3.amazonaws.com/spec.ccfc.min/img/quickstart_guide/x86_64/rootfs/bionic.rootfs.ext4 + +`vmlinux.bin` example : https://s3.amazonaws.com/spec.ccfc.min/img/quickstart_guide/x86_64/kernels/vmlinux.bin + +```rust +use firepilot::microvm::{BootSource, Config, Drive, MicroVM}; +use firepilot::Firecracker; + +let FIRECRACKER_PATH = PathBuf::from("/YOUR_PATH_HERE/firecracker"); +let KERNEL_IMAGE_PATH = PathBuf::from("/YOUR_PATH_HERE/vmlinux.bin"); +let ROOTFS_PATH = PathBuf::from("/YOUR_PATH_HERE/rootfs.ext4"); + +let firecracker = Firecracker::new(Some(firepilot::FirecrackerOptions { + command: Some(FIRECRACKER_PATH), + ..Default::default() + })) + .unwrap(); + +let vm = MicroVM::from(Config { + boot_source: BootSource { + kernel_image_path: KERNEL_IMAGE_PATH, + boot_args: None, + initrd_path: None, + }, + drives: vec![Drive { + drive_id: "rootfs".to_string(), + path_on_host: ROOTFS_PATH, + is_read_only: false, + is_root_device: true, + }], + network_interfaces: vec![], +}); + +// Start the VM in a new thread because it is blocking +thread::spawn(move || { + firecracker.start(&vm).unwrap(); +}); +``` + +## Developing + +### Build + +It requires to have `cargo 1.66` or higher and `protobuf-compiler` installed. + +``` +apt update -y && apt install -y protobuf-compiler +cargo build +``` + +## License + +The Polyxia project belongs to Polytech Montpellier and is released under the MIT license. Please see the [LICENSE](LICENSE) file for more information. From 104cceaa03b79b6f3ee1207551e4c4a635d793e2 Mon Sep 17 00:00:00 2001 From: Sylvain Reynaud Date: Wed, 22 Feb 2023 14:13:12 +0100 Subject: [PATCH 2/2] fix(ci): setup firecracker binary for integration tests Signed-off-by: Sylvain Reynaud --- .github/workflows/main.yml | 20 +++++++++++++++ src/lib.rs | 52 +++++++++++++++++++++++++++----------- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 46efba7..5150b4e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -61,6 +61,26 @@ jobs: use-cross: true command: build args: --bins --tests + # setup firecracker binary for integration tests + - name: Setup Firecracker + run: | + mkdir -p fixtures + release_url="https://github.com/firecracker-microvm/firecracker/releases" + latest=$(basename $(curl -fsSLI -o /dev/null -w %{url_effective} ${release_url}/latest)) + arch=`uname -m` + curl -L ${release_url}/download/${latest}/firecracker-${latest}-${arch}.tgz \ + | tar -xz + mv release-${latest}-$(uname -m)/firecracker-${latest}-$(uname -m) ./fixtures/firecracker + - name: Setup vmlinux.bin + run: | + curl https://s3.amazonaws.com/spec.ccfc.min/img/quickstart_guide/x86_64/kernels/vmlinux.bin -o ./fixtures/vmlinux.bin + - name: Setup vmlinux.bin + run: | + curl https://s3.amazonaws.com/spec.ccfc.min/img/quickstart_guide/x86_64/rootfs/bionic.rootfs.ext4 -o ./fixtures/rootfs.ext4 + ls -lh ./fixtures + pwd + ls -hl + echo $PATH - uses: actions-rs/cargo@v1 name: Test Debug with: diff --git a/src/lib.rs b/src/lib.rs index 9005102..41eba01 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -167,13 +167,30 @@ impl Executable for Firecracker { #[cfg(test)] mod tests { + use std::env::{join_paths, split_paths, var_os}; use std::path::PathBuf; + use std::thread; - use crate::microvm::{BootSource, Config, Drive, MicroVM, NetworkInterface}; + use crate::microvm::{BootSource, Config, Drive, MicroVM /* , NetworkInterface */}; use crate::{Firecracker, FirecrackerOptions}; + const TEST_FIRECRACKER_BIN_PATH: &str = "./fixtures/firecracker"; + const TEST_FIXTURES_DIR_PATH: &str = "./fixtures/"; + const TEST_VMLINUX_BIN_PATH: &str = "./fixtures/vmlinux.bin"; + const TEST_ROOTFS_PATH: &str = "./fixtures/rootfs.ext4"; + /* const TEST_GUEST_MAC: &str = "AA:FC:00:00:00:01"; + const TEST_IFACE_ID: &str = "eth0"; + const TEST_HOST_DEV_NAME: &str = "tap0"; */ + #[test] fn test_can_instantiate_firecracker_from_path() { + // add firecracker to $PATH + let path = var_os("PATH").unwrap_or_default(); + let mut paths = split_paths(&path).collect::>(); + paths.push(PathBuf::from(TEST_FIXTURES_DIR_PATH)); + let new_path = join_paths(paths).unwrap(); + std::env::set_var("PATH", new_path); + let firecracker = Firecracker::new(None); assert!(firecracker.is_ok()) } @@ -181,7 +198,7 @@ mod tests { #[test] fn test_can_instantiate_firecracker_from_custom_path() { let firecracker = Firecracker::new(Some(FirecrackerOptions { - command: Some(PathBuf::from("./fixtures/firecracker")), + command: Some(PathBuf::from(TEST_FIRECRACKER_BIN_PATH)), ..FirecrackerOptions::default() })); assert!(firecracker.is_ok()) @@ -198,30 +215,35 @@ mod tests { #[test] fn test_it_run_vm_from_config() { + // show pwd + println!("pwd: {}", std::env::current_dir().unwrap().display()); + // list files in TEST_FIXTURES_DIR_PATH + for entry in std::fs::read_dir(TEST_FIXTURES_DIR_PATH).unwrap() { + let entry = entry.unwrap(); + let path = entry.path(); + println!("file: {}", path.display()); + } let firecracker = Firecracker::new(None).unwrap(); let vm = MicroVM::from(Config { boot_source: BootSource { - kernel_image_path: PathBuf::from( - "/home/debian/developer/firepilot/fixtures/hello-vmlinux.bin", - ), + kernel_image_path: PathBuf::from(TEST_VMLINUX_BIN_PATH), boot_args: None, initrd_path: None, }, drives: vec![Drive { drive_id: "rootfs".to_string(), - path_on_host: PathBuf::from( - "/home/debian/developer/firepilot/fixtures/rootfs.ext4", - ), + path_on_host: PathBuf::from(TEST_ROOTFS_PATH), is_read_only: false, is_root_device: true, }], - network_interfaces: vec![NetworkInterface { - iface_id: "eth0".to_string(), - guest_mac: Some("AA:FC:00:00:00:01".to_string()), - host_dev_name: "tap0".to_string(), - }], + network_interfaces: vec![/* NetworkInterface { + iface_id: TEST_IFACE_ID.to_string(), + guest_mac: Some(TEST_GUEST_MAC.to_string()), + host_dev_name: TEST_HOST_DEV_NAME.to_string(), + } */], + }); + thread::spawn(move || { + firecracker.start(&vm).unwrap(); }); - - firecracker.start(&vm).unwrap(); } }