Skip to content

Commit 03f7556

Browse files
DolceTriadedanobi
authored andcommitted
vmtest: Add additional config options
Add a VMConfig struct to the config that will allow customizing the VM's CPUs, RAM, BIOS image, and additional host mounts. Further, allow passing in arbitrary QEMU arguments (if for example you want to add additional hardware).
1 parent 72fd22b commit 03f7556

File tree

6 files changed

+361
-36
lines changed

6 files changed

+361
-36
lines changed

docs/config.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,45 @@ The following fields are supported:
3939
* Note that the specified command is run inside a `bash` shell by default
4040
* `vmtest`'s environment variables are also propagated into the VM during
4141
command execution
42+
* `vm` (VMConfig)
43+
* Optional sub-table
44+
* Configures the VM.
45+
* See the VMConfig struct below.
46+
47+
### `[[target.vm]]`
48+
49+
The VMConfig struct that configures the QEMU VM.
50+
51+
* `num_cpus` (int)
52+
* Optional field
53+
* Number of CPUs in the VM.
54+
* Default: 2
55+
* `memory` (string)
56+
* Optional field
57+
* Amount of RAM for the VM.
58+
* Accepts a QEMU parsable string for the -m flag like 256M or 4G.
59+
* Default: 4G
60+
* `mounts` (Map<String, Mount>)
61+
* Optional sub-table
62+
* Map of additional host mounts for the VM.
63+
* Key is the path in the VM and the value contains information about the host path.
64+
* See below for definition of the Mount object.
65+
* `bios` (string)
66+
* Optional field
67+
* Path to the BIOS file.
68+
* This is only used if the UEFI flag from target is true.
69+
* `extra_args` (List<string>)
70+
* Optional field
71+
* Extra arguments to pass to QEMU.
72+
73+
### `[[target.vm.mounts]]`
74+
75+
The Mount struct for defining additional host mounts into the VM.
76+
77+
* `host_path` (string)
78+
* Required field
79+
* Path on the host.
80+
* `writable` (bool)
81+
* Optional field
82+
* Whether this mount is writable in the VM.
83+
* Default: false

src/config.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,80 @@
1+
use std::collections::HashMap;
12
use std::path::PathBuf;
23
use std::vec::Vec;
34

45
use serde_derive::Deserialize;
56

7+
/// Config for a mount
8+
#[derive(Deserialize, Clone)]
9+
pub struct Mount {
10+
/// Path on the host for the mount.
11+
pub host_path: PathBuf,
12+
/// Mount the location r/w.
13+
///
14+
/// Default: false
15+
#[serde(default)]
16+
pub writable: bool,
17+
}
18+
19+
/// VM Config for a target
20+
#[derive(Deserialize)]
21+
pub struct VMConfig {
22+
/// Number of CPUs in the VM.
23+
///
24+
/// Default: 2
25+
#[serde(default = "VMConfig::default_cpus")]
26+
pub num_cpus: u8,
27+
/// Amount of RAM for the VM.
28+
///
29+
/// Accepts a QEMU parsable string for the -m flag like 256M or 4G.
30+
/// Default: 4G
31+
#[serde(default = "VMConfig::default_memory")]
32+
pub memory: String,
33+
/// Map of additional Host mounts.
34+
///
35+
/// Key is the path in the VM and the value is the path on the host.
36+
/// * Only respected when using an image.
37+
#[serde(default = "HashMap::new")]
38+
pub mounts: HashMap<String, Mount>,
39+
40+
/// Path to the BIOS file.
41+
///
42+
/// If this is empty, the default OS locations will be tried:
43+
/// * /usr/share/edk2/ovmf/OVMF_CODE.fd
44+
/// * /usr/share/OVMF/OVMF_CODE.fd
45+
/// * /usr/share/edk2-ovmf/x64/OVMF_CODE.fd
46+
pub bios: Option<PathBuf>,
47+
48+
/// Extra arguments to pass to QEMU.
49+
#[serde(default = "Vec::new")]
50+
pub extra_args: Vec<String>,
51+
// TODO: Consider adding higher level interfaces for adding
52+
// additional hardware to the VM (USB, HDDs, CDROM, TPM, etc).
53+
// For now, people can use extra_args to add them.
54+
}
55+
56+
impl VMConfig {
57+
fn default_cpus() -> u8 {
58+
2
59+
}
60+
61+
fn default_memory() -> String {
62+
"4G".into()
63+
}
64+
}
65+
66+
impl Default for VMConfig {
67+
fn default() -> Self {
68+
Self {
69+
num_cpus: Self::default_cpus(),
70+
memory: Self::default_memory(),
71+
mounts: HashMap::new(),
72+
bios: None,
73+
extra_args: Vec::new(),
74+
}
75+
}
76+
}
77+
678
/// Config for a single target
779
#[derive(Deserialize)]
880
pub struct Target {
@@ -29,6 +101,10 @@ pub struct Target {
29101
pub kernel_args: Option<String>,
30102
/// Command to run inside virtual machine.
31103
pub command: String,
104+
105+
/// VM Configuration.
106+
#[serde(default)]
107+
pub vm: VMConfig,
32108
}
33109

34110
/// Config containing full test matrix
@@ -74,3 +150,20 @@ fn test_triple_quoted_strings_backslash() {
74150
r#"this string has \back \slash\es"#
75151
);
76152
}
153+
154+
#[test]
155+
fn test_default_vmconfig() {
156+
let config: Config = toml::from_str(
157+
r#"
158+
[[target]]
159+
name = "test"
160+
command = "real command"
161+
"#,
162+
)
163+
.unwrap();
164+
assert_eq!(config.target[0].vm.memory, "4G");
165+
assert_eq!(config.target[0].vm.num_cpus, 2);
166+
assert_eq!(config.target[0].vm.bios, None);
167+
assert_eq!(config.target[0].vm.extra_args.len(), 0);
168+
assert_eq!(config.target[0].vm.mounts.len(), 0);
169+
}

src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use console::user_attended;
99
use env_logger::{fmt::Target as LogTarget, Builder};
1010
use regex::Regex;
1111

12-
use ::vmtest::{Config, Target, Ui, Vmtest};
12+
use ::vmtest::{Config, Target, Ui, VMConfig, Vmtest};
1313

1414
#[derive(Parser, Debug)]
1515
#[clap(version)]
@@ -75,6 +75,7 @@ fn config(args: &Args) -> Result<Vmtest> {
7575
kernel: Some(kernel.clone()),
7676
kernel_args: args.kargs.clone(),
7777
command: args.command.join(" "),
78+
vm: VMConfig::default(),
7879
}],
7980
};
8081

0 commit comments

Comments
 (0)