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

enable passing server options for notebook server launch #68

Merged
merged 9 commits into from
Oct 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ COPY src/ui/src /app/src/
RUN npm run-script build


FROM python:3.6-alpine
FROM python:3.7-alpine

MAINTAINER renku

Expand Down
1 change: 0 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ gunicorn = "*"
gevent = "*"

[dev-packages]
ipdb = "*"
chartpress = "*"

[requires]
330 changes: 107 additions & 223 deletions Pipfile.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion helm-chart/minikube-values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jupyterhub:
baseUrl: /
services:
notebooks:
api_token: notebookstoken
apiToken: notebookstoken
proxy:
secretToken: f89ddee5ba10f2268fcefcd4e353235c255493095cd65addf29ebebf8df86255
service:
Expand Down
2 changes: 1 addition & 1 deletion helm-chart/renku-notebooks/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ apiVersion: v1
appVersion: '1.0'
description: A Helm chart for the Renku Notebooks service
name: renku-notebooks
version: 0.2.0
version: 0.2.1
13 changes: 13 additions & 0 deletions helm-chart/renku-notebooks/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "notebooks.fullname" . }}-options
labels:
app: {{ template "notebooks.name" . }}
chart: {{ template "notebooks.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
data:
server_options.json: |
{{ toJson .Values.serverOptions }}
21 changes: 17 additions & 4 deletions helm-chart/renku-notebooks/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ spec:
labels:
app: {{ template "notebooks.name" . }}
release: {{ .Release.Name }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
spec:
{{ if eq .Values.securityContext.enabled true }}
securityContext:
Expand All @@ -28,7 +30,7 @@ spec:
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
leafty marked this conversation as resolved.
Show resolved Hide resolved
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: DEFAULT_NOTEBOOK_IMAGE
- name: NOTEBOOKS_DEFAULT_IMAGE
value: "{{ .Values.jupyterhub.singleuser.image.name }}:{{ .Values.jupyterhub.singleuser.image.tag }}"
{{ if eq .Values.debug true }}
- name: FLASK_DEBUG
Expand All @@ -39,7 +41,7 @@ spec:
value: {{ .Values.jupyterhub.singleuser.defaultUrl }}
{{ end }}
- name: JUPYTERHUB_API_TOKEN
value: {{ .Values.jupyterhub.hub.services.notebooks.api_token }}
value: {{ .Values.jupyterhub.hub.services.notebooks.apiToken }}
- name: JUPYTERHUB_API_URL
value: {{ template "notebooks.http" . }}://{{ .Values.global.renku.domain }}{{ .Values.jupyterhub.hub.baseUrl }}hub/api
- name: JUPYTERHUB_SERVICE_PREFIX
Expand All @@ -48,8 +50,10 @@ spec:
value: {{ .Values.jupyterhub.hub.baseUrl }}
- name: JUPYTERHUB_CLIENT_ID
value: {{ .Values.jupyterhub.hub.services.notebooks.oauth_client_id }}
{{ if .Values.gitlab.registry.secret }}
- name: GITLAB_REGISTRY_SECRET
value: {{ template "renku.fullname" . }}-registry
value: {{ .Values.gitlab.registry.secret }}
{{ end }}
- name: GITLAB_URL
{{ if .Values.gitlab.url }}
value: {{ .Values.gitlab.url }}
Expand All @@ -59,11 +63,15 @@ spec:
- name: IMAGE_BUILD_TIMEOUT
value: "{{ .Values.imageBuildTimeout }}"
- name: IMAGE_REGISTRY
value: {{required "An image registry must be specified." .Values.imageRegistry }}
value: {{ required "An image registry must be specified." .Values.gitlab.registry.host }}
ports:
- name: http
containerPort: 8000
protocol: TCP
volumeMounts:
- name: server-options
mountPath: /etc/renku-notebooks/server_options.json
Copy link
Member

Choose a reason for hiding this comment

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

subPath: server_options.json
livenessProbe:
httpGet:
path: /health
Expand All @@ -76,6 +84,11 @@ spec:
periodSeconds: 30
resources:
{{ toYaml .Values.resources | indent 12 }}
volumes:
- name: server-options
configMap:
name: {{ template "notebooks.fullname" . }}-options

serviceAccountName: {{ if .Values.rbac.create }}"{{ template "notebooks.fullname" . }}"{{ else }}"{{ .Values.rbac.serviceAccountName }}"{{ end }}
{{- with .Values.nodeSelector }}
nodeSelector:
Expand Down
35 changes: 31 additions & 4 deletions helm-chart/renku-notebooks/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@

global:
useHTTPS: false
gitlab:
urlPrefix: /

gitlab:
## specify the GitLab instance URL
url:
registry:
## Set the default image registry
host: registry.example.com
## Set the registry secret key
secret:

replicaCount: 1

image:
repository: renku/renku-notebooks
tag: '0.2.0'
tag: 'latest'
pullPolicy: IfNotPresent

## Optionally specify an array of imagePullSecrets.
Expand All @@ -23,7 +30,6 @@ image:
# pullSecrets:
# - myRegistrKeySecretName

## Set the default image registry
# imageRegistry:

## set the image build timeout
Expand Down Expand Up @@ -75,14 +81,35 @@ tolerations: []

affinity: {}

serverOptions:
resources:
cpu_request:
displayName: Number of CPUs
type: integer
default: 1
range: [1, 8]
mem_request:
displayName: Memory
type: enum
default: 2G
options: [2G, 4G, 8G]
gpu:
displayName: Number of GPUs
type: integer
default: 0
range: [0, 4]
leafty marked this conversation as resolved.
Show resolved Hide resolved
defaultUrl:
default: /lab
options: [/lab]

## Configuration for the jupyterhub service
jupyterhub:
rbac:
enabled: true
hub:
image:
name: renku/jupyterhub-k8s
tag: '0.2.0'
tag: 'latest'
allowNamedServers: true
services:
notebooks:
Expand Down Expand Up @@ -140,7 +167,7 @@ jupyterhub:
singleuser:
image:
name: renku/singleuser
tag: '0.2.0'
tag: 'latest'
storage:
type: none
defaultUrl: /lab
Expand Down
75 changes: 45 additions & 30 deletions jupyterhub/spawners.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ def start(self, *args, **kwargs):
commit_sha = options.get('commit_sha')
commit_sha_7 = commit_sha[:7]
self.image = options.get('image')
self.default_url = options.get('default_url')

url = os.getenv('GITLAB_URL', 'http://gitlab.renku.build')

Expand All @@ -112,8 +111,8 @@ def start(self, *args, **kwargs):
# gather project permissions for the logged in user
permissions = gl_project.attributes['permissions']
access_level = max([
x[1].get('access_level', 0) for x in permissions.items()
if x[1]
x[1].get('access_level', 0)
for x in permissions.items() if x[1]
])
self.log.debug(
'access level for user {username} in '
Expand All @@ -133,8 +132,6 @@ def start(self, *args, **kwargs):
raise web.HTTPError(401, 'Not authorized to view project.')
return



self.cmd = 'jupyterhub-singleuser'
try:
result = yield super().start(*args, **kwargs)
Expand All @@ -151,6 +148,7 @@ def start(self, *args, **kwargs):

return result


try:
import docker
from dockerspawner import DockerSpawner
Expand Down Expand Up @@ -198,8 +196,8 @@ def start(self):
# make sure we have the alpine/git image
images = yield self.docker('images')
if not any([
'alpine/git:latest' in i['RepoTags'] for i in images
if i['RepoTags']
'alpine/git:latest' in i['RepoTags']
for i in images if i['RepoTags']
]):
alpine_git = yield self.docker(
'pull', 'alpine/git', tag='latest'
Expand Down Expand Up @@ -285,38 +283,29 @@ def get_pod_manifest(self):
options = self.user_options
commit_sha_7 = options.get('commit_sha')[:7]

# https://gist.github.com/tallclair/849601a16cebeee581ef2be50c351841
init_container_name = 'git-clone'
rokroskar marked this conversation as resolved.
Show resolved Hide resolved
volume_name = self.pod_name[:54] + '-git-repo'

# set the notebook container image
self.image_spec = self.image
## Configure the git repository volume
git_volume_name = self.pod_name[:54] + '-git-repo'

#: Define a new empty volume.
# 1. Define a new empty volume.
self.volumes = [
volume for volume in self.volumes if volume['name'] != volume_name
volume
for volume in self.volumes if volume['name'] != git_volume_name
]
volume = {
'name': volume_name,
'name': git_volume_name,
'emptyDir': {},
}
self.volumes.append(volume)

#: Define a volume mount for both init and notebook containers.
# 2. Define a volume mount for both init and notebook containers.
mount_path = f'/home/jovyan/{options["project"]}'

# set the repository path to the working directory
self.working_dir = mount_path
self.notebook_dir = mount_path

volume_mount = {
'mountPath': mount_path,
'name': volume_name,
'name': git_volume_name,
}

branch = options.get('branch', 'master')

#: Define an init container.
# 3. Configure the init container
init_container_name = 'git-clone'
self.init_containers = [
container for container in self.init_containers
if not container.name.startswith(init_container_name)
Expand All @@ -336,9 +325,9 @@ def get_pod_manifest(self):
'git lfs install --local &&'
'git config push.default simple &&'
'chown 1000:100 -Rc {mount_path}'.format(
branch=options.get('branch'),
branch=options.get('branch', 'master'),
commit_sha=options.get('commit_sha'),
mount_path=mount_path,
mount_path=volume_mount['mountPath'],
repository=repository,
)
],
Expand All @@ -348,21 +337,47 @@ def get_pod_manifest(self):
)
self.init_containers.append(init_container)

#: Share volume mount with notebook.
# 4. Configure notebook container git repo volume mount
self.volume_mounts = [
volume_mount for volume_mount in self.volume_mounts
if volume_mount['mountPath'] != mount_path
]
self.volume_mounts.append(volume_mount)

## Process the requested server options
server_options = options.get('server_options', {})
self.log.debug('server_options: {}'.format(server_options))
self.default_url = server_options.get('default_url')
self.cpu_guarantee = float(
server_options['resources'].get('cpu_request', 0.1)
)
self.mem_guarantee = server_options['resources'].get(
'mem_request', '500M'
)

gpu = server_options['resources'].get('gpu', {})
if gpu:
self.extra_resource_limits = {
"nvidia.com/gpu": str(gpu)
}

## Finalize the pod configuration

# Set the notebook container image
self.image_spec = self.image

# Set the repository path to the working directory
self.working_dir = mount_path
self.notebook_dir = mount_path

pod = yield super().get_pod_manifest()

# Because repository comes from a coroutine, we can't put it simply in `get_env()`
pod.spec.containers[0].env.append(
client.V1EnvVar('CI_REPOSITORY_URL', repository)
)

# add image pull secrets
# Add image pull secrets
if options.get('image_pull_secrets'):
secrets = [
client.V1LocalObjectReference(name=name)
Expand Down
Loading