diff --git a/swan-cern/Chart.lock b/swan-cern/Chart.lock
index 0b4e8ac2..9f0db905 100644
--- a/swan-cern/Chart.lock
+++ b/swan-cern/Chart.lock
@@ -1,9 +1,9 @@
dependencies:
- name: swan
- repository: https://registry.cern.ch/chartrepo/swan
- version: 0.1.6
+ repository: file://../swan
+ version: 0.2.0
- name: fluentd
repository: http://registry.cern.ch/chartrepo/cern
version: 0.1.5
-digest: sha256:e3728208418e25f1b1cd3f2486eae02b3e640bb1354df411036835ee7ef6d26f
-generated: "2022-02-01T09:20:32.294197039+01:00"
+digest: sha256:75996331669b40fbdc6c92c87487e8e063fb7249a6082d73a1229ec766e64604
+generated: "2022-04-21T14:28:14.504289838+02:00"
diff --git a/swan-cern/Chart.yaml b/swan-cern/Chart.yaml
index ffbc2caf..1108d5ed 100644
--- a/swan-cern/Chart.yaml
+++ b/swan-cern/Chart.yaml
@@ -9,8 +9,8 @@ description: The chart to deploy SWAN at CERN
#
dependencies:
- name: swan
- version: 0.1.6
- repository: https://registry.cern.ch/chartrepo/swan
+ version: 0.2.0
+ repository: file://../swan
- name: fluentd
repository: http://registry.cern.ch/chartrepo/cern
version: 0.1.5
diff --git a/swan-cern/files/swan_config_cern.py b/swan-cern/files/swan_config_cern.py
index c91b7a65..d381dac6 100644
--- a/swan-cern/files/swan_config_cern.py
+++ b/swan-cern/files/swan_config_cern.py
@@ -1,4 +1,4 @@
-import os, subprocess
+
from kubernetes import client
from kubernetes.client.rest import ApiException
@@ -190,6 +190,19 @@ def _init_eos_containers(self, eos_secret_name):
)
)
+ #the notebook container needs to run as root as it needs to
+ #add an user and switch to that user
+ #it also need to set command and args to none in order to
+ #run the systemuser.sh script as defined in the image
+ #(we set jupyterhub-singleuser in the values as that is what
+ #is needed for authenticated binder)
+
+ run_as_root=client.V1SecurityContext(run_as_user=0)
+
+ notebook_container.security_context=run_as_root
+ notebook_container.command=None
+ notebook_container.args=None
+
# add the base containers after side container (to start after side container)
existing_containers = self.pod.spec.containers
pod_spec_containers.extend(existing_containers)
@@ -200,11 +213,11 @@ def _init_eos_containers(self, eos_secret_name):
# https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html
# This is defined in the configuration to allow overring iindependently
# of which config file is loaded first
-# c.SwanKubeSpawner.modify_pod_hook = swan_pod_hook
+# c.SwanSpawner.modify_pod_hook = swan_pod_hook
def swan_pod_hook_prod(spawner, pod):
"""
:param spawner: Swan Kubernetes Spawner
- :type spawner: swanspawner.SwanKubeSpawner
+ :type spawner: swanspawner.SwanSpawner
:param pod: default pod definition set by jupyterhub
:type pod: client.V1Pod
@@ -219,7 +232,4 @@ def swan_pod_hook_prod(spawner, pod):
# Get configuration parameters from environment variables
swan_container_namespace = os.environ.get('POD_NAMESPACE', 'default')
-c.SwanKubeSpawner.modify_pod_hook = swan_pod_hook_prod
-
-# Required for swan systemuser.sh
-c.SwanKubeSpawner.cmd = None
\ No newline at end of file
+c.SwanSpawner.modify_pod_hook = swan_pod_hook_prod
diff --git a/swan-cern/files/swan_spark_config.py b/swan-cern/files/swan_spark_config.py
index 1a6e3a85..1f8c4116 100644
--- a/swan-cern/files/swan_spark_config.py
+++ b/swan-cern/files/swan_spark_config.py
@@ -13,6 +13,12 @@
class SwanSparkPodHookHandler(SwanPodHookHandlerProd):
def get_swan_user_pod(self):
+
+
+ if 'binder_ref_url' in self.spawner.user_options.keys():
+ # we don't need any customization if running within binder
+ return self.pod
+
super().get_swan_user_pod()
# get hadoop token
@@ -170,8 +176,6 @@ def _spark_enabled(self):
"""
user_roles = self.spawner.user_roles
- print(self.spawner.user_options)
- print(self.spawner.user_roles)
cluster = self.spawner.user_options[self.spawner.spark_cluster_field]
if cluster == "analytix" and "analytix" not in user_roles:
@@ -337,7 +341,7 @@ def _init_spark(self, pod_labels):
def spark_modify_pod_hook(spawner, pod):
"""
:param spawner: Swan Kubernetes Spawner
- :type spawner: swanspawner.SwanKubeSpawner
+ :type spawner: swanspawner.SwanSpawner
:param pod: default pod definition set by jupyterhub
:type pod: client.V1Pod
@@ -350,4 +354,4 @@ def spark_modify_pod_hook(spawner, pod):
# Get configuration parameters from environment variables
# swan_container_namespace = os.environ.get('POD_NAMESPACE', 'default')
-c.SwanKubeSpawner.modify_pod_hook = spark_modify_pod_hook
+c.SwanSpawner.modify_pod_hook = spark_modify_pod_hook
diff --git a/swan-cern/swan.dev.values.yaml b/swan-cern/swan.dev.values.yaml
index 43ab435a..176fd298 100644
--- a/swan-cern/swan.dev.values.yaml
+++ b/swan-cern/swan.dev.values.yaml
@@ -1,126 +1,127 @@
swan:
- jupyterhub:
- hub:
- image:
- name: "gitlab-registry.cern.ch/swan/docker-images/jupyterhub"
- tag: "v1.13"
- config:
- KeyCloakAuthenticator:
- allowed_roles:
- - swan-admins
- - swan-qa
- - swan-devs
- extraVolumes:
- - name: swan-jh
- configMap:
- name: swan-scripts
- items:
- - key: jupyterhub_form.html
- path: jupyterhub_form.html
- - key: swan_config.py
- path: swan_config.py
- - name: swan-jh-cern
- configMap:
- name: swan-scripts-cern
- items:
- - key: options_form_config.json
- path: options_form_config.json
- - key: swan_config_cern.py
- path: swan_config_cern.py
- - key: swan_spark_config.py
- path: swan_spark_config.py
- - name: swan-cull-scripts
- configMap:
- name: swan-scripts-cern
- items:
- - key: cull_check_ticket.sh
- path: cull_check_ticket.sh
- - key: cull_delete_ticket.sh
- path: cull_delete_ticket.sh
- defaultMode: 356 # 0544 perm
- - name: swan-tokens-scripts
- configMap:
- name: swan-scripts-env-dev
- items:
- - key: webhdfs_token.sh
- path: webhdfs_token.sh
- - key: eos_token.sh
- path: eos_token.sh
- - key: sparkk8s_token.sh
- path: sparkk8s_token.sh
- defaultMode: 356 # 0544 perm
- - name: swan-secrets
- secret:
- secretName: swan-cern
- items:
- - key: eos.cred
- path: eos.cred
- - key: hadoop.cred
- path: hadoop.cred
- - key: sparkk8s.cred
- path: sparkk8s.cred
- - name: cvmfs
- hostPath:
- path: /var/cvmfs
- type: Directory
- db:
- type: sqlite-memory
- custom:
- cvmfs:
- deployDaemonSet: true
- deployCsiDriver: false
- useCsiDriver: false
- repositories:
- - mount: cvmfs-config.cern.ch
- - mount: sft.cern.ch
- proxy: 'http://ca-proxy-sft.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: sft-nightlies.cern.ch
- proxy: 'http://ca-proxy-sft.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: alice.cern.ch
- proxy: 'http://ca-proxy-alice.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: alice-ocdb.cern.ch
- proxy: 'http://ca-proxy-alice.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: alice-nightlies.cern.ch
- proxy: 'http://ca-proxy-alice.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: alpha.cern.ch
- - mount: ams.cern.ch
- - mount: atlas.cern.ch
- proxy: 'http://ca-proxy-atlas.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: atlas-condb.cern.ch
- proxy: 'http://ca-proxy-atlas.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: atlas-nightlies.cern.ch
- proxy: 'http://ca-proxy-atlas.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: clicbp.cern.ch
- - mount: cms.cern.ch
- proxy: 'http://cmsmeyproxy.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: cms-ib.cern.ch
- proxy: 'http://cmsmeyproxy.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: cms-bril.cern.ch
- proxy: 'http://cmsmeyproxy.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: compass.cern.ch
- proxy: 'http://ca-proxy-compass.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: compass-condb.cern.ch
- proxy: 'http://ca-proxy-compass.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: fcc.cern.ch
- - mount: ganga.cern.ch
- - mount: geant4.cern.ch
- - mount: lhcb.cern.ch
- proxy: 'http://ca-proxy-lhcb.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: lhcb-condb.cern.ch
- proxy: 'http://ca-proxy-lhcb.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: lhcbdev.cern.ch
- proxy: 'http://ca-proxy-lhcb.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: na61.cern.ch
- - mount: na62.cern.ch
- - mount: projects.cern.ch
- - mount: sw.hsf.org
- eos:
- deployDaemonSet: false
- deployCsiDriver: true
- useCsiDriver: true
- prePuller:
- hook:
- enabled: false
+ binderhub:
+ jupyterhub:
+ hub:
+ image:
+ name: "gitlab-registry.cern.ch/swan/docker-images/jupyterhub"
+ tag: "v1.13"
+ config:
+ KeyCloakAuthenticator:
+ allowed_roles:
+ - swan-admins
+ - swan-qa
+ - swan-devs
+ extraVolumes:
+ - name: swan-jh
+ configMap:
+ name: swan-scripts
+ items:
+ - key: jupyterhub_form.html
+ path: jupyterhub_form.html
+ - key: swan_config.py
+ path: swan_config.py
+ - name: swan-jh-cern
+ configMap:
+ name: swan-scripts-cern
+ items:
+ - key: options_form_config.json
+ path: options_form_config.json
+ - key: swan_config_cern.py
+ path: swan_config_cern.py
+ - key: swan_spark_config.py
+ path: swan_spark_config.py
+ - name: swan-cull-scripts
+ configMap:
+ name: swan-scripts-cern
+ items:
+ - key: cull_check_ticket.sh
+ path: cull_check_ticket.sh
+ - key: cull_delete_ticket.sh
+ path: cull_delete_ticket.sh
+ defaultMode: 356 # 0544 perm
+ - name: swan-tokens-scripts
+ configMap:
+ name: swan-scripts-env-dev
+ items:
+ - key: webhdfs_token.sh
+ path: webhdfs_token.sh
+ - key: eos_token.sh
+ path: eos_token.sh
+ - key: sparkk8s_token.sh
+ path: sparkk8s_token.sh
+ defaultMode: 356 # 0544 perm
+ - name: swan-secrets
+ secret:
+ secretName: swan-cern
+ items:
+ - key: eos.cred
+ path: eos.cred
+ - key: hadoop.cred
+ path: hadoop.cred
+ - key: sparkk8s.cred
+ path: sparkk8s.cred
+ - name: cvmfs
+ hostPath:
+ path: /var/cvmfs
+ type: Directory
+ db:
+ type: sqlite-memory
+ custom:
+ cvmfs:
+ deployDaemonSet: true
+ deployCsiDriver: false
+ useCsiDriver: false
+ repositories:
+ - mount: cvmfs-config.cern.ch
+ - mount: sft.cern.ch
+ proxy: 'http://ca-proxy-sft.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: sft-nightlies.cern.ch
+ proxy: 'http://ca-proxy-sft.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: alice.cern.ch
+ proxy: 'http://ca-proxy-alice.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: alice-ocdb.cern.ch
+ proxy: 'http://ca-proxy-alice.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: alice-nightlies.cern.ch
+ proxy: 'http://ca-proxy-alice.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: alpha.cern.ch
+ - mount: ams.cern.ch
+ - mount: atlas.cern.ch
+ proxy: 'http://ca-proxy-atlas.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: atlas-condb.cern.ch
+ proxy: 'http://ca-proxy-atlas.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: atlas-nightlies.cern.ch
+ proxy: 'http://ca-proxy-atlas.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: clicbp.cern.ch
+ - mount: cms.cern.ch
+ proxy: 'http://cmsmeyproxy.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: cms-ib.cern.ch
+ proxy: 'http://cmsmeyproxy.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: cms-bril.cern.ch
+ proxy: 'http://cmsmeyproxy.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: compass.cern.ch
+ proxy: 'http://ca-proxy-compass.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: compass-condb.cern.ch
+ proxy: 'http://ca-proxy-compass.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: fcc.cern.ch
+ - mount: ganga.cern.ch
+ - mount: geant4.cern.ch
+ - mount: lhcb.cern.ch
+ proxy: 'http://ca-proxy-lhcb.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: lhcb-condb.cern.ch
+ proxy: 'http://ca-proxy-lhcb.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: lhcbdev.cern.ch
+ proxy: 'http://ca-proxy-lhcb.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: na61.cern.ch
+ - mount: na62.cern.ch
+ - mount: projects.cern.ch
+ - mount: sw.hsf.org
+ eos:
+ deployDaemonSet: false
+ deployCsiDriver: true
+ useCsiDriver: true
+ prePuller:
+ hook:
+ enabled: false
hadoopTokenGenerator:
extraVolumes:
- name: swan-tokens-scripts
@@ -129,4 +130,4 @@ hadoopTokenGenerator:
items:
- key: hadoop_token.sh
path: hadoop_token.sh
- defaultMode: 500
\ No newline at end of file
+ defaultMode: 500
diff --git a/swan-cern/templates/hadoop-token-generator.yaml b/swan-cern/templates/hadoop-token-generator.yaml
index bd83bc67..ef8a9c1c 100644
--- a/swan-cern/templates/hadoop-token-generator.yaml
+++ b/swan-cern/templates/hadoop-token-generator.yaml
@@ -31,13 +31,13 @@ spec:
name: hub
key: hub.services.hadoop-token-generator.apiToken
- name: HADOOP_CONF_HOME
- value: {{ .Values.swan.jupyterhub.custom.spark.configurationPath }}
+ value: {{ .Values.swan.binderhub.jupyterhub.custom.spark.configurationPath }}
livenessProbe:
exec:
command:
- ls
- - {{ .Values.swan.jupyterhub.custom.spark.configurationPath }}
+ - {{ .Values.swan.binderhub.jupyterhub.custom.spark.configurationPath }}
initialDelaySeconds: 5
periodSeconds: 5
diff --git a/swan-cern/values.yaml b/swan-cern/values.yaml
index 6b5fb8e9..095c9cae 100644
--- a/swan-cern/values.yaml
+++ b/swan-cern/values.yaml
@@ -3,209 +3,247 @@ swan:
deployDaemonSet: &cvmfsDeployDS true
deployCsiDriver: &cvmfsDeployCSI false
useCsiDriver: &cvmfsUseCSI false
+ prefetcher:
+ enabled: true
+ jobs:
+ cron_opennotebook_python2_ipy:
+ command: "source /cvmfs/sft.cern.ch/lcg/views/LCG_99python2/x86_64-centos7-gcc8-opt/setup.sh && ( timeout 20s python -m ipykernel > /dev/null 2>&1 || true )"
+ minute: '*/15'
+ cron_opennotebook_python2_root:
+ command: "source /cvmfs/sft.cern.ch/lcg/views/LCG_99python2/x86_64-centos7-gcc8-opt/setup.sh && ( timeout 20s python -m JupyROOT.kernel.rootkernel > /dev/null 2>&1 || true )"
+ minute: '*/15'
+ cron_opennotebook_python3_root:
+ command: "source /cvmfs/sft.cern.ch/lcg/views/LCG_101swan/x86_64-centos7-gcc8-opt/setup.sh && ( timeout 20s python -m JupyROOT.kernel.rootkernel > /dev/null 2>&1 || true )"
+ minute: '*/15'
+ cron_opennotebook_python3nx_ipy:
+ command: "source /cvmfs/sft.cern.ch/lcg/views/LCG_95apython3_nxcals/x86_64-centos7-gcc7-opt/setup.sh && ( timeout 20s python -m ipykernel > /dev/null 2>&1 || true )"
+ minute: '*/15'
+ cron_opennotebook_python3nx_spark:
+ command: "source /cvmfs/sft.cern.ch/lcg/views/LCG_100_nxcals/x86_64-centos7-gcc9-opt/setup.sh && ( timeout 20s python -c 'import pyspark' > /dev/null 2>&1 || true )"
+ minute: '*/15'
+ cron_opennotebook_cuda_tensorflow:
+ command: "(lsmod | grep nvidia) && source /cvmfs/sft.cern.ch/lcg/views/LCG_101cuda/x86_64-centos7-gcc8-opt/setup.sh && ( timeout 60s python -c 'import tensorflow' > /dev/null 2>&1 || true )"
+ minute: '5,20,35,50'
+ cron_opennoteook_cuda_torch:
+ command: "(lsmod | grep nvidia) && source /cvmfs/sft.cern.ch/lcg/views/LCG_101cuda/x86_64-centos7-gcc8-opt/setup.sh && ( timeout 60s python -c 'import torch' > /dev/null 2>&1 || true )"
+ minute: '10,25,40,55'
eos:
deployDaemonSet: &eosDeployDS false
deployCsiDriver: &eosDeployCSI true
useCsiDriver: &eosUseCSI true
- jupyterhub:
- hub:
- extraVolumeMounts:
- - name: swan-jh-cern
- mountPath: /srv/jupyterhub/options_form_config.json
- subPath: options_form_config.json
- - name: swan-jh
- mountPath: /srv/jupyterhub/jupyterhub_form.html
- subPath: jupyterhub_form.html
- - name: swan-jh
- mountPath: /usr/local/etc/jupyterhub/jupyterhub_config.d/1_swan_config.py
- subPath: swan_config.py
- - name: swan-jh-cern
- mountPath: /usr/local/etc/jupyterhub/jupyterhub_config.d/2_swan_config_cern.py
- subPath: swan_config_cern.py
- - name: swan-jh-cern
- mountPath: /usr/local/etc/jupyterhub/jupyterhub_config.d/3_swan_spark_config.py
- subPath: swan_spark_config.py
- - name: swan-secrets
- mountPath: /srv/jupyterhub/private/eos.cred
- subPath: eos.cred
- - name: swan-secrets
- mountPath: /srv/jupyterhub/private/hadoop.cred
- subPath: hadoop.cred
- - name: swan-secrets
- mountPath: /srv/jupyterhub/private/sparkk8s.cred
- subPath: sparkk8s.cred
- - name: swan-cull-scripts
- mountPath: /srv/jupyterhub/culler/check_ticket.sh
- subPath: cull_check_ticket.sh
- - name: swan-cull-scripts
- mountPath: /srv/jupyterhub/culler/delete_ticket.sh
- subPath: cull_delete_ticket.sh
- - name: swan-tokens-scripts
- mountPath: /srv/jupyterhub/private/eos_token.sh
- subPath: eos_token.sh
- - name: swan-tokens-scripts
- mountPath: /srv/jupyterhub/private/webhdfs_token.sh
- subPath: webhdfs_token.sh
- - name: swan-tokens-scripts
- mountPath: /srv/jupyterhub/private/sparkk8s_token.sh
- subPath: sparkk8s_token.sh
- - name: cvmfs
- mountPath: /cvmfs
- extraVolumes:
- - name: cvmfs
- hostPath:
- path: /var/cvmfs
- type: Directory
- - name: swan-jh
- configMap:
- name: swan-scripts
- items:
- - key: jupyterhub_form.html
- path: jupyterhub_form.html
- - key: swan_config.py
- path: swan_config.py
- - name: swan-jh-cern
- configMap:
- name: swan-scripts-cern
- items:
- - key: options_form_config.json
- path: options_form_config.json
- - key: swan_config_cern.py
- path: swan_config_cern.py
- - key: swan_spark_config.py
- path: swan_spark_config.py
- - name: swan-cull-scripts
- configMap:
- name: swan-scripts-cern
- items:
- - key: cull_check_ticket.sh
- path: cull_check_ticket.sh
- - key: cull_delete_ticket.sh
- path: cull_delete_ticket.sh
- defaultMode: 356 # 0544 perm
- - name: swan-tokens-scripts
- configMap:
- name: swan-scripts-env-prod
- items:
- - key: webhdfs_token.sh
- path: webhdfs_token.sh
- - key: eos_token.sh
- path: eos_token.sh
- - key: sparkk8s_token.sh
- path: sparkk8s_token.sh
- defaultMode: 356 # 0544 perm
- - name: swan-secrets
- secret:
- secretName: swan-cern
- items:
- - key: eos.cred
- path: eos.cred
- - key: hadoop.cred
- path: hadoop.cred
- - key: sparkk8s.cred
- path: sparkk8s.cred
- config:
- KeyCloakAuthenticator:
- oidc_issuer: https://auth.cern.ch/auth/realms/cern
- exchange_tokens:
- - eos-service
- - cernbox-service
- logout_redirect_uri: https://cern.ch/swan
- auto_login: True
- username_key: preferred_username
- client_id: # placeholder, check secrets
- client_secret: # placeholder, check secrets
- oauth_callback_url: # placeholder, check secrets
- JupyterHub:
- allow_named_servers: False
- extraConfig:
- 00-authConf: |
- def pre_spawn_hook(authenticator, spawner, auth_state):
- spawner.environment['ACCESS_TOKEN'] = auth_state['exchanged_tokens']['eos-service']
- spawner.environment['OAUTH_INSPECTION_ENDPOINT'] = authenticator.userdata_url.replace('https://', '')
- spawner.user_uid = str(str(auth_state['oauth_user']['cern_uid'])) # k8s only supports values as strings!
- decoded_token = authenticator._decode_token(auth_state['access_token'])
- spawner.user_roles = authenticator.claim_roles_key(authenticator, decoded_token)
- c.KeyCloakAuthenticator.pre_spawn_hook = pre_spawn_hook
- 02-spawnError: |
- SPAWN_ERROR_MESSAGE = """SWAN could not start a session for your user, please try again. If the problem persists, please check:
-
- - Do you have a CERNBox account? If not, click here.
- - Is there a problem with the service? Find information here.
- - If none of the options apply, please open a Support Ticket.
-
"""
-
- # SWAN@CERN error message
- c.SpawnHandlersConfigs.spawn_error_message = SPAWN_ERROR_MESSAGE
- db:
- type: postgres
- # placeholder for postgres connection url
- url:
- # placeholder for postgres password
- password:
- services:
- hadoop-token-generator: {} # apiToken is generated by the chart
-
- custom:
- cull:
- # 6 hours
- timeout: 21600
- checkEosAuth: true
- hooksDir: /srv/jupyterhub/culler
- cvmfs:
- deployDaemonSet: *cvmfsDeployDS
- deployCsiDriver: *cvmfsDeployCSI
- useCsiDriver: *cvmfsUseCSI
- repositories:
- - mount: cvmfs-config.cern.ch
- - mount: sft.cern.ch
- proxy: 'http://ca-proxy-sft.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: sft-nightlies.cern.ch
- proxy: 'http://ca-proxy-sft.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: alice.cern.ch
- proxy: 'http://ca-proxy-alice.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: alice-ocdb.cern.ch
- proxy: 'http://ca-proxy-alice.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: alice-nightlies.cern.ch
- proxy: 'http://ca-proxy-alice.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: alpha.cern.ch
- - mount: ams.cern.ch
- - mount: atlas.cern.ch
- proxy: 'http://ca-proxy-atlas.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: atlas-condb.cern.ch
- proxy: 'http://ca-proxy-atlas.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: atlas-nightlies.cern.ch
- proxy: 'http://ca-proxy-atlas.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: clicbp.cern.ch
- - mount: cms.cern.ch
- proxy: 'http://cmsmeyproxy.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: cms-ib.cern.ch
- proxy: 'http://cmsmeyproxy.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: cms-bril.cern.ch
- proxy: 'http://cmsmeyproxy.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: compass.cern.ch
- proxy: 'http://ca-proxy-compass.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: compass-condb.cern.ch
- proxy: 'http://ca-proxy-compass.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: fcc.cern.ch
- - mount: ganga.cern.ch
- - mount: geant4.cern.ch
- - mount: lhcb.cern.ch
- proxy: 'http://ca-proxy-lhcb.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: lhcb-condb.cern.ch
- proxy: 'http://ca-proxy-lhcb.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: lhcbdev.cern.ch
- proxy: 'http://ca-proxy-lhcb.cern.ch:3128;http://ca-proxy.cern.ch:3128'
- - mount: na61.cern.ch
- - mount: na62.cern.ch
- - mount: projects.cern.ch
- - mount: sw.hsf.org
- eos:
- deployDaemonSet: *eosDeployDS
- deployCsiDriver: *eosDeployCSI
- useCsiDriver: *eosUseCSI
- spark:
- configurationPath: /cvmfs/sft.cern.ch/lcg/etc/hadoop-confext
+ binderhub:
+ jupyterhub:
+ hub:
+ extraVolumeMounts:
+ - name: swan-jh-cern
+ mountPath: /srv/jupyterhub/options_form_config.json
+ subPath: options_form_config.json
+ - name: swan-jh
+ mountPath: /srv/jupyterhub/jupyterhub_form.html
+ subPath: jupyterhub_form.html
+ - name: swan-jh
+ mountPath: /usr/local/etc/jupyterhub/jupyterhub_config.d/1_swan_config.py
+ subPath: swan_config.py
+ - name: swan-jh-cern
+ mountPath: /usr/local/etc/jupyterhub/jupyterhub_config.d/2_swan_config_cern.py
+ subPath: swan_config_cern.py
+ - name: swan-jh-cern
+ mountPath: /usr/local/etc/jupyterhub/jupyterhub_config.d/3_swan_spark_config.py
+ subPath: swan_spark_config.py
+ - name: swan-secrets
+ mountPath: /srv/jupyterhub/private/eos.cred
+ subPath: eos.cred
+ - name: swan-secrets
+ mountPath: /srv/jupyterhub/private/hadoop.cred
+ subPath: hadoop.cred
+ - name: swan-secrets
+ mountPath: /srv/jupyterhub/private/sparkk8s.cred
+ subPath: sparkk8s.cred
+ - name: swan-cull-scripts
+ mountPath: /srv/jupyterhub/culler/check_ticket.sh
+ subPath: cull_check_ticket.sh
+ - name: swan-cull-scripts
+ mountPath: /srv/jupyterhub/culler/delete_ticket.sh
+ subPath: cull_delete_ticket.sh
+ - name: swan-tokens-scripts
+ mountPath: /srv/jupyterhub/private/eos_token.sh
+ subPath: eos_token.sh
+ - name: swan-tokens-scripts
+ mountPath: /srv/jupyterhub/private/webhdfs_token.sh
+ subPath: webhdfs_token.sh
+ - name: swan-tokens-scripts
+ mountPath: /srv/jupyterhub/private/sparkk8s_token.sh
+ subPath: sparkk8s_token.sh
+ - name: cvmfs
+ mountPath: /cvmfs
+ extraVolumes:
+ - name: cvmfs
+ hostPath:
+ path: /var/cvmfs
+ type: Directory
+ - name: swan-jh
+ configMap:
+ name: swan-scripts
+ items:
+ - key: jupyterhub_form.html
+ path: jupyterhub_form.html
+ - key: swan_config.py
+ path: swan_config.py
+ - name: swan-jh-cern
+ configMap:
+ name: swan-scripts-cern
+ items:
+ - key: options_form_config.json
+ path: options_form_config.json
+ - key: swan_config_cern.py
+ path: swan_config_cern.py
+ - key: swan_spark_config.py
+ path: swan_spark_config.py
+ - name: swan-cull-scripts
+ configMap:
+ name: swan-scripts-cern
+ items:
+ - key: cull_check_ticket.sh
+ path: cull_check_ticket.sh
+ - key: cull_delete_ticket.sh
+ path: cull_delete_ticket.sh
+ defaultMode: 356 # 0544 perm
+ - name: swan-tokens-scripts
+ configMap:
+ name: swan-scripts-env-prod
+ items:
+ - key: webhdfs_token.sh
+ path: webhdfs_token.sh
+ - key: eos_token.sh
+ path: eos_token.sh
+ - key: sparkk8s_token.sh
+ path: sparkk8s_token.sh
+ defaultMode: 356 # 0544 perm
+ - name: swan-secrets
+ secret:
+ secretName: swan-cern
+ items:
+ - key: eos.cred
+ path: eos.cred
+ - key: hadoop.cred
+ path: hadoop.cred
+ - key: sparkk8s.cred
+ path: sparkk8s.cred
+ config:
+ KeyCloakAuthenticator:
+ oidc_issuer: https://auth.cern.ch/auth/realms/cern
+ exchange_tokens:
+ - eos-service
+ - cernbox-service
+ logout_redirect_uri: https://cern.ch/swan
+ auto_login: True
+ username_key: preferred_username
+ client_id: # placeholder, check secrets
+ client_secret: # placeholder, check secrets
+ oauth_callback_url: # placeholder, check secrets
+ JupyterHub:
+ allow_named_servers: False
+ extraConfig:
+ 00-authConf: |
+ def pre_spawn_hook(authenticator, spawner, auth_state):
+ try:
+ spawner.environment['ACCESS_TOKEN'] = auth_state['exchanged_tokens']['eos-service']
+ spawner.environment['OAUTH_INSPECTION_ENDPOINT'] = authenticator.userdata_url.replace('https://', '')
+ spawner.user_uid = str(str(auth_state['oauth_user']['cern_uid'])) # k8s only supports values as strings!
+ decoded_token = authenticator._decode_token(auth_state['access_token'])
+ spawner.user_roles = authenticator.claim_roles_key(authenticator, decoded_token)
+ except:
+ pass
+ c.KeyCloakAuthenticator.pre_spawn_hook = pre_spawn_hook
+ 01-hook-swancern: |
+ 02-spawnError: |
+ SPAWN_ERROR_MESSAGE = """SWAN could not start a session for your user, please try again. If the problem persists, please check:
+
+ - Do you have a CERNBox account? If not, click here.
+ - Is there a problem with the service? Find information here.
+ - If none of the options apply, please open a Support Ticket.
+
"""
+
+ # SWAN@CERN error message
+ c.SpawnHandlersConfigs.spawn_error_message = SPAWN_ERROR_MESSAGE
+ 03-disableIPv6: |
+ c.KubeSpawner.init_containers = [{
+ "name": "init-iptables",
+ "image": "cern/cc7-base:20181210",
+ "command": ["/bin/bash", "-c", "sysctl -w net.ipv6.conf.all.disable_ipv6=1"],
+ "securityContext": {
+ "privileged": True
+ }
+ }]
+ db:
+ type: postgres
+ # placeholder for postgres connection url
+ url:
+ # placeholder for postgres password
+ password:
+ services:
+ hadoop-token-generator: {} # apiToken is generated by the chart
+
+ custom:
+ cull:
+ # 6 hours
+ timeout: 21600
+ checkEosAuth: true
+ hooksDir: /srv/jupyterhub/culler
+ cvmfs:
+ deployDaemonSet: *cvmfsDeployDS
+ deployCsiDriver: *cvmfsDeployCSI
+ useCsiDriver: *cvmfsUseCSI
+ repositories:
+ - mount: cvmfs-config.cern.ch
+ - mount: sft.cern.ch
+ proxy: 'http://ca-proxy-sft.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: sft-nightlies.cern.ch
+ proxy: 'http://ca-proxy-sft.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: alice.cern.ch
+ proxy: 'http://ca-proxy-alice.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: alice-ocdb.cern.ch
+ proxy: 'http://ca-proxy-alice.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: alice-nightlies.cern.ch
+ proxy: 'http://ca-proxy-alice.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: alpha.cern.ch
+ - mount: ams.cern.ch
+ - mount: atlas.cern.ch
+ proxy: 'http://ca-proxy-atlas.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: atlas-condb.cern.ch
+ proxy: 'http://ca-proxy-atlas.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: atlas-nightlies.cern.ch
+ proxy: 'http://ca-proxy-atlas.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: clicbp.cern.ch
+ - mount: cms.cern.ch
+ proxy: 'http://cmsmeyproxy.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: cms-ib.cern.ch
+ proxy: 'http://cmsmeyproxy.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: cms-bril.cern.ch
+ proxy: 'http://cmsmeyproxy.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: compass.cern.ch
+ proxy: 'http://ca-proxy-compass.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: compass-condb.cern.ch
+ proxy: 'http://ca-proxy-compass.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: fcc.cern.ch
+ - mount: ganga.cern.ch
+ - mount: geant4.cern.ch
+ - mount: lhcb.cern.ch
+ proxy: 'http://ca-proxy-lhcb.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: lhcb-condb.cern.ch
+ proxy: 'http://ca-proxy-lhcb.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: lhcbdev.cern.ch
+ proxy: 'http://ca-proxy-lhcb.cern.ch:3128;http://ca-proxy.cern.ch:3128'
+ - mount: na61.cern.ch
+ - mount: na62.cern.ch
+ - mount: projects.cern.ch
+ - mount: sw.hsf.org
+ eos:
+ deployDaemonSet: *eosDeployDS
+ deployCsiDriver: *eosDeployCSI
+ useCsiDriver: *eosUseCSI
+ spark:
+ configurationPath: /cvmfs/sft.cern.ch/lcg/etc/hadoop-confext
swanCern:
secrets:
eos:
diff --git a/swan/Chart.lock b/swan/Chart.lock
index 43e71849..21663983 100644
--- a/swan/Chart.lock
+++ b/swan/Chart.lock
@@ -1,7 +1,7 @@
dependencies:
-- name: jupyterhub
+- name: binderhub
repository: https://jupyterhub.github.io/helm-chart/
- version: 1.2.0
+ version: 0.2.0-n905.h3d3e24e
- name: fusex
repository: https://registry.cern.ch/chartrepo/eos
version: 0.1.0
@@ -10,9 +10,9 @@ dependencies:
version: 0.3.1
- name: cvmfs
repository: https://registry.cern.ch/chartrepo/sciencebox
- version: 0.0.4
+ version: 0.0.5
- name: cvmfs-csi
repository: http://registry.cern.ch/chartrepo/cern
version: 0.1.0
-digest: sha256:b8c51c9df17635614483cc7a57c5b4936ff18cf2f3b830e6f8555cec7c1eff68
-generated: "2022-01-07T10:40:34.001728425+01:00"
+digest: sha256:2b7545bef6fcaeb13c20f76ae5c44c69168e944a662c9a9650aeb082abc09d29
+generated: "2022-04-21T14:26:38.496141383+02:00"
diff --git a/swan/Chart.yaml b/swan/Chart.yaml
index 7450c893..184253d7 100644
--- a/swan/Chart.yaml
+++ b/swan/Chart.yaml
@@ -2,15 +2,15 @@ apiVersion: v2
#
name: swan
type: application
-version: 0.1.6
+version: 0.2.0
appVersion: 0.1.2 # Using swanhub version
#
description: A fully-fledged SWAN instance with jupyterhub, EOS, and CVMFS
icon: https://swan.docs.cern.ch/images/logos/logo_swan_letters.png
#
dependencies:
- - name: jupyterhub
- version: 1.2.0
+ - name: binderhub
+ version: 0.2.0-n905.h3d3e24e
repository: https://jupyterhub.github.io/helm-chart/
- name: fusex
@@ -23,7 +23,7 @@ dependencies:
condition: eos.deployCsiDriver
- name: cvmfs
- version: 0.0.4
+ version: 0.0.5
repository: https://registry.cern.ch/chartrepo/sciencebox
condition: cvmfs.deployDaemonSet
- name: cvmfs-csi
diff --git a/swan/files/swan_config.py b/swan/files/swan_config.py
index f55d4add..72d9a40f 100644
--- a/swan/files/swan_config.py
+++ b/swan/files/swan_config.py
@@ -10,7 +10,7 @@
class SwanPodHookHandler:
def __init__(self, spawner, pod):
"""
- :type spawner: swanspawner.SwanKubeSpawner
+ :type spawner: swanspawner.SwanSpawner
:type pod: client.V1Pod
"""
self.spawner = spawner
@@ -18,6 +18,11 @@ def __init__(self, spawner, pod):
def get_swan_user_pod(self):
+ if 'binder_ref_url' in self.spawner.user_options.keys():
+ # we don't need any customization if running within binder
+ return self.pod
+
+
# pod labels
pod_labels = dict(
lcg_release = self.spawner.user_options[self.spawner.lcg_rel_field].split('/')[0],
@@ -135,11 +140,11 @@ def _add_or_replace_by_name(self, list, element):
# https://jupyterhub-kubespawner.readthedocs.io/en/latest/spawner.html
# This is defined in the configuration to allow overring iindependently
# of which config file is loaded first
-# c.SwanKubeSpawner.modify_pod_hook = swan_pod_hook
+# c.SwanSpawner.modify_pod_hook = swan_pod_hook
def swan_pod_hook(spawner, pod):
"""
:param spawner: Swan Kubernetes Spawner
- :type spawner: swanspawner.SwanKubeSpawner
+ :type spawner: swanspawner.SwanSpawner
:param pod: default pod definition set by jupyterhub
:type pod: client.V1Pod
@@ -152,7 +157,7 @@ def swan_pod_hook(spawner, pod):
"""
Configuration for JupyterHub
"""
-c.SwanKubeSpawner.modify_pod_hook = swan_pod_hook
+c.SwanSpawner.modify_pod_hook = swan_pod_hook
# Hub services
@@ -208,11 +213,11 @@ def swan_pod_hook(spawner, pod):
# Init lists for volumes and volume_mounts
-c.SwanKubeSpawner.volumes = []
-c.SwanKubeSpawner.volume_mounts = []
+c.SwanSpawner.volumes = []
+c.SwanSpawner.volume_mounts = []
# add /dev/shm (for pyTorch and others)
-c.SwanKubeSpawner.volumes.append(
+c.SwanSpawner.volumes.append(
client.V1Volume(
name='devshm',
empty_dir=client.V1EmptyDirVolumeSource(
@@ -220,7 +225,7 @@ def swan_pod_hook(spawner, pod):
)
)
)
-c.SwanKubeSpawner.volume_mounts.append(
+c.SwanSpawner.volume_mounts.append(
client.V1VolumeMount(
name='devshm',
mount_path='/dev/shm',
@@ -231,14 +236,14 @@ def swan_pod_hook(spawner, pod):
if get_config("custom.eos.deployDaemonSet", False):
# Access via bind-mount from the host
logging.info("EOS access via DaemonSet")
- c.SwanKubeSpawner.volume_mounts.append(
+ c.SwanSpawner.volume_mounts.append(
client.V1VolumeMount(
name='eos',
mount_path='/eos',
mount_propagation='HostToContainer'
),
)
- c.SwanKubeSpawner.volumes.append(
+ c.SwanSpawner.volumes.append(
client.V1Volume(
name='eos',
host_path=client.V1HostPathVolumeSource(
@@ -250,14 +255,14 @@ def swan_pod_hook(spawner, pod):
get_config("custom.eos.useCsiDriver", False)):
# Access via CSI driver (still a bind-mount in practical terms)
logging.info("EOS access via CSI driver")
- c.SwanKubeSpawner.volume_mounts.append(
+ c.SwanSpawner.volume_mounts.append(
client.V1VolumeMount(
name='eos',
mount_path='/eos',
mount_propagation='HostToContainer'
),
)
- c.SwanKubeSpawner.volumes.append(
+ c.SwanSpawner.volumes.append(
client.V1Volume(
name='eos',
host_path=client.V1HostPathVolumeSource(
@@ -274,7 +279,7 @@ def swan_pod_hook(spawner, pod):
if get_config("custom.cvmfs.deployDaemonSet", False):
# Access via bind-mount from the host
logging.info("CVMFS access via DaemonSet")
- c.SwanKubeSpawner.volumes.append(
+ c.SwanSpawner.volumes.append(
client.V1Volume(
name='cvmfs',
host_path=client.V1HostPathVolumeSource(
@@ -282,7 +287,7 @@ def swan_pod_hook(spawner, pod):
)
)
)
- c.SwanKubeSpawner.volume_mounts.append(
+ c.SwanSpawner.volume_mounts.append(
client.V1VolumeMount(
name='cvmfs',
mount_path='/cvmfs',
@@ -296,7 +301,7 @@ def swan_pod_hook(spawner, pod):
cvmfs_repos = get_config('custom.cvmfs.repositories', [])
for cvmfs_repo_path in cvmfs_repos:
cvmfs_repo_id = cvmfs_repo_path['mount'].replace('.', '-')
- c.SwanKubeSpawner.volumes.append(
+ c.SwanSpawner.volumes.append(
client.V1Volume(
name='cvmfs-'+cvmfs_repo_id,
persistent_volume_claim=client.V1PersistentVolumeClaimVolumeSource(
@@ -304,7 +309,7 @@ def swan_pod_hook(spawner, pod):
)
)
)
- c.SwanKubeSpawner.volume_mounts.append(
+ c.SwanSpawner.volume_mounts.append(
client.V1VolumeMount(
name='cvmfs-'+cvmfs_repo_id,
mount_path='/cvmfs/'+cvmfs_repo_path['mount'],
@@ -317,4 +322,4 @@ def swan_pod_hook(spawner, pod):
pass
# Required for swan systemuser.sh
-c.SwanKubeSpawner.cmd = None
+c.SwanSpawner.cmd = None
diff --git a/swan/swan.secrets.template.yaml b/swan/swan.secrets.template.yaml
index af7f48f4..644c86f2 100644
--- a/swan/swan.secrets.template.yaml
+++ b/swan/swan.secrets.template.yaml
@@ -1,36 +1,98 @@
-jupyterhub:
- proxy:
- # generate with openssl rand -hex 32
- # encrypt communications between the hub and the configurable-http-proxy
- secretToken:
- hub:
- # database backend to use for the hub database
- db:
- url:
- password:
+swan:
+ binderhub:
+ image:
+ name: registry.cern.ch/binder/binderhub
+ tag: v1.0.0-alpha
extraEnv:
- # openssl rand -hex 32
- # to encrypt auth state
- JUPYTERHUB_CRYPT_KEY:
- # openssl rand -hex 32
- # to sign cookies
- cookieSecret:
+ REQUESTS_CA_BUNDLE: /etc/pki/tls/certs/ca-bundle.crt
config:
- KeyCloakAuthenticator:
- client_id:
- client_secret:
- # https:///hub/oauth_callback
- oauth_callback_url:
- ingress:
- # List of hosts to route requests to the proxy
- tls:
- - secretName: swan-tls-cert
- hosts:
- -
-swan:
+ Launcher:
+ allow_named_servers: true
+ BinderHub:
+ debug: true
+ base_url: /binder/
+ auth_enabled: true
+ use_registry: true
+ image_prefix: registry.cern.ch/binder/exp1-
+ hub_url: https://swanrc.cern.ch/
+ DockerRegistry:
+ token_url: "https://registry.cern.ch/v2/token?service=registry.cern.ch"
+ service:
+ type: NodePort
+ registry:
+ url: https://registry.cern.ch
+ username: robot-binder+binder
+ password: ......
+ jupyterhub:
+ singleuser:
+ storage:
+ type: none
+ image:
+ tag: v5.15.4
+ # understand why this is needed and what is in swan/values.yaml is not enough
+ hub:
+ redirectToServer: false
+ image:
+ name: gitlab-registry.cern.ch/rcastell/publicregistry/jupyterhub
+ tag: v2.0.alfa13
+ # database backend to use for the hub database
+ db:
+ type: sqlite-memory
+ services:
+ binder:
+ oauth_no_confirm: true
+ oauth_redirect_uri: "http://swanrc.cern.ch/binder/oauth_callback"
+ oauth_client_id: "service-binder-oauth-client-test"
+ config:
+ JupyterHub:
+ allow_named_servers: true
+ named_server_limit_per_user: 5
+ admin_access: true
+ SwanBinderSpawner:
+ default_url: 'lab'
+ auth_enabled: true
+ KeyCloakAuthenticator:
+ admin_users:
+ - .....
+ client_id:
+ client_secret:
+ oauth_callback_url: https:///hub/oauth_callback
+ extraConfig:
+ 03-swanbinder: |
+ c.JupyterHub.spawner_class = swanspawner.SwanBinderSpawner
+ c.SwanBinderSpawner.cmd = 'jupyterhub-singleuser'
+ jupyterhub:
+ proxy:
+ # generate with openssl rand -hex 32
+ # encrypt communications between the hub and the configurable-http-proxy
+ secretToken:
+ hub:
+ # database backend to use for the hub database (when commented use sqlite-memory for dev purposes)
+# db:
+# url:
+# password:
+ extraEnv:
+ # openssl rand -hex 32
+ # to encrypt auth state
+ JUPYTERHUB_CRYPT_KEY:
+ # openssl rand -hex 32
+ # to sign cookies
+ cookieSecret:
+ config:
+ KeyCloakAuthenticator:
+ client_id:
+ client_secret:
+ # https:///hub/oauth_callback
+ oauth_callback_url:
+ ingress:
+ # List of hosts to route requests to the proxy (use the main alias if dns load balanced)
+ tls:
+ - secretName: swan-tls-cert
+ hosts:
+ -
secrets:
# ssl termination certificate
ingress:
- #this two keys are the output of "echo host{cert|key}.pem | base64 -w0"
+ #this two keys are the output of "cat host{cert|key}.pem | base64 -w0"
cert:
key:
diff --git a/swan/templates/ingress.yaml b/swan/templates/ingress.yaml
new file mode 100644
index 00000000..415172f9
--- /dev/null
+++ b/swan/templates/ingress.yaml
@@ -0,0 +1,33 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: {{ include "jupyterhub.ingress.fullname" . }}
+ labels:
+ {{- include "jupyterhub.labels" . | nindent 4 }}
+ {{- with .Values.binderhub.jupyterhub.ingress.annotations }}
+ annotations:
+ {{- . | toYaml | nindent 4 }}
+ {{- end }}
+spec:
+ {{- with .Values.binderhub.jupyterhub.ingress.ingressClassName }}
+ ingressClassName: "{{ . }}"
+ {{- end }}
+ rules:
+ {{- range $host := .Values.binderhub.jupyterhub.ingress.hosts | default (list "") }}
+ - http:
+ paths:
+ - path: {{ $.Values.binderhub.jupyterhub.hub.baseUrl | trimSuffix "/" }}/binder
+ pathType: {{ $.Values.binderhub.jupyterhub.ingress.pathType }}
+ backend:
+ service:
+ name: binder
+ port:
+ number: 80
+ {{- if $host }}
+ host: {{ $host | quote }}
+ {{- end }}
+ {{- end }}
+ {{- with .Values.binderhub.jupyterhub.ingress.tls }}
+ tls:
+ {{- . | toYaml | nindent 4 }}
+ {{- end }}
diff --git a/swan/templates/secrets.yaml b/swan/templates/secrets.yaml
index afda13ee..13ee2d33 100644
--- a/swan/templates/secrets.yaml
+++ b/swan/templates/secrets.yaml
@@ -5,12 +5,12 @@ metadata:
name: swan
namespace: {{ .Release.Namespace }}
data:
-{{ if eq .Values.jupyterhub.hub.db.type "postgres" }}
- jupyterhub.hub.db.password: {{ (required "PostgresDB password must be specified (helm --set jupyterhub.hub.db.password= ..)!" .Values.jupyterhub.hub.db.password) | b64enc | quote }}
+{{ if eq .Values.binderhub.jupyterhub.hub.db.type "postgres" }}
+ jupyterhub.hub.db.password: {{ (required "PostgresDB password must be specified (helm --set jupyterhub.hub.db.password= ..)!" .Values.binderhub.jupyterhub.hub.db.password) | b64enc | quote }}
{{ end }}
---
-{{ if .Values.jupyterhub.ingress.enabled }}
-{{ range .Values.jupyterhub.ingress.tls }}
+{{ if .Values.binderhub.jupyterhub.ingress.enabled }}
+{{ range .Values.binderhub.jupyterhub.ingress.tls }}
apiVersion: v1
kind: Secret
type: kubernetes.io/tls
diff --git a/swan/templates/storageclasses.yaml b/swan/templates/storageclasses.yaml
index 8d17e9b6..fb72b58f 100644
--- a/swan/templates/storageclasses.yaml
+++ b/swan/templates/storageclasses.yaml
@@ -1,5 +1,5 @@
-{{ if or .Values.jupyterhub.custom.cvmfs.deployCsiDriver .Values.jupyterhub.custom.cvmfs.useCsiDriver }}
-{{- range .Values.jupyterhub.custom.cvmfs.repositories }}
+{{ if or .Values.binderhub.jupyterhub.custom.cvmfs.deployCsiDriver .Values.binderhub.jupyterhub.custom.cvmfs.useCsiDriver }}
+{{- range .Values.binderhub.jupyterhub.custom.cvmfs.repositories }}
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
diff --git a/swan/values.yaml b/swan/values.yaml
index fbef7282..2cd8db69 100644
--- a/swan/values.yaml
+++ b/swan/values.yaml
@@ -29,6 +29,13 @@ cvmfs:
- sft-nightlies.cern.ch
mountOptions:
hostMountpoint: /var/cvmfs
+ # Prefetcher is provided only by the daemonSet
+ prefetcher:
+ enabled: true
+ jobs:
+ cron_opennotebook_python3_ipy:
+ command: "source /cvmfs/sft.cern.ch/lcg/views/LCG_101swan/x86_64-centos7-gcc8-opt/setup.sh && ( timeout 20s python -m ipykernel > /dev/null 2>&1 || true )"
+ minute: '*/15'
#
# EOS access
@@ -63,174 +70,169 @@ eosxd:
#
# JupyerHub
#
-jupyterhub:
- singleuser:
- uid: 0
- fsGid: 0
- storage:
- type: none
- image:
- name: "gitlab-registry.cern.ch/swan/docker-images/systemuser"
- tag: "v5.14.1"
- pullPolicy: "Always"
- cloudMetadata:
- # until we configure networkPolicy
- blockWithIptables: true
- ip: 169.254.169.254
- networkPolicy:
- enabled: false
- ingress:
- enabled: true
- annotations:
- kubernetes.io/ingress.class: nginx
- #tls:
- # - secretName: swan-tls-cert
- # placeholder for hostname
- hosts:
- proxy:
- service:
- type: ClusterIP
- chp:
+binderhub:
+ jupyterhub:
+ singleuser:
+ fsGid: 0
+ storage:
+ type: none
image:
- name: "jupyterhub/configurable-http-proxy"
- tag: "4.5.0"
- pullPolicy: "IfNotPresent"
+ name: "gitlab-registry.cern.ch/swan/docker-images/systemuser"
+ tag: "v5.14.1"
+ pullPolicy: "Always"
+ cloudMetadata:
+ # until we configure networkPolicy
+ blockWithIptables: true
+ ip: 169.254.169.254
+ networkPolicy:
+ enabled: false
+ ingress:
+ enabled: true
+ annotations:
+ kubernetes.io/ingress.class: nginx
+ #tls:
+ # - secretName: swan-tls-cert
+ # placeholder for hostname
+ hosts:
+ proxy:
+ service:
+ type: ClusterIP
+ chp:
+ image:
+ name: "jupyterhub/configurable-http-proxy"
+ tag: "4.5.0"
+ pullPolicy: "IfNotPresent"
+ resources:
+ requests:
+ cpu: 200m
+ memory: 512Mi
+ # placeholder for hub secret token
+ secretToken:
+ hub:
+ fsGid: 0
+ containerSecurityContext:
+ runAsUser: 0
+ runAsGroup: 0
+ deploymentStrategy:
+ type: RollingUpdate
resources:
requests:
cpu: 200m
memory: 512Mi
- # placeholder for hub secret token
- secretToken:
- hub:
- fsGid: 0
- containerSecurityContext:
- runAsUser: 0
- runAsGroup: 0
- deploymentStrategy:
- type: RollingUpdate
- resources:
- requests:
- cpu: 200m
- memory: 512Mi
- livenessProbe:
- enabled: false
- readinessProbe:
- enabled: false
- image:
- name: "gitlab-registry.cern.ch/swan/docker-images/jupyterhub"
- tag: "v1.18"
- pullPolicy: "Always"
- extraVolumeMounts:
- - name: swan-jh
- mountPath: /srv/jupyterhub/options_form_config.json
- subPath: options_form_config.json
- - name: swan-jh
- mountPath: /srv/jupyterhub/jupyterhub_form.html
- subPath: jupyterhub_form.html
- - name: swan-jh
- mountPath: /usr/local/etc/jupyterhub/jupyterhub_config.d/1_swan_config.py
- subPath: swan_config.py
- extraVolumes:
- - name: swan-jh
- configMap:
- name: swan-scripts
- items:
- - key: options_form_config.json
- path: options_form_config.json
- - key: jupyterhub_form.html
- path: jupyterhub_form.html
- - key: swan_config.py
- path: swan_config.py
- config:
- KeyCloakAuthenticator:
- # Config missing
- oidc_issuer:
- admin_role: swan-admins
- scope:
- - profile
- - email
- - offline_access
- exchange_tokens: []
- logout_redirect_uri: https://cern.ch/swan
- auto_login: True
- username_key: preferred_username
- client_id: # placeholder, check secrets
- client_secret: # placeholder, check secrets
- oauth_callback_url: # placeholder, check secrets
- SwanSpawner:
- options_form_config: /srv/jupyterhub/options_form_config.json
- # Give notebook 45s to start a webserver and max 60s for whole spawn process
- http_timeout: 45
- start_timeout: 60
- consecutive_failure_limit: 0
- SwanKubeSpawner:
- # set home directory to EOS
- local_home: False
- SpawnHandlersConfigs:
- # disable some defaults of swanspawner that do now work for kube-spawner
- # FIXME remove this from the spawner once we support only k8s
- metrics_on: False
- local_home: True
- JupyterHub:
- authenticator_class: keycloakauthenticator.KeyCloakAuthenticator
- spawner_class: swanspawner.SwanKubeSpawner
- cleanup_servers: False
- tornado_settings:
- # currently we customize spawnhandler to stay in form before redirecting the user, as upstream does
- # FIXME remove once we remove the the metrics from the spawn
- slow_spawn_timeout: 15
- allow_named_servers: False
- extraConfig:
- 00-authConf: |
- def pre_spawn_hook(authenticator, spawner, auth_state):
- raise Exception("Please configure pre_spawn_hook")
- c.KeyCloakAuthenticator.pre_spawn_hook = pre_spawn_hook
- networkPolicy:
- enabled: false
- # placeholder for hub cookieSecret
- # when empty, it generates a new randomly
- cookieSecret:
- rbac:
- enabled: true
- scheduling:
- userScheduler:
- enabled: false
- podPriority:
- enabled: false
- prePuller:
- hook:
- enabled: true
- continuous:
- enabled: false
- containerSecurityContext:
- allowPrivilegeEscalation: true
- debug:
- enabled: true
- # disable upstream cull, but enable custom one
- cull:
- enabled: false
- custom:
- cull:
+ livenessProbe:
+ enabled: false
+ readinessProbe:
+ enabled: false
+ image:
+ name: "gitlab-registry.cern.ch/swan/docker-images/jupyterhub"
+ tag: "v1.18"
+ pullPolicy: "Always"
+ extraVolumeMounts:
+ - name: swan-jh
+ mountPath: /srv/jupyterhub/options_form_config.json
+ subPath: options_form_config.json
+ - name: swan-jh
+ mountPath: /srv/jupyterhub/jupyterhub_form.html
+ subPath: jupyterhub_form.html
+ - name: swan-jh
+ mountPath: /usr/local/etc/jupyterhub/jupyterhub_config.d/1_swan_config.py
+ subPath: swan_config.py
+ extraVolumes:
+ - name: swan-jh
+ configMap:
+ name: swan-scripts
+ items:
+ - key: options_form_config.json
+ path: options_form_config.json
+ - key: jupyterhub_form.html
+ path: jupyterhub_form.html
+ - key: swan_config.py
+ path: swan_config.py
+ config:
+ KeyCloakAuthenticator:
+ # Config missing
+ oidc_issuer:
+ admin_role: swan-admins
+ scope:
+ - profile
+ - email
+ - offline_access
+ exchange_tokens: []
+ logout_redirect_uri: https://cern.ch/swan
+ auto_login: True
+ username_key: preferred_username
+ client_id: # placeholder, check secrets
+ client_secret: # placeholder, check secrets
+ oauth_callback_url: # placeholder, check secrets
+ SwanSpawner:
+ options_form_config: /srv/jupyterhub/options_form_config.json
+ # Give notebook 45s to start a webserver and max 60s for whole spawn process
+ http_timeout: 45
+ start_timeout: 60
+ consecutive_failure_limit: 0
+ SwanKubeSpawner:
+ # set home directory to EOS
+ local_home: False
+ SpawnHandlersConfigs:
+ # disable some defaults of swanspawner that do now work for kube-spawner
+ # FIXME remove this from the spawner once we support only k8s
+ metrics_on: False
+ local_home: True
+ JupyterHub:
+ authenticator_class: keycloakauthenticator.KeyCloakAuthenticator
+ spawner_class: swanspawner.SwanKubeSpawner
+ cleanup_servers: False
+ tornado_settings:
+ # currently we customize spawnhandler to stay in form before redirecting the user, as upstream does
+ # FIXME remove once we remove the the metrics from the spawn
+ slow_spawn_timeout: 15
+ allow_named_servers: False
+ extraConfig:
+ 00-authConf: |
+ def pre_spawn_hook(authenticator, spawner, auth_state):
+ raise Exception("Please configure pre_spawn_hook")
+ c.KeyCloakAuthenticator.pre_spawn_hook = pre_spawn_hook
+ networkPolicy:
+ enabled: false
+ # placeholder for hub cookieSecret
+ # when empty, it generates a new randomly
+ cookieSecret:
+ rbac:
enabled: true
- every: 600
- # 2 hours
- timeout: 7200
- users: true
- checkEosAuth: false
- cvmfs:
- prefetcher:
+ scheduling:
+ userScheduler:
enabled: false
- image:
- name: "gitlab-registry.cern.ch/swan/docker-images/cvmfs-prefetcher"
- tag: "v1.1"
- deployDaemonSet: *cvmfsDeployDS
- deployCsiDriver: *cvmfsDeployCSI
- useCsiDriver: *cvmfsUseCSI
- repositories: *cvmfsRepos
- eos:
- deployDaemonSet: *eosDeployDS
- deployCsiDriver: *eosDeployCSI
- useCsiDriver: *eosUseCSI
+ podPriority:
+ enabled: false
+ prePuller:
+ hook:
+ enabled: true
+ continuous:
+ enabled: false
+ containerSecurityContext:
+ allowPrivilegeEscalation: true
+ debug:
+ enabled: true
+ # disable upstream cull, but enable custom one
+ cull:
+ enabled: false
+ custom:
+ cull:
+ enabled: true
+ every: 600
+ # 2 hours
+ timeout: 7200
+ users: true
+ checkEosAuth: false
+ cvmfs:
+ deployDaemonSet: *cvmfsDeployDS
+ deployCsiDriver: *cvmfsDeployCSI
+ useCsiDriver: *cvmfsUseCSI
+ repositories: *cvmfsRepos
+ eos:
+ deployDaemonSet: *eosDeployDS
+ deployCsiDriver: *eosDeployCSI
+ useCsiDriver: *eosUseCSI
# placeholders for swan credentials
swan:
secrets: