Add a custom login page and assignments directory for each user on a Jupyter Hub server

https://pythonforundergradengineers.com/assignments-dir-and-custom-login-page-to-jupyterhub.html

Try BinderHub

In [ ]:
!gcloud container clusters create \
  --machine-type n1-standard-1 \
  --num-nodes 1 --enable-autoscaling --min-nodes 0 --max-nodes 2 \
  --zone us-central1-b --cluster-version latest \
  jhub
In [ ]:
!gcloud container clusters get-credentials jhub --zone us-central1-b --project sandbox-243014
In [ ]:
!kubectl create clusterrolebinding cluster-admin-binding \
  --clusterrole=cluster-admin \
  --user=saintway.sakaru@gmail.com
In [ ]:
!kubectl --namespace kube-system create serviceaccount tiller
In [ ]:
!kubectl create clusterrolebinding tiller --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
In [ ]:
!helm init --service-account tiller --wait --upgrade
In [ ]:
!kubectl create namespace kronhub

Install JupyterHub

In [ ]:
%%bash
helm repo add jupyterhub https://jupyterhub.github.io/helm-chart/
helm repo update
helm upgrade jupyterhub jupyterhub/jupyterhub --install --namespace kronhub --values config.yaml
helm list
In [ ]:
!kubectl get service --namespace kronhub
In [ ]:
!kubectl describe service proxy-public --namespace kronhub

Install BinderHub

In [ ]:
# Create Service Account kronhub-builder (groups can be set!)
!mkdir ~/kronhub
  • one way for secret.yaml
In [ ]:
%%bash
cat << EOF > ~/kronhub/secret.yaml
jupyterhub:
  hub:
    services:
      binder:
        apiToken: "$(openssl rand -hex 32)"
  proxy:
    secretToken: "$(openssl rand -hex 32)"
registry:
  url: https://gcr.io
  password: |
$(cat ~/sandbox-243014-09712d6ea91c.json | sed -r 's#[ ]*([^ ].*)#    \1#g')
EOF
  • another way for secret.yaml
In [ ]:
%%bash
echo "\
jupyterhub:
  hub:
    services:
      binder:
        apiToken: \"$(openssl rand -hex 32)\"
  proxy:
    secretToken: \"$(openssl rand -hex 32)\"
registry:
  url: https://gcr.io
  password: |
$(cat ~/sandbox-243014-09712d6ea91c.json | sed -r 's#[ ]*([^ ].*)#    \1#g')\
" > ~/kronhub/secret.yaml
  • config.yaml
In [ ]:
%%bash
cat << EOF > ~/kronhub/config.yaml
replicas: 1.0
config:
  BinderHub:
    use_registry: true
    image_prefix: gcr.io/$(\
      cat ~/sandbox-243014-09712d6ea91c.json \
    | grep -oe '"project_id": "[^"]*",' \
    | sed -r 's#"project_id": "([^"]*)",#\1#g' \
    )/kronhub-
EOF
In [ ]:
# get project id in many ways
!gcloud config get-value project
!gcloud config list --format 'value(core.project)'
!gcloud config configurations list --format 'value(PROJECT)'
In [ ]:
%%bash
helm repo add jupyterhub https://jupyterhub.github.io/helm-chart
helm repo update

helm install

In [ ]:
%%bash
helm install jupyterhub/binderhub --version=0.2.0-29e7546 --name=binderhub --namespace=kronhub \
  -f ~/kronhub/secret.yaml -f ~/kronhub/config.yaml
In [ ]:
!cd ~ && git clone https://github.com/jupyterhub/binderhub.git
In [ ]:
!cd ~/binderhub/helm-chart/binderhub && helm dependency update
In [ ]:
!cd ~/binderhub/helm-chart && helm dep up binderhub
In [ ]:
!helm list
In [ ]:
%%bash
cat << EOF > ~/kronhub/config.yaml
replicas: 1.0
config:
  BinderHub:
    use_registry: true
    image_prefix: gcr.io/$(\
      cat ~/sandbox-243014-09712d6ea91c.json \
    | grep -oe '"project_id": "[^"]*",' \
    | sed -r 's#"project_id": "([^"]*)",#\1#g' \
    )/kronhub-
    hub_url: $(kubectl --namespace=kronhub get svc proxy-public \
               -o custom-columns=':.status.loadBalancer.ingress[0].ip' \
             | grep -oe '[^\n]*')
EOF
In [ ]:
!helm upgrade binderhub jupyterhub/binderhub --version=0.2.0-29e7546 -f ~/kronhub/secret.yaml -f ~/kronhub/config.yaml
In [ ]:
!kubectl get svc --namespace kronhub proxy-public -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
In [ ]:
!kubectl --namespace=kronhub get svc binder
In [ ]:
%%bash
cat << EOF > ~/kronhub/config.yaml
replicas: 1.0
config:
  BinderHub:
    use_registry: true
    image_prefix: gcr.io/$(\
      cat ~/sandbox-243014-09712d6ea91c.json \
    | grep -oe '"project_id": "[^"]*",' \
    | sed -r 's#"project_id": "([^"]*)",#\1#g' \
    )/kronhub-
    hub_url: $(kubectl --namespace=kronhub get svc proxy-public \
               -o custom-columns=':.status.loadBalancer.ingress[0].ip' \
             | grep -oe '[^\n]*')
    auth_enabled: true

jupyterhub:
  cull:
    # do cull authenticated users
    users: True

  hub:
    redirectToServer: false
    services:
      binder:
        oauth_redirect_uri: "http://$(kubectl --namespace=kronhub get svc binder -o jsonpath='{.status.loadBalancer.ingress[0].ip}')/oauth_callback"
        oauth_client_id: "binder-oauth-client-test"
    extraConfig:
      binder: |
        from kubespawner import KubeSpawner

        class BinderSpawner(KubeSpawner):
          def start(self):
            if 'image' in self.user_options:
              # binder service sets the image spec via user options
              self.image = self.user_options['image']
            return super().start()
        c.JupyterHub.spawner_class = BinderSpawner

  singleuser:
    # to make notebook servers aware of hub
    cmd: jupyterhub-singleuser

  auth: {}
EOF

Comments

2020-04-10