From 2458e6c3d82eb1c3ad64132f4941293b6c690790 Mon Sep 17 00:00:00 2001 From: Maurus Decimus <11444311+mdecimus@users.noreply.github.com> Date: Fri, 24 Apr 2026 14:32:52 +0200 Subject: [PATCH] Add `system(node_hostname)` and `system(node_role)` expression variables --- CHANGELOG.md | 1 + crates/common/src/expr/eval.rs | 10 ++++++++++ crates/common/src/expr/functions/array.rs | 4 ++-- crates/common/src/expr/mod.rs | 2 ++ crates/common/src/expr/tokenizer.rs | 2 ++ crates/common/src/scripts/functions/array.rs | 4 ++-- 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0583e2ff..ca5353a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. This projec This version includes **multiple breaking changes**. If you are upgrading from v0.15.x and below, please read the [upgrading documentation](https://github.com/stalwartlabs/stalwart/blob/main/UPGRADING/v0_16.md) for more information on how to upgrade from previous versions. ## Added +- `system('node_hostname')` and `system('node_role')` expression variables to retrieve the local node hostname and cluster role respectively. ## Changed diff --git a/crates/common/src/expr/eval.rs b/crates/common/src/expr/eval.rs index 3d2b41d9..3fc27a8f 100644 --- a/crates/common/src/expr/eval.rs +++ b/crates/common/src/expr/eval.rs @@ -227,6 +227,16 @@ impl<'x, V: ResolveVariable> EvalContext<'x, V, Expression, &mut Vec stack.push(self.core.core.network.node_id.into()), + SystemVariable::NodeHostname => { + stack.push(self.core.registry().local_hostname().into()) + } + SystemVariable::NodeRole => stack.push( + self.core + .registry() + .cluster_role() + .unwrap_or_default() + .into(), + ), SystemVariable::Metric(variable) => { stack.push(Variable::Float(Collector::read_metric(*variable))); } diff --git a/crates/common/src/expr/functions/array.rs b/crates/common/src/expr/functions/array.rs index 31b08a14..69f10e28 100644 --- a/crates/common/src/expr/functions/array.rs +++ b/crates/common/src/expr/functions/array.rs @@ -24,9 +24,9 @@ pub(crate) fn fn_sort(mut v: Vec) -> Variable { let is_asc = v[1].to_bool(); let mut arr = v.remove(0).into_array(); if is_asc { - arr.sort_unstable_by(|a, b| b.cmp(a)); - } else { arr.sort_unstable(); + } else { + arr.sort_unstable_by(|a, b| b.cmp(a)); } arr.into() } diff --git a/crates/common/src/expr/mod.rs b/crates/common/src/expr/mod.rs index aa6b2a04..d07c1490 100644 --- a/crates/common/src/expr/mod.rs +++ b/crates/common/src/expr/mod.rs @@ -175,6 +175,8 @@ pub enum SystemVariable { Hostname, Domain, NodeId, + NodeHostname, + NodeRole, Metric(MetricType), } diff --git a/crates/common/src/expr/tokenizer.rs b/crates/common/src/expr/tokenizer.rs index 125cb807..01a8c863 100644 --- a/crates/common/src/expr/tokenizer.rs +++ b/crates/common/src/expr/tokenizer.rs @@ -119,6 +119,8 @@ impl<'x> Tokenizer<'x> { "domain" => SystemVariable::Domain, "hostname" => SystemVariable::Hostname, "node_id" => SystemVariable::NodeId, + "node_hostname" => SystemVariable::NodeHostname, + "node_role" => SystemVariable::NodeRole, other => { return Err(format!( "Invalid system variable name {:?}", diff --git a/crates/common/src/scripts/functions/array.rs b/crates/common/src/scripts/functions/array.rs index 9d6be10c..6d537e49 100644 --- a/crates/common/src/scripts/functions/array.rs +++ b/crates/common/src/scripts/functions/array.rs @@ -26,9 +26,9 @@ pub fn fn_sort<'x>(_: &'x Context<'x>, v: Vec) -> Variable { let is_asc = v[1].to_bool(); let mut arr = (*v[0].to_array()).clone(); if is_asc { - arr.sort_unstable_by(|a, b| b.cmp(a)); - } else { arr.sort_unstable(); + } else { + arr.sort_unstable_by(|a, b| b.cmp(a)); } arr.into() }