From f15f3cb2e8f3e718c0be2c3164c2d88f19b47698 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Mon, 4 Aug 2025 14:28:27 +0100 Subject: [PATCH 1/4] wip: patch pod definition for build jobs --- .../binderhub.values.yaml | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/config/clusters/projectpythia-binder/binderhub.values.yaml b/config/clusters/projectpythia-binder/binderhub.values.yaml index 23bc527b6e..44387af5da 100644 --- a/config/clusters/projectpythia-binder/binderhub.values.yaml +++ b/config/clusters/projectpythia-binder/binderhub.values.yaml @@ -122,6 +122,29 @@ binderhub-service: nodeSelector: hub.jupyter.org/node-purpose: capi.stackhpc.com/node-group: user-m3-large + extraConfig: | + from binderhub.build import KubernetesBuildExecutor + from kubernetes import client + + class LimitedBuildExecutor(KubernetesBuildExecutor): + + def pre_process_pod(self, pod): + container, = pod.spec.containers + container.resources.requests['ephemeral-storage'] = "9Gi" + print("Patching build pod definition to set ephemeral-storage request:\n", pod) + return pod + + @property + def pod(self): + # No custom error handling, this is internal + return self._pod + + @pod.setter + def pod(self, value): + self._pod = self.pre_process_pod(value) + + c.BinderHub.build_class = LimitedBuildExecutor + config: GitHubRepoProvider: allowed_specs: From 1df334ff0a8743775f488acd260753508b99283d Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Mon, 4 Aug 2025 14:39:35 +0100 Subject: [PATCH 2/4] fix: turn on brain.py --- .../binderhub.values.yaml | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/config/clusters/projectpythia-binder/binderhub.values.yaml b/config/clusters/projectpythia-binder/binderhub.values.yaml index 44387af5da..bc60ea0149 100644 --- a/config/clusters/projectpythia-binder/binderhub.values.yaml +++ b/config/clusters/projectpythia-binder/binderhub.values.yaml @@ -122,28 +122,29 @@ binderhub-service: nodeSelector: hub.jupyter.org/node-purpose: capi.stackhpc.com/node-group: user-m3-large - extraConfig: | - from binderhub.build import KubernetesBuildExecutor - from kubernetes import client + extraConfig: + patch-build-spec.py: | + from binderhub.build import KubernetesBuildExecutor + from kubernetes import client - class LimitedBuildExecutor(KubernetesBuildExecutor): + class LimitedBuildExecutor(KubernetesBuildExecutor): - def pre_process_pod(self, pod): - container, = pod.spec.containers - container.resources.requests['ephemeral-storage'] = "9Gi" - print("Patching build pod definition to set ephemeral-storage request:\n", pod) - return pod + def pre_process_pod(self, pod): + container, = pod.spec.containers + container.resources.requests['ephemeral-storage'] = "9Gi" + print("Patching build pod definition to set ephemeral-storage request:\n", pod) + return pod - @property - def pod(self): - # No custom error handling, this is internal - return self._pod + @property + def pod(self): + # No custom error handling, this is internal + return self._pod - @pod.setter - def pod(self, value): - self._pod = self.pre_process_pod(value) + @pod.setter + def pod(self, value): + self._pod = self.pre_process_pod(value) - c.BinderHub.build_class = LimitedBuildExecutor + c.BinderHub.build_class = LimitedBuildExecutor config: GitHubRepoProvider: From e45fcab2c4a7c169e6e1856196e897099e92bc64 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Mon, 4 Aug 2025 15:09:18 +0100 Subject: [PATCH 3/4] revert-later: add staging hub --- .../projectpythia-binder/cluster.yaml | 6 + .../projectpythia-binder/staging.values.yaml | 186 ++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 config/clusters/projectpythia-binder/staging.values.yaml diff --git a/config/clusters/projectpythia-binder/cluster.yaml b/config/clusters/projectpythia-binder/cluster.yaml index 3852ec2a4e..217f4ac171 100644 --- a/config/clusters/projectpythia-binder/cluster.yaml +++ b/config/clusters/projectpythia-binder/cluster.yaml @@ -14,3 +14,9 @@ hubs: helm_chart_values_files: - binderhub.values.yaml - enc-binderhub.secret.values.yaml +- name: staging + display_name: Staging Project Pythia BinderHub on Jetstream2 + domain: staging.binder-pythia.jetstream2.2i2c.cloud + helm_chart: basehub + helm_chart_values_files: + - staging.values.yaml diff --git a/config/clusters/projectpythia-binder/staging.values.yaml b/config/clusters/projectpythia-binder/staging.values.yaml new file mode 100644 index 0000000000..ac2b538146 --- /dev/null +++ b/config/clusters/projectpythia-binder/staging.values.yaml @@ -0,0 +1,186 @@ +jupyterhub: + scheduling: + corePods: + nodeAffinity: + matchNodePurpose: ignore + userPods: + nodeAffinity: + matchNodePurpose: ignore + userScheduler: + nodeSelector: + capi.stackhpc.com/node-group: core + ingress: + hosts: + - staging.binder-pythia.jetstream2.2i2c.cloud + tls: + - secretName: https-auto-tls + hosts: + - staging.binder-pythia.jetstream2.2i2c.cloud + + custom: + binderhubUI: + enabled: true + 2i2c: + add_staff_user_ids_to_admin_users: false + jupyterhubConfigurator: + enabled: false + singleuserAdmin: + extraVolumeMounts: [] + homepage: + templateVars: + enabled: false + singleuser: + cpu: + limit: 4 + memory: + limit: 8G + guarantee: 8G + nodeSelector: + capi.stackhpc.com/node-group: user-m3-large + storage: + type: none + extraVolumeMounts: [] + initContainers: [] + profileList: [] + cmd: + - python3 + - -c + - | + import os + import sys + + try: + import jupyterlab + import jupyterlab.labapp + major = int(jupyterlab.__version__.split(".", 1)[0]) + except Exception as e: + print("Failed to import jupyterlab: {e}", file=sys.stderr) + have_lab = False + else: + have_lab = major >= 3 + + if have_lab: + # technically, we could accept another jupyter-server-based frontend + print("Launching jupyter-lab", file=sys.stderr) + exe = "jupyter-lab" + else: + print("jupyter-lab not found, launching jupyter-notebook", file=sys.stderr) + exe = "jupyter-notebook" + + # launch the notebook server + os.execvp(exe, sys.argv) + # Custom selectors are needed because the magnum driver doesn't yet support + # custom labeling due to a bug + proxy: + chp: + nodeSelector: + capi.stackhpc.com/node-group: core + traefik: + nodeSelector: + capi.stackhpc.com/node-group: core + prePuller: + hook: + nodeSelector: + capi.stackhpc.com/node-group: user-m3-large + hub: + nodeSelector: + capi.stackhpc.com/node-group: core + loadRoles: + binder: + services: + - binder + scopes: + - servers + - admin:users + user: + scopes: + - self + - access:services!service=binder + redirectToServer: false + config: + BinderSpawnerMixin: + auth_enabled: false + cors_allow_origin: '*' + JupyterHub: + authenticator_class: 'null' + +binderhub-service: + enabled: true + networkPolicy: + enabled: true + nodeSelector: + capi.stackhpc.com/node-group: core + hub.jupyter.org/node-purpose: + ingress: + enabled: true + hosts: + - staging.binder-pythia.jetstream2.2i2c.cloud + tls: + - secretName: https-auto-tls + hosts: + - staging.binder-pythia.jetstream2.2i2c.cloud + + dockerApi: + nodeSelector: + hub.jupyter.org/node-purpose: + capi.stackhpc.com/node-group: user-m3-large + extraConfig: + patch-build-spec.py: | + from binderhub.build import KubernetesBuildExecutor + from kubernetes import client + + class LimitedBuildExecutor(KubernetesBuildExecutor): + + def pre_process_pod(self, pod): + container, = pod.spec.containers + container.resources.requests['ephemeral-storage'] = "9Gi" + print("Patching build pod definition to set ephemeral-storage request:\n", pod) + return pod + + @property + def pod(self): + # No custom error handling, this is internal + return self._pod + + @pod.setter + def pod(self, value): + self._pod = self.pre_process_pod(value) + + c.BinderHub.build_class = LimitedBuildExecutor + + config: + GitHubRepoProvider: + allowed_specs: + - ^ProjectPythia/.*$ + - ^ktyle/.*$ + - ^binder-examples/.* + BinderHub: + base_url: / + hub_url: https://hub.projectpythia.org + badge_base_url: https://binder.projectpythia.org + auth_enabled: false + enable_api_only_mode: false + image_prefix: quay.io/imagebuilding-non-gcp-hubs/jetstream2-projectpythia-pythia-binder- + banner_message: Binder on Jetstream2 for use with Project Pythia + about_message: '' + cors_allow_origin: '*' + use_registry: false + KubernetesBuildExecutor: + node_selector: + # Schedule builder pods to run on user nodes only + hub.jupyter.org/node-purpose: + capi.stackhpc.com/node-group: user-m3-large + extraEnv: + - name: JUPYTERHUB_API_TOKEN + valueFrom: + secretKeyRef: + name: '{{ include "jupyterhub.hub.fullname" . }}' + key: hub.services.binder.apiToken + - name: JUPYTERHUB_CLIENT_ID + value: service-binder + - name: JUPYTERHUB_API_URL + value: https://hub.projectpythia.org/hub/api + # Without this, the redirect URL to /hub/api/... gets + # appended to binderhub's URL instead of the hub's + - name: JUPYTERHUB_BASE_URL + value: https://hub.projectpythia.org/ From dd125b9a4689e9b352a22919ed124fb4db4fafa0 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Mon, 4 Aug 2025 15:18:27 +0100 Subject: [PATCH 4/4] Revert "revert-later: add staging hub" This reverts commit e45fcab2c4a7c169e6e1856196e897099e92bc64. --- .../projectpythia-binder/cluster.yaml | 6 - .../projectpythia-binder/staging.values.yaml | 186 ------------------ 2 files changed, 192 deletions(-) delete mode 100644 config/clusters/projectpythia-binder/staging.values.yaml diff --git a/config/clusters/projectpythia-binder/cluster.yaml b/config/clusters/projectpythia-binder/cluster.yaml index 217f4ac171..3852ec2a4e 100644 --- a/config/clusters/projectpythia-binder/cluster.yaml +++ b/config/clusters/projectpythia-binder/cluster.yaml @@ -14,9 +14,3 @@ hubs: helm_chart_values_files: - binderhub.values.yaml - enc-binderhub.secret.values.yaml -- name: staging - display_name: Staging Project Pythia BinderHub on Jetstream2 - domain: staging.binder-pythia.jetstream2.2i2c.cloud - helm_chart: basehub - helm_chart_values_files: - - staging.values.yaml diff --git a/config/clusters/projectpythia-binder/staging.values.yaml b/config/clusters/projectpythia-binder/staging.values.yaml deleted file mode 100644 index ac2b538146..0000000000 --- a/config/clusters/projectpythia-binder/staging.values.yaml +++ /dev/null @@ -1,186 +0,0 @@ -jupyterhub: - scheduling: - corePods: - nodeAffinity: - matchNodePurpose: ignore - userPods: - nodeAffinity: - matchNodePurpose: ignore - userScheduler: - nodeSelector: - capi.stackhpc.com/node-group: core - ingress: - hosts: - - staging.binder-pythia.jetstream2.2i2c.cloud - tls: - - secretName: https-auto-tls - hosts: - - staging.binder-pythia.jetstream2.2i2c.cloud - - custom: - binderhubUI: - enabled: true - 2i2c: - add_staff_user_ids_to_admin_users: false - jupyterhubConfigurator: - enabled: false - singleuserAdmin: - extraVolumeMounts: [] - homepage: - templateVars: - enabled: false - singleuser: - cpu: - limit: 4 - memory: - limit: 8G - guarantee: 8G - nodeSelector: - capi.stackhpc.com/node-group: user-m3-large - storage: - type: none - extraVolumeMounts: [] - initContainers: [] - profileList: [] - cmd: - - python3 - - -c - - | - import os - import sys - - try: - import jupyterlab - import jupyterlab.labapp - major = int(jupyterlab.__version__.split(".", 1)[0]) - except Exception as e: - print("Failed to import jupyterlab: {e}", file=sys.stderr) - have_lab = False - else: - have_lab = major >= 3 - - if have_lab: - # technically, we could accept another jupyter-server-based frontend - print("Launching jupyter-lab", file=sys.stderr) - exe = "jupyter-lab" - else: - print("jupyter-lab not found, launching jupyter-notebook", file=sys.stderr) - exe = "jupyter-notebook" - - # launch the notebook server - os.execvp(exe, sys.argv) - # Custom selectors are needed because the magnum driver doesn't yet support - # custom labeling due to a bug - proxy: - chp: - nodeSelector: - capi.stackhpc.com/node-group: core - traefik: - nodeSelector: - capi.stackhpc.com/node-group: core - prePuller: - hook: - nodeSelector: - capi.stackhpc.com/node-group: user-m3-large - hub: - nodeSelector: - capi.stackhpc.com/node-group: core - loadRoles: - binder: - services: - - binder - scopes: - - servers - - admin:users - user: - scopes: - - self - - access:services!service=binder - redirectToServer: false - config: - BinderSpawnerMixin: - auth_enabled: false - cors_allow_origin: '*' - JupyterHub: - authenticator_class: 'null' - -binderhub-service: - enabled: true - networkPolicy: - enabled: true - nodeSelector: - capi.stackhpc.com/node-group: core - hub.jupyter.org/node-purpose: - ingress: - enabled: true - hosts: - - staging.binder-pythia.jetstream2.2i2c.cloud - tls: - - secretName: https-auto-tls - hosts: - - staging.binder-pythia.jetstream2.2i2c.cloud - - dockerApi: - nodeSelector: - hub.jupyter.org/node-purpose: - capi.stackhpc.com/node-group: user-m3-large - extraConfig: - patch-build-spec.py: | - from binderhub.build import KubernetesBuildExecutor - from kubernetes import client - - class LimitedBuildExecutor(KubernetesBuildExecutor): - - def pre_process_pod(self, pod): - container, = pod.spec.containers - container.resources.requests['ephemeral-storage'] = "9Gi" - print("Patching build pod definition to set ephemeral-storage request:\n", pod) - return pod - - @property - def pod(self): - # No custom error handling, this is internal - return self._pod - - @pod.setter - def pod(self, value): - self._pod = self.pre_process_pod(value) - - c.BinderHub.build_class = LimitedBuildExecutor - - config: - GitHubRepoProvider: - allowed_specs: - - ^ProjectPythia/.*$ - - ^ktyle/.*$ - - ^binder-examples/.* - BinderHub: - base_url: / - hub_url: https://hub.projectpythia.org - badge_base_url: https://binder.projectpythia.org - auth_enabled: false - enable_api_only_mode: false - image_prefix: quay.io/imagebuilding-non-gcp-hubs/jetstream2-projectpythia-pythia-binder- - banner_message: Binder on Jetstream2 for use with Project Pythia - about_message: '' - cors_allow_origin: '*' - use_registry: false - KubernetesBuildExecutor: - node_selector: - # Schedule builder pods to run on user nodes only - hub.jupyter.org/node-purpose: - capi.stackhpc.com/node-group: user-m3-large - extraEnv: - - name: JUPYTERHUB_API_TOKEN - valueFrom: - secretKeyRef: - name: '{{ include "jupyterhub.hub.fullname" . }}' - key: hub.services.binder.apiToken - - name: JUPYTERHUB_CLIENT_ID - value: service-binder - - name: JUPYTERHUB_API_URL - value: https://hub.projectpythia.org/hub/api - # Without this, the redirect URL to /hub/api/... gets - # appended to binderhub's URL instead of the hub's - - name: JUPYTERHUB_BASE_URL - value: https://hub.projectpythia.org/