From 992ff55405d31d1eeca32bc85517388eeeb031b4 Mon Sep 17 00:00:00 2001 From: Mauran Date: Wed, 1 May 2024 14:56:00 +0200 Subject: [PATCH] feat: send code through cli and api to vm Signed-off-by: Mauran --- proto/vmm.proto | 7 +++-- src/agent/src/main.rs | 2 +- src/api/src/service.rs | 13 +++++++--- src/cli/src/services.rs | 17 ++++++------ src/shared-models/src/lib.rs | 4 +-- src/vmm/src/args.rs | 10 ++++--- src/vmm/src/core/devices/virtio/net/device.rs | 17 ++++++++---- src/vmm/src/core/vmm.rs | 17 +++++++----- src/vmm/src/grpc/server.rs | 26 ++++++++++++++----- src/vmm/src/main.rs | 10 ++++--- 10 files changed, 81 insertions(+), 42 deletions(-) diff --git a/proto/vmm.proto b/proto/vmm.proto index 4b394ab..e954584 100644 --- a/proto/vmm.proto +++ b/proto/vmm.proto @@ -36,10 +36,9 @@ service VmmService { } message RunVmmRequest { - - Language language = 1; - string code = 2; - string env = 3; + string workload_name = 1; + Language language = 2; + string code = 3; LogLevel log_level = 4; } diff --git a/src/agent/src/main.rs b/src/agent/src/main.rs index 5945d48..93437f2 100644 --- a/src/agent/src/main.rs +++ b/src/agent/src/main.rs @@ -7,7 +7,7 @@ use tonic::transport::Server; #[derive(Debug, Parser)] struct Args { - #[clap(long, env, default_value = "localhost")] + #[clap(long, env, default_value = "0.0.0.0")] grpc_server_address: String, #[clap(long, env, default_value = "50051")] grpc_server_port: u16, diff --git a/src/api/src/service.rs b/src/api/src/service.rs index a312bf8..4d081e9 100644 --- a/src/api/src/service.rs +++ b/src/api/src/service.rs @@ -6,7 +6,7 @@ use actix_web::{post, web, HttpResponse, Responder}; use actix_web_lab::sse; use async_stream::stream; use serde::Serialize; -use shared_models::CloudletDtoRequest; +use shared_models::{CloudletDtoRequest, Language}; use tokio_stream::StreamExt; use tonic::Streaming; @@ -16,10 +16,17 @@ pub async fn run(req_body: web::Json) -> impl Responder { let mut client = VmmClient::new().await.unwrap(); + println!("Request: {:?}", req); + let vmm_request = RunVmmRequest { + workload_name: req.workload_name, code: req.code, - env: req.env, - language: req.language as i32, + language: match req.language { + Language::PYTHON => 0, + Language::NODE => 1, + Language::RUST => 2, + _ => unreachable!("Invalid language") + }, log_level: req.log_level as i32, }; diff --git a/src/cli/src/services.rs b/src/cli/src/services.rs index b2987e0..097e306 100644 --- a/src/cli/src/services.rs +++ b/src/cli/src/services.rs @@ -7,24 +7,25 @@ use std::{error::Error, path::PathBuf}; #[derive(Deserialize)] struct TomlConfig { #[serde(rename = "workload-name")] - _workload_name: String, + workload_name: String, language: Language, - _action: String, - _server: ServerConfig, + action: String, + server: ServerConfig, build: BuildConfig, } #[derive(Deserialize)] struct ServerConfig { - _address: String, - _port: u16, + address: String, + port: u16, } #[derive(Deserialize)] struct BuildConfig { #[serde(rename = "source-code-path")] source_code_path: PathBuf, - _release: bool, + #[serde(rename = "release")] + release: bool, } pub struct CloudletClient {} @@ -34,15 +35,15 @@ impl CloudletClient { let config: TomlConfig = toml::from_str(&config).expect("Error while parsing the config file"); + let workload_name = config.workload_name; let code: String = ConfigFileHandler::read_file(&config.build.source_code_path) .expect("Error while reading the code file"); - let env = ""; let language = config.language; CloudletDtoRequest { + workload_name, language, code, - env: env.to_string(), log_level: shared_models::LogLevel::INFO, } } diff --git a/src/shared-models/src/lib.rs b/src/shared-models/src/lib.rs index e32fe1b..930e287 100644 --- a/src/shared-models/src/lib.rs +++ b/src/shared-models/src/lib.rs @@ -22,16 +22,16 @@ pub enum LogLevel { #[derive(Deserialize, Debug)] pub struct TomlClientConfigFile { + pub worklaod_name: String, pub language: Language, - pub env_path: PathBuf, pub code_path: PathBuf, pub log_level: LogLevel, } #[derive(Serialize, Deserialize, Debug)] pub struct CloudletDtoRequest { + pub workload_name: String, pub language: Language, - pub env: String, pub code: String, pub log_level: LogLevel, } diff --git a/src/vmm/src/args.rs b/src/vmm/src/args.rs index d4e9bcc..3feceef 100644 --- a/src/vmm/src/args.rs +++ b/src/vmm/src/args.rs @@ -42,11 +42,15 @@ pub struct CliArguments { /// IPv4 address of the host tap interface. #[clap(long, env, required = true)] - pub network_host_ip: Ipv4Addr, + pub iface_host_addr: Ipv4Addr, - /// Subnet mask of the host tap interface. + /// Subnet mask for network. #[clap(long, env, required = true)] - pub network_host_netmask: Ipv4Addr, + pub netmask: Ipv4Addr, + + /// IPv4 address of the guest eth0 interface. + #[clap(long, env, required = true)] + pub iface_guest_addr: Ipv4Addr, /// Verbosity level. #[command(flatten)] diff --git a/src/vmm/src/core/devices/virtio/net/device.rs b/src/vmm/src/core/devices/virtio/net/device.rs index d388564..bf8acf8 100644 --- a/src/vmm/src/core/devices/virtio/net/device.rs +++ b/src/vmm/src/core/devices/virtio/net/device.rs @@ -42,8 +42,9 @@ impl Net { mem: Arc, device_mgr: Arc>, mmio_cfg: MmioConfig, - ip_addr: Ipv4Addr, - mask: Ipv4Addr, + tap_addr: Ipv4Addr, + netmask: Ipv4Addr, + iface_guest_addr: Ipv4Addr, irq: u32, endpoint: RemoteEndpoint, vm_fd: Arc, @@ -73,7 +74,7 @@ impl Net { // Set offload flags to match the relevant virtio features of the device (for now, // statically set in the constructor. - let tap = open_tap(None, Some(ip_addr), Some(mask), &mut None, None, None) + let tap = open_tap(None, Some(tap_addr), Some(netmask), &mut None, None, None) .map_err(Error::TunTap)?; // The layout of the header is specified in the standard and is 12 bytes in size. We @@ -87,9 +88,15 @@ impl Net { tap: Arc::new(Mutex::new(tap)), })); - let param = register_mmio_device(mmio_cfg, device_mgr, irq, None, net.clone()) + let vmmio_param = register_mmio_device(mmio_cfg, device_mgr, irq, None, net.clone()) .map_err(Error::Virtio)?; - cmdline_extra_parameters.push(param); + let ip_pnp_param: String = format!( + "ip={}::{}:{}::eth0:off", + iface_guest_addr, tap_addr, netmask + ); + + cmdline_extra_parameters.push(vmmio_param); + cmdline_extra_parameters.push(ip_pnp_param); Ok(net) } diff --git a/src/vmm/src/core/vmm.rs b/src/vmm/src/core/vmm.rs index 6b5097a..902b7ad 100644 --- a/src/vmm/src/core/vmm.rs +++ b/src/vmm/src/core/vmm.rs @@ -58,8 +58,9 @@ pub struct VMM { event_mgr: EventMgr, vcpus: Vec, - tap_ip_addr: Ipv4Addr, - tap_netmask: Ipv4Addr, + tap_addr: Ipv4Addr, + netmask: Ipv4Addr, + iface_guest_addr: Ipv4Addr, net_devices: Vec>>, serial: Arc>>, slip_pty: Arc>, @@ -68,7 +69,7 @@ pub struct VMM { impl VMM { /// Create a new VMM. - pub fn new(tap_ip_addr: Ipv4Addr, tap_netmask: Ipv4Addr) -> Result { + pub fn new(tap_addr: Ipv4Addr, netmask: Ipv4Addr, iface_guest_addr: Ipv4Addr) -> Result { // Open /dev/kvm and get a file descriptor to it. let kvm = Kvm::new().map_err(Error::KvmIoctl)?; @@ -110,8 +111,9 @@ impl VMM { )), slip_pty: Arc::new(Mutex::new(slip_pty)), epoll, - tap_ip_addr, - tap_netmask, + tap_addr, + netmask, + iface_guest_addr, net_devices: Vec::new(), }; @@ -380,8 +382,9 @@ impl VMM { mem, self.device_mgr.clone(), mmio_cfg, - self.tap_ip_addr, - self.tap_netmask, + self.tap_addr, + self.netmask, + self.iface_guest_addr, irq, self.event_mgr.lock().unwrap().remote_endpoint(), self.vm_fd.clone(), diff --git a/src/vmm/src/grpc/server.rs b/src/vmm/src/grpc/server.rs index 1a8fb2c..86880a1 100644 --- a/src/vmm/src/grpc/server.rs +++ b/src/vmm/src/grpc/server.rs @@ -43,12 +43,12 @@ impl VmmServiceTrait for VmmService { type RunStream = ReceiverStream>; - async fn run(&self, _request: Request) -> Result { + async fn run(&self, request: Request) -> Result { let (tx, rx) = tokio::sync::mpsc::channel(4); const HOST_IP: Ipv4Addr = Ipv4Addr::new(172, 29, 0, 1); - const VM_IP: Ipv4Addr = Ipv4Addr::new(172, 29, 0, 2); const HOST_NETMASK: Ipv4Addr = Ipv4Addr::new(255, 255, 0, 0); + const GUEST_IP: Ipv4Addr = Ipv4Addr::new(172, 29, 0, 2); // 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") @@ -77,7 +77,7 @@ impl VmmServiceTrait for VmmService { initramfs_path.push("./tools/rootfs/initramfs.img"); // // Create a new VMM - let mut vmm = VMM::new(HOST_IP, HOST_NETMASK).map_err(VmmErrors::VmmNew)?; + let mut vmm = VMM::new(HOST_IP, HOST_NETMASK, GUEST_IP).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)) @@ -96,20 +96,34 @@ impl VmmServiceTrait for VmmService { tokio::time::sleep(Duration::from_secs(2)).await; println!("Connecting to Agent service"); - WorkloadClient::new(VM_IP, 50051).await + WorkloadClient::new(GUEST_IP, 50051).await }) .await .unwrap(); // Send the grpc request to start the agent - let execute_request = ExecuteRequest {}; + let vmm_request = request.into_inner(); + println!("HERRREEEE {}", vmm_request.language); + let agent_request = ExecuteRequest { + workload_name: vmm_request.workload_name, + language: match vmm_request.language { + 0 => "python".to_string(), + 1 => "node".to_string(), + 2 => "rust".to_string(), + _ => unreachable!("Invalid language") + }, + action: 2, // Prepare and run + code: vmm_request.code, + config_str: "[build]\nrelease = true".to_string(), + }; + match grpc_client { Ok(mut client) => { info!("Successfully connected to Agent service"); // Start the execution - let mut response_stream = client.execute(execute_request).await?; + let mut response_stream = client.execute(agent_request).await?; // Process each message as it arrives while let Some(response) = response_stream.message().await? { diff --git a/src/vmm/src/main.rs b/src/vmm/src/main.rs index 9947bf0..e12f375 100644 --- a/src/vmm/src/main.rs +++ b/src/vmm/src/main.rs @@ -38,9 +38,13 @@ async fn main() -> Result<(), Box> { .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(); + let mut vmm = VMM::new( + cli_args.iface_host_addr, + cli_args.netmask, + cli_args.iface_guest_addr, + ) + .map_err(VmmErrors::VmmNew) + .unwrap(); vmm.configure( cli_args.cpus,