Skip to content

Commit

Permalink
feat(mcrun): add polymorphic binary for MicroVM and supervisor modes (#…
Browse files Browse the repository at this point in the history
…121)

Add a new `mcrun` binary that can operate in two modes:
- MicroVM mode: provides an isolated execution environment
- Supervisor mode: manages and monitors child processes

Key changes:
- Add new mcrun binary with CLI interface and subcommands
- Create MicroVmMonitor for process monitoring and logging
- Add CLI argument parsing for both modes
- Integrate with sandbox database for metrics/metadata
- Move orchestrator.rs to monitor.rs with implementation
- Update path resolution utilities in monoutils

Note: Initial implementation with basic functionality. Further testing and validation required.
  • Loading branch information
appcypher authored Jan 30, 2025
1 parent 82be71c commit 44f6277
Show file tree
Hide file tree
Showing 15 changed files with 437 additions and 57 deletions.
4 changes: 4 additions & 0 deletions monocore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ path = "lib/lib.rs"
name = "monocore"
path = "bin/monocore.rs"

[[bin]]
name = "mcrun"
path = "bin/mcrun.rs"

[[test]]
name = "integration_cli"
path = "tests/cli/mod.rs"
Expand Down
154 changes: 154 additions & 0 deletions monocore/bin/mcrun.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
//! `mcrun` is a polymorphic binary that can operate in two modes: MicroVM or supervisor.
//!
//! # Overview
//!
//! This binary provides a unified interface for running either:
//! - A MicroVM that provides an isolated execution environment
//! - A supervisor process that can manage and monitor child processes
//!
//! ## Usage
//!
//! ### MicroVM Mode
//!
//! To run as a MicroVM:
//! ```bash
//! mcrun microvm \
//! --root-path=/path/to/rootfs \
//! --ram-mib=1024 \
//! --mapped-dirs=/host/path:/guest/path \
//! --port-map=8080:80 \
//! --workdir-path=/app \
//! --exec-path=/usr/bin/python3 \
//! --args="-m" --args="http.server" --args="8080"
//! ```
//!
//! ### Supervisor Mode
//!
//! To run as a supervisor:
//! ```bash
//! mcrun supervisor \
//! --log-dir=/path/to/logs \
//! --child-name=my_vm \
//! --db-path=/path/to/mcrun.db
//! ```
use std::env;

use anyhow::Result;
use clap::Parser;
use monocore::{
cli::{McrunArgs, McrunSubcommand},
config::{EnvPair, PathPair, PortPair},
runtime::MicroVmMonitor,
vm::MicroVm,
};
use monoutils::runtime::Supervisor;

//--------------------------------------------------------------------------------------------------
// Constants
//--------------------------------------------------------------------------------------------------

/// Log file prefix for mcrun processes
const MCRUN_LOG_PREFIX: &str = "mcrun";

//--------------------------------------------------------------------------------------------------
// Functions: main
//--------------------------------------------------------------------------------------------------

#[tokio::main]
async fn main() -> Result<()> {
// Initialize logging without ANSI colors
tracing_subscriber::fmt().with_ansi(false).init();

// Parse command line arguments
let args = McrunArgs::parse();

match args.subcommand {
McrunSubcommand::Microvm {
root_path,
num_vcpus,
ram_mib,
mapped_dirs,
port_map,
workdir_path,
exec_path,
args,
env,
} => {
// Parse mapped directories
let mapped_dirs: Vec<PathPair> = mapped_dirs
.iter()
.map(|s| s.parse())
.collect::<Result<_, _>>()?;

// Parse port mappings
let port_map: Vec<PortPair> = port_map
.iter()
.map(|s| s.parse())
.collect::<Result<_, _>>()?;

// Parse environment variables
let env: Vec<EnvPair> = env.iter().map(|s| s.parse()).collect::<Result<_, _>>()?;

// Create and configure MicroVM
let mut builder = MicroVm::builder()
.root_path(root_path)
.num_vcpus(num_vcpus)
.ram_mib(ram_mib)
.mapped_dirs(mapped_dirs)
.port_map(port_map)
.exec_path(exec_path)
.args(args.iter().map(|s| s.as_str()))
.env(env);

if let Some(workdir_path) = workdir_path {
builder = builder.workdir_path(workdir_path);
}

// Build and start the MicroVM
let vm = builder.build()?;

tracing::info!("Starting MicroVM");
vm.start()?;
}
McrunSubcommand::Supervisor {
log_dir,
child_name,
sandbox_db_path,
} => {
// Get current executable path
let current_exe = env::current_exe()?;

// Get supervisor PID
let supervisor_pid = std::process::id();

// Create microvm monitor
let microvm_monitor = MicroVmMonitor::new(sandbox_db_path, supervisor_pid).await?;

// Compose child arguments - these are placeholders that will be overridden
let child_args = vec![
"microvm".to_string(),
"--root-path=/".to_string(),
"--ram-mib=512".to_string(),
];

// Compose child environment variables
let child_envs = vec![("RUST_LOG", "info")];

// Create and start supervisor
let mut supervisor = Supervisor::new(
current_exe,
child_args,
child_envs,
child_name,
MCRUN_LOG_PREFIX,
log_dir,
microvm_monitor,
);

supervisor.start().await?;
}
}

Ok(())
}
75 changes: 75 additions & 0 deletions monocore/lib/cli/args/mcrun.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use std::path::PathBuf;

