enable kernel/dtrfs upgrade (#1)

Co-authored-by: Ramil_Algayev <pro.remred@gmail.com>
Reviewed-on: SNP/daemon#1
This commit is contained in:
ghe0 2024-12-21 20:10:57 +00:00
parent 80e899dd37
commit 3ba140a830
2 changed files with 57 additions and 30 deletions

@ -35,7 +35,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let path = entry.path(); let path = entry.path();
if path.is_file() { if path.is_file() {
let vm_id = path.file_name().unwrap().to_str().unwrap(); let vm_id = path.file_name().unwrap().to_str().unwrap();
let content = std::fs::read_to_string(crate::constants::VM_CONFIG_DIR.to_string() + vm_id + ".yaml")?; let content = std::fs::read_to_string(
crate::constants::VM_CONFIG_DIR.to_string() + vm_id + ".yaml",
)?;
let vm: crate::state::VM = serde_yaml::from_str(&content)?; let vm: crate::state::VM = serde_yaml::from_str(&content)?;
vm.delete(&mut res)?; vm.delete(&mut res)?;
println!("deleted vm {}", vm.uuid); println!("deleted vm {}", vm.uuid);
@ -46,14 +48,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let entry = entry?; let entry = entry?;
let path = entry.path(); let path = entry.path();
if path.is_file() { if path.is_file() {
let new_vm_req = UpdateVMReq::from_file(path.to_str().unwrap())?; let update_vm_req = UpdateVMReq::from_file(path.to_str().unwrap())?;
let content = std::fs::read_to_string(crate::constants::VM_CONFIG_DIR.to_string() + &new_vm_req.uuid + ".yaml")?; let content = std::fs::read_to_string(
crate::constants::VM_CONFIG_DIR.to_string() + &update_vm_req.uuid + ".yaml",
)?;
let mut vm: crate::state::VM = serde_yaml::from_str(&content)?; let mut vm: crate::state::VM = serde_yaml::from_str(&content)?;
vm.update(new_vm_req, &config, &mut res).unwrap(); vm.update(update_vm_req, &config, &mut res).unwrap();
println!("updated vm {}", vm.uuid); println!("updated vm {}", vm.uuid);
} }
} }
Ok(()) Ok(())
} }

