Skip to content

Commit

Permalink
Merge pull request #798 from OpenSourceBrain/develop
Browse files Browse the repository at this point in the history
Latest develop to GHA tests
  • Loading branch information
pgleeson authored Nov 15, 2023
2 parents d4aef22 + a450414 commit 2b826c4
Show file tree
Hide file tree
Showing 40 changed files with 348 additions and 447 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ body {
}

.login-pf-logo {
background: url(../img/osblogo.png) no-repeat;
background: url(../img/osb-logo.png) no-repeat;
background-size: contain;
width: 132px;
height: 20px;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
2 changes: 1 addition & 1 deletion applications/accounts/themes/custom/login/template.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</#list>
</#if>
<title>${msg("loginTitle",(realm.displayName!''))}</title>
<link rel="icon" href="${url.resourcesPath}/img/favicon.ico" />
<link rel="icon" href="${url.resourcesPath}/img/favicon.svg" />
<#if properties.stylesCommon?has_content>
<#list properties.stylesCommon?split(' ') as style>
<link href="${url.resourcesCommonPath}/${style}" rel="stylesheet" />
Expand Down
2 changes: 0 additions & 2 deletions applications/jupyterhub/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ COPY --chown=1000:1000 theming/spawn_pending.html /usr/local/share/jupyterhub/te
COPY --chown=1000:1000 theming/hot_fix_for_eventsource.js /usr/local/share/jupyterhub/static/hot_fix_for_eventsource.js
COPY --chown=1000:1000 theming/arrow-dropdown.svg /usr/local/share/jupyterhub/static/arrow-dropdown.svg

COPY hub/jupyter_notebook_config.py /etc/jupyter/jupyter_notebook_config.py

RUN chmod 777 /usr/src/app -R
USER jovyan

Expand Down
File renamed without changes.
9 changes: 9 additions & 0 deletions applications/jupyterhub/deploy/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
kind: ConfigMap
apiVersion: v1
metadata:
name: "jupyterhub-notebook-config"
labels:
app: jupytehub
data:
{{- (.Files.Glob "resources/jupyterhub/applications/*").AsConfig | nindent 2 }}
---
1 change: 1 addition & 0 deletions applications/jupyterhub/deploy/values-minimal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ harness:
dependencies:
soft: [nfsserver, accounts]
hard: []
nfs_volumes: false
2 changes: 1 addition & 1 deletion applications/jupyterhub/deploy/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ harness:
quota-ws-maxmem: 1
# sets the storage dedicated to the user data in Gb units (float)
quota-storage-max : 1.25

nfs_volumes: false
hub:
config:
JupyterHub:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ def get(self):
self.request.cookies.clear()
raw_user = self.get_anonymous_user()

# open external resources
if 'open=' in self.request.uri:
url = self.request.uri.split('open=').pop()
self._set_cookie("loadurl", bytes(url, 'utf-8'), encrypted=False, httponly=False)

# legacy nwb explorer support
elif 'nwbfile=' in self.request.uri:
url = self.request.uri.split('nwbfile=').pop().split("&")[0]
self._set_cookie("nwbloadurl", bytes(url, 'utf-8'), encrypted=False, httponly=False)

print("JH user: ", raw_user.__dict__)
self.set_login_cookie(raw_user)
user = yield gen.maybe_future(self.process_user(raw_user, self))
Expand Down Expand Up @@ -99,7 +109,8 @@ def get_handlers(self, app):
'process_user': self.process_user
}
return [
('/chkclogin', CloudHarnessAuthenticateHandler, extra_settings)
('/chkclogin', CloudHarnessAuthenticateHandler, extra_settings),
('/nwbfile=.*', CloudHarnessAuthenticateHandler, extra_settings)
]

def login_url(self, base_url):
Expand Down
73 changes: 55 additions & 18 deletions applications/jupyterhub/src/osb_jupyter/osb_jupyter/jupyterhub.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import re
from jupyterhub.user import User
from kubespawner.spawner import KubeSpawner

from cloudharness.auth import AuthClient
from cloudharness import log
from cloudharness import applications
from urllib.parse import parse_qs, urlparse


def affinity_spec(key, value):
Expand All @@ -22,9 +24,11 @@ def affinity_spec(key, value):
'topologyKey': 'kubernetes.io/hostname'
}


class CookieNotFound(Exception):
pass


