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

Add kube profile spawner #137

Merged
merged 17 commits into from
Apr 17, 2018
Merged

Conversation

gsemet
Copy link
Contributor

@gsemet gsemet commented Mar 1, 2018

Reference #135

Adds profile_list parameter to KubeSpawner allowing override of one or several parameter (ex: cpu_limit, image_spec, or any other KubeSpawner parameter)

Here an example:

c.JupyterHub.spawner_class = 'kubespawner.KubeSpawner'
c.KubeSpawner.namespace = ...
c.KubeSpawner.start_timeout = ...
c.KubeSpawner.singleuser_image_spec = ...
c.KubeSpawner.singleuser_extra_labels = ...
c.KubeSpawner.singleuser_uid = ...
...
c.KubeSpawner.profile_list = [
    {
        'display_name': 'Training Env - Python',
        'kubespawner_override': {
            'singleuser_image_spec': 'training/python:label',
            'cpu_limit': 1,
        }
    },
    {   
        'display_name': 'Training Env - Datascience',
        'kubespawner_override': {
            'singleuser_image_spec': 'training/datascience:label',
            'cpu_limit': 4,
        }
    }, {
        'display_name': 'DataScience - Small instance',
        'kubespawner_override': {
            'singleuser_image_spec': 'datascience/small:label',
            'cpu_limit': 10,
        }
    }, {
        'display_name': 'DataScience - Medium instance',
        'kubespawner_override': {
            'singleuser_image_spec': 'datascience/medium:label',
            'cpu_limit': 48,
        }
    }, {
        'display_name': 'DataScience - Medium instance (GPUx2)',
        'kubespawner_override': {
            'singleuser_image_spec': 'datascience/medium:label',
            'cpu_limit': 48,
            'extra_resource_guarantees': {"nvidia.com/gpu": "2"},
        }
    }
]

I have not fully tested this version, and if we agree, this class can be merged into KubeSpawner ultimately.

Screenshot:
profilespawner

@yuvipanda
Copy link
Collaborator

Hey, @gsemet! Apologies for the late review!

This actually looks good to me as is! Can you merge it into KubeSpawner itself, rather than having it be a separate spawner? I think we can merge it afterwards...

@gsemet
Copy link
Contributor Author

gsemet commented Mar 7, 2018

Sure. I just have one issue. When the container is pending stop and you want to restart it it shows a 400 error “pending stop”, I do not remember seeing it with the normal kubespawner, it was just waiting.
If it is ok for you, I’ll merge it.

@gsemet gsemet force-pushed the profile_spawner branch 3 times, most recently from 86addb8 to 1338224 Compare March 7, 2018 19:12
@gsemet
Copy link
Contributor Author

gsemet commented Mar 9, 2018

