mirror of
				https://github.com/edera-dev/krata.git
				synced 2025-11-03 23:29:39 +00:00 
			
		
		
		
	hypha: implement the ability to override the command line to execute
This commit is contained in:
		@ -1,5 +1,6 @@
 | 
			
		||||
use crate::error::Result;
 | 
			
		||||
use crate::hypha_err;
 | 
			
		||||
use crate::shared::LaunchInfo;
 | 
			
		||||
use log::trace;
 | 
			
		||||
use nix::libc::dup2;
 | 
			
		||||
use nix::unistd::execve;
 | 
			
		||||
@ -27,6 +28,7 @@ const OVERLAY_UPPER_PATH: &str = "/overlay/upper";
 | 
			
		||||
 | 
			
		||||
const NEW_ROOT_PATH: &str = "/newroot";
 | 
			
		||||
const IMAGE_CONFIG_JSON_PATH: &str = "/config/image/config.json";
 | 
			
		||||
const LAUNCH_CONFIG_JSON_PATH: &str = "/config/launch.json";
 | 
			
		||||
 | 
			
		||||
pub struct ContainerInit {}
 | 
			
		||||
 | 
			
		||||
@ -49,12 +51,13 @@ impl ContainerInit {
 | 
			
		||||
 | 
			
		||||
        self.mount_squashfs_images()?;
 | 
			
		||||
        let config = self.parse_image_config()?;
 | 
			
		||||
        let launch = self.parse_launch_config()?;
 | 
			
		||||
        self.mount_new_root()?;
 | 
			
		||||
        self.nuke_initrd()?;
 | 
			
		||||
        self.bind_new_root()?;
 | 
			
		||||
        self.map_console(console)?;
 | 
			
		||||
        if let Some(cfg) = config.config() {
 | 
			
		||||
            self.run(cfg)?;
 | 
			
		||||
            self.run(cfg, &launch)?;
 | 
			
		||||
        } else {
 | 
			
		||||
            return hypha_err!("unable to determine what to execute, image config doesn't tell us");
 | 
			
		||||
        }
 | 
			
		||||
@ -131,6 +134,12 @@ impl ContainerInit {
 | 
			
		||||
        Ok(config)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn parse_launch_config(&mut self) -> Result<LaunchInfo> {
 | 
			
		||||
        trace!("parsing launch config");
 | 
			
		||||
        let launch_config = Path::new(LAUNCH_CONFIG_JSON_PATH);
 | 
			
		||||
        Ok(serde_json::from_str(&fs::read_to_string(launch_config)?)?)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn nuke_initrd(&mut self) -> Result<()> {
 | 
			
		||||
        trace!("nuking initrd");
 | 
			
		||||
        let initrd_dev = fs::metadata("/")?.st_dev();
 | 
			
		||||
@ -189,14 +198,20 @@ impl ContainerInit {
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn run(&mut self, config: &Config) -> Result<()> {
 | 
			
		||||
    fn run(&mut self, config: &Config, launch: &LaunchInfo) -> Result<()> {
 | 
			
		||||
        let mut cmd = match config.cmd() {
 | 
			
		||||
            None => vec![],
 | 
			
		||||
            Some(value) => value.clone(),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if launch.run.is_some() {
 | 
			
		||||
            cmd = launch.run.as_ref().unwrap().clone();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if cmd.is_empty() {
 | 
			
		||||
            cmd.push("/bin/sh".to_string());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        trace!("running container command: {}", cmd.join(" "));
 | 
			
		||||
        let path = cmd.remove(0);
 | 
			
		||||
        let mut env = match config.env() {
 | 
			
		||||
@ -205,10 +220,8 @@ impl ContainerInit {
 | 
			
		||||
        };
 | 
			
		||||
        env.push("HYPHA_CONTAINER=1".to_string());
 | 
			
		||||
        let path_cstr = CString::new(path)?;
 | 
			
		||||
        let mut cmd_cstr = ContainerInit::strings_as_cstrings(cmd)?;
 | 
			
		||||
        cmd_cstr.push(CString::new("")?);
 | 
			
		||||
        let mut env_cstr = ContainerInit::strings_as_cstrings(env)?;
 | 
			
		||||
        env_cstr.push(CString::new("")?);
 | 
			
		||||
        let cmd_cstr = ContainerInit::strings_as_cstrings(cmd)?;
 | 
			
		||||
        let env_cstr = ContainerInit::strings_as_cstrings(env)?;
 | 
			
		||||
        let mut working_dir = config
 | 
			
		||||
            .working_dir()
 | 
			
		||||
            .as_ref()
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
use crate::error::Result;
 | 
			
		||||
use crate::image::ImageInfo;
 | 
			
		||||
use crate::shared::LaunchInfo;
 | 
			
		||||
use backhand::{FilesystemWriter, NodeHeader};
 | 
			
		||||
use std::fs;
 | 
			
		||||
use std::fs::File;
 | 
			
		||||
@ -32,12 +33,13 @@ impl ConfigBlock<'_> {
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn build(&self) -> Result<()> {
 | 
			
		||||
    pub fn build(&self, launch_config: &LaunchInfo) -> 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 launch = serde_json::to_string(launch_config)?;
 | 
			
		||||
        let mut writer = FilesystemWriter::default();
 | 
			
		||||
        writer.push_dir(
 | 
			
		||||
            "/image",
 | 
			
		||||
@ -58,6 +60,16 @@ impl ConfigBlock<'_> {
 | 
			
		||||
                mtime: 0,
 | 
			
		||||
            },
 | 
			
		||||
        )?;
 | 
			
		||||
        writer.push_file(
 | 
			
		||||
            launch.as_bytes(),
 | 
			
		||||
            "/launch.json",
 | 
			
		||||
            NodeHeader {
 | 
			
		||||
                permissions: 384,
 | 
			
		||||
                uid: 0,
 | 
			
		||||
                gid: 0,
 | 
			
		||||
                mtime: 0,
 | 
			
		||||
            },
 | 
			
		||||
        )?;
 | 
			
		||||
        if let Some(config_bundle_content) = config_bundle_content.as_ref() {
 | 
			
		||||
            writer.push_file(
 | 
			
		||||
                config_bundle_content.as_slice(),
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ use crate::error::{HyphaError, Result};
 | 
			
		||||
use crate::image::cache::ImageCache;
 | 
			
		||||
use crate::image::name::ImageName;
 | 
			
		||||
use crate::image::{ImageCompiler, ImageInfo};
 | 
			
		||||
use crate::shared::LaunchInfo;
 | 
			
		||||
use loopdev::LoopControl;
 | 
			
		||||
use std::io::{Read, Write};
 | 
			
		||||
use std::path::PathBuf;
 | 
			
		||||
@ -59,6 +60,7 @@ impl Controller {
 | 
			
		||||
        compiler.compile(&image)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[allow(clippy::too_many_arguments)]
 | 
			
		||||
    pub fn launch(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        kernel_path: &str,
 | 
			
		||||
@ -67,12 +69,15 @@ impl Controller {
 | 
			
		||||
        image: &str,
 | 
			
		||||
        vcpus: u32,
 | 
			
		||||
        mem: u64,
 | 
			
		||||
        run: Option<Vec<String>>,
 | 
			
		||||
    ) -> Result<u32> {
 | 
			
		||||
        let uuid = Uuid::new_v4();
 | 
			
		||||
        let name = format!("hypha-{uuid}");
 | 
			
		||||
        let image_info = self.compile(image)?;
 | 
			
		||||
        let launch_config = LaunchInfo { run };
 | 
			
		||||
 | 
			
		||||
        let cfgblk = ConfigBlock::new(&uuid, &image_info, config_bundle_path)?;
 | 
			
		||||
        cfgblk.build()?;
 | 
			
		||||
        cfgblk.build(&launch_config)?;
 | 
			
		||||
 | 
			
		||||
        let image_squashfs_path = image_info
 | 
			
		||||
            .image_squashfs
 | 
			
		||||
 | 
			
		||||
@ -3,3 +3,4 @@ pub mod container;
 | 
			
		||||
pub mod ctl;
 | 
			
		||||
pub mod error;
 | 
			
		||||
pub mod image;
 | 
			
		||||
mod shared;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								hypha/src/shared/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								hypha/src/shared/mod.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize, Deserialize)]
 | 
			
		||||
pub struct LaunchInfo {
 | 
			
		||||
    pub run: Option<Vec<String>>,
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user