From 868939803240b682cec59646d0968e738496594e Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Wed, 17 Jan 2024 08:18:12 -0800 Subject: [PATCH] create hypha --- Cargo.toml | 3 ++- hypha/Cargo.toml | 22 +++++++++++++++++ hypha/bin/agent.rs | 9 +++++++ hypha/bin/container.rs | 5 ++++ hypha/src/agent/mod.rs | 50 ++++++++++++++++++++++++++++++++++++++ hypha/src/container/mod.rs | 1 + hypha/src/error.rs | 42 ++++++++++++++++++++++++++++++++ hypha/src/lib.rs | 3 +++ 8 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 hypha/Cargo.toml create mode 100644 hypha/bin/agent.rs create mode 100644 hypha/bin/container.rs create mode 100644 hypha/src/agent/mod.rs create mode 100644 hypha/src/container/mod.rs create mode 100644 hypha/src/error.rs create mode 100644 hypha/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index aeed5fc..ba62f88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ members = [ "xenstore", "xenevtchn", "xencall", - "xenclient" + "xenclient", + "hypha", ] resolver = "2" diff --git a/hypha/Cargo.toml b/hypha/Cargo.toml new file mode 100644 index 0000000..cfecf75 --- /dev/null +++ b/hypha/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "hypha" +version = "0.0.1" +edition = "2021" +resolver = "2" + +[dependencies.xenclient] +path = "../xenclient" + +[dependencies] +log = "0.4.20" + +[lib] +path = "src/lib.rs" + +[[bin]] +name = "hypha-agent" +path = "bin/agent.rs" + +[[bin]] +name = "hypha-container" +path = "bin/container.rs" diff --git a/hypha/bin/agent.rs b/hypha/bin/agent.rs new file mode 100644 index 0000000..124b4b7 --- /dev/null +++ b/hypha/bin/agent.rs @@ -0,0 +1,9 @@ +use hypha::agent::Agent; +use hypha::error::Result; + +fn main() -> Result<()> { + let mut agent = Agent::new()?; + let domid = agent.launch()?; + println!("launched domain: {}", domid); + Ok(()) +} diff --git a/hypha/bin/container.rs b/hypha/bin/container.rs new file mode 100644 index 0000000..ec04ad7 --- /dev/null +++ b/hypha/bin/container.rs @@ -0,0 +1,5 @@ +use hypha::error::Result; + +fn main() -> Result<()> { + Ok(()) +} diff --git a/hypha/src/agent/mod.rs b/hypha/src/agent/mod.rs new file mode 100644 index 0000000..19447e9 --- /dev/null +++ b/hypha/src/agent/mod.rs @@ -0,0 +1,50 @@ +use crate::error::{HyphaError, Result}; +use std::fs::{read_dir, DirEntry}; +use xenclient::create::DomainConfig; +use xenclient::XenClient; + +pub struct Agent { + client: XenClient, +} + +impl Agent { + pub fn new() -> Result { + let client = XenClient::open()?; + Ok(Agent { client }) + } + + pub fn launch(&mut self) -> Result { + let kernel_path = self.find_boot_path("vmlinuz-")?; + let initrd_path = self.find_boot_path("initrd.img-")?; + + let config = DomainConfig { + max_vcpus: 1, + mem_mb: 512, + kernel_path, + initrd_path, + cmdline: "debug elevator=noop".to_string(), + }; + Ok(self.client.create(config)?) + } + + fn find_boot_path(&self, prefix: &str) -> Result { + let vmlinuz = read_dir("/boot")? + .filter(|x| x.is_ok()) + .map(|x| x.unwrap()) + .filter(|x| { + x.file_name() + .to_str() + .ok_or(HyphaError::new("invalid direntry")) + .map(|x| x.starts_with(prefix)) + .unwrap_or(false) + }) + .collect::>(); + Ok(vmlinuz + .first() + .ok_or(HyphaError::new("unable to find suitable image"))? + .path() + .to_str() + .ok_or(HyphaError::new("invalid direntry"))? + .to_string()) + } +} diff --git a/hypha/src/container/mod.rs b/hypha/src/container/mod.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/hypha/src/container/mod.rs @@ -0,0 +1 @@ + diff --git a/hypha/src/error.rs b/hypha/src/error.rs new file mode 100644 index 0000000..04fee49 --- /dev/null +++ b/hypha/src/error.rs @@ -0,0 +1,42 @@ +use std::error::Error; +use std::fmt::{Display, Formatter}; +use xenclient::XenClientError; + +pub type Result = std::result::Result; + +#[derive(Debug)] +pub struct HyphaError { + message: String, +} + +impl HyphaError { + pub fn new(msg: &str) -> HyphaError { + HyphaError { + message: msg.to_string(), + } + } +} + +impl Display for HyphaError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.message) + } +} + +impl Error for HyphaError { + fn description(&self) -> &str { + &self.message + } +} + +impl From for HyphaError { + fn from(value: std::io::Error) -> Self { + HyphaError::new(value.to_string().as_str()) + } +} + +impl From for HyphaError { + fn from(value: XenClientError) -> Self { + HyphaError::new(value.to_string().as_str()) + } +} diff --git a/hypha/src/lib.rs b/hypha/src/lib.rs new file mode 100644 index 0000000..9ef2f72 --- /dev/null +++ b/hypha/src/lib.rs @@ -0,0 +1,3 @@ +pub mod agent; +pub mod container; +pub mod error;