vmm: Move kernel check to VmConfig::validate() method

Replace the existing VmConfig::valid() check with a call into
.validate() as part of earlier config setup or boot API checks.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2020-04-06 17:00:38 +01:00
parent 3b0da2d895
commit aaf382eee2
2 changed files with 210 additions and 52 deletions

View File

@ -331,7 +331,9 @@ fn start_vmm(cmd_arguments: ArgMatches) {
} }
}; };
if cmd_arguments.is_present("vm-config") && vm_config.valid() { // Can't test for "vm-config" group as some have default values. The kernel
// is the only required option for booting the VM.
if cmd_arguments.is_present("kernel") {
// Create and boot the VM based off the VM config we just built. // Create and boot the VM based off the VM config we just built.
let sender = api_request_sender.clone(); let sender = api_request_sender.clone();
vmm::api::vm_create( vmm::api::vm_create(
@ -441,8 +443,8 @@ mod unit_tests {
use crate::{create_app, prepare_default_values}; use crate::{create_app, prepare_default_values};
use std::path::PathBuf; use std::path::PathBuf;
use vmm::config::{ use vmm::config::{
CmdlineConfig, ConsoleConfig, ConsoleOutputMode, CpusConfig, MemoryConfig, RngConfig, CmdlineConfig, ConsoleConfig, ConsoleOutputMode, CpusConfig, KernelConfig, MemoryConfig,
VmConfig, VmParams, RngConfig, VmConfig, VmParams,
}; };
fn get_vm_config_from_vec(args: &[&str]) -> VmConfig { fn get_vm_config_from_vec(args: &[&str]) -> VmConfig {
@ -485,8 +487,8 @@ mod unit_tests {
#[test] #[test]
fn test_valid_vm_config_default() { fn test_valid_vm_config_default() {
let cli = vec!["cloud-hypervisor"]; let cli = vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"];
let openapi = r#"{}"#; let openapi = r#"{ "kernel": {"path": "/path/to/kernel"} }"#;
// First we check we get identical VmConfig structures. // First we check we get identical VmConfig structures.
let (result_vm_config, _) = compare_vm_config_cli_vs_json(&cli, openapi, true); let (result_vm_config, _) = compare_vm_config_cli_vs_json(&cli, openapi, true);
@ -505,7 +507,9 @@ mod unit_tests {
hotplug_method: HotplugMethod::Acpi, hotplug_method: HotplugMethod::Acpi,
hotplug_size: None, hotplug_size: None,
}, },
kernel: None, kernel: Some(KernelConfig {
path: PathBuf::from("/path/to/kernel"),
}),
initramfs: None, initramfs: None,
cmdline: CmdlineConfig { cmdline: CmdlineConfig {
args: String::from(""), args: String::from(""),
@ -542,22 +546,43 @@ mod unit_tests {
fn test_valid_vm_config_cpus() { fn test_valid_vm_config_cpus() {
vec![ vec![
( (
vec!["cloud-hypervisor", "--cpus", "boot=1"], vec![
"cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--cpus",
"boot=1",
],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"cpus": {"boot_vcpus": 1, "max_vcpus": 1} "cpus": {"boot_vcpus": 1, "max_vcpus": 1}
}"#, }"#,
true, true,
), ),
( (
vec!["cloud-hypervisor", "--cpus", "boot=1,max=3"], vec![
"cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--cpus",
"boot=1,max=3",
],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"cpus": {"boot_vcpus": 1, "max_vcpus": 3} "cpus": {"boot_vcpus": 1, "max_vcpus": 3}
}"#, }"#,
true, true,
), ),
( (
vec!["cloud-hypervisor", "--cpus", "boot=2,max=4"], vec![
"cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--cpus",
"boot=2,max=4",
],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"cpus": {"boot_vcpus": 1, "max_vcpus": 3} "cpus": {"boot_vcpus": 1, "max_vcpus": 3}
}"#, }"#,
false, false,
@ -573,61 +598,69 @@ mod unit_tests {
fn test_valid_vm_config_memory() { fn test_valid_vm_config_memory() {
vec![ vec![
( (
vec!["cloud-hypervisor", "--memory", "size=1073741824"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1073741824"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"memory": {"size": 1073741824} "memory": {"size": 1073741824}
}"#, }"#,
true, true,
), ),
( (
vec!["cloud-hypervisor", "--memory", "size=1G"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"memory": {"size": 1073741824} "memory": {"size": 1073741824}
}"#, }"#,
true, true,
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "--memory",
"size=1G,file=/path/to/shared/file", "size=1G,file=/path/to/shared/file",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"memory": {"size": 1073741824, "file": "/path/to/shared/file"} "memory": {"size": 1073741824, "file": "/path/to/shared/file"}
}"#, }"#,
true, true,
), ),
( (
vec!["cloud-hypervisor", "--memory", "size=1G,mergeable=on"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,mergeable=on"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"memory": {"size": 1073741824, "mergeable": true} "memory": {"size": 1073741824, "mergeable": true}
}"#, }"#,
true, true,
), ),
( (
vec!["cloud-hypervisor", "--memory", "size=1G,mergeable=off"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,mergeable=off"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"memory": {"size": 1073741824, "mergeable": false} "memory": {"size": 1073741824, "mergeable": false}
}"#, }"#,
true, true,
), ),
( (
vec!["cloud-hypervisor", "--memory", "size=1G,mergeable=on"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,mergeable=on"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"memory": {"size": 1073741824, "mergeable": false} "memory": {"size": 1073741824, "mergeable": false}
}"#, }"#,
false, false,
), ),
( (
vec!["cloud-hypervisor", "--memory", "size=1G,hotplug_size=1G"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,hotplug_size=1G"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"memory": {"size": 1073741824, "hotplug_method": "Acpi", "hotplug_size": 1073741824} "memory": {"size": 1073741824, "hotplug_method": "Acpi", "hotplug_size": 1073741824}
}"#, }"#,
true, true,
), ),
( (
vec!["cloud-hypervisor", "--memory", "size=1G,hotplug_method=virtio-mem,hotplug_size=1G"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--memory", "size=1G,hotplug_method=virtio-mem,hotplug_size=1G"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"memory": {"size": 1073741824, "hotplug_method": "VirtioMem", "hotplug_size": 1073741824} "memory": {"size": 1073741824, "hotplug_method": "VirtioMem", "hotplug_size": 1073741824}
}"#, }"#,
true, true,
@ -657,8 +690,15 @@ mod unit_tests {
#[test] #[test]
fn test_valid_vm_config_cmdline() { fn test_valid_vm_config_cmdline() {
vec![( vec![(
vec!["cloud-hypervisor", "--cmdline", "arg1=foo arg2=bar"], vec![
"cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--cmdline",
"arg1=foo arg2=bar",
],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"cmdline": {"args": "arg1=foo arg2=bar"} "cmdline": {"args": "arg1=foo arg2=bar"}
}"#, }"#,
true, true,
@ -675,11 +715,14 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--disk", "--disk",
"path=/path/to/disk/1", "path=/path/to/disk/1",
"path=/path/to/disk/2", "path=/path/to/disk/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"disks": [ "disks": [
{"path": "/path/to/disk/1"}, {"path": "/path/to/disk/1"},
{"path": "/path/to/disk/2"} {"path": "/path/to/disk/2"}
@ -690,11 +733,14 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--disk", "--disk",
"path=/path/to/disk/1", "path=/path/to/disk/1",
"path=/path/to/disk/2", "path=/path/to/disk/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"disks": [ "disks": [
{"path": "/path/to/disk/1"} {"path": "/path/to/disk/1"}
] ]
@ -704,11 +750,14 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--disk", "--disk",
"vhost_user=true,socket=/tmp/socket1", "vhost_user=true,socket=/tmp/socket1",
"path=/path/to/disk/2", "path=/path/to/disk/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"disks": [ "disks": [
{"vhost_user":true, "vhost_socket":"/tmp/socket1"}, {"vhost_user":true, "vhost_socket":"/tmp/socket1"},
{"path": "/path/to/disk/2"} {"path": "/path/to/disk/2"}
@ -719,11 +768,14 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--disk", "--disk",
"vhost_user=true,socket=/tmp/socket1,wce=true", "vhost_user=true,socket=/tmp/socket1,wce=true",
"path=/path/to/disk/2", "path=/path/to/disk/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"disks": [ "disks": [
{"vhost_user":true, "vhost_socket":"/tmp/socket1", "wce":true}, {"vhost_user":true, "vhost_socket":"/tmp/socket1", "wce":true},
{"path": "/path/to/disk/2"} {"path": "/path/to/disk/2"}
@ -745,15 +797,17 @@ mod unit_tests {
// randomly generated. There's no way we can have twice the same // randomly generated. There's no way we can have twice the same
// default value. // default value.
( (
vec!["cloud-hypervisor", "--net", "mac="], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--net", "mac="],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [] "net": []
}"#, }"#,
false, false,
), ),
( (
vec!["cloud-hypervisor", "--net", "mac=12:34:56:78:90:ab"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--net", "mac=12:34:56:78:90:ab"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab"} {"mac": "12:34:56:78:90:ab"}
] ]
@ -762,11 +816,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0", "mac=12:34:56:78:90:ab,tap=tap0",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0"} {"mac": "12:34:56:78:90:ab", "tap": "tap0"}
] ]
@ -775,11 +830,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4", "mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4"} {"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4"}
] ]
@ -788,11 +844,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8", "mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8"} {"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8"}
] ]
@ -801,11 +858,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4", "mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4} {"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4}
] ]
@ -814,11 +872,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4,queue_size=128", "mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4,queue_size=128",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4, "queue_size": 128} {"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4, "queue_size": 128}
] ]
@ -827,11 +886,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256", "mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8"} {"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8"}
] ]
@ -840,11 +900,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8", "mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256} {"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256}
] ]
@ -853,11 +914,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=on", "mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": true} {"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": true}
] ]
@ -866,11 +928,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=on", "mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": true} {"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": true}
], ],
@ -880,11 +943,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--net", "--net",
"mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=off", "mac=12:34:56:78:90:ab,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=2,queue_size=256,iommu=off",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": false} {"mac": "12:34:56:78:90:ab", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 2, "queue_size": 256, "iommu": false}
] ]
@ -892,8 +956,9 @@ mod unit_tests {
true, true,
), ),
( (
vec!["cloud-hypervisor", "--net", "mac=12:34:56:78:90:ab,vhost_user=true,socket=/tmp/socket"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel", "--net", "mac=12:34:56:78:90:ab,vhost_user=true,socket=/tmp/socket"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"net": [ "net": [
{"mac": "12:34:56:78:90:ab", "vhost_user": true, "vhost_socket": "/tmp/socket"} {"mac": "12:34:56:78:90:ab", "vhost_user": true, "vhost_socket": "/tmp/socket"}
] ]
@ -910,8 +975,15 @@ mod unit_tests {
#[test] #[test]
fn test_valid_vm_config_rng() { fn test_valid_vm_config_rng() {
vec![( vec![(
vec!["cloud-hypervisor", "--rng", "src=/path/to/entropy/source"], vec![
"cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--rng",
"src=/path/to/entropy/source",
],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"rng": {"src": "/path/to/entropy/source"} "rng": {"src": "/path/to/entropy/source"}
}"#, }"#,
true, true,
@ -927,12 +999,13 @@ mod unit_tests {
vec![ vec![
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--fs", "--fs",
"tag=virtiofs1,sock=/path/to/sock1", "tag=virtiofs1,sock=/path/to/sock1",
"tag=virtiofs2,sock=/path/to/sock2", "tag=virtiofs2,sock=/path/to/sock2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"fs": [ "fs": [
{"tag": "virtiofs1", "sock": "/path/to/sock1"}, {"tag": "virtiofs1", "sock": "/path/to/sock1"},
{"tag": "virtiofs2", "sock": "/path/to/sock2"} {"tag": "virtiofs2", "sock": "/path/to/sock2"}
@ -942,12 +1015,13 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--fs", "--fs",
"tag=virtiofs1,sock=/path/to/sock1", "tag=virtiofs1,sock=/path/to/sock1",
"tag=virtiofs2,sock=/path/to/sock2", "tag=virtiofs2,sock=/path/to/sock2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"fs": [ "fs": [
{"tag": "virtiofs1", "sock": "/path/to/sock1"} {"tag": "virtiofs1", "sock": "/path/to/sock1"}
] ]
@ -956,11 +1030,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--fs", "--fs",
"tag=virtiofs1,sock=/path/to/sock1,num_queues=4", "tag=virtiofs1,sock=/path/to/sock1,num_queues=4",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"fs": [ "fs": [
{"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4} {"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4}
] ]
@ -969,11 +1044,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--fs", "--fs",
"tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128" "tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128"
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"fs": [ "fs": [
{"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128} {"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
] ]
@ -982,11 +1058,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--fs", "--fs",
"tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128,dax=on" "tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128,dax=on"
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"fs": [ "fs": [
{"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128} {"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
] ]
@ -995,11 +1072,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--fs", "--fs",
"tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128,dax=on" "tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128,dax=on"
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"fs": [ "fs": [
{"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "dax": true} {"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "dax": true}
] ]
@ -1008,11 +1086,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--fs", "--fs",
"tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128" "tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128"
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"fs": [ "fs": [
{"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "dax": true} {"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "dax": true}
] ]
@ -1021,11 +1100,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--fs", "--fs",
"tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128,cache_size=8589934592" "tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128,cache_size=8589934592"
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"fs": [ "fs": [
{"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128} {"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
] ]
@ -1034,11 +1114,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--fs", "--fs",
"tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128" "tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128"
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"fs": [ "fs": [
{"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "cache_size": 8589934592} {"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "cache_size": 8589934592}
] ]
@ -1047,11 +1128,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--fs", "--fs",
"tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128,cache_size=4294967296" "tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128,cache_size=4294967296"
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"fs": [ "fs": [
{"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "cache_size": 4294967296} {"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "cache_size": 4294967296}
] ]
@ -1060,11 +1142,12 @@ mod unit_tests {
), ),
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor", "--kernel", "/path/to/kernel",
"--fs", "--fs",
"tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128,cache_size=4294967296" "tag=virtiofs1,sock=/path/to/sock1,num_queues=4,queue_size=128,cache_size=4294967296"
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"fs": [ "fs": [
{"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128} {"tag": "virtiofs1", "sock": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
] ]
@ -1084,11 +1167,14 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--pmem", "--pmem",
"file=/path/to/img/1,size=1G", "file=/path/to/img/1,size=1G",
"file=/path/to/img/2,size=2G", "file=/path/to/img/2,size=2G",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"pmem": [ "pmem": [
{"file": "/path/to/img/1", "size": 1073741824}, {"file": "/path/to/img/1", "size": 1073741824},
{"file": "/path/to/img/2", "size": 2147483648} {"file": "/path/to/img/2", "size": 2147483648}
@ -1099,10 +1185,13 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--pmem", "--pmem",
"file=/path/to/img/1,size=1G,iommu=on", "file=/path/to/img/1,size=1G,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"pmem": [ "pmem": [
{"file": "/path/to/img/1", "size": 1073741824, "iommu": true} {"file": "/path/to/img/1", "size": 1073741824, "iommu": true}
], ],
@ -1113,10 +1202,13 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--pmem", "--pmem",
"file=/path/to/img/1,size=1G,iommu=on", "file=/path/to/img/1,size=1G,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"pmem": [ "pmem": [
{"file": "/path/to/img/1", "size": 1073741824, "iommu": true} {"file": "/path/to/img/1", "size": 1073741824, "iommu": true}
] ]
@ -1126,10 +1218,13 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--pmem", "--pmem",
"file=/path/to/img/1,size=1G,mergeable=on", "file=/path/to/img/1,size=1G,mergeable=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"pmem": [ "pmem": [
{"file": "/path/to/img/1", "size": 1073741824, "mergeable": true} {"file": "/path/to/img/1", "size": 1073741824, "mergeable": true}
] ]
@ -1139,10 +1234,13 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--pmem", "--pmem",
"file=/path/to/img/1,size=1G,mergeable=off", "file=/path/to/img/1,size=1G,mergeable=off",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"pmem": [ "pmem": [
{"file": "/path/to/img/1", "size": 1073741824, "mergeable": false} {"file": "/path/to/img/1", "size": 1073741824, "mergeable": false}
] ]
@ -1160,21 +1258,41 @@ mod unit_tests {
fn test_valid_vm_config_serial_console() { fn test_valid_vm_config_serial_console() {
vec![ vec![
( (
vec!["cloud-hypervisor"], vec!["cloud-hypervisor", "--kernel", "/path/to/kernel"],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"serial": {"mode": "Null"}, "serial": {"mode": "Null"},
"console": {"mode": "Tty"} "console": {"mode": "Tty"}
}"#, }"#,
true, true,
), ),
( (
vec!["cloud-hypervisor", "--serial", "null", "--console", "tty"], vec![
r#"{}"#, "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--serial",
"null",
"--console",
"tty",
],
r#"{
"kernel": {"path": "/path/to/kernel"}
}"#,
true, true,
), ),
( (
vec!["cloud-hypervisor", "--serial", "tty", "--console", "off"], vec![
"cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--serial",
"tty",
"--console",
"off",
],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"serial": {"mode": "Tty"}, "serial": {"mode": "Tty"},
"console": {"mode": "Off"} "console": {"mode": "Off"}
}"#, }"#,
@ -1193,11 +1311,14 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--device", "--device",
"path=/path/to/device/1", "path=/path/to/device/1",
"path=/path/to/device/2", "path=/path/to/device/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"devices": [ "devices": [
{"path": "/path/to/device/1"}, {"path": "/path/to/device/1"},
{"path": "/path/to/device/2"} {"path": "/path/to/device/2"}
@ -1208,11 +1329,14 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--device", "--device",
"path=/path/to/device/1", "path=/path/to/device/1",
"path=/path/to/device/2", "path=/path/to/device/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"devices": [ "devices": [
{"path": "/path/to/device/1"} {"path": "/path/to/device/1"}
] ]
@ -1222,10 +1346,13 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--device", "--device",
"path=/path/to/device,iommu=on", "path=/path/to/device,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"devices": [ "devices": [
{"path": "/path/to/device", "iommu": true} {"path": "/path/to/device", "iommu": true}
], ],
@ -1236,10 +1363,13 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--device", "--device",
"path=/path/to/device,iommu=on", "path=/path/to/device,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"devices": [ "devices": [
{"path": "/path/to/device", "iommu": true} {"path": "/path/to/device", "iommu": true}
] ]
@ -1249,10 +1379,13 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--device", "--device",
"path=/path/to/device,iommu=off", "path=/path/to/device,iommu=off",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"devices": [ "devices": [
{"path": "/path/to/device", "iommu": false} {"path": "/path/to/device", "iommu": false}
] ]
@ -1272,11 +1405,14 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--vsock", "--vsock",
"cid=123,sock=/path/to/sock/1", "cid=123,sock=/path/to/sock/1",
"cid=456,sock=/path/to/sock/2", "cid=456,sock=/path/to/sock/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"vsock": [ "vsock": [
{"cid": 123, "sock": "/path/to/sock/1"}, {"cid": 123, "sock": "/path/to/sock/1"},
{"cid": 456, "sock": "/path/to/sock/2"} {"cid": 456, "sock": "/path/to/sock/2"}
@ -1287,11 +1423,14 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--vsock", "--vsock",
"cid=123,sock=/path/to/sock/1", "cid=123,sock=/path/to/sock/1",
"cid=456,sock=/path/to/sock/2", "cid=456,sock=/path/to/sock/2",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"vsock": [ "vsock": [
{"cid": 123, "sock": "/path/to/sock/1"} {"cid": 123, "sock": "/path/to/sock/1"}
] ]
@ -1301,10 +1440,13 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--vsock", "--vsock",
"cid=124,sock=/path/to/sock/1", "cid=124,sock=/path/to/sock/1",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"vsock": [ "vsock": [
{"cid": 123, "sock": "/path/to/sock/1"} {"cid": 123, "sock": "/path/to/sock/1"}
] ]
@ -1314,10 +1456,13 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--vsock", "--vsock",
"cid=123,sock=/path/to/sock/1,iommu=on", "cid=123,sock=/path/to/sock/1,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"vsock": [ "vsock": [
{"cid": 123, "sock": "/path/to/sock/1", "iommu": true} {"cid": 123, "sock": "/path/to/sock/1", "iommu": true}
], ],
@ -1328,10 +1473,13 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--vsock", "--vsock",
"cid=123,sock=/path/to/sock/1,iommu=on", "cid=123,sock=/path/to/sock/1,iommu=on",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"vsock": [ "vsock": [
{"cid": 123, "sock": "/path/to/sock/1", "iommu": true} {"cid": 123, "sock": "/path/to/sock/1", "iommu": true}
] ]
@ -1341,10 +1489,13 @@ mod unit_tests {
( (
vec![ vec![
"cloud-hypervisor", "cloud-hypervisor",
"--kernel",
"/path/to/kernel",
"--vsock", "--vsock",
"cid=123,sock=/path/to/sock/1,iommu=off", "cid=123,sock=/path/to/sock/1,iommu=off",
], ],
r#"{ r#"{
"kernel": {"path": "/path/to/kernel"},
"vsock": [ "vsock": [
{"cid": 123, "sock": "/path/to/sock/1", "iommu": false} {"cid": 123, "sock": "/path/to/sock/1", "iommu": false}
] ]

View File

@ -82,6 +82,8 @@ pub enum Error {
pub enum ValidationError { pub enum ValidationError {
/// Both console and serial are tty. /// Both console and serial are tty.
DoubleTtyMode, DoubleTtyMode,
/// No kernel specified
KernelMissing,
} }
type ValidationResult<T> = std::result::Result<T, ValidationError>; type ValidationResult<T> = std::result::Result<T, ValidationError>;
@ -91,6 +93,7 @@ impl fmt::Display for ValidationError {
use self::ValidationError::*; use self::ValidationError::*;
match self { match self {
DoubleTtyMode => write!(f, "Console mode tty specified for both serial and console"), DoubleTtyMode => write!(f, "Console mode tty specified for both serial and console"),
KernelMissing => write!(f, "No kernel specified"),
} }
} }
} }
@ -1190,11 +1193,9 @@ pub struct VmConfig {
} }
impl VmConfig { impl VmConfig {
pub fn valid(&self) -> bool {
self.kernel.is_some()
}
pub fn validate(&self) -> ValidationResult<()> { pub fn validate(&self) -> ValidationResult<()> {
self.kernel.as_ref().ok_or(ValidationError::KernelMissing)?;
if self.console.mode == ConsoleOutputMode::Tty && self.serial.mode == ConsoleOutputMode::Tty if self.console.mode == ConsoleOutputMode::Tty && self.serial.mode == ConsoleOutputMode::Tty
{ {
return Err(ValidationError::DoubleTtyMode); return Err(ValidationError::DoubleTtyMode);
@ -1815,7 +1816,9 @@ mod tests {
hotplug_method: HotplugMethod::Acpi, hotplug_method: HotplugMethod::Acpi,
hotplug_size: None, hotplug_size: None,
}, },
kernel: None, kernel: Some(KernelConfig {
path: PathBuf::from("/path/to/kernel"),
}),
initramfs: None, initramfs: None,
cmdline: CmdlineConfig { cmdline: CmdlineConfig {
args: String::from(""), args: String::from(""),
@ -1850,6 +1853,10 @@ mod tests {
invalid_config.console.mode = ConsoleOutputMode::Tty; invalid_config.console.mode = ConsoleOutputMode::Tty;
assert!(invalid_config.validate().is_err()); assert!(invalid_config.validate().is_err());
let mut invalid_config = valid_config.clone();
invalid_config.kernel = None;
assert!(invalid_config.validate().is_err());
Ok(()) Ok(())
} }
} }