From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 7BA0C8E0AD for ; Thu, 10 Nov 2022 15:38:08 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 651EC287DB for ; Thu, 10 Nov 2022 15:38:08 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS for ; Thu, 10 Nov 2022 15:38:05 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id A7181449EC for ; Thu, 10 Nov 2022 15:38:04 +0100 (CET) From: Fiona Ebner To: pve-devel@lists.proxmox.com Date: Thu, 10 Nov 2022 15:37:43 +0100 Message-Id: <20221110143800.98047-5-f.ebner@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20221110143800.98047-1-f.ebner@proxmox.com> References: <20221110143800.98047-1-f.ebner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.028 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH proxmox-perl-rs 1/2] pve-rs: add resource scheduling module X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 10 Nov 2022 14:38:08 -0000 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 --- Makefile | 1 + pve-rs/Cargo.toml | 1 + pve-rs/src/lib.rs | 1 + pve-rs/src/resource_scheduling/mod.rs | 1 + pve-rs/src/resource_scheduling/static.rs | 116 +++++++++++++++++++++++ 5 files changed, 120 insertions(+) create mode 100644 pve-rs/src/resource_scheduling/mod.rs create mode 100644 pve-rs/src/resource_scheduling/static.rs diff --git a/Makefile b/Makefile index 0836c9d..3ddafd0 100644 --- a/Makefile +++ b/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 \ diff --git a/pve-rs/Cargo.toml b/pve-rs/Cargo.toml index 855c72d..daa6bff 100644 --- a/pve-rs/Cargo.toml +++ b/pve-rs/Cargo.toml @@ -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"] } diff --git a/pve-rs/src/lib.rs b/pve-rs/src/lib.rs index 26b998b..562a4d4 100644 --- a/pve-rs/src/lib.rs +++ b/pve-rs/src/lib.rs @@ -5,4 +5,5 @@ pub mod common; pub mod apt; pub mod openid; +pub mod resource_scheduling; pub mod tfa; diff --git a/pve-rs/src/resource_scheduling/mod.rs b/pve-rs/src/resource_scheduling/mod.rs new file mode 100644 index 0000000..a28f1c9 --- /dev/null +++ b/pve-rs/src/resource_scheduling/mod.rs @@ -0,0 +1 @@ +pub mod r#static; diff --git a/pve-rs/src/resource_scheduling/static.rs b/pve-rs/src/resource_scheduling/static.rs new file mode 100644 index 0000000..c47dcd3 --- /dev/null +++ b/pve-rs/src/resource_scheduling/static.rs @@ -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 as "PVE::RS::ResourceScheduling::Static"); + + struct Usage { + nodes: HashMap, + } + + pub struct Scheduler { + inner: Mutex, + } + + #[export(raw_return)] + fn new(#[raw] class: Value) -> Result { + 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 { + 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, Error> { + let usage = this.inner.lock().unwrap(); + let nodes = usage.nodes.values().collect::>(); + + proxmox_resource_scheduling::pve_static::score_nodes_to_start_service(&nodes, &service) + } +} -- 2.30.2