diff --git a/hypha/src/ctl/cfgblk.rs b/hypha/src/ctl/cfgblk.rs new file mode 100644 index 0000000..92ca83e --- /dev/null +++ b/hypha/src/ctl/cfgblk.rs @@ -0,0 +1,49 @@ +use crate::error::Result; +use crate::image::ImageInfo; +use backhand::{FilesystemWriter, NodeHeader}; +use std::fs; +use std::fs::File; +use std::path::PathBuf; +use uuid::Uuid; + +pub struct ConfigBlock<'a> { + pub image_info: &'a ImageInfo, + pub file: PathBuf, +} + +impl ConfigBlock<'_> { + pub fn new<'a>(uuid: &Uuid, image_info: &'a ImageInfo) -> Result> { + let mut file = std::env::temp_dir().clone(); + file.push(format!("hypha-cfg-{}", uuid)); + fs::create_dir_all(&file)?; + file.push("config.squashfs"); + Ok(ConfigBlock { image_info, file }) + } + + pub fn build(&self) -> Result<()> { + let manifest = self.image_info.config.to_string()?; + let mut writer = FilesystemWriter::default(); + writer.push_dir( + "/image", + NodeHeader { + permissions: 384, + uid: 0, + gid: 0, + mtime: 0, + }, + )?; + writer.push_file( + manifest.as_bytes(), + "/image/config.json", + NodeHeader { + permissions: 384, + uid: 0, + gid: 0, + mtime: 0, + }, + )?; + let mut file = File::create(&self.file)?; + writer.write(&mut file)?; + Ok(()) + } +} diff --git a/hypha/src/ctl/mod.rs b/hypha/src/ctl/mod.rs index 3004a9e..1c10e7b 100644 --- a/hypha/src/ctl/mod.rs +++ b/hypha/src/ctl/mod.rs @@ -1,3 +1,6 @@ +mod cfgblk; + +use crate::ctl::cfgblk::ConfigBlock; use crate::error::{HyphaError, Result}; use crate::image::cache::ImageCache; use crate::image::name::ImageName; @@ -55,10 +58,16 @@ impl Controller { let uuid = Uuid::new_v4(); let name = format!("hypha-{uuid}"); let image_info = self.compile()?; - let squashfs_path = image_info - .squashfs + let cfgblk = ConfigBlock::new(&uuid, &image_info)?; + cfgblk.build()?; + let cfgblk_squashfs_path = cfgblk + .file .to_str() - .ok_or_else(|| HyphaError::new("failed to convert squashfs path to string"))?; + .ok_or_else(|| HyphaError::new("failed to convert config squashfs path to string"))?; + let image_squashfs_path = image_info + .image_squashfs + .to_str() + .ok_or_else(|| HyphaError::new("failed to convert image squashfs path to string"))?; let config = DomainConfig { backend_domid: 0, name: &name, @@ -66,13 +75,21 @@ impl Controller { mem_mb: self.mem, kernel_path: self.kernel_path.as_str(), initrd_path: self.initrd_path.as_str(), - cmdline: "elevator=noop", - disks: vec![DomainDisk { - vdev: "xvda", - pdev: squashfs_path, - writable: false, - }], + cmdline: "quiet elevator=noop", + disks: vec![ + DomainDisk { + vdev: "xvda", + pdev: image_squashfs_path, + writable: false, + }, + DomainDisk { + vdev: "xvdb", + pdev: cfgblk_squashfs_path, + writable: false, + }, + ], }; - Ok(self.client.create(&config)?) + let domid = self.client.create(&config)?; + Ok(domid) } } diff --git a/hypha/src/image/cache.rs b/hypha/src/image/cache.rs index 12df611..73c0ee6 100644 --- a/hypha/src/image/cache.rs +++ b/hypha/src/image/cache.rs @@ -55,7 +55,7 @@ impl ImageCache { squashfs_path.push(format!("{}.squashfs", digest)); manifest_path.push(format!("{}.manifest.json", digest)); config_path.push(format!("{}.config.json", digest)); - fs::copy(&info.squashfs, &squashfs_path)?; + fs::copy(&info.image_squashfs, &squashfs_path)?; let manifest_text = serde_json::to_string_pretty(&info.manifest)?; fs::write(&manifest_path, manifest_text)?; let config_text = serde_json::to_string_pretty(&info.config)?; diff --git a/hypha/src/image/mod.rs b/hypha/src/image/mod.rs index d324883..78c101f 100644 --- a/hypha/src/image/mod.rs +++ b/hypha/src/image/mod.rs @@ -20,7 +20,7 @@ use walkdir::WalkDir; pub const IMAGE_SQUASHFS_VERSION: u64 = 1; pub struct ImageInfo { - pub squashfs: PathBuf, + pub image_squashfs: PathBuf, pub manifest: ImageManifest, pub config: ImageConfiguration, } @@ -32,7 +32,7 @@ impl ImageInfo { config: ImageConfiguration, ) -> Result { Ok(ImageInfo { - squashfs, + image_squashfs: squashfs, manifest, config, })