Skip to content

Commit

Permalink
feat(cp): process spawning and first vm spawning
Browse files Browse the repository at this point in the history
  • Loading branch information
sousandrei committed Sep 17, 2022
1 parent f001a19 commit 6af1475
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 47 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
debug
target
Cargo.lock
Cargo.lock
assets/firecracker
assets/vmlinux
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
[package]
name = "firesquid"
version = "0.1.0"
authors = ["Andrei Sousa <sousandrei@gmail.com>"]
edition = "2018"
name = "firesquid"
version = "0.1.0"

[dependencies]
[dependencies]
hyper = {version = "0.13.8", features = ["stream"]}
hyperlocal = "0.7"
tokio = {version = "0.2.22", features = ["uds", "stream", "macros"]}
75 changes: 75 additions & 0 deletions src/cp/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
extern crate hyper;
extern crate hyperlocal;
extern crate tokio;

use hyper::{Body, Client, Method, Request};
use hyperlocal::{UnixClientExt, Uri};
use std::path::Path;
use std::process::Command;

pub fn spawn(vm_name: &str) {
let mut child = Command::new("./assets/firecracker")
.args(&["--api-sock", &format!("./tmp/{}.socket", vm_name)])
.spawn()
.expect("eita");

set_kernel(vm_name).expect(&format!("failing setting kernel for {}", vm_name));
set_drive(vm_name).expect(&format!("failing setting drive for {}", vm_name));
start_machine(vm_name).expect(&format!("failing booting {}", vm_name));

// child.kill().expect("cannot kill vm");
child
.wait()
.expect(&format!("error waiting for {}", vm_name));
}

#[tokio::main]
async fn set_kernel(vm_name: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let url = "/boot-source";
let body = &format!("{{\"kernel_image_path\":\"./tmp/{}.vmlinux\",\"boot_args\":\"console=ttyS0 reboot=k panic=1 pci=off\"}}",vm_name);

make_request(vm_name, url, body).await
}

#[tokio::main]
async fn set_drive(vm_name: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let url = "/drives/rootfs";
let body = &format!("{{\"drive_id\":\"rootfs\",\"path_on_host\":\"./tmp/{}.ext4\",\"is_root_device\":true,\"is_read_only\":false}}",vm_name);

make_request(vm_name, url, body).await
}

#[tokio::main]
async fn start_machine(vm_name: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let url = "/actions";
let body = "{\"action_type\":\"InstanceStart\"}";

make_request(vm_name, url, body).await
}

async fn make_request(
vm_name: &str,
url: &str,
body: &str,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let vm_path = format!("./tmp/{}.socket", vm_name);
let path = Path::new(&vm_path);
let url: Uri = Uri::new(path, url).into();

println!("{:?}", url);

let client = Client::unix();

let req = Request::builder()
.method(Method::PUT)
.uri(url)
.header("Accept", "Accept: application/json")
.header("Content-Type", "Accept: application/json")
.body(Body::from(body.to_owned()))?;

let resp = client.request(req).await?;

println!("Response: {}", resp.status());

Ok(())
}
1 change: 0 additions & 1 deletion src/iops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pub fn initialize_tmp(path: &str) -> IoError {
}

pub fn initialize_vm(vm_name: &str) -> IoError {
socket::create_socket(vm_name, DEFAULT_TMP_PATH)?;
kernel::create_kernel(vm_name, DEFAULT_TMP_PATH)?;
drive::create_drive(vm_name, DEFAULT_TMP_PATH)
}
Expand Down
42 changes: 0 additions & 42 deletions src/iops/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,6 @@ use std::fs;
use std::io::{Error, ErrorKind};
use std::path::PathBuf;

pub fn create_socket(socket_name: &str, tmp_path: &str) -> super::IoError {
let socket_path = format!("{}/{}.socket", tmp_path, socket_name);
let mut path = PathBuf::from(socket_path);

path = match fs::canonicalize(&path) {
Ok(p) => p,
Err(e) => match e.kind() {
ErrorKind::NotFound => path,
_ => panic!("Error resolving tmp path [{}]", e),
},
};

if path.exists() {
return Err(Error::new(
ErrorKind::InvalidInput,
format!("Socket file already exists [{}]", path.display()),
));
}

match fs::File::create(&path) {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
}

pub fn delete_socket(socket_name: &str, tmp_path: &str) -> super::IoError {
let socket_path = format!("{}/{}.socket", tmp_path, socket_name);
let mut path = PathBuf::from(socket_path);
Expand All @@ -49,23 +24,6 @@ pub fn delete_socket(socket_name: &str, tmp_path: &str) -> super::IoError {
fs::remove_file(&path)
}

#[test]
fn create_socket_works() {
const SOCKET_NAME: &str = "./vm2";
const SOCKET_FOLDER: &str = "./tmp_socket";

let _ = fs::create_dir(SOCKET_FOLDER);
let _ = create_socket(SOCKET_NAME, SOCKET_FOLDER);

let socket_path = format!("{}/{}.socket", SOCKET_FOLDER, SOCKET_NAME);
let path = PathBuf::from(socket_path);

assert_eq!(path.exists(), true);

let _ = fs::remove_file(&path);
let _ = fs::remove_dir(SOCKET_FOLDER);
}

#[test]
fn delete_socket_works() {
const SOCKET_NAME: &str = "./vm2";
Expand Down
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod cp;
mod iops;

fn main() {
Expand All @@ -11,6 +12,8 @@ fn main() {
Err(e) => eprintln!("vm initialization error: {}", e),
}

cp::spawn("vm1");

match iops::terminate_vm("vm1") {
Ok(_) => println!("vm terminated"),
Err(e) => eprintln!("vm termination error: {}", e),
Expand Down

0 comments on commit 6af1475

Please sign in to comment.