Closed yuvipanda closed 1 month ago
I've dealt with this temporarily by removing the username label. I see the three options as:
We add a username annotation, which doesn't have this restriction.
Most users / admins won't have a strong need to target by username label, so my preference is to do (3)
This issue has been mentioned on Jupyter Community Forum. There might be relevant details there:
https://discourse.jupyter.org/t/advanced-z2jh-deeply-customizing-the-spawner/8432/1
I lean in favor of option 3 as well.
The same problem happen with @ in username. example with a username like: user@factory.org
@djangoliv this shouldn't be happening for labels starting with @
as they should be escaped by escapism. Are you still seeing this issue?
I agree that annotations make more sense. What's the case for usernames in labels? Metrics, mostly (e.g. aggregating cpu usage by user)?
@minrk yep, metrics.
FWIW, I was just today working on solving the ~same problem for user subdomains in JupyterHub in https://github.com/jupyterhub/jupyterhub/pull/4471 and have a scheme that I think always produces a unique safe string (DNS label in my case, similar rules here) from any arbitrary string:
u-{filter(lowercase_chars+digits)}--{hash}
)--
in my case), fallback on trim-and-hash if found to avoid collisions with escaped resultsThis satisfies my goals:
-2d
problem, necessary for escapism itself to avoid collisions)Of course, you can just always use the trim-and-hash scheme, if you don't mind the hashes on the end of the labels (k8s users are used to meaningless junk on the ends of most strings). Then you don't need the multi-stage escape. But if you like having the simple strings in the 90% of cases where they are valid, then this approach ought to work, and be more robust than using escapism which doesn't address things like start/end character or length requirements.
btw, to be explicit - I support option 3 as well. The only issue is that users are still affected by this bug, it's just a subset of users who opt-in to the known-to-work-only-sometimes feature. So the bug doesn't go away, it just comes up less often.
Note that this is the challenge, our escaping isn't enough because it doesn't give special treatment to the criteria of not starting/ending with a alphanum.
apiVersion: v1
kind: ConfigMap
metadata:
name: label-demo
labels:
environment: -production
data:
test: hi
kubectl apply -f test.yaml
The ConfigMap "label-demo" is invalid: metadata.labels: Invalid value: "-production": a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyValue', or 'my_value', or '12345', regex used for validation is '(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?')
Right. All the rules must be taken into account, including start, end, and length, not just body characters. The trouble with escaping alone is that it doesn't handle length or boundary conditions. And the challenge with multiple schemes is avoiding collisions.
We can do roughly:
def best_safe_slug(name):
if could_collide(name):
# if the input matches a pattern that could be produced by either scheme, make sure it gets escaped again
return always_safe(name)
nice_name = nice_scheme(name) # guaranteed unique, not guaranteed to be valid, e.g. the name itself
if is_valid(nice_name):
return nice_name
return always_safe(name)
This scheme can be used to produce all of our restricted strings (resource names, labels, etc.) with different functions for is_valid
, even after templating, and guarantee we always produce a valid, unique value. It's mainly a question of when things like truncate & hash are used (i.e. always or only when needed), because we can't avoid it if we want to accept every valid input.
Bug description
When a user with a username that starts with a non alphanumeric character (like '-' or '_') tries to spawn, it fails with:
Expected behaviour
A pod starts for the user
Actual behaviour
A user server spawns a pod with a label for the user's name. Label values can't start with non-alphanumeric chars, so this fails.
How to reproduce
Setup simple kubespawner instance and try logging in with a username starting with '_'