mirror of
				https://github.com/edera-dev/krata.git
				synced 2025-11-03 23:29:39 +00:00 
			
		
		
		
	hypha: implement basic container init
This commit is contained in:
		
							
								
								
									
										48
									
								
								hypha/src/container/init.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								hypha/src/container/init.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,48 @@
 | 
			
		||||
use crate::error::Result;
 | 
			
		||||
use std::fs;
 | 
			
		||||
use std::path::Path;
 | 
			
		||||
use sys_mount::{FilesystemType, Mount, MountFlags};
 | 
			
		||||
 | 
			
		||||
const IMAGE_BLOCK_DEVICE_PATH: &str = "/dev/xvda";
 | 
			
		||||
const CONFIG_BLOCK_DEVICE_PATH: &str = "/dev/xvdb";
 | 
			
		||||
 | 
			
		||||
const IMAGE_MOUNT_PATH: &str = "/image";
 | 
			
		||||
const CONFIG_MOUNT_PATH: &str = "/config";
 | 
			
		||||
 | 
			
		||||
pub struct ContainerInit {}
 | 
			
		||||
 | 
			
		||||
impl Default for ContainerInit {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        Self::new()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ContainerInit {
 | 
			
		||||
    pub fn new() -> ContainerInit {
 | 
			
		||||
        ContainerInit {}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn init(&mut self) -> Result<()> {
 | 
			
		||||
        self.prepare_mounts()?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn prepare_mounts(&mut self) -> Result<()> {
 | 
			
		||||
        let image_mount_path = Path::new(IMAGE_MOUNT_PATH);
 | 
			
		||||
        let config_mount_path = Path::new(CONFIG_MOUNT_PATH);
 | 
			
		||||
        self.mount_squashfs(Path::new(IMAGE_BLOCK_DEVICE_PATH), image_mount_path)?;
 | 
			
		||||
        self.mount_squashfs(Path::new(CONFIG_BLOCK_DEVICE_PATH), config_mount_path)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn mount_squashfs(&mut self, from: &Path, to: &Path) -> Result<()> {
 | 
			
		||||
        if !to.is_dir() {
 | 
			
		||||
            fs::create_dir(to)?;
 | 
			
		||||
        }
 | 
			
		||||
        Mount::builder()
 | 
			
		||||
            .fstype(FilesystemType::Manual("squashfs"))
 | 
			
		||||
            .flags(MountFlags::RDONLY)
 | 
			
		||||
            .mount(from, to)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
 | 
			
		||||
pub mod init;
 | 
			
		||||
 | 
			
		||||
@ -8,12 +8,17 @@ use uuid::Uuid;
 | 
			
		||||
 | 
			
		||||
pub struct ConfigBlock<'a> {
 | 
			
		||||
    pub image_info: &'a ImageInfo,
 | 
			
		||||
    pub config_bundle: Option<&'a str>,
 | 
			
		||||
    pub file: PathBuf,
 | 
			
		||||
    pub dir: PathBuf,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ConfigBlock<'_> {
 | 
			
		||||
    pub fn new<'a>(uuid: &Uuid, image_info: &'a ImageInfo) -> Result<ConfigBlock<'a>> {
 | 
			
		||||
    pub fn new<'a>(
 | 
			
		||||
        uuid: &Uuid,
 | 
			
		||||
        image_info: &'a ImageInfo,
 | 
			
		||||
        config_bundle: Option<&'a str>,
 | 
			
		||||
    ) -> Result<ConfigBlock<'a>> {
 | 
			
		||||
        let mut dir = std::env::temp_dir().clone();
 | 
			
		||||
        dir.push(format!("hypha-cfg-{}", uuid));
 | 
			
		||||
        fs::create_dir_all(&dir)?;
 | 
			
		||||
@ -21,12 +26,17 @@ impl ConfigBlock<'_> {
 | 
			
		||||
        file.push("config.squashfs");
 | 
			
		||||
        Ok(ConfigBlock {
 | 
			
		||||
            image_info,
 | 
			
		||||
            config_bundle,
 | 
			
		||||
            file,
 | 
			
		||||
            dir,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn build(&self) -> Result<()> {
 | 
			
		||||
        let config_bundle_content = match self.config_bundle {
 | 
			
		||||
            None => None,
 | 
			
		||||
            Some(path) => Some(fs::read(path)?),
 | 
			
		||||
        };
 | 
			
		||||
        let manifest = self.image_info.config.to_string()?;
 | 
			
		||||
        let mut writer = FilesystemWriter::default();
 | 
			
		||||
        writer.push_dir(
 | 
			
		||||
@ -48,6 +58,18 @@ impl ConfigBlock<'_> {
 | 
			
		||||
                mtime: 0,
 | 
			
		||||
            },
 | 
			
		||||
        )?;
 | 
			
		||||
        if let Some(config_bundle_content) = config_bundle_content.as_ref() {
 | 
			
		||||
            writer.push_file(
 | 
			
		||||
                config_bundle_content.as_slice(),
 | 
			
		||||
                "/bundle",
 | 
			
		||||
                NodeHeader {
 | 
			
		||||
                    permissions: 384,
 | 
			
		||||
                    uid: 0,
 | 
			
		||||
                    gid: 0,
 | 
			
		||||
                    mtime: 0,
 | 
			
		||||
                },
 | 
			
		||||
            )?;
 | 
			
		||||
        }
 | 
			
		||||
        let mut file = File::create(&self.file)?;
 | 
			
		||||
        writer.write(&mut file)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
 | 
			
		||||
@ -63,6 +63,7 @@ impl Controller {
 | 
			
		||||
        &mut self,
 | 
			
		||||
        kernel_path: &str,
 | 
			
		||||
        initrd_path: &str,
 | 
			
		||||
        config_bundle_path: Option<&str>,
 | 
			
		||||
        image: &str,
 | 
			
		||||
        vcpus: u32,
 | 
			
		||||
        mem: u64,
 | 
			
		||||
@ -70,7 +71,7 @@ impl Controller {
 | 
			
		||||
        let uuid = Uuid::new_v4();
 | 
			
		||||
        let name = format!("hypha-{uuid}");
 | 
			
		||||
        let image_info = self.compile(image)?;
 | 
			
		||||
        let cfgblk = ConfigBlock::new(&uuid, &image_info)?;
 | 
			
		||||
        let cfgblk = ConfigBlock::new(&uuid, &image_info, config_bundle_path)?;
 | 
			
		||||
        cfgblk.build()?;
 | 
			
		||||
 | 
			
		||||
        let image_squashfs_path = image_info
 | 
			
		||||
@ -110,6 +111,7 @@ impl Controller {
 | 
			
		||||
                    writable: false,
 | 
			
		||||
                },
 | 
			
		||||
            ],
 | 
			
		||||
            filesystems: vec![],
 | 
			
		||||
            extra_keys: vec![
 | 
			
		||||
                ("hypha/uuid".to_string(), uuid.to_string()),
 | 
			
		||||
                (
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,15 @@ impl Error for HyphaError {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[macro_export]
 | 
			
		||||
macro_rules! hypha_err {
 | 
			
		||||
    ($($arg:tt)*) => {{
 | 
			
		||||
        use $crate::error::HyphaError;
 | 
			
		||||
        let text = std::fmt::format(format_args!($($arg)*));
 | 
			
		||||
        Err(HyphaError::new(text.as_str()))
 | 
			
		||||
    }}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<std::io::Error> for HyphaError {
 | 
			
		||||
    fn from(value: std::io::Error) -> Self {
 | 
			
		||||
        HyphaError::new(value.to_string().as_str())
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user