fix: improve ssh agent worker naming (#6211)

* remove ssh suffix

* use hostname tags

* feat

* feat

* update sqlx

* use hostname

* use worker prefix

* nits
This commit is contained in:
dieriba
2025-07-21 15:43:25 +02:00
committed by GitHub
parent ec0da9cb1a
commit 1036488b3b
8 changed files with 53 additions and 53 deletions

View File

@@ -0,0 +1,22 @@
{
"db_name": "PostgreSQL",
"query": "\n SELECT \n tag\n FROM \n v2_job\n WHERE \n id = $1\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "tag",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": [
false
]
},
"hash": "49e2430af74ec10857e5df7f7e1ad1b53ba70bb51b0259a1f765f76db9b733ad"
}

View File

@@ -1 +1 @@
5ee3df2b86049b8fb5808d7024e27785ae6415e8
0a3c1d10b8936caaf76e57ea1df59c245caad268

View File

@@ -54,8 +54,8 @@ use windmill_common::{
stats_oss::schedule_stats,
triggers::TriggerKind,
utils::{
create_default_worker_suffix, create_ssh_agent_worker_suffix, worker_name_with_suffix,
Mode, GIT_VERSION, HOSTNAME, MODE_AND_ADDONS,
create_default_worker_suffix, worker_name_with_suffix, Mode, GIT_VERSION, HOSTNAME,
MODE_AND_ADDONS,
},
worker::{
reload_custom_tags_setting, Connection, HUB_CACHE_DIR, TMP_DIR, TMP_LOGS_DIR, WORKER_GROUP,
@@ -365,7 +365,7 @@ async fn windmill_main() -> anyhow::Result<()> {
"Creating http client for cluster using base internal url {}",
std::env::var("BASE_INTERNAL_URL").unwrap_or_default()
);
let suffix = create_ssh_agent_worker_suffix(&hostname);
let suffix = create_default_worker_suffix(&hostname);
(
Connection::Http(build_agent_http_client(&suffix)),
Some(suffix),

View File

@@ -611,7 +611,7 @@ pub async fn run_server(
.nest("/mqtt_triggers", mqtt_triggers_service)
.nest("/sqs_triggers", sqs_triggers_service)
.nest("/gcp_triggers", gcp_triggers_service)
.nest("/postgres_triggers", postgres_triggers_service),
.nest("/postgres_triggers", postgres_triggers_service),
)
.nest("/workspaces", workspaces::global_service())
.nest(

View File

@@ -198,20 +198,13 @@ fn instance_name(hostname: &str) -> String {
const DEFAULT_WORKER_SUFFIX_LEN: usize = 5;
pub const SSH_AGENT_WORKER_SUFFIX: &'static str = "/ssh";
pub fn create_worker_suffix(hostname: &str, rd_string_len: usize, ssh_ag_worker: bool) -> String {
let mut wk_suffix = format!("{}-{}", instance_name(hostname), rd_string(rd_string_len));
if ssh_ag_worker {
wk_suffix.push_str(SSH_AGENT_WORKER_SUFFIX);
}
pub fn create_worker_suffix(hostname: &str, rd_string_len: usize) -> String {
let wk_suffix = format!("{}-{}", instance_name(hostname), rd_string(rd_string_len));
wk_suffix
}
pub fn create_ssh_agent_worker_suffix(hostname: &str) -> String {
create_worker_suffix(hostname, DEFAULT_WORKER_SUFFIX_LEN, true)
}
pub fn create_default_worker_suffix(hostname: &str) -> String {
create_worker_suffix(hostname, DEFAULT_WORKER_SUFFIX_LEN, false)
create_worker_suffix(hostname, DEFAULT_WORKER_SUFFIX_LEN)
}
pub fn worker_name_with_suffix(is_agent: bool, worker_group: &str, suffix: &str) -> String {
@@ -222,6 +215,14 @@ pub fn worker_name_with_suffix(is_agent: bool, worker_group: &str, suffix: &str)
}
}
pub fn retrieve_common_worker_prefix(worker_name: &str) -> String {
let (prefix, _) = worker_name.rsplit_once('-').unzip();
prefix
.expect("Invalid worker_name: expected at least one '-' in the name")
.to_owned()
}
pub fn paginate(pagination: Pagination) -> (usize, usize) {
let per_page = pagination
.per_page

View File

@@ -13,6 +13,7 @@ use anyhow::anyhow;
use futures::TryFutureExt;
use tokio::time::timeout;
use windmill_common::client::AuthedClient;
use windmill_common::utils::retrieve_common_worker_prefix;
use windmill_common::{
agent_workers::DECODED_AGENT_TOKEN,
apps::AppScriptId,
@@ -779,7 +780,8 @@ pub fn start_interactive_worker_shell(
} else {
let pulled_job = match &conn {
Connection::Sql(db) => {
let query = ("".to_string(), make_pull_query(&[hostname.to_owned()]));
let common_worker_prefix = retrieve_common_worker_prefix(&worker_name);
let query = ("".to_string(), make_pull_query(&[common_worker_prefix]));
#[cfg(feature = "benchmark")]
let mut bench = windmill_common::bench::BenchmarkIter::new();
@@ -1221,10 +1223,9 @@ pub async fn run_worker(
)),
_ => None,
};
// If we're the first worker to run, we start another background process that listens for a specific tag.
// This tag is associated only with jobs using Bash as the script language.
// For agent workers, the expected tag format is the worker name suffixed with "-ssh".
// For regular workers, the tag is simply the machine's hostname and if not found the randomly generated hostname.
// The tag itself is simply the workers common name (for example, wk-{worker_group}-{instance_name}).
let interactive_shell = if i_worker == 1 {
let it_shell = start_interactive_worker_shell(
conn.clone(),

View File

@@ -86,14 +86,6 @@ export function isJobReRunnable(j: Job): boolean {
}
export const WORKER_NAME_PREFIX = 'wk'
export const AGENT_WORKER_NAME_PREFIX = 'ag'
const SSH_AGENT_WORKER_SUFFIX = '/ssh'
export function isAgentWorkerShell(workerName: string) {
return (
workerName.startsWith(AGENT_WORKER_NAME_PREFIX) && workerName.endsWith(SSH_AGENT_WORKER_SUFFIX)
)
}
export function isJobSelectable(selectionType: RunsSelectionMode) {
const f: (j: Job) => boolean = {
@@ -137,6 +129,12 @@ export function displayDateOnly(dateString: string | Date | undefined): string {
}
}
export function retrieveCommonWorkerPrefix(workerName: string): string {
const lastDashIndex = workerName.lastIndexOf('-')
return workerName.substring(0, lastDashIndex)
}
export function subtractDaysFromDateString(
dateString: string | undefined,
days: number

View File

@@ -25,14 +25,7 @@
userWorkspaces
} from '$lib/stores'
import { sendUserToast } from '$lib/toast'
import {
AGENT_WORKER_NAME_PREFIX,
displayDate,
groupBy,
isAgentWorkerShell,
pluralize,
truncate
} from '$lib/utils'
import { displayDate, groupBy, pluralize, retrieveCommonWorkerPrefix, truncate } from '$lib/utils'
import { AlertTriangle, LineChart, List, Plus, Search, Terminal } from 'lucide-svelte'
import { getContext, onDestroy, onMount } from 'svelte'
@@ -585,7 +578,8 @@
<tr class="border-t">
<Cell
first
colspan={(!config || config?.dedicated_worker == undefined) && ($superadmin || $devopsRole)
colspan={(!config || config?.dedicated_worker == undefined) &&
($superadmin || $devopsRole)
? 12
: 9}
scope="colgroup"
@@ -606,11 +600,6 @@
</Cell>
</tr>
{#if workers}
{@const sshWorker = workers.find((worker) => {
return (
isAgentWorkerShell(worker.worker) && isWorkerMaybeAlive(worker.last_ping)
)
})?.worker}
{#each workers as { worker, custom_tags, last_ping, started_at, jobs_executed, last_job_id, last_job_workspace_id, occupancy_rate_15s, occupancy_rate_5m, occupancy_rate_30m, occupancy_rate, wm_version, vcpus, memory, memory_usage, wm_memory_usage }}
{@const isWorkerAlive = isWorkerMaybeAlive(last_ping)}
<tr>
@@ -706,18 +695,7 @@
sendUserToast('Worker must be alive', true)
return
}
if (worker.startsWith(AGENT_WORKER_NAME_PREFIX)) {
if (!sshWorker) {
sendUserToast(
'Unexpected error could not find agent worker handling repl feature',
true
)
return
}
tag = sshWorker
} else {
tag = hostname
}
tag = retrieveCommonWorkerPrefix(worker)
replForWorkerDrawer?.openDrawer()
}}
startIcon={{ icon: Terminal }}