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