Skip to content

Sanitize ensemble IDs for Kubernetes label compatibility - #158

Merged
ploxiln merged 2 commits into
FoundationDB:mainfrom
Adityakk9031:#129
Jul 7, 2026
Merged

ploxiln merged 2 commits into
FoundationDB:mainfrom
Adityakk9031:#129

Conversation

@Adityakk9031

Copy link
Copy Markdown
Contributor

Description

Ensemble IDs that contain characters invalid for Kubernetes labels (e.g., /
in usernames like praza-dev/tclinkenbeard) cause joshua-agent pods to crash
with an unhelpful ApiException(422) when trying to patch their pod label.
The agent then enters an infinite crash-loop as the scaler recreates it.

Fixes #129

Root Cause

joshua_model.create_ensemble() constructs the ensemble ID directly from the
username without sanitization:

timestamp + "-" + userid:27 + "-" + hash:16

Kubernetes label values only allow [a-zA-Z0-9_.-] and must start/end with
alphanumeric. When this unsanitized ID is later used as a label value in
joshua_agent._run_ensemble(), the K8s API rejects it.

Changes

joshua/joshua_model.py

  • New sanitize_for_k8s_label() function — Replaces characters invalid for
    K8s labels with -, strips leading/trailing non-alphanumeric characters,
    and falls back to 'x' if the result is empty.
  • Applied in create_ensemble() — The ensemble ID is now sanitized at
    creation time, preventing invalid IDs from entering the system.

joshua/joshua_agent.py

  • Defense-in-depth — The ensemble value is also sanitized immediately
    before the K8s label patch call. This catches any pre-existing ensembles
    (created before this fix) that may have invalid characters.

Example

Username praza-dev/tclinkenbeard previously produced ensemble ID:
20260320-194628-praza-dev/tclinkenbeard... (contains / → K8s rejects)

After fix: 20260320-194628-praza-dev-tclinkenbeard... (/ → - → valid)

@Adityakk9031

Copy link
Copy Markdown
Contributor Author

@saintstack have a look please

Comment thread joshua/joshua_agent.py
v1.patch_namespaced_pod(pod_name, namespace, {"metadata":{"labels":{"ensemble":ensemble}}})
sanitized_ensemble = joshua_model.sanitize_for_k8s_label(ensemble)
if pod_desc.metadata.labels.get('ensemble', '') != sanitized_ensemble:
v1.patch_namespaced_pod(pod_name, namespace, {"metadata":{"labels":{"ensemble":sanitized_ensemble}}})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW I think we do not really need this "belt-and-suspenders" change, because this problem has existed for so long ... in the rare case that someone already specified an ensemble username with unacceptable characters, it has already been killing all their joshua agents, so they presumably already figured out that they have to manually delete such pre-existing ensembles.

ploxiln
ploxiln previously approved these changes Jul 6, 2026

@ploxiln ploxiln left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise, LGTM

@Adityakk9031

Copy link
Copy Markdown
Contributor Author

@ploxiln Yeah, it's mostly there as defense-in-depth to catch older client versions or manual DB edits. I'm happy to remove it though if you think it's unnecessary noise

@ploxiln

ploxiln commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Yeah, I'd either delete that bit, or add a short comment like:

# Just in case of ensembles created before joshua_model sanitize id fix

@Adityakk9031

Copy link
Copy Markdown
Contributor Author

@ploxiln done please check

@ploxiln
ploxiln merged commit 18e4eb4 into FoundationDB:main Jul 7, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Joshua should not start if ensemble name cannot be used as a k8s label

2 participants