diff --git a/src/runtime-rs/crates/hypervisor/ch-config/src/ch_api.rs b/src/runtime-rs/crates/hypervisor/ch-config/src/ch_api.rs index 5a5ab90cc5..2b5b34c750 100644 --- a/src/runtime-rs/crates/hypervisor/ch-config/src/ch_api.rs +++ b/src/runtime-rs/crates/hypervisor/ch-config/src/ch_api.rs @@ -2,8 +2,10 @@ // // SPDX-License-Identifier: Apache-2.0 -use crate::{DeviceConfig, DiskConfig, FsConfig, NetConfig, VmConfig, VsockConfig}; -use anyhow::{anyhow, Result}; +use crate::{ + DeviceConfig, DiskConfig, FsConfig, NetConfig, VmConfig, VmInfo, VmResize, VsockConfig, +}; +use anyhow::{anyhow, Context, Result}; use api_client::simple_api_full_command_and_response; use serde::{Deserialize, Serialize}; @@ -190,3 +192,34 @@ pub async fn cloud_hypervisor_vm_vsock_add( }) .await? } + +pub async fn cloud_hypervisor_vm_info(mut socket: UnixStream) -> Result { + let vm_info = task::spawn_blocking(move || -> Result> { + let response = simple_api_full_command_and_response(&mut socket, "GET", "vm.info", None) + .map_err(|e| anyhow!(format!("failed to run get vminfo with err: {:?}", e)))?; + + Ok(response) + }) + .await??; + + let vm_info = vm_info.ok_or(anyhow!("failed to get vminfo"))?; + serde_json::from_str(&vm_info).with_context(|| format!("failed to serde {}", vm_info)) +} + +pub async fn cloud_hypervisor_vm_resize( + mut socket: UnixStream, + vmresize: VmResize, +) -> Result> { + task::spawn_blocking(move || -> Result> { + let response = simple_api_full_command_and_response( + &mut socket, + "PUT", + "vm.resize", + Some(&serde_json::to_string(&vmresize)?), + ) + .map_err(|e| anyhow!(e))?; + + Ok(response) + }) + .await? +} diff --git a/src/runtime-rs/crates/hypervisor/ch-config/src/lib.rs b/src/runtime-rs/crates/hypervisor/ch-config/src/lib.rs index 5c90f9b8c3..0e3e4122fd 100644 --- a/src/runtime-rs/crates/hypervisor/ch-config/src/lib.rs +++ b/src/runtime-rs/crates/hypervisor/ch-config/src/lib.rs @@ -500,6 +500,32 @@ pub struct NamedHypervisorConfig { pub guest_protection_to_use: GuestProtection, } +#[derive(Clone, Debug, Deserialize, Serialize, Default)] +pub struct VmResize { + pub desired_vcpus: Option, + pub desired_ram: Option, + pub desired_balloon: Option, +} + +/// VmInfo : Virtual Machine information +#[derive(Clone, Default, Debug, Serialize, Deserialize)] +pub struct VmInfo { + pub config: VmConfig, + pub state: State, + #[serde(skip_serializing_if = "Option::is_none")] + pub memory_actual_size: Option, +} + +#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub enum State { + #[default] + Created, + Running, + Shutdown, + Paused, +} + // Returns true if the enabled guest protection is Intel TDX. pub fn guest_protection_is_tdx(guest_protection_to_use: GuestProtection) -> bool { matches!(guest_protection_to_use, GuestProtection::Tdx)