writing files correctly
This commit is contained in:
parent
d4c5cc2634
commit
df34fc719c
@ -7,7 +7,7 @@
|
|||||||
source "/etc/detee/daemon/vms/$VM_UUID"
|
source "/etc/detee/daemon/vms/$VM_UUID"
|
||||||
|
|
||||||
mandatory_vars=("KERNEL" "INITRD" "PARAMS" "CPU_TYPE" \
|
mandatory_vars=("KERNEL" "INITRD" "PARAMS" "CPU_TYPE" \
|
||||||
"VCPUS" "MEMORY" "MAX_MEMORY" "DISK" "DISK_SIZE")
|
"VCPUS" "MEMORY" "MAX_MEMORY" "DISK")
|
||||||
for var in "${mandatory_vars[@]}"; do
|
for var in "${mandatory_vars[@]}"; do
|
||||||
if [ -z "${!var}" ]; then
|
if [ -z "${!var}" ]; then
|
||||||
echo "Environment variable $var is not set."
|
echo "Environment variable $var is not set."
|
||||||
@ -51,8 +51,6 @@ done <<< "$( echo "$interfaces" )"
|
|||||||
|
|
||||||
vm_disk="/root/dtrfs/arch-1-ghe0.qcow2"
|
vm_disk="/root/dtrfs/arch-1-ghe0.qcow2"
|
||||||
|
|
||||||
[[ -f $DISK ]] || qemu-img create -f qcow2 ${DISK} ${DISK_SIZE}
|
|
||||||
|
|
||||||
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 \
|
||||||
|
@ -19,7 +19,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// println!("{:#?}", config);
|
// println!("{:#?}", config);
|
||||||
// let config = Config::from_file("test_data/config5.yaml")?;
|
// let config = Config::from_file("test_data/config5.yaml")?;
|
||||||
// println!("{:#?}", config);
|
// println!("{:#?}", config);
|
||||||
let new_vm_req = NewVMRequest::from_file("test_data/new_vm_req4.yaml")?;
|
let new_vm_req = NewVMRequest::from_file("test_data/new_vm_req2.yaml")?;
|
||||||
// println!("{:#?}", new_vm_req);
|
// println!("{:#?}", new_vm_req);
|
||||||
|
|
||||||
// let new_vm_req = NewVMRequest::from_file("test_data/new_vm_req2.yaml")?;
|
// let new_vm_req = NewVMRequest::from_file("test_data/new_vm_req2.yaml")?;
|
||||||
@ -29,11 +29,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// let new_vm_req = NewVMRequest::from_file("test_data/new_vm_req4.yaml")?;
|
// let new_vm_req = NewVMRequest::from_file("test_data/new_vm_req4.yaml")?;
|
||||||
// println!("{:#?}", new_vm_req);
|
// 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);
|
||||||
let new_vm_req = NewVMRequest::from_file("test_data/new_vm_req4.yaml")?;
|
|
||||||
let vm = state::VM::new(new_vm_req, &config, &mut res);
|
|
||||||
let new_vm_req = NewVMRequest::from_file("test_data/new_vm_req4.yaml")?;
|
|
||||||
let vm = state::VM::new(new_vm_req, &config, &mut res);
|
|
||||||
println!("vm: {:#?}", vm);
|
println!("vm: {:#?}", vm);
|
||||||
println!("res: {:#?}", res);
|
println!("{:?}", vm.unwrap().start());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
97
src/state.rs
97
src/state.rs
@ -205,6 +205,22 @@ impl Resources {
|
|||||||
self.reserved_ports.insert(*host_port);
|
self.reserved_ports.insert(*host_port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn free_vm_resources(&mut self, vm: &VM) {
|
||||||
|
self.reserved_vcpus -= vm.vcpus;
|
||||||
|
self.reserved_memory -= vm.memory;
|
||||||
|
for nic in vm.nics.iter() {
|
||||||
|
if let Some(vtap) = nic.if_config.vtap_name() {
|
||||||
|
self.reserved_if_names.remove(&vtap);
|
||||||
|
}
|
||||||
|
for ip in nic.ips.iter() {
|
||||||
|
self.reserved_ips.remove(&ip.address.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (host_port, _) in vm.fw_ports.iter() {
|
||||||
|
self.reserved_ports.remove(host_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -427,6 +443,28 @@ impl VM {
|
|||||||
Ok(vm)
|
Ok(vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn start(&self) -> Result<()> {
|
||||||
|
self.create_disk()?;
|
||||||
|
self.write_vm_config()?;
|
||||||
|
self.write_systemd_unit_file()?;
|
||||||
|
// TODO: systemctl daemon-reload
|
||||||
|
// TODO: systemctl start
|
||||||
|
// TODO: systemctl enable
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete(&self, res: &mut Resources) -> Result<()> {
|
||||||
|
// TODO: systemctl stop
|
||||||
|
// TODO: systemctl disable
|
||||||
|
res.free_vm_resources(&self);
|
||||||
|
self.delete_systemd_unit_file()?;
|
||||||
|
// TODO: systemctl daemon-reload
|
||||||
|
self.delete_disk()?;
|
||||||
|
self.delete_vm_config()?;
|
||||||
|
self.delete_vtap_interfaces()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn deploy(&self) -> Result<()> {
|
pub fn deploy(&self) -> Result<()> {
|
||||||
self.create_disk()?;
|
self.create_disk()?;
|
||||||
self.write_vm_config()?;
|
self.write_vm_config()?;
|
||||||
@ -435,20 +473,11 @@ impl VM {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(&self) -> Result<()> {
|
|
||||||
// TODO: systemctl disable, systemctl stop
|
|
||||||
self.delete_disk()?;
|
|
||||||
self.delete_vtap_interfaces()?;
|
|
||||||
self.delete_systemd_unit_file()?;
|
|
||||||
// TODO: systemctl daemon-reload
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// For the MVP, the T-Contract offers VM+IP+Disk as a bundle.
|
// For the MVP, the T-Contract offers VM+IP+Disk as a bundle.
|
||||||
// This means we can enforce the path to the disk.
|
// This means we can enforce the path to the disk.
|
||||||
// This may change in the future as the VM is allowed to have multiple disks.
|
// This may change in the future as the VM is allowed to have multiple disks.
|
||||||
pub fn disk_path(&self) -> String {
|
pub fn disk_path(&self) -> String {
|
||||||
VM_DISK_DIR.to_string() + "/" + &self.uuid + ".qcow2"
|
VM_DISK_DIR.to_string() + &self.uuid + ".qcow2"
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kernel_params(&self) -> String {
|
pub fn kernel_params(&self) -> String {
|
||||||
@ -493,11 +522,11 @@ impl VM {
|
|||||||
|
|
||||||
vars += &format!(
|
vars += &format!(
|
||||||
"KERNEL={}\n",
|
"KERNEL={}\n",
|
||||||
VM_BOOT_DIR.to_string() + "/" + &self.kernel_sha
|
VM_BOOT_DIR.to_string() + &self.kernel_sha
|
||||||
);
|
);
|
||||||
vars += &format!(
|
vars += &format!(
|
||||||
"INITRD={}\n",
|
"INITRD={}\n",
|
||||||
VM_BOOT_DIR.to_string() + "/" + &self.dtrfs_sha
|
VM_BOOT_DIR.to_string() + &self.dtrfs_sha
|
||||||
);
|
);
|
||||||
vars += &format!("PARAMS={}\n", self.kernel_params());
|
vars += &format!("PARAMS={}\n", self.kernel_params());
|
||||||
vars += &format!("CPU_TYPE={}\n", QEMU_VM_CPU_TYPE);
|
vars += &format!("CPU_TYPE={}\n", QEMU_VM_CPU_TYPE);
|
||||||
@ -505,15 +534,14 @@ impl VM {
|
|||||||
vars += &format!("MEMORY={}MB\n", self.memory);
|
vars += &format!("MEMORY={}MB\n", self.memory);
|
||||||
vars += &format!("MAX_MEMORY={}MB\n", self.memory + 256);
|
vars += &format!("MAX_MEMORY={}MB\n", self.memory + 256);
|
||||||
vars += &format!("DISK={}\n", self.disk_path());
|
vars += &format!("DISK={}\n", self.disk_path());
|
||||||
vars += &format!("DISK_SIZE={}GB\n", self.disk_size);
|
|
||||||
|
|
||||||
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())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_vm_config(&self) -> Result<()> {
|
pub fn delete_vm_config(&self) -> Result<()> {
|
||||||
remove_file(VM_CONFIG_DIR.to_string() + "/" + &self.uuid)?;
|
remove_file(VM_CONFIG_DIR.to_string() + &self.uuid)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,27 +568,27 @@ impl VM {
|
|||||||
|
|
||||||
pub fn write_systemd_unit_file(&self) -> Result<()> {
|
pub fn write_systemd_unit_file(&self) -> Result<()> {
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
contents += &format!("[Unit]");
|
contents += &format!("[Unit]\n");
|
||||||
contents += &format!("Description=DeTEE {}", self.uuid);
|
contents += &format!("Description=DeTEE {}\n", self.uuid);
|
||||||
contents += &format!("After=network.target");
|
contents += &format!("After=network.target\n");
|
||||||
contents += &format!("");
|
contents += &format!("\n");
|
||||||
contents += &format!("[Service]");
|
contents += &format!("[Service]\n");
|
||||||
contents += &format!("Type=simple");
|
contents += &format!("Type=simple\n");
|
||||||
contents += &format!("Environment=VM_UUID={}", self.uuid);
|
contents += &format!("Environment=VM_UUID={}\n", self.uuid);
|
||||||
contents += &format!("ExecStart={}", START_VM_SCRIPT);
|
contents += &format!("ExecStart={}\n", START_VM_SCRIPT);
|
||||||
contents += &format!("ExecStop=/bin/kill -s SIGINT $MAINPID");
|
contents += &format!("ExecStop=/bin/kill -s SIGINT $MAINPID\n");
|
||||||
contents += &format!("Restart=always");
|
contents += &format!("Restart=always\n");
|
||||||
contents += &format!("");
|
contents += &format!("\n");
|
||||||
contents += &format!("[Install]");
|
contents += &format!("[Install]\n");
|
||||||
contents += &format!("WantedBy=multi-user.target");
|
contents += &format!("WantedBy=multi-user.target\n");
|
||||||
|
|
||||||
let mut file = File::create("/etc/systemd/system/".to_string() + &self.uuid + ".service")?;
|
let mut file = 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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_systemd_unit_file(&self) -> Result<()> {
|
pub fn delete_systemd_unit_file(&self) -> Result<()> {
|
||||||
remove_file("/etc/systemd/system/".to_string() + &self.uuid + ".service")?;
|
remove_file("/tmp/etc/systemd/system/".to_string() + &self.uuid + ".service")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,14 +596,17 @@ impl VM {
|
|||||||
let result = Command::new("qemu-img")
|
let result = Command::new("qemu-img")
|
||||||
.arg("create")
|
.arg("create")
|
||||||
.arg("-f")
|
.arg("-f")
|
||||||
|
.arg("qcow2")
|
||||||
.arg(self.disk_path())
|
.arg(self.disk_path())
|
||||||
.arg(self.disk_size.to_string() + "G")
|
.arg(self.disk_size.to_string() + "G")
|
||||||
.output()?;
|
.output()?;
|
||||||
if !result.status.success() {
|
if !result.status.success() {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"Could not create VM Disk:\n{:?}\n{:?}",
|
"Could not create VM Disk:\n{:?}\n{:?}",
|
||||||
result.stdout,
|
String::from_utf8(result.stdout)
|
||||||
result.stderr
|
.unwrap_or("Could not grab stdout from creation script.".to_string()),
|
||||||
|
String::from_utf8(result.stderr)
|
||||||
|
.unwrap_or("Could not grab stderr from creation script.".to_string()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -592,7 +623,7 @@ fn download_and_check_sha(url: &str, sha: &str) -> Result<()> {
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::copy;
|
use std::io::copy;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
let save_path = VM_BOOT_DIR.to_string() + "/" + sha;
|
let save_path = VM_BOOT_DIR.to_string() + sha;
|
||||||
let response = get(url)?;
|
let response = get(url)?;
|
||||||
if !response.status().is_success() {
|
if !response.status().is_success() {
|
||||||
return Err(anyhow!("Failed to download file: {}", response.status()));
|
return Err(anyhow!("Failed to download file: {}", response.status()));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
uuid: "default-uuid"
|
uuid: "DuTenPulaMeaCuUUIDulTauCuTot"
|
||||||
hostname: "testing-vm"
|
hostname: "testing-vm"
|
||||||
admin_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAAKeyExampleForTesting"
|
admin_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAAKeyExampleForTesting"
|
||||||
extra_ports: [1234, 5678]
|
extra_ports: [1234, 5678]
|
||||||
|
Loading…
Reference in New Issue
Block a user