-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(vmm): add grpc server to handle api requests (#26)
* feat: grpc and cli in lumper Signed-off-by: Mauran <[email protected]> --------- Signed-off-by: Mauran <[email protected]>
- Loading branch information
1 parent
e3bd31d
commit 2338841
Showing
6 changed files
with
166 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
tonic_build::compile_protos("../../proto/vmm.proto")?; | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,9 @@ | ||
pub mod core; | ||
pub mod service; | ||
|
||
#[derive(Debug)] | ||
pub enum VmmErrors { | ||
VmmNew(core::Error), | ||
VmmConfigure(core::Error), | ||
VmmRun(core::Error), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,60 @@ | ||
use crate::args::CliArguments; | ||
use crate::args::{CliArgs, Commands}; | ||
use clap::Parser; | ||
use tonic::transport::Server; | ||
use tracing::info; | ||
use vmm::core::{self, vmm::VMM}; | ||
|
||
use vmm::{ | ||
core::vmm::VMM, | ||
service::{vmmorchestrator, VmmService}, | ||
VmmErrors, | ||
}; | ||
mod args; | ||
|
||
#[derive(Debug)] | ||
pub enum Error { | ||
VmmNew(core::Error), | ||
VmmConfigure(core::Error), | ||
VmmRun(core::Error), | ||
} | ||
|
||
/// The application entry point. | ||
fn main() -> Result<(), Error> { | ||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
// Parse the configuration and configure logger verbosity | ||
let args = CliArguments::parse(); | ||
tracing_subscriber::fmt() | ||
.with_max_level(args.convert_log_to_tracing()) | ||
.init(); | ||
let args = CliArgs::parse(); | ||
|
||
info!( | ||
app_name = env!("CARGO_PKG_NAME"), | ||
app_version = env!("CARGO_PKG_VERSION"), | ||
"Starting application", | ||
); | ||
|
||
// Create a new VMM | ||
let mut vmm = | ||
VMM::new(args.network_host_ip, args.network_host_netmask).map_err(Error::VmmNew)?; | ||
|
||
vmm.configure(args.cpus, args.memory, &args.kernel, &args.initramfs) | ||
.map_err(Error::VmmConfigure)?; | ||
|
||
// Run the VMM | ||
vmm.run().map_err(Error::VmmRun)?; | ||
let addr = "[::1]:50051".parse().unwrap(); | ||
let vmm_service = VmmService; | ||
|
||
// check if the args is grpc or command | ||
match args.command { | ||
Commands::Grpc => { | ||
Server::builder() | ||
.add_service(vmmorchestrator::vmm_service_server::VmmServiceServer::new( | ||
vmm_service, | ||
)) | ||
.serve(addr) | ||
.await?; | ||
} | ||
Commands::Cli(cli_args) => { | ||
tracing_subscriber::fmt() | ||
.with_max_level(cli_args.convert_log_to_tracing()) | ||
.init(); | ||
// Create a new VMM | ||
let mut vmm = VMM::new(cli_args.network_host_ip, cli_args.network_host_netmask) | ||
.map_err(VmmErrors::VmmNew) | ||
.unwrap(); | ||
|
||
vmm.configure( | ||
cli_args.cpus, | ||
cli_args.memory, | ||
&cli_args.kernel, | ||
&cli_args.initramfs, | ||
) | ||
.map_err(VmmErrors::VmmConfigure) | ||
.unwrap(); | ||
|
||
// Run the VMM | ||
vmm.run().map_err(VmmErrors::VmmRun).unwrap(); | ||
} | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
use self::vmmorchestrator::{ | ||
vmm_service_server::VmmService as VmmServiceTrait, RunVmmRequest, RunVmmResponse, | ||
}; | ||
use crate::core::vmm::VMM; | ||
use crate::VmmErrors; | ||
use std::{ | ||
convert::From, | ||
net::Ipv4Addr, | ||
path::{Path, PathBuf}, | ||
process::{Command, Stdio}, | ||
}; | ||
use tonic::{Request, Response, Status}; | ||
use tracing::{error, info}; | ||
|
||
pub mod vmmorchestrator { | ||
tonic::include_proto!("vmmorchestrator"); | ||
} | ||
|
||
// Implement the From trait for VmmErrors into Status | ||
impl From<VmmErrors> for Status { | ||
fn from(error: VmmErrors) -> Self { | ||
// You can create a custom Status variant based on the error | ||
match error { | ||
VmmErrors::VmmNew(_) => Status::internal("Error creating VMM"), | ||
VmmErrors::VmmConfigure(_) => Status::internal("Error configuring VMM"), | ||
VmmErrors::VmmRun(_) => Status::internal("Error running VMM"), | ||
} | ||
} | ||
} | ||
|
||
#[derive(Default)] | ||
pub struct VmmService; | ||
|
||
#[tonic::async_trait] | ||
impl VmmServiceTrait for VmmService { | ||
async fn run( | ||
&self, | ||
_request: Request<RunVmmRequest>, | ||
) -> Result<Response<RunVmmResponse>, Status> { | ||
let response = vmmorchestrator::RunVmmResponse {}; | ||
|
||
const HOST_IP: Ipv4Addr = Ipv4Addr::new(172, 29, 0, 1); | ||
const HOST_NETMASK: Ipv4Addr = Ipv4Addr::new(255, 255, 0, 0); | ||
|
||
// Check if the kernel is on the system, else build it | ||
if !Path::new("./tools/kernel/linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin") | ||
.exists() | ||
{ | ||
info!("Kernel not found, building kernel"); | ||
// Execute the script using sh and capture output and error streams | ||
let output = Command::new("sh") | ||
.arg("./tools/kernel/mkkernel.sh") | ||
.stdout(Stdio::piped()) | ||
.stderr(Stdio::piped()) | ||
.output() | ||
.expect("Failed to execute the kernel build script"); | ||
|
||
// Print output and error streams | ||
error!("Script output: {}", String::from_utf8_lossy(&output.stdout)); | ||
error!("Script errors: {}", String::from_utf8_lossy(&output.stderr)); | ||
}; | ||
|
||
let kernel_path = &Path::new( | ||
"./tools/kernel/linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin", | ||
); | ||
let mut initramfs_path: PathBuf = PathBuf::new(); | ||
|
||
// Todo - Check if the initramfs for the specified language is on the system, else build it | ||
initramfs_path.push("./tools/rootfs/initramfs.img"); | ||
|
||
// // Create a new VMM | ||
let mut vmm = VMM::new(HOST_IP, HOST_NETMASK).map_err(VmmErrors::VmmNew)?; | ||
|
||
// Configure the VMM parameters might need to be calculated rather than hardcoded | ||
vmm.configure(1, 512, kernel_path, &Some(initramfs_path)) | ||
.map_err(VmmErrors::VmmConfigure)?; | ||
// Run the VMM | ||
vmm.run().map_err(VmmErrors::VmmRun)?; | ||
|
||
Ok(Response::new(response)) | ||
} | ||
} |