Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort env to reliably expand nested env references #510

Merged
merged 6 commits into from
Jul 21, 2021

Conversation

consideRatio
Copy link
Member

@consideRatio consideRatio commented Jun 4, 2021

KubeSpawner exposes a dictionary as configuration of environment variables, but a k8s container specification contain an ordered list where the order actually matters.

How the order matters

If an environment variable is set to be a string that contains $(SOME_ENV), it will be expanded if SOME_ENV has been defined earlier in the ordered list in the container specification.

What this PR does

This PR makes KubeSpawner emit the container's environment list in a way that first and foremost ensures as many environment variables are expanded as possible.

Is this a breaking change?

In a way yes, but I think most users will think of it as a bugfix - that the changed behavior will always be appreciated.

Related

Copy link
Member Author

@consideRatio consideRatio left a comment

Choose a reason for hiding this comment

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

@yuvipanda @minrk could you have a look at this? I'd like to cut z2jh 1.1.0 with this included in a kubespawner release.

Comment on lines -2139 to +2179
{
'name': 'JUPYTERHUB_SSL_KEYFILE',
'value': '/etc/jupyterhub/ssl/ssl.key',
},
{
'name': 'JUPYTERHUB_SSL_CERTFILE',
'value': '/etc/jupyterhub/ssl/ssl.crt',
},
{'name': 'JUPYTERHUB_USER', 'value': 'TEST'},
{
'name': 'JUPYTERHUB_SSL_CLIENT_CA',
'value': '/etc/jupyterhub/ssl/notebooks-ca_trust.crt',
},
{
'name': 'JUPYTERHUB_SSL_KEYFILE',
'value': '/etc/jupyterhub/ssl/ssl.key',
},
{'name': 'JUPYTERHUB_USER', 'value': 'TEST'},
Copy link
Member Author

Choose a reason for hiding this comment

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

Just re-ordered.

Comment on lines -2179 to -2198


def test_make_namespace():
labels = {
'heritage': 'jupyterhub',
'component': 'singleuser-server',
}
namespace = api_client.sanitize_for_serialization(
make_namespace(name='test-namespace', labels=labels)
)
assert namespace == {
'metadata': {
'annotations': {},
'labels': {
'component': 'singleuser-server',
'heritage': 'jupyterhub',
},
'name': 'test-namespace',
},
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This test function was defined twice. Removed.

Comment on lines -2015 to -2087
def test_make_pod_with_ssl():
"""
Test specification of a pod with ssl enabled
"""
assert api_client.sanitize_for_serialization(
make_pod(
name='ssl',
image='jupyter/singleuser:latest',
env={
'JUPYTERHUB_SSL_KEYFILE': 'TEST_VALUE',
'JUPYTERHUB_SSL_CERTFILE': 'TEST',
'JUPYTERHUB_USER': 'TEST',
},
working_dir='/',
cmd=['jupyterhub-singleuser'],
port=8888,
image_pull_policy='IfNotPresent',
ssl_secret_name='ssl',
ssl_secret_mount_path="/etc/jupyterhub/ssl/",
)
) == {
"metadata": {
"name": "ssl",
"annotations": {},
"labels": {},
},
"spec": {
'automountServiceAccountToken': False,
"containers": [
{
"env": [
{
'name': 'JUPYTERHUB_SSL_KEYFILE',
'value': '/etc/jupyterhub/ssl/ssl.key',
},
{
'name': 'JUPYTERHUB_SSL_CERTFILE',
'value': '/etc/jupyterhub/ssl/ssl.crt',
},
{'name': 'JUPYTERHUB_USER', 'value': 'TEST'},
{
'name': 'JUPYTERHUB_SSL_CLIENT_CA',
'value': '/etc/jupyterhub/ssl/notebooks-ca_trust.crt',
},
],
"name": "notebook",
"image": "jupyter/singleuser:latest",
"imagePullPolicy": "IfNotPresent",
"args": ["jupyterhub-singleuser"],
"ports": [{"name": "notebook-port", "containerPort": 8888}],
'volumeMounts': [
{
'mountPath': '/etc/jupyterhub/ssl/',
'name': 'jupyterhub-internal-certs',
}
],
'workingDir': '/',
"resources": {"limits": {}, "requests": {}},
}
],
'restartPolicy': 'OnFailure',
'volumes': [
{
'name': 'jupyterhub-internal-certs',
'secret': {'defaultMode': 511, 'secretName': 'ssl'},
}
],
},
"kind": "Pod",
"apiVersion": "v1",
}


Copy link
Member Author

Choose a reason for hiding this comment

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

This test function was added twice. Removed this entry.

@consideRatio consideRatio changed the title Sort env to reliably resolve nested env references Sort env to reliably resolve and expand nested env references Jul 18, 2021
@consideRatio consideRatio changed the title Sort env to reliably resolve and expand nested env references Sort env to reliably expand nested env references Jul 18, 2021
kubespawner/objects.py Outdated Show resolved Hide resolved
"env_var_key": env_var_key,
"env_var_obj": env_var_obj,
}

Copy link
Member

Choose a reason for hiding this comment

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

I think this can be simplified with a single key function passed to sorted. To do that, you'll need all transitive dependencies in the deps field, which can be computed after this direct-dependency dict exists. Need to avoid infinite loops with cycles.

Copy link
Member Author

Choose a reason for hiding this comment

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

@minrk I gave this a shot but I failed to arrive at something that I felt were about was simpler. I believe that even if I end up going for a pairwise comparison strategy which can have a clean sorted() statement, I perceived myself ending up shifting the complexity to first create a list that contained enough information to be pairwise comparable.

I did refactor my existing code to be simpler to read though. If you think it is acceptable as it is now, I suggest we go for it. I'd also be happy to replace this logic with an alternative implementation if you'd like to provide one, but I'd like that implementation to pass the test cases I've implemented.

@consideRatio consideRatio requested a review from minrk July 20, 2021 05:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants