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" | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										18
									
								
								scripts/start_qemu_vm.sh
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										18
									
								
								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 )" | ||||
|     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