vmm: {De}serialize VmConfig

We use the serde crate to serialize and deserialize the VmVConfig
structure. This structure will be passed from the HTTP API caller as a
JSON payload and we need to deserialize it into a VmConfig.

For a convenient use of the HTTP API, we also provide Default traits
implementations for some of the VmConfig fields (vCPUs, memory, etc...).

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Samuel Ortiz 2019-09-27 11:40:50 +02:00
parent f2de4d0315
commit f674019ea1
5 changed files with 87 additions and 21 deletions

14
Cargo.lock generated
View File

@ -767,6 +767,16 @@ name = "serde"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.41"
@ -1084,6 +1094,9 @@ dependencies = [
"net_util 0.1.0",
"pci 0.1.0",
"qcow 0.1.0",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"vfio 0.0.1",
@ -1226,6 +1239,7 @@ dependencies = [
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e"
"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
"checksum signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4f61c4d59f3aaa9f61bba6450a9b80ba48362fd7d651689e7a10c453b1f6dc68"
"checksum signal-hook-registry 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1797d48f38f91643908bb14e35e79928f9f4b3cefb2420a564dde0991b4358dc"

View File

@ -79,6 +79,9 @@ fn main() {
}
}
let default_vcpus = format! {"{}", config::DEFAULT_VCPUS};
let default_memory = &format! {"size={}M", config::DEFAULT_MEMORY_MB};
let cmd_arguments = App::new("cloud-hypervisor")
.version(crate_version!())
.author(crate_authors!())
@ -89,7 +92,7 @@ fn main() {
Arg::with_name("cpus")
.long("cpus")
.help("Number of virtual CPUs")
.default_value(config::DEFAULT_VCPUS)
.default_value(&default_vcpus)
.group("vm-config"),
)
.arg(
@ -99,7 +102,7 @@ fn main() {
"Memory parameters \"size=<guest_memory_size>,\
file=<backing_file_path>\"",
)
.default_value(config::DEFAULT_MEMORY)
.default_value(&default_memory)
.group("vm-config"),
)
.arg(

View File

@ -25,6 +25,9 @@ micro_http = { path = "../micro_http" }
net_util = { path = "../net_util" }
pci = {path = "../pci", optional = true}
qcow = { path = "../qcow" }
serde = {version = ">=1.0.27", features = ["rc"] }
serde_derive = ">=1.0.27"
serde_json = ">=1.0.9"
vfio = { path = "../vfio", optional = true }
vm-virtio = { path = "../vm-virtio" }
vm-allocator = { path = "../vm-allocator" }

View File

@ -12,8 +12,8 @@ use std::net::Ipv4Addr;
use std::path::PathBuf;
use std::result;
pub const DEFAULT_VCPUS: &str = "1";
pub const DEFAULT_MEMORY: &str = "size=512M";
pub const DEFAULT_VCPUS: u8 = 1;
pub const DEFAULT_MEMORY_MB: u64 = 512;
pub const DEFAULT_RNG_SOURCE: &str = "/dev/urandom";
/// Errors associated with VM configuration parameters.
@ -114,7 +114,7 @@ fn parse_size(size: &str) -> Result<u64> {
Ok(res << shift)
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CpusConfig(pub u8);
impl CpusConfig {
@ -131,7 +131,13 @@ impl From<&CpusConfig> for u8 {
}
}
#[derive(Clone, Debug)]
impl Default for CpusConfig {
fn default() -> Self {
CpusConfig(DEFAULT_VCPUS)
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct MemoryConfig {
pub size: u64,
pub file: Option<PathBuf>,
@ -172,12 +178,21 @@ impl MemoryConfig {
}
}
#[derive(Clone, Debug)]
impl Default for MemoryConfig {
fn default() -> Self {
MemoryConfig {
size: DEFAULT_MEMORY_MB << 20,
file: None,
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct KernelConfig {
pub path: PathBuf,
}
#[derive(Clone)]
#[derive(Clone, Deserialize, Serialize)]
pub struct CmdlineConfig {
pub args: String,
}
@ -192,7 +207,7 @@ impl CmdlineConfig {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DiskConfig {
pub path: PathBuf,
}
@ -205,7 +220,7 @@ impl DiskConfig {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct NetConfig {
pub tap: Option<String>,
pub ip: Ipv4Addr,
@ -257,7 +272,7 @@ impl NetConfig {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct RngConfig {
pub src: PathBuf,
}
@ -270,7 +285,15 @@ impl RngConfig {
}
}
#[derive(Clone, Debug)]
impl Default for RngConfig {
fn default() -> Self {
RngConfig {
src: PathBuf::from(DEFAULT_RNG_SOURCE),
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct FsConfig {
pub tag: String,
pub sock: PathBuf,
@ -358,7 +381,7 @@ impl FsConfig {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct PmemConfig {
pub file: PathBuf,
pub size: u64,
@ -391,7 +414,7 @@ impl PmemConfig {
}
}
#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, Deserialize, Serialize)]
pub enum ConsoleOutputMode {
Off,
Tty,
@ -408,7 +431,7 @@ impl ConsoleOutputMode {
}
}
#[derive(Clone)]
#[derive(Clone, Deserialize, Serialize)]
pub struct ConsoleConfig {
pub file: Option<PathBuf>,
pub mode: ConsoleOutputMode,
@ -440,9 +463,23 @@ impl ConsoleConfig {
Err(Error::ParseConsoleParam)
}
}
pub fn default_serial() -> Self {
ConsoleConfig {
file: None,
mode: ConsoleOutputMode::Null,
}
}
pub fn default_console() -> Self {
ConsoleConfig {
file: None,
mode: ConsoleOutputMode::Tty,
}
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DeviceConfig {
pub path: PathBuf,
}
@ -455,14 +492,14 @@ impl DeviceConfig {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct VuConfig {
pub sock: String,
pub num_queues: usize,
pub queue_size: u16,
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct VhostUserNetConfig {
pub mac: MacAddr,
pub vu_cfg: VuConfig,
@ -521,7 +558,7 @@ impl VhostUserNetConfig {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct VsockConfig {
pub cid: u64,
pub sock: PathBuf,
@ -554,7 +591,7 @@ impl VsockConfig {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct VhostUserBlkConfig {
pub wce: bool,
pub vu_cfg: VuConfig,
@ -610,18 +647,23 @@ impl VhostUserBlkConfig {
}
}
#[derive(Clone)]
#[derive(Clone, Deserialize, Serialize)]
pub struct VmConfig {
#[serde(default)]
pub cpus: CpusConfig,
#[serde(default)]
pub memory: MemoryConfig,
pub kernel: Option<KernelConfig>,
pub cmdline: CmdlineConfig,
pub disks: Option<Vec<DiskConfig>>,
pub net: Option<Vec<NetConfig>>,
#[serde(default)]
pub rng: RngConfig,
pub fs: Option<Vec<FsConfig>>,
pub pmem: Option<Vec<PmemConfig>>,
#[serde(default = "ConsoleConfig::default_serial")]
pub serial: ConsoleConfig,
#[serde(default = "ConsoleConfig::default_console")]
pub console: ConsoleConfig,
pub devices: Option<Vec<DeviceConfig>>,
pub vhost_user_net: Option<Vec<VhostUserNetConfig>>,

View File

@ -8,6 +8,10 @@ extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate vmm_sys_util;
use crate::api::{ApiError, ApiRequest, ApiResponse, ApiResponsePayload};