@ -239,15 +239,15 @@ impl Resources {
self.reserved_storage self.reserved_storage
.entry(vm.storage_dir.clone()) .entry(vm.storage_dir.clone())
.and_modify(|gb| *gb += vm.disk_size_gb) .and_modify(|gb| *gb = gb.saturating_add(vm.disk_size_gb))
.or_insert(vm.disk_size_gb); .or_insert(vm.disk_size_gb);
let _ = self.save_to_disk(); let _ = self.save_to_disk();
} }
fn free_vm_resources(&mut self, vm: &VM) { fn free_vm_resources(&mut self, vm: &VM) {
self.existing_vms.remove(&vm.uuid); self.existing_vms.remove(&vm.uuid);
self.reserved_vcpus -= vm.vcpus; self.reserved_vcpus = self.reserved_vcpus.saturating_sub(vm.vcpus);
self.reserved_memory -= vm.memory_mb; self.reserved_memory = self.reserved_memory.saturating_sub(vm.memory_mb);
for nic in vm.nics.iter() { for nic in vm.nics.iter() {
if let Some(vtap) = nic.if_config.vtap_name() { if let Some(vtap) = nic.if_config.vtap_name() {
self.reserved_if_names.remove(&vtap); self.reserved_if_names.remove(&vtap);
@ -387,6 +387,11 @@ pub struct UpdateVMReq {
vcpus: usize, vcpus: usize,
memory_mb: usize, memory_mb: usize,
disk_size_gb: usize, disk_size_gb: usize,
// we are not using Option<String>, as these will be passed from gRPC
kernel_url: String,
kernel_sha: String,
dtrfs_url: String,
dtrfs_sha: String,
} }
impl UpdateVMReq { impl UpdateVMReq {
@ -439,17 +444,14 @@ impl VM {
return Err(VMCreationErrors::DiskTooSmall); return Err(VMCreationErrors::DiskTooSmall);
} }
if let Err(kernel_file_error) = if let Err(kernel_err) = res.download_boot_file(req.kernel_url, req.kernel_sha.clone()) {
res.download_boot_file(req.kernel_url, req.kernel_sha.clone())
{
return Err(VMCreationErrors::BootFileError(format!( return Err(VMCreationErrors::BootFileError(format!(
"Could not get kernel: {kernel_file_error:?}" "Could not get kernel: {kernel_err:?}"
))); )));
}; };
if let Err(dtrfs_file_error) = res.download_boot_file(req.dtrfs_url, req.dtrfs_sha.clone()) if let Err(dtrfs_err) = res.download_boot_file(req.dtrfs_url, req.dtrfs_sha.clone()) {
{
return Err(VMCreationErrors::BootFileError(format!( return Err(VMCreationErrors::BootFileError(format!(
"Could not get dtrfs: {dtrfs_file_error:?}" "Could not get dtrfs: {dtrfs_err:?}"
))); )));
}; };
@ -520,7 +522,6 @@ impl VM {
Ok(vm) Ok(vm)
} }
// TODO: test to see if this works
pub fn update( pub fn update(
&mut self, &mut self,
req: UpdateVMReq, req: UpdateVMReq,
@ -550,17 +551,40 @@ impl VM {
return Err(VMCreationErrors::DiskTooSmall); return Err(VMCreationErrors::DiskTooSmall);
} }
res.reserved_memory -= self.memory_mb; if !req.kernel_sha.is_empty() || !req.dtrfs_sha.is_empty() {
res.reserved_memory += req.memory_mb; if req.kernel_sha.is_empty() || req.dtrfs_sha.is_empty() {
res.reserved_vcpus -= self.vcpus; return Err(VMCreationErrors::BootFileError(
res.reserved_vcpus += req.vcpus; "Kernel and DTRFS can be upgraded only as a bundle".to_string(),
));
}
if let Err(kern_err) = res.download_boot_file(req.kernel_url, req.kernel_sha.clone()) {
return Err(VMCreationErrors::BootFileError(format!(
"Could not get kernel: {kern_err:?}"
)));
};
if let Err(dtrfs_err) = res.download_boot_file(req.dtrfs_url, req.dtrfs_sha.clone()) {
return Err(VMCreationErrors::BootFileError(format!(
"Could not get dtrfs: {dtrfs_err:?}"
)));
};
self.kernel_sha = req.kernel_sha;
self.dtrfs_sha = req.dtrfs_sha;
}
// Update the resources
res.reserved_memory = res.reserved_memory.saturating_add(req.memory_mb);
res.reserved_memory = res.reserved_memory.saturating_sub(self.memory_mb);
res.reserved_vcpus = res.reserved_vcpus.saturating_add(req.vcpus);
res.reserved_vcpus = res.reserved_vcpus.saturating_sub(self.vcpus);
res.reserved_storage res.reserved_storage
.entry(self.storage_dir.clone()) .entry(self.storage_dir.clone())
.and_modify(|gb| { .and_modify(|gb| {
*gb -= self.disk_size_gb; *gb = gb.saturating_add(req.disk_size_gb);
*gb += req.disk_size_gb; *gb = gb.saturating_sub(self.disk_size_gb);
}); });
let _ = res.save_to_disk();
self.memory_mb = req.memory_mb; self.memory_mb = req.memory_mb;
self.vcpus = req.vcpus; self.vcpus = req.vcpus;
@ -582,7 +606,7 @@ impl VM {
return Err(VMCreationErrors::HypervizorError(e.to_string())); return Err(VMCreationErrors::HypervizorError(e.to_string()));
} }
if let Err(e) = systemctl_stop_and_disable(&self.uuid) { if let Err(e) = systemctl_start_and_enable(&self.uuid) {
return Err(VMCreationErrors::HypervizorError(e.to_string())); return Err(VMCreationErrors::HypervizorError(e.to_string()));
} }
@ -599,14 +623,14 @@ impl VM {
} }
pub fn delete(&self, res: &mut Resources) -> Result<()> { pub fn delete(&self, res: &mut Resources) -> Result<()> {
systemctl_stop_and_disable(&self.uuid)?; let _ = systemctl_stop_and_disable(&self.uuid);
let _ = self.delete_systemd_unit_file();
let _ = systemctl_reload();
let _ = self.delete_disk();
let _ = self.delete_sh_exports();
let _ = self.delete_vtap_interfaces();
let _ = self.delete_config();
res.free_vm_resources(&self); res.free_vm_resources(&self);
self.delete_systemd_unit_file()?;
systemctl_reload()?;
self.delete_disk()?;
self.delete_sh_exports()?;
self.delete_vtap_interfaces()?;
self.delete_config()?;
Ok(()) Ok(())
} }