mirror of
https://git.proxmox.com/git/proxmox-perl-rs
synced 2025-08-14 00:10:21 +00:00
pve-rs: add resource scheduling module
backed by the proxmox-resource-scheduling crate. Initially to be used by the HA manager to allow it basing its decision where to start a new or recovered service on static usage information rather than just counting. Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
This commit is contained in:
parent
9488180f9e
commit
887c0e2074
1
Makefile
1
Makefile
@ -56,6 +56,7 @@ gen:
|
||||
perl ./scripts/genpackage.pl PVE \
|
||||
PVE::RS::APT::Repositories \
|
||||
PVE::RS::OpenId \
|
||||
PVE::RS::ResourceScheduling::Static \
|
||||
PVE::RS::TFA
|
||||
perl ./scripts/genpackage.pl PMG \
|
||||
PMG::RS::APT::Repositories \
|
||||
|
@ -33,6 +33,7 @@ perlmod = { version = "0.13", features = [ "exporter" ] }
|
||||
proxmox-apt = "0.9"
|
||||
proxmox-http = { version = "0.7", features = ["client-sync", "client-trait"] }
|
||||
proxmox-openid = "0.9.5"
|
||||
proxmox-resource-scheduling = "0.1"
|
||||
proxmox-subscription = "0.3"
|
||||
proxmox-sys = "0.4"
|
||||
proxmox-tfa = { version = "2.1", features = ["api"] }
|
||||
|
@ -5,4 +5,5 @@ pub mod common;
|
||||
|
||||
pub mod apt;
|
||||
pub mod openid;
|
||||
pub mod resource_scheduling;
|
||||
pub mod tfa;
|
||||
|
1
pve-rs/src/resource_scheduling/mod.rs
Normal file
1
pve-rs/src/resource_scheduling/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod r#static;
|
116
pve-rs/src/resource_scheduling/static.rs
Normal file
116
pve-rs/src/resource_scheduling/static.rs
Normal file
@ -0,0 +1,116 @@
|
||||
#[perlmod::package(name = "PVE::RS::ResourceScheduling::Static", lib = "pve_rs")]
|
||||
mod export {
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use anyhow::{bail, Error};
|
||||
|
||||
use perlmod::Value;
|
||||
use proxmox_resource_scheduling::pve_static::{StaticNodeUsage, StaticServiceUsage};
|
||||
|
||||
perlmod::declare_magic!(Box<Scheduler> : &Scheduler as "PVE::RS::ResourceScheduling::Static");
|
||||
|
||||
struct Usage {
|
||||
nodes: HashMap<String, StaticNodeUsage>,
|
||||
}
|
||||
|
||||
pub struct Scheduler {
|
||||
inner: Mutex<Usage>,
|
||||
}
|
||||
|
||||
#[export(raw_return)]
|
||||
fn new(#[raw] class: Value) -> Result<Value, Error> {
|
||||
let inner = Usage {
|
||||
nodes: HashMap::new(),
|
||||
};
|
||||
|
||||
Ok(perlmod::instantiate_magic!(
|
||||
&class, MAGIC => Box::new(Scheduler { inner: Mutex::new(inner) })
|
||||
))
|
||||
}
|
||||
|
||||
#[export]
|
||||
fn add_node(
|
||||
#[try_from_ref] this: &Scheduler,
|
||||
nodename: String,
|
||||
maxcpu: usize,
|
||||
maxmem: usize,
|
||||
) -> Result<(), Error> {
|
||||
let mut usage = this.inner.lock().unwrap();
|
||||
|
||||
if usage.nodes.contains_key(&nodename) {
|
||||
bail!("node {} already added", nodename);
|
||||
}
|
||||
|
||||
let node = StaticNodeUsage {
|
||||
name: nodename.clone(),
|
||||
cpu: 0.0,
|
||||
maxcpu,
|
||||
mem: 0,
|
||||
maxmem,
|
||||
};
|
||||
|
||||
usage.nodes.insert(nodename, node);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[export]
|
||||
fn remove_node(#[try_from_ref] this: &Scheduler, nodename: &str) {
|
||||
let mut usage = this.inner.lock().unwrap();
|
||||
|
||||
usage.nodes.remove(nodename);
|
||||
}
|
||||
|
||||
#[export]
|
||||
fn list_nodes(#[try_from_ref] this: &Scheduler) -> Vec<String> {
|
||||
let usage = this.inner.lock().unwrap();
|
||||
|
||||
usage
|
||||
.nodes
|
||||
.keys()
|
||||
.map(|nodename| nodename.to_string())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[export]
|
||||
fn contains_node(#[try_from_ref] this: &Scheduler, nodename: &str) -> bool {
|
||||
let usage = this.inner.lock().unwrap();
|
||||
|
||||
usage.nodes.contains_key(nodename)
|
||||
}
|
||||
|
||||
/// Add usage of `service` to the node's usage.
|
||||
#[export]
|
||||
fn add_service_usage_to_node(
|
||||
#[try_from_ref] this: &Scheduler,
|
||||
nodename: &str,
|
||||
service: StaticServiceUsage,
|
||||
) -> Result<(), Error> {
|
||||
let mut usage = this.inner.lock().unwrap();
|
||||
|
||||
match usage.nodes.get_mut(nodename) {
|
||||
Some(node) => {
|
||||
node.add_service_usage(&service);
|
||||
Ok(())
|
||||
}
|
||||
None => bail!("node '{}' not present in usage hashmap", nodename),
|
||||
}
|
||||
}
|
||||
|
||||
/// Scores all previously added nodes for starting a `service` on. Scoring is done according to
|
||||
/// the static memory and CPU usages of the nodes as if the service would already be running on
|
||||
/// each.
|
||||
///
|
||||
/// Returns a vector of (nodename, score) pairs. Scores are between 0.0 and 1.0 and a higher
|
||||
/// score is better.
|
||||
#[export]
|
||||
fn score_nodes_to_start_service(
|
||||
#[try_from_ref] this: &Scheduler,
|
||||
service: StaticServiceUsage,
|
||||
) -> Result<Vec<(String, f64)>, Error> {
|
||||
let usage = this.inner.lock().unwrap();
|
||||
let nodes = usage.nodes.values().collect::<Vec<&StaticNodeUsage>>();
|
||||
|
||||
proxmox_resource_scheduling::pve_static::score_nodes_to_start_service(&nodes, &service)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user