VM works on SNP server
This commit is contained in:
parent
a8347f633d
commit
82273f63e5
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -149,7 +149,7 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "daemon"
|
||||
name = "detee-snp-daemon"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "daemon"
|
||||
name = "detee-snp-daemon"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
|
20
scripts/start_qemu_vm.sh
Normal file → Executable file
20
scripts/start_qemu_vm.sh
Normal file → Executable file
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
[[ -z "$VM_UUID" ]] || {
|
||||
[[ -z "$VM_UUID" ]] && {
|
||||
echo "Environment variable VM_UUID is not set."
|
||||
exit 1
|
||||
}
|
||||
@ -17,6 +17,7 @@ done
|
||||
|
||||
interfaces=$(env | grep -oE '^NETWORK_INTERFACE_[0-9]*')
|
||||
nat_configured="false"
|
||||
vtap_fd_counter=3
|
||||
while read -r interface; do
|
||||
|
||||
interface_type="$( echo ${!interface} | cut -d '_' -f1 )"
|
||||
@ -24,13 +25,21 @@ while read -r interface; do
|
||||
if [[ "$interface_type" == "macvtap" || "$interface_type" == "ipvtap" ]]; then
|
||||
interface_device="$( echo ${!interface} | cut -d '_' -f2 )"
|
||||
interface_name="$( echo ${!interface} | cut -d '_' -f3 )"
|
||||
ip link add link $interface_device name $interface_name type $interface_type mode bridge
|
||||
if [[ "$interface_type" == "macvtap" ]]; then
|
||||
ip link add link $interface_device name $interface_name type $interface_type mode bridge
|
||||
else
|
||||
ip link add link $interface_device name $interface_name type $interface_type
|
||||
fi
|
||||
ip link set $interface_name up
|
||||
ip link set $interface_name promisc on
|
||||
|
||||
vtap_index="$(cat /sys/class/net/${interface_name}/ifindex)"
|
||||
vtap_addr="$(cat /sys/class/net/${interface_name}/address)"
|
||||
qemu_device_params="-netdev tap,id=hostnet1,fd=3 3<>/dev/tap${macvtap_index}"
|
||||
qemu_device_params+=" -device virtio-net-pci,netdev=hostnet1,mac=${macvtap_addr},romfile="
|
||||
|
||||
fd_number=$vtap_fd_counter
|
||||
exec {fd_number}<> /dev/tap${vtap_index}
|
||||
qemu_device_params="-netdev tap,id=hostnet1,fd=${fd_number} -device virtio-net-pci,netdev=hostnet1,mac=${vtap_addr},romfile="
|
||||
((vtap_fd_counter++))
|
||||
fi
|
||||
|
||||
if [[ "$interface_type" == "NAT" && "$nat_configured" == "false" ]]; then
|
||||
@ -54,7 +63,8 @@ vm_disk="/root/dtrfs/arch-1-ghe0.qcow2"
|
||||
qemu-system-x86_64 $qemu_device_params \
|
||||
-enable-kvm -cpu $CPU_TYPE -vga none \
|
||||
-machine q35,confidential-guest-support=sev0,memory-backend=ram1 \
|
||||
-smp $VCPUS,maxcpus=$VCPUS -m $MEMORY,slots=5,maxmem=$MAX_MEMORY \
|
||||
-smp $VCPUS,maxcpus=$VCPUS \
|
||||
-m $MEMORY,slots=5,maxmem=$MAX_MEMORY \
|
||||
-no-reboot -bios /usr/share/edk2/ovmf/OVMF.amdsev.fd \
|
||||
-drive file=${DISK},if=none,id=disk0,format=qcow2 \
|
||||
-device virtio-blk-pci,drive=disk0 \
|
||||
|
@ -3,7 +3,7 @@
|
||||
pub(crate) const DEFAULT_OVMF: &str = "/usr/share/edk2/ovmf/OVMF.amdsev.fd";
|
||||
pub(crate) const VM_BOOT_DIR: &str = "/var/lib/detee/boot/";
|
||||
pub(crate) const VM_CONFIG_DIR: &str = "/etc/detee/daemon/vms/";
|
||||
pub(crate) const DAEMON_CONFIG_PATH: &str = "/etc/detee/daemon/config.json";
|
||||
pub(crate) const DAEMON_CONFIG_PATH: &str = "/etc/detee/daemon/config.yaml";
|
||||
pub(crate) const START_VM_SCRIPT: &str = "/usr/local/bin/detee/start_qemu_vm.sh";
|
||||
// TODO: research if other CPU types provide better performance
|
||||
pub(crate) const QEMU_VM_CPU_TYPE: &str = "EPYC-v4";
|
||||
|
27
src/main.rs
27
src/main.rs
@ -7,29 +7,12 @@ use crate::config::Config;
|
||||
use crate::state::NewVMRequest;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = Config::from_file("prod_setting/config1.yaml")?;
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let config = Config::from_file(crate::constants::DAEMON_CONFIG_PATH)?;
|
||||
let mut res = state::Resources::new(&config.volumes);
|
||||
// println!("{:#?}", config);
|
||||
|
||||
// let config = Config::from_file("test_data/config2.yaml")?;
|
||||
// println!("{:#?}", config);
|
||||
// let config = Config::from_file("test_data/config3.yaml")?;
|
||||
// println!("{:#?}", config);
|
||||
// let config = Config::from_file("test_data/config4.yaml")?;
|
||||
// println!("{:#?}", config);
|
||||
// let config = Config::from_file("test_data/config5.yaml")?;
|
||||
// println!("{:#?}", config);
|
||||
let new_vm_req = NewVMRequest::from_file("test_data/new_vm_req3.yaml")?;
|
||||
// println!("{:#?}", new_vm_req);
|
||||
|
||||
// let new_vm_req = NewVMRequest::from_file("test_data/new_vm_req2.yaml")?;
|
||||
// println!("{:#?}", new_vm_req);
|
||||
// let new_vm_req = NewVMRequest::from_file("test_data/new_vm_req3.yaml")?;
|
||||
// println!("{:#?}", new_vm_req);
|
||||
// let new_vm_req = NewVMRequest::from_file("test_data/new_vm_req4.yaml")?;
|
||||
// println!("{:#?}", new_vm_req);
|
||||
let new_vm_req = NewVMRequest::from_file(&args[1])?;
|
||||
let vm = state::VM::new(new_vm_req, &config, &mut res);
|
||||
println!("vm: {:#?}", vm);
|
||||
println!("{:?}", vm.unwrap().start());
|
||||
println!("Got VM: {:#?}", vm);
|
||||
println!("Starting VM... \n{:?}", vm.unwrap().start());
|
||||
Ok(())
|
||||
}
|
||||
|
52
src/state.rs
52
src/state.rs
@ -38,7 +38,7 @@ impl Resources {
|
||||
available_gb: config_vol.max_reservation_gb,
|
||||
});
|
||||
}
|
||||
Resources {
|
||||
let mut res = Resources {
|
||||
reserved_vcpus: 0,
|
||||
reserved_memory: 0,
|
||||
reserved_ports: HashSet::new(),
|
||||
@ -46,7 +46,9 @@ impl Resources {
|
||||
reserved_ips: HashSet::new(),
|
||||
reserved_if_names: HashSet::new(),
|
||||
boot_files: HashSet::new(),
|
||||
}
|
||||
};
|
||||
res.scan_boot_files().unwrap();
|
||||
res
|
||||
}
|
||||
|
||||
fn available_storage_pool(&mut self, required_gb: usize) -> Option<String> {
|
||||
@ -319,9 +321,7 @@ pub struct VM {
|
||||
// currently hardcoded to EPYC-v4
|
||||
// cpu_type: String,
|
||||
vcpus: usize,
|
||||
// memory in MB
|
||||
memory_mb: usize,
|
||||
// disk size in GB
|
||||
disk_size_gb: usize,
|
||||
kernel_sha: String,
|
||||
dtrfs_sha: String,
|
||||
@ -510,7 +510,7 @@ impl VM {
|
||||
for nic in self.nics.iter() {
|
||||
for ip in nic.ips.iter() {
|
||||
ip_string += &format!(
|
||||
"detee_net_eth{}={}_{}_{}",
|
||||
"detee_net_eth{}={}_{}_{} ",
|
||||
i, ip.address, ip.mask, ip.gateway
|
||||
);
|
||||
}
|
||||
@ -527,12 +527,14 @@ impl VM {
|
||||
let mut i = 0;
|
||||
for nic in self.nics.iter() {
|
||||
let mut interface = String::new();
|
||||
interface += &format!("NETWORK_INTERFACE_{}={}", i, nic.if_config.if_type());
|
||||
interface += &format!(r#"export NETWORK_INTERFACE_{}="{}"#, i, nic.if_config.if_type());
|
||||
// device is currently ignored in case of NAT cause we assume QEMU userspace NAT
|
||||
if let Some(vtap_name) = nic.if_config.vtap_name() {
|
||||
interface += &format!("_{}_{}", nic.if_config.device_name(), vtap_name);
|
||||
}
|
||||
vars += &format!("{}\n", interface);
|
||||
interface += r#"""#;
|
||||
vars += &format!(r#"{}"#, interface);
|
||||
vars += "\n";
|
||||
i += 1;
|
||||
}
|
||||
|
||||
@ -541,17 +543,32 @@ impl VM {
|
||||
ports += &format!("{}:{} ", port.0, port.1);
|
||||
}
|
||||
if ports != "" {
|
||||
vars += &format!("NAT_PORT_FW={}", ports.trim_end());
|
||||
vars += &format!(r#"NAT_PORT_FW="{}""#, ports.trim_end());
|
||||
vars += "\n";
|
||||
}
|
||||
|
||||
vars += &format!("KERNEL={}\n", VM_BOOT_DIR.to_string() + &self.kernel_sha);
|
||||
vars += &format!("INITRD={}\n", VM_BOOT_DIR.to_string() + &self.dtrfs_sha);
|
||||
vars += &format!("PARAMS={}\n", self.kernel_params());
|
||||
vars += &format!("CPU_TYPE={}\n", QEMU_VM_CPU_TYPE);
|
||||
vars += &format!("VCPUS={}\n", self.vcpus);
|
||||
vars += &format!("MEMORY={}MB\n", self.memory_mb);
|
||||
vars += &format!("MAX_MEMORY={}MB\n", self.memory_mb + 256);
|
||||
vars += &format!("DISK={}\n", self.disk_path());
|
||||
vars += &format!(
|
||||
r#"export KERNEL="{}""#,
|
||||
VM_BOOT_DIR.to_string() + &self.kernel_sha
|
||||
);
|
||||
vars += "\n";
|
||||
vars += &format!(
|
||||
r#"export INITRD="{}""#,
|
||||
VM_BOOT_DIR.to_string() + &self.dtrfs_sha
|
||||
);
|
||||
vars += "\n";
|
||||
vars += &format!(r#"export PARAMS="{}""#, self.kernel_params());
|
||||
vars += "\n";
|
||||
vars += &format!(r#"export CPU_TYPE="{}""#, QEMU_VM_CPU_TYPE);
|
||||
vars += "\n";
|
||||
vars += &format!(r#"export VCPUS="{}""#, self.vcpus);
|
||||
vars += "\n";
|
||||
vars += &format!(r#"export MEMORY="{}M""#, self.memory_mb);
|
||||
vars += "\n";
|
||||
vars += &format!(r#"export MAX_MEMORY="{}M""#, self.memory_mb + 256);
|
||||
vars += "\n";
|
||||
vars += &format!(r#"export DISK="{}""#, self.disk_path());
|
||||
vars += "\n";
|
||||
|
||||
let mut file = File::create(VM_CONFIG_DIR.to_string() + &self.uuid)?;
|
||||
file.write_all(vars.as_bytes())?;
|
||||
@ -600,8 +617,7 @@ impl VM {
|
||||
contents += &format!("[Install]\n");
|
||||
contents += &format!("WantedBy=multi-user.target\n");
|
||||
|
||||
let mut file =
|
||||
File::create("/tmp/etc/systemd/system/".to_string() + &self.uuid + ".service")?;
|
||||
let mut file = File::create("/etc/systemd/system/".to_string() + &self.uuid + ".service")?;
|
||||
file.write_all(contents.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user