api-server/src/api/cluster/node.rs

72 lines
2.2 KiB
Rust
Raw Normal View History

2024-11-07 04:41:49 +00:00
use std::time::Duration;
use proxmox_api::nodes::node::lxc::vmid::migrate;
use proxmox_api::nodes::node::tasks::upid;
use sea_orm::{ActiveModelTrait, EntityTrait, IntoActiveModel, Set};
use tokio::time::sleep;
use crate::api::entity::nodes;
use crate::api::entity::nodes::P5xError;
use crate::api::services::Services;
/** Migrate an LXC container from its current PVE node to the given PVE node. */
2024-11-07 04:41:49 +00:00
pub async fn migrate_node(
svc: &Services<'_>,
node: nodes::Model,
to_host: &str,
) -> Result<nodes::Model, P5xError> {
// Ask the PVE API to start migrating the node
let params = migrate::PostParams::new(to_host.to_string());
let upid = svc.pve_node(&node.pve_host)
.map_err(P5xError::ServiceError)?
.lxc()
.vmid(node.vm_id())
.migrate()
.post(params)
.map_err(P5xError::PveError)?;
// Wait for the UPID to finish
wait_upid(svc, &node.pve_host, &upid).await?;
// Persist the node
let mut node = node.into_active_model();
node.pve_host = Set(to_host.to_string());
let node = node.save(svc.db).await.map_err(P5xError::DbErr)?;
nodes::Entity::find_by_id(node.id.unwrap())
.one(svc.db)
.await
.map_err(P5xError::DbErr)?
.ok_or(P5xError::BadPostcondition("Could not look up node after persisting"))
}
/** Wait for a PVE task to complete using its UPID */
2024-11-07 04:41:49 +00:00
pub async fn wait_upid(svc: &Services<'_>, node: &str, upid: &str) -> Result<(), P5xError> {
info!("Waiting for UPID {upid} on node {node}");
let pve = svc.pve_node(node)
.map_err(P5xError::ServiceError)?;
loop {
let status = pve.tasks()
.upid(upid)
.status()
.get()
.map_err(P5xError::PveError)?;
if status.status == upid::status::Status::Running {
sleep(Duration::from_secs(1)).await;
continue;
}
if let Some(s) = status.exitstatus {
if s == "OK" {
info!("UPID {upid} on node {node} finished");
return Ok(());
}
error!("UPID {upid} on node {node} failed");
return Err(P5xError::UpidFailed(node.to_string(), upid.to_string()));
}
}
}