use clap::{Parser, Subcommand};

use crate::cli::styles;

//--------------------------------------------------------------------------------------------------
// Types
//--------------------------------------------------------------------------------------------------

/// Arguments for the mcrun command
#[derive(Debug, Parser)]
#[command(name = "mcrun", author, styles=styles::styles())]
pub struct McrunArgs {
/// The subcommand to run
#[command(subcommand)]
pub subcommand: McrunSubcommand,
}

/// Available subcommands for managing microvms
#[derive(Subcommand, Debug)]
pub enum McrunSubcommand {
/// Run as microvm
Microvm {
/// Root filesystem path
#[arg(long)]
root_path: PathBuf,

/// Number of virtual CPUs
#[arg(long)]
num_vcpus: u8,

/// RAM size in MiB
#[arg(long)]
ram_mib: u32,

/// Directory mappings (host:guest format)
#[arg(long)]
mapped_dirs: Vec<String>,

/// Port mappings (host:guest format)
#[arg(long)]
port_map: Vec<String>,

/// Working directory path
#[arg(long)]
workdir_path: Option<String>,

/// Executable path
#[arg(long)]
exec_path: String,

/// Arguments for the executable
#[arg(long)]
args: Vec<String>,

/// Environment variables (KEY=VALUE format)
#[arg(long)]
env: Vec<String>,
},
/// Run as supervisor
Supervisor {
/// Directory for log files
#[arg(long)]
log_dir: PathBuf,

/// Name of the child process
#[arg(long)]
child_name: String,

/// Path to the sandbox metrics and metadata database file
#[arg(long)]
sandbox_db_path: PathBuf,
},
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod mcrun;
mod monocore;

//--------------------------------------------------------------------------------------------------
// Types
// Exports
//--------------------------------------------------------------------------------------------------

/// TODO: Implement this
pub struct Orchestrator {}
pub use mcrun::*;
pub use monocore::*;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::path::PathBuf;

use super::styles;
use crate::cli::styles;
use clap::Parser;
use typed_path::Utf8UnixPathBuf;

Expand Down
9 changes: 6 additions & 3 deletions monocore/lib/config/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ pub const DEFAULT_NUM_VCPUS: u8 = 1;
/// The default amount of RAM in MiB to use for the MicroVm.
pub const DEFAULT_RAM_MIB: u32 = 1024;

/// Default port for the HTTP server
pub const DEFAULT_SERVER_PORT: u16 = 3456;

/// The path where all monocore global data is stored.
pub static DEFAULT_MONOCORE_HOME: LazyLock<PathBuf> =
LazyLock::new(|| dirs::home_dir().unwrap().join(MONOCORE_HOME_DIR));

/// The default path for the mcrun binary.
pub const DEFAULT_MCRUN_BIN_PATH: &str = "./mcrun";

/// The default path for the monofs binary.
pub const DEFAULT_MONOFS_BIN_PATH: &str = "./monofs";

/// The default configuration file content
pub(crate) const DEFAULT_CONFIG: &str = r#"# Sandbox configurations
sandboxes: []
Expand Down
4 changes: 2 additions & 2 deletions monocore/lib/runtime/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! Runtime components for the Monocore runtime.
mod orchestrator;
mod monitor;

//--------------------------------------------------------------------------------------------------
// Exports
//--------------------------------------------------------------------------------------------------

pub use orchestrator::*;
pub use monitor::*;
Loading

0 comments on commit 44f6277

Please sign in to comment.