Initial commit

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

1
.gitignore vendored

@ -0,0 +1 @@
/target

297
Cargo.lock generated

@ -0,0 +1,297 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "config"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369"
dependencies = [
"lazy_static",
"nom",
"rust-ini",
"serde 1.0.125",
"serde-hjson",
"serde_json",
"toml",
"yaml-rust",
]
[[package]]
name = "itoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "kiam"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fec32b07a91b3ac2bca298af854b84860969f099811888fe0d9edf7bee95ce2"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lexical-core"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21f866863575d0e1d654fbeeabdc927292fdf862873dc3c96c6f753357e13374"
dependencies = [
"arrayvec",
"bitflags",
"cfg-if",
"ryu",
"static_assertions",
]
[[package]]
name = "linked-hash-map"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]]
name = "memchr"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "nom"
version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
"lexical-core",
"memchr",
"version_check",
]
[[package]]
name = "num-traits"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
dependencies = [
"num-traits 0.2.14",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "proc-macro2"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957056ecddbeba1b26965114e191d2e8589ce74db242b6ea25fc4062427a5c19"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
[[package]]
name = "rust-ini"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "serde"
version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
[[package]]
name = "serde"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde-hjson"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8"
dependencies = [
"lazy_static",
"num-traits 0.1.43",
"regex",
"serde 0.8.23",
]
[[package]]
name = "serde_derive"
version = "1.0.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
dependencies = [
"itoa",
"ryu",
"serde 1.0.125",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "toml"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
dependencies = [
"serde 1.0.125",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "vore"
version = "0.1.0"
dependencies = [
"anyhow",
"vore-core",
]
[[package]]
name = "vore-core"
version = "0.1.0"
dependencies = [
"anyhow",
"config",
"kiam",
"serde 1.0.125",
]
[[package]]
name = "vored"
version = "0.1.0"
dependencies = [
"anyhow",
"vore-core",
]
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]

@ -0,0 +1,2 @@
[workspace]
members = ["vored", "vore", "vore-core"]

@ -0,0 +1,21 @@
[machine]
name = "win10"
memory = "12G"
[cpu]
amount = 12
[[disk]]
path = "/dev/disk/by-id/wwn-0x500a0751f008e09d"
[[disk]]
path = "/dev/disk/by-id/wwn-0x5002538e4038852d"
[uefi]
enabled = true
[scream]
enabled = true
[looking-glass]
enabled = true

@ -0,0 +1,146 @@
/bin/qemu-system-x86_64
-name
guest=win10,debug-threads=on
-S
-object
secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-1-win10/master-key.aes
-blockdev
{"driver":"file","filename":"/usr/share/OVMF/OVMF_CODE.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}
-blockdev
{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}
-blockdev
{"driver":"file","filename":"/usr/share/OVMF/OVMF_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}
-blockdev
{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"}
-machine
pc-q35-3.0,accel=kvm,usb=off,vmport=off,dump-guest-core=off,kernel_irqchip=on,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format,memory-backend=pc.ram
-cpu
host,migratable=on,hv-time,hv-relaxed,hv-vapic,hv-spinlocks=0x1fff,hv-vendor-id=whatever,kvm=off
-m
16384
-object
memory-backend-ram,id=pc.ram,size=17179869184
-overcommit
mem-lock=off
-smp
12,sockets=1,dies=1,cores=6,threads=2
-object
iothread,id=iothread1
-uuid
29d2307c-ee76-4471-85f1-ee758121a99b
-no-user-config
-nodefaults
-chardev
socket,id=charmonitor,fd=29,server=on,wait=off
-mon
chardev=charmonitor,id=monitor,mode=control
-rtc
base=localtime,driftfix=slew
-global
kvm-pit.lost_tick_policy=delay
-no-hpet
-no-shutdown
-global
ICH9-LPC.disable_s3=1
-global
ICH9-LPC.disable_s4=1
-boot
strict=on
-device
i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e
-device
pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0
-device
pcie-root-port,port=0x10,chassis=3,id=pci.3,bus=pcie.0,multifunction=on,addr=0x2
-device
pcie-root-port,port=0x11,chassis=4,id=pci.4,bus=pcie.0,addr=0x2.0x1
-device
pcie-root-port,port=0x12,chassis=5,id=pci.5,bus=pcie.0,addr=0x2.0x2
-device
pcie-root-port,port=0x13,chassis=6,id=pci.6,bus=pcie.0,addr=0x2.0x3
-device
pcie-root-port,port=0x14,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x4
-device
pcie-root-port,port=0x15,chassis=8,id=pci.8,bus=pcie.0,addr=0x2.0x5
-device
pcie-root-port,port=0x16,chassis=9,id=pci.9,bus=pcie.0,addr=0x2.0x6
-device
pcie-root-port,port=0x17,chassis=10,id=pci.10,bus=pcie.0,addr=0x2.0x7
-device
pcie-root-port,port=0x18,chassis=11,id=pci.11,bus=pcie.0,multifunction=on,addr=0x3
-device
pcie-root-port,port=0x19,chassis=12,id=pci.12,bus=pcie.0,addr=0x3.0x1
-device
pcie-root-port,port=0x1a,chassis=13,id=pci.13,bus=pcie.0,addr=0x3.0x2
-device
pcie-root-port,port=0x1b,chassis=14,id=pci.14,bus=pcie.0,addr=0x3.0x3
-device
nec-usb-xhci,id=usb,bus=pci.3,addr=0x0
-device
virtio-scsi-pci,id=scsi0,bus=pci.9,addr=0x0
-device
virtio-serial-pci,id=virtio-serial0,bus=pci.4,addr=0x0
-blockdev
{"driver":"host_device","filename":"/dev/disk/by-id/wwn-0x500a0751f008e09d","aio":"threads","node-name":"libvirt-2-storage","cache":{"direct":false,"no-flush":false},"auto-read-only":true,"discard":"unmap"}
-blockdev
{"node-name":"libvirt-2-format","read-only":false,"discard":"unmap","cache":{"direct":false,"no-flush":false},"driver":"raw","file":"libvirt-2-storage"}
-device
scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=3,device_id=drive-scsi0-0-0-3,drive=libvirt-2-format,id=scsi0-0-0-3,bootindex=1,write-cache=on
-blockdev
{"driver":"host_device","filename":"/dev/disk/by-id/wwn-0x5002538e4038852d","aio":"threads","node-name":"libvirt-1-storage","cache":{"direct":false,"no-flush":false},"auto-read-only":true,"discard":"unmap"}
-blockdev
{"node-name":"libvirt-1-format","read-only":false,"discard":"unmap","cache":{"direct":false,"no-flush":false},"driver":"raw","file":"libvirt-1-storage"}
-device
virtio-blk-pci,bus=pci.11,addr=0x0,drive=libvirt-1-format,id=virtio-disk4,write-cache=on
-netdev
tap,fd=31,id=hostnet0,vhost=on,vhostfd=32
-device
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:9e:48:64,bus=pci.8,addr=0x0
-netdev
tap,fd=33,id=hostnet1,vhost=on,vhostfd=34
-device
virtio-net-pci,netdev=hostnet1,id=net1,mac=52:54:00:fa:57:7d,bus=pci.10,addr=0x0
-chardev
pty,id=charserial0
-device
isa-serial,chardev=charserial0,id=serial0
-chardev
spicevmc,id=charchannel0,name=vdagent
-device
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0
-device
virtio-mouse-pci,id=input0,bus=pci.13,addr=0x0
-audiodev
id=audio1,driver=spice
-spice
unix,addr=/tmp/win.sock,disable-ticketing=on,seamless-migration=on
-device
cirrus-vga,id=video0,bus=pcie.0,addr=0x1
-device
ich9-intel-hda,id=sound0,bus=pcie.0,addr=0x1b
-device
hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0,audiodev=audio1
-device
vfio-pci,host=0000:08:00.0,id=hostdev0,bus=pci.6,addr=0x0
-device
vfio-pci,host=0000:08:00.1,id=hostdev1,bus=pci.7,addr=0x0
-device
vfio-pci,host=0000:0a:00.3,id=hostdev2,bus=pci.14,addr=0x0
-device
virtio-balloon-pci,id=balloon0,bus=pci.5,addr=0x0
-device
usb-kbd
-audiodev
pa,id=win10,server=/run/user/1000/pulse/native
-sandbox
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny
-object
memory-backend-file,id=shmmem-shmem0,mem-path=/dev/shm/looking-glass,size=67108864,share=on
-device
ivshmem-plain,id=shmem0,memdev=shmmem-shmem0,bus=pci.2,addr=0x1
-object
memory-backend-file,id=shmmem-shmem1,mem-path=/dev/shm/scream,size=2097152,share=on
-device
ivshmem-plain,id=shmem1,memdev=shmmem-shmem1,bus=pci.2,addr=0x2
-msg
timestamp=on

@ -0,0 +1,13 @@
[package]
name = "vore-core"
version = "0.1.0"
authors = ["eater <=@eater.me>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
config = "0.11.0"
serde = { version = "1.0.125", features = ["serde_derive"] }
anyhow = "1.0.40"
kiam = "0.1"

@ -0,0 +1,269 @@
use anyhow::{Context, Error};
use config::{Config, File, FileFormat, Value};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::str::FromStr;
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct InstanceConfig {
pub name: String,
pub kvm: bool,
pub memory: u64,
pub cpu: CpuConfig,
pub disks: Vec<DiskConfig>,
pub uefi: UefiConfig,
pub looking_glass: LookingGlassConfig,
pub scream: ScreamConfig,
}
impl InstanceConfig {
pub fn from_toml(toml: &str) -> Result<Self, anyhow::Error> {
let toml = Config::new().with_merged(File::from_str(toml, FileFormat::Toml))?;
Self::from_config(toml)
}
pub fn from_config(config: Config) -> Result<InstanceConfig, anyhow::Error> {
let mut instance_config = InstanceConfig::default();
if let Ok(name) = config.get_str("machine.name") {
instance_config.name = name
}
if let Ok(kvm) = config.get::<Value>("machine.kvm") {
instance_config.kvm = kvm.into_bool().context("machine.kvm should be a boolean")?;
}
if let Ok(mem) = config.get::<Value>("machine.memory") {
let mem = mem
.into_str()
.context("machine.memory should be a string or number")?;
instance_config.memory = parse_size(&mem)?;
}
if let Ok(cpu) = config.get_table("cpu") {
instance_config.cpu.apply_table(cpu)?
}
if let Ok(disks) = config.get::<Value>("disk") {
let arr = disks.into_array().context("disk should be an array")?;
for (i, disk) in arr.into_iter().enumerate() {
let table = disk
.into_table()
.with_context(|| format!("disk[{}] should be a table", i))?;
instance_config.disks.push(DiskConfig::from_table(table)?);
}
}
Ok(instance_config)
}
}
impl Default for InstanceConfig {
fn default() -> Self {
InstanceConfig {
name: "vore".to_string(),
kvm: true,
// 2 GB
memory: 2 * 1024 * 1024 * 1024,
cpu: Default::default(),
disks: vec![],
uefi: Default::default(),
looking_glass: Default::default(),
scream: Default::default(),
}
}
}
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct CpuConfig {
pub amount: u64,
pub cores: u64,
pub threads: u64,
pub dies: u64,
pub sockets: u64,
}
impl Default for CpuConfig {
fn default() -> Self {
CpuConfig {
amount: 2,
cores: 1,
threads: 2,
dies: 1,
sockets: 1,
}
}
}
fn get_positive_number_from_table(
table: &HashMap<String, Value>,
key: &str,
prefix: &str,
) -> Result<Option<u64>, Error> {
table
.get(key)
.cloned()
.map(|x| {
x.into_int()
.with_context(|| format!("Failed to parse {}.{} as number", prefix, key))
.and_then(|x| {
Some(x)
.filter(|x| !x.is_negative())
.map(|x| x as u64)
.ok_or_else(|| {
anyhow::Error::msg(format!("{}.{} can't be negative", prefix, key))
})
})
})
.transpose()
}
impl CpuConfig {
fn apply_table(&mut self, table: HashMap<String, Value>) -> Result<(), anyhow::Error> {
if let Some(amount) = get_positive_number_from_table(&table, "amount", "cpu")? {
self.amount = amount;
}
if let Some(cores) = get_positive_number_from_table(&table, "cores", "cpu")? {
self.cores = cores;
}
if let Some(threads) = get_positive_number_from_table(&table, "threads", "cpu")? {
self.threads = threads;
}
if let Some(dies) = get_positive_number_from_table(&table, "dies", "cpu")? {
self.dies = dies;
}
if let Some(sockets) = get_positive_number_from_table(&table, "sockets", "cpu")? {
self.sockets = sockets;
}
if !table.contains_key("amount") {
self.amount = self.sockets * self.dies * self.cores * self.threads;
} else {
if table
.keys()
.any(|x| ["cores", "sockets", "dies", "threads"].contains(&x.as_str()))
{
let calc_amount = self.sockets * self.dies * self.cores * self.threads;
if self.amount != calc_amount {
Err(anyhow::Error::msg(format!("Amount of cpu's ({}) from sockets ({}), dies ({}), cores ({}) and threads ({}) differs from specified ({}) cpu's", calc_amount, self.sockets, self.dies, self.cores, self.threads, self.amount)))?;
}
} else {
if (self.amount % 2) == 0 {
self.cores = self.amount / 2;
} else {
self.threads = 1;
self.cores = self.amount;
}
}
}
Ok(())
}
}
fn parse_size(orig_input: &str) -> Result<u64, anyhow::Error> {
let input = orig_input.to_string().to_lowercase().replace(" ", "");
let mut input = input.strip_suffix("b").unwrap_or(&input);
let mut modifier: u64 = 1;
if input.chars().last().unwrap_or('_').is_alphabetic() {
modifier = match input.chars().last().unwrap() {
'k' => {
return Err(anyhow::Error::msg(
"size can only be specified in megabytes or larger",
));
}
'm' => 1,
'g' => 1024,
't' => 1024 * 1024,
_ => {
return Err(anyhow::Error::msg(format!(
"'{}' is not a valid size",
orig_input
)));
}
};
input = &input[..input.len() - 1];
}
if input.len() == 0 {
return Err(anyhow::Error::msg(format!(
"'{}' is not a valid size",
orig_input
)));
}
u64::from_str(input)
.context(format!("'{}' is not a valid size", orig_input))
.map(|x| x * modifier)
}
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct UefiConfig {
pub enabled: bool,
}
impl Default for UefiConfig {
fn default() -> Self {
UefiConfig { enabled: false }
}
}
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct ScreamConfig {
pub enabled: bool,
}
impl Default for ScreamConfig {
fn default() -> Self {
ScreamConfig { enabled: false }
}
}
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct LookingGlassConfig {
pub enabled: bool,
}
impl Default for LookingGlassConfig {
fn default() -> Self {
LookingGlassConfig { enabled: false }
}
}
#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct DiskConfig {
pub disk_type: String,
pub path: String,
}
impl DiskConfig {
pub fn from_table(table: HashMap<String, Value>) -> Result<DiskConfig, anyhow::Error> {
let path = table
.get("path")
.cloned()
.ok_or_else(|| anyhow::Error::msg("Disk needs a path"))?
.into_str()
.context("Disk path must be a string")?;
let disk_type = if let Some(disk_type) = table.get("type").cloned() {
disk_type.into_str()?
} else {
(kiam::when! {
path.starts_with("/dev") => "raw",
path.ends_with(".qcow2") => "qcow2",
_ => return Err(anyhow::Error::msg("Can't figure out from path what type of disk driver should be used"))
}).to_string()
};
let disk = DiskConfig { disk_type, path };
// TODO: Add blockdev details
Ok(disk)
}
}

@ -0,0 +1,3 @@
mod instance_config;
pub use instance_config::*;

@ -0,0 +1,11 @@
[package]
name = "vore"
version = "0.1.0"
authors = ["eater <=@eater.me>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.40"
vore-core = { path = "../vore-core" }

@ -0,0 +1,5 @@
use vore_core::InstanceConfig;
fn main() {
let cfg = InstanceConfig::from_toml(include_str!("../../config/example.toml")).unwrap();
}

@ -0,0 +1,11 @@
[package]
name = "vored"
version = "0.1.0"
authors = ["eater <=@eater.me>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.40"
vore-core = { path = "../vore-core" }

@ -0,0 +1,141 @@
use std::fmt::{Display, Formatter};
use std::process::Child;
use vore_core::InstanceConfig;
#[derive(Debug)]
pub struct Instance {
config: InstanceConfig,
qemu: Option<Qemu>,
}
impl Instance {
pub fn from_config(config: InstanceConfig) -> Instance {
Instance { config, qemu: None }
}
pub fn spawn_qemu(&self) -> Result<(), anyhow::Error> {
Ok(())
}
}
#[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>,
}

@ -0,0 +1,9 @@
use crate::instance::build_qemu_command;
use vore_core::InstanceConfig;
mod instance;
fn main() {
let cfg = InstanceConfig::from_toml(include_str!("../../config/example.toml")).unwrap();
println!("Hello, world! {}", build_qemu_command(&cfg));
}
Loading…
Cancel
Save