main
eater 3 years ago
parent 9ed17eca06
commit 92452ce4d6
Signed by: eater
GPG Key ID: AD2560A0F84F0759

47
Cargo.lock generated

@ -33,6 +33,21 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bstr"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d"
dependencies = [
"memchr",
]
[[package]]
name = "cc"
version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -55,6 +70,15 @@ dependencies = [
"yaml-rust",
]
[[package]]
name = "erased-serde"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0465971a8cc1fa2455c8465aaa377131e1f1cf4983280f474a13e68793aa770c"
dependencies = [
"serde 1.0.125",
]
[[package]]
name = "itoa"
version = "0.4.7"
@ -98,6 +122,21 @@ version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "mlua"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f2fc8e1085d53b72898c59ceee1980b5826b0c98ce99886b7518f0ead00e5cb"
dependencies = [
"bstr",
"cc",
"erased-serde",
"lazy_static",
"num-traits 0.2.14",
"pkg-config",
"serde 1.0.125",
]
[[package]]
name = "nom"
version = "5.1.2"
@ -127,6 +166,12 @@ dependencies = [
"autocfg",
]
[[package]]
name = "pkg-config"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
[[package]]
name = "proc-macro2"
version = "1.0.26"
@ -276,7 +321,9 @@ dependencies = [
"anyhow",
"config",
"kiam",
"mlua",
"serde 1.0.125",
"toml",
]
[[package]]

@ -0,0 +1,23 @@
[qemu]
script = "qemu.lua"
default = [
"-rtc", "driftfix=slew",
"-serial", "stdio",
"-no-hpet",
"-boot", "strict=on"
]
arch.i686 = []
arch.x86_64 = ["-global", "kvm-pit.lost_tick_policy=discard"]
uefi = [
# OVMF will hang if S3 is not disabled
# disable S4 too, since libvirt does that 🤷
# https://bugs.archlinux.org/task/59465#comment172528
"-global", "ICH9-LPC.disable_s3=1",
"-global", "ICH9-LPC.disable_s4=1"
]
[[disk.default]]
flag = "blockdev"

@ -0,0 +1,37 @@
function build_command(instance, args)
args:add("-rtc", "driftfix=slew")
args:add("-serial", "stdio")
args:add("-no-hpet")
args:add("-boot", "strict=on")
if instance.kvm then
args:add("-enable-kvm")
end
if instance.arch == "x86_64" or instance.arch == "i868" then
args:add("-global", "kvm-pit.lost_tick_policy=discard")
end
args:add("-no-user-config")
args:add("-no-defaults")
args:add("-no-shutdown")
args:add("-m", tostring(instance.memory))
local cpu = instance.cpu;
args:add(string.format("%d,sockets=%d,dies=%d,cores=%d,threads=%d",
cpu.amount,
cpu.sockets,
cpu.dies,
cpu.cores,
cpu.threads))
if instance.uefi.enabled and string.find(instance.chipset, "q35") == 0 then
-- OVMF will hang if S3 is not disabled
-- disable S4 too, since libvirt does that 🤷
-- https://bugs.archlinux.org/task/59465#comment172528
args:add("-global", "ICH9-LPC.disable_s3=1")
args:add("-global", "ICH9-LPC.disable_s4=1")
end
return args
end

@ -9,5 +9,7 @@ edition = "2018"
[dependencies]
config = "0.11.0"
serde = { version = "1.0.125", features = ["serde_derive"] }
toml = "*"
anyhow = "1.0.40"
kiam = "0.1"
kiam = "0.1"
mlua = { version = "0.5.3", features = ["lua54", "serialize"] }

@ -0,0 +1,21 @@
use anyhow::Context;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GlobalConfig {
pub qemu: GlobalQemuConfig,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GlobalQemuConfig {
pub default: Vec<String>,
pub arch: HashMap<String, Vec<String>>,
pub uefi: Vec<String>,
}
impl GlobalConfig {
pub fn load(toml: &str) -> Result<GlobalConfig, anyhow::Error> {
toml::from_str(toml).context("Failed to parse toml for global config")
}
}

@ -7,6 +7,8 @@ use std::str::FromStr;
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct InstanceConfig {
pub name: String,
pub arch: String,
pub chipset: String,
pub kvm: bool,
pub memory: u64,
pub cpu: CpuConfig,
@ -61,6 +63,8 @@ impl Default for InstanceConfig {
fn default() -> Self {
InstanceConfig {
name: "vore".to_string(),
arch: std::env::consts::ARCH.to_string(),
chipset: "q35".to_string(),
kvm: true,
// 2 GB
memory: 2 * 1024 * 1024 * 1024,

@ -1,3 +1,7 @@
mod global_config;
mod instance_config;
mod qemu;
pub use global_config::*;
pub use instance_config::*;
pub use qemu::build_qemu_command;

@ -0,0 +1,47 @@
use crate::{GlobalConfig, InstanceConfig};
use mlua::{Function, LuaSerdeExt, MultiValue, ToLua, UserData, UserDataMethods, Value};
use serde::Deserialize;
#[derive(Debug, Default, Deserialize, Clone)]
struct LuaFreeList(Vec<String>);
impl UserData for LuaFreeList {
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
methods.add_method_mut("add", |_, this, args: MultiValue| {
for item in args.iter() {
if let Value::String(item) = item {
this.0.push(item.to_str()?.to_string())
}
}
Ok(Value::Nil)
})
}
}
pub fn build_qemu_command(config: &InstanceConfig, global_config: &GlobalConfig) -> Vec<String> {
let lua = mlua::Lua::new();
// TODO: load correct script
lua.load(include_str!("../../config/qemu.lua"))
.eval::<()>()
.unwrap();
let val: Function = lua.globals().get("build_command").unwrap();
let item = LuaFreeList::default();
let multi = MultiValue::from_vec(vec![
lua.to_value(config).unwrap(),
item.to_lua(&lua).unwrap(),
]);
let mut x = val.call::<MultiValue, LuaFreeList>(multi).unwrap();
println!("{:?}", x);
let mut cmd: Vec<String> = vec![];
cmd.push("-name".to_string());
cmd.push(format!("guest={},debug-threads=on", config.name));
cmd.push("-S".to_string());
cmd.push("-msg".to_string());
cmd.push("timestamps=on".to_string());
cmd.append(&mut x.0);
cmd
}

@ -1,4 +1,3 @@
use std::fmt::{Display, Formatter};
use std::process::Child;
use vore_core::InstanceConfig;
@ -18,123 +17,6 @@ impl Instance {
}
}
#[derive(Debug, Clone)]
pub struct ArgumentList {
items: Vec<Argument>,
}
impl Display for ArgumentList {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let item = self.items.iter().fold(String::new(), |mut x, item| {
if x.len() > 0 {
x.push_str(" ")
}
x.push_str(item.as_str());
x
});
f.write_str(&item)
}
}
impl ArgumentList {
pub fn new(command: &'static str) -> ArgumentList {
ArgumentList {
items: vec![Argument::Borrowed(command)],
}
}
pub fn pair(&mut self, key: &'static str, value: String) {
self.push(key);
self.push(value);
}
}
pub trait PushArgument<T> {
fn push(&mut self, argument: T);
fn push_pair(&mut self, key: T, value: T) {
self.push(key);
self.push(value);
}
}
impl PushArgument<String> for ArgumentList {
fn push(&mut self, argument: String) {
self.items.push(Argument::Owned(argument))
}
}
impl PushArgument<&'static str> for ArgumentList {
fn push(&mut self, argument: &'static str) {
self.items.push(Argument::Borrowed(argument))
}
}
#[derive(Debug, Clone)]
enum Argument {
Owned(String),
Borrowed(&'static str),
}
impl Argument {
fn as_str(&self) -> &str {
match self {
Argument::Owned(owned) => &owned,
Argument::Borrowed(borrowed) => borrowed,
}
}
}
pub fn build_qemu_command(config: &InstanceConfig) -> ArgumentList {
let mut cmd = ArgumentList::new("qemu-system-x86_64");
cmd.pair("-name", format!("guest={},debug-threads=on", config.name));
cmd.push("-S");
cmd.push("-no-user-config");
cmd.push("-no-defaults");
cmd.push("-no-shutdown");
if config.kvm {
cmd.push("-enable-kvm");
}
cmd.pair("-m", config.memory.to_string());
if config.uefi.enabled {
// OVMF will hang if S3 is not disabled
// disable S4 too, since libvirt does that 🤷
// https://bugs.archlinux.org/task/59465#comment172528
cmd.push_pair("-global", "ICH9-LPC.disable_s3=1");
cmd.push_pair("-global", "ICH9-LPC.disable_s4=1");
}
cmd.push_pair("-rtc", "driftfix=slew");
cmd.push_pair("-serial", "stdio");
#[cfg(any(target_arch = "x86_64", target_arch = "i686"))]
{
cmd.push_pair("-global", "kvm-pit.lost_tick_policy=discard")
}
cmd.push("-no-hpet");
cmd.push_pair("-boot", "strict=on");
cmd.pair(
"-smp",
format!(
"{},sockets={},dies={},cores={},threads={}",
config.cpu.amount,
config.cpu.sockets,
config.cpu.dies,
config.cpu.cores,
config.cpu.threads
),
);
cmd.push_pair("-msg", "timestamp=on");
cmd
}
#[derive(Debug)]
pub struct Qemu {
process: Option<Child>,

@ -1,9 +1,10 @@
use crate::instance::build_qemu_command;
use vore_core::InstanceConfig;
use vore_core::{build_qemu_command, GlobalConfig, InstanceConfig};
mod instance;
fn main() {
let cfg = InstanceConfig::from_toml(include_str!("../../config/example.toml")).unwrap();
println!("Hello, world! {}", build_qemu_command(&cfg));
let global = GlobalConfig::load(include_str!("../../config/global.toml")).unwrap();
println!("Hello, world! {:?}", build_qemu_command(&cfg, &global));
print!("hello world {:#?}", global);
}

Loading…
Cancel
Save