I have a few change to update (I'll do is asap) before this PR being ready to merge

@gsemet gsemet changed the title Add kube profile spawner WIP: Add kube profile spawner Mar 9, 2018
@gsemet gsemet changed the title WIP: Add kube profile spawner Add kube profile spawner Mar 11, 2018

__all__ = [KubeSpawner]
__all__ = [KubeSpawner, KubeProfileSpawner]
Copy link

Choose a reason for hiding this comment

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

Can probably remove KubeProfileSpawner from here now?

@gsemet
Copy link
Contributor Author

gsemet commented Mar 11, 2018

updated my PR. I'll be happy if someone can test it

@gsemet
Copy link
Contributor Author

gsemet commented Mar 11, 2018

I'll test it tomorow on our baremetal kube cluster

@sylus
Copy link

sylus commented Mar 15, 2018

I took a look at this by adding the following to forked requirements.txt hub docker image:

git+git://github.com/gsemet/kubespawner@profile_spawner#egg=jupyterhub-kubespawner

And then in my config.yaml helm chart

  image:
    name: govcloud/zero-to-jupyterhub-k8s
    tag: v0.6
  extraConfig: |
    c.KubeSpawner.single_user_profile_list = [
        {
            'display_name': 'Training Env - Python',
            'kubespawner_overrride': {
                'image_spec': 'jupyterhub/python:0.8',
                'cpu_limit': 10,
            }
        },
        {
            'display_name': 'Training Env - SAS',
            'kubespawner_overrride': {
                'image_spec': 'jupyterhub/sas:0.8',
                'cpu_limit': 10,
            }
        }, {
            'display_name': 'DataScience - Pachyderm',
            'kubespawner_overrride': {
                'image_spec': 'jupyterhub/pachyderm:0.8',
                'cpu_limit': 10,
            }
        }
    ]

The interface does get updated but doesn't seem to do anything?

3_spawner

Looking at WrapSpawner + DockerSpawner are we not supposed to now check self.user_options before the make_pod assignment in

def make_pod(

Thanks for the amazing work!


options_form = Unicode()

single_user_profile_list = List(
Copy link
Member

Choose a reason for hiding this comment

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

Can this be profile_list? I want to move toward removing the singleuser_ prefix from config, since everything here is necessarily about configuring singleuser pods, it's redundant.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -781,6 +783,46 @@ def _hub_connect_port_default(self):
"""
)

form_template = Unicode(
"""<label for="profile">Please select a profile for your Jupyter:</label>
Copy link
Member

Choose a reason for hiding this comment

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

s/Jupyter/environment/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

form_template = Unicode(
"""<label for="profile">Please select a profile for your Jupyter:</label>
<select class="form-control" name="profile" required autofocus>
{input_template}
Copy link
Member

Choose a reason for hiding this comment

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

call this {inputs} since it is not input_template, but the result of input_template being rendered multiple times.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

the first item starts selected."""
)

first_template = Unicode('selected',
Copy link
Member

Choose a reason for hiding this comment

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

If this isn't a template, maybe not have 'template' in the name. Maybe first_input?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@gsemet
Copy link
Contributor Author

gsemet commented Mar 16, 2018

Ok, i'll rebase and test these changes next week :)

@sylus
Copy link

sylus commented Mar 16, 2018

Was there any feedback on my comment was curious for my own edification that this was still missing logic in make_pod to be functional?

@gsemet
Copy link
Contributor Author

gsemet commented Mar 16, 2018

I have actually not tested the image spec override so I may have made a mistake. I’ll see that next week, prev week was too busy ! But sure, I’ll take all your feedback into account, and the image override should work, was a reason to implement this profile_list feature !

@gsemet gsemet force-pushed the profile_spawner branch 2 times, most recently from fb77366 to e7c4735 Compare March 19, 2018 15:52
@gsemet
Copy link
Contributor Author

gsemet commented Mar 19, 2018

@sylus, you took my example that had a typo: kubespawner_overrride. Please change it to kubespawner_override :)

@gsemet
Copy link
Contributor Author

gsemet commented Mar 19, 2018

Just tested it now. It works :) I only tested with the following override:

'cpu_limit': 1,
'mem_limit': '1G',

And they are well applied on the started pod.

config=True,
help="Text to substitute as {first} in inputs"
)

Copy link
Contributor

Choose a reason for hiding this comment

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

unintended whitespaces?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

should be resolved

@clkao
Copy link
Contributor

clkao commented Mar 22, 2018

This looks great! the PR description example config should use profile_list instead of single_user_profile_list

@gsemet
Copy link
Contributor Author

gsemet commented Mar 22, 2018

updating with example in documentation

@gsemet gsemet force-pushed the profile_spawner branch 2 times, most recently from 16512fd to 7eb0403 Compare March 22, 2018 12:27
@clkao
Copy link
Contributor

clkao commented Mar 25, 2018

with this PR merged, it seems #108 can be done by subclassing kubespawner making the profile list dynamic based on auth_state?

@yuvipanda
Copy link
Collaborator

@gsemet I've made some changes. If this looks good to you, I'm happy to merge :) I highly appreciate your patience in getting this change through!

@gsemet
Copy link
Contributor Author

gsemet commented Apr 17, 2018

/me approve !

@yuvipanda yuvipanda merged commit 5170da9 into jupyterhub:master Apr 17, 2018
@yuvipanda
Copy link
Collaborator

Congratulations on getting this big patch merged in, @gsemet! And thank you for your patience in reworking based on feedback and waiting!

@gsemet
Copy link
Contributor Author

gsemet commented Apr 17, 2018

thanks to you! I use it everyday, hope it will please others as much !

@manics
Copy link
Member

manics commented Apr 18, 2018

Any chance of getting this into the next release of zero-to-jupyterhub?

@choldgraf
Copy link
Member

@manics we merged this into jupyterhub for k8s, though I think it uncovered a memory bug that @minrk spotted...but yes I think it'll make it in soonishfully!

@gsemet
Copy link
Contributor Author

gsemet commented Apr 19, 2018

tell me if you need test, i can do it pretty easily for now on our kube cluster

@jgerardsimcock
Copy link

Is this currently in the any of the jupyterhub helm-charts?

@choldgraf
Copy link
Member

@jgerardsimcock we are working on getting it into the Z2JH helm chart, but it isn't in there yet

@ablekh
Copy link

ablekh commented Jun 4, 2018

@choldgraf Any news/outlook on integrating this very useful update (congratulations, @gsemet !) into Z2JH Helm chart (I assume, v0.7)? @minrk said today (jupyterhub/zero-to-jupyterhub-k8s#545 (comment)) that this feature is already integrated, so double checking ... BTW, has v0.7 already been published as GA?

@gsemet
Copy link
Contributor Author

gsemet commented Jun 4, 2018

Glad to see it is useful to others. !
i can help documentation on z2jh when possible :)

@choldgraf
Copy link
Member

choldgraf commented Jun 4, 2018

@minrk 's opinion is usually more correct than mine, so I'll agree with him :-)

@ablekh
Copy link

ablekh commented Jun 4, 2018

@choldgraf What about the (general) availability of v0.7 Helm chart?

@minrk
Copy link
Member

minrk commented Jun 12, 2018

hub.extraConfig can always be used as an escape hatch for configuration that isn't yet exposed via helm charts. v0.7 is not a published version yet, but it is quite close. We need to finalize our 0.9 release of JupyterHub (this week) and probably polish and make releases of kubespawner and oauthenticator first as well.

@consideRatio
Copy link
Member

Ah good summary @minrk! I'll put in work towards a helm chart release from now on.

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.