def change_pod_manifest(self: KubeSpawner):
"""
Application Hook to change the manifest of the notebook image
Expand All @@ -47,7 +51,8 @@ def get_from_cookie(cookie_name):
return cookie.value

def user_volume_is_legacy(user_id):
print("User id", user_id, "max", self.config['apps']['jupyterhub'].get('legacyusermax', 0))
print("User id", user_id, "max",
self.config['apps']['jupyterhub'].get('legacyusermax', 0))
return int(user_id) < self.config['apps']['jupyterhub'].get('legacyusermax', 0)

def workspace_volume_is_legacy(workspace_id):
Expand Down Expand Up @@ -75,7 +80,6 @@ def workspace_volume_is_legacy(workspace_id):
self.volumes.append(ws_pvc)

app_user = get_app_user(self.user)


# Add labels to use for affinity
clean_username = "".join(c for c in app_user.username if c.isalnum())
Expand All @@ -85,11 +89,10 @@ def workspace_volume_is_legacy(workspace_id):
'user': str(self.user.id),
}



self.common_labels = labels
self.extra_labels = labels
self.storage_class = f'{self.config["namespace"]}-nfs-client'
if self.config['apps']['jupyterhub'].get('nfs_volumes', False):
self.storage_class = f'{self.config["namespace"]}-nfs-client'

if not user_volume_is_legacy(self.user.id):
# User pod affinity is by default added by cloudharness
Expand All @@ -98,10 +101,11 @@ def workspace_volume_is_legacy(workspace_id):
workspace = get_workspace(workspace_id, get_from_cookie("accessToken"))
write_access = has_user_write_access(
workspace, self.user, app_user=app_user)

if workspace_volume_is_legacy(workspace_id):
# Pods with write access must be on the same node
self.pod_affinity_required.append(affinity_spec('workspace', workspace_id))
self.pod_affinity_required.append(
affinity_spec('workspace', workspace_id))
from pprint import pprint
pprint(self.volumes)
self.pod_name = f'ws-{clean_username}-{workspace_id}-{appname}'
Expand All @@ -111,6 +115,13 @@ def workspace_volume_is_legacy(workspace_id):
'mountPath': '/opt/workspace',
'readOnly': not write_access
})
if "image=" in self.handler.request.uri and is_user_trusted(self.user):
print("Image override")
image = parse_qs(urlparse(self.handler.request.uri).query)['image'][0]
print("Image is", image)
self.image = image
self.pod_name = f"{self.pod_name}--{re.sub('[^0-9a-zA-Z]+', '-', image)}"

except CookieNotFound:
# Setup a readonly default session
self.pod_name = f'anonymous-{self.user.name}-{appname}'
Expand All @@ -122,29 +133,55 @@ def workspace_volume_is_legacy(workspace_id):
except Exception as e:
log.error('Change pod manifest failed due to an error.', exc_info=True)

# Add customized config map for jupyter notebook config
self.volumes.append({
'name': 'jupyterhub-notebook-config',
'configMap': {'name': 'jupyterhub-notebook-config'}
})
self.volume_mounts.append({
'name': 'jupyterhub-notebook-config',
'subPath': 'jupyter_notebook_config.py',
'mountPath': '/etc/jupyter/jupyter_notebook_config.py',
'readOnly': True
})
self.volume_mounts.append({
'name': 'jupyterhub-notebook-config',
'subPath': 'jupyter_notebook_config.py',
'mountPath': '/opt/conda/etc/jupyter/nbconfig/jupyter_notebook_config.py',
'readOnly': True
})




def get_app_user(user: User):
auth_client = AuthClient()
kc_user = auth_client.get_user(user.name)
return kc_user


def has_user_write_access(workspace, user: User, app_user=None):
print('Checking access, name:', user.name, "workspace:", workspace["id"])


workspace_owner = workspace["user"]["id"]
print("Workspace owner", workspace_owner, "-", workspace["user"]["username"])

if workspace_owner == user.name:
return True
print("Workspace owner", workspace_owner,
"-", workspace["user"]["username"])
return workspace_owner == user.name or is_user_trusted(user)


def is_user_trusted(user: User):
auth_client = AuthClient()
return auth_client.user_has_realm_role(app_user.id, 'administrator')
kc_user = auth_client.get_user(user.name)
return auth_client.user_has_realm_role(kc_user.id, 'administrator') or\
auth_client.user_has_realm_role(kc_user.id, 'trusted')


def get_workspace(workspace_id, token, workspace_base_url=None):
if workspace_base_url is None:
workspace_conf: applications.ApplicationConfiguration = applications.get_configuration('workspaces')
workspace_conf: applications.ApplicationConfiguration = applications.get_configuration(
'workspaces')
workspace_base_url = workspace_conf.get_service_address()
import requests
workspace = requests.get(f"{workspace_base_url}/api/workspace/{workspace_id}", headers={"Authorization": f"Bearer {token}"}).json()

return workspace
workspace = requests.get(f"{workspace_base_url}/api/workspace/{workspace_id}",
headers={"Authorization": f"Bearer {token}"}).json()

return workspace
2 changes: 0 additions & 2 deletions applications/jupyterlab/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ RUN cat ~/.bashrc

USER root

COPY hub/jupyter_notebook_config.py /etc/jupyter/jupyter_notebook_config.py

# RUN chown jovyan /opt
# RUN chown -R jovyan /opt/conda # give user permission to update existing packages

Expand Down
66 changes: 0 additions & 66 deletions applications/jupyterlab/hub/jupyter_notebook_config.py

This file was deleted.

Loading

0 comments on commit 2b826c4

Please sign in to comment.