Skip to content

Commit 85da881

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents f655b3a + 90833c1 commit 85da881

File tree

47 files changed

+681
-176
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+681
-176
lines changed

CONTRIBUTING.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ Pull requests are the best way to propose changes to the notebooks repository:
4040
- Run the [piplock-renewal.yaml](https://github.com/opendatahub-io/notebooks/blob/main/.github/workflows/piplock-renewal.yaml) against your fork branch, check [here](https://github.com/opendatahub-io/notebooks/blob/main/README.md) for more info.
4141
- Test the changes locally, by manually running the `$ make jupyter-${NOTEBOOK_NAME}-ubi8-python-3.8` from the terminal.
4242
43+
### Working with linters
44+
45+
- Run pre-commit before you commit, to lint the Python sources that have been put under its management
46+
```
47+
uv run pre-commit run --all-files
48+
```
49+
- If you like, you can install pre-commit to run automatically using `uv run pre-commit install`, as per its [install instructions](https://pre-commit.com/#3-install-the-git-hook-scripts)
4350
4451
### Some basic instructions how to apply the new tests into [openshift-ci](https://github.com/openshift/release)
4552

codeserver/ubi9-python-3.11/Dockerfile.cpu

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ USER 1001
1717
# Install micropipenv to deploy packages from Pipfile.lock
1818
RUN pip install --no-cache-dir -U "micropipenv[toml]"
1919

20-
# Install the oc client
20+
# Install the oc client begin
2121
RUN curl -L https://mirror.openshift.com/pub/openshift-v4/$(uname -m)/clients/ocp/stable/openshift-client-linux.tar.gz \
2222
-o /tmp/openshift-client-linux.tar.gz && \
2323
tar -xzvf /tmp/openshift-client-linux.tar.gz oc && \
2424
rm -f /tmp/openshift-client-linux.tar.gz
25+
# Install the oc client end
2526

2627

2728
####################

codeserver/ubi9-python-3.12/Dockerfile.cpu

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ USER 1001
1717
# Install micropipenv to deploy packages from Pipfile.lock
1818
RUN pip install --no-cache-dir -U "micropipenv[toml]"
1919

20-
# Install the oc client
20+
# Install the oc client begin
2121
RUN curl -L https://mirror.openshift.com/pub/openshift-v4/$(uname -m)/clients/ocp/stable/openshift-client-linux.tar.gz \
2222
-o /tmp/openshift-client-linux.tar.gz && \
2323
tar -xzvf /tmp/openshift-client-linux.tar.gz oc && \
2424
rm -f /tmp/openshift-client-linux.tar.gz
25+
# Install the oc client end
2526

2627

2728
####################

docs/developer-guide.md

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
The following sections are aimed to provide a comprehensive guide for developers, enabling them to understand the project's architecture and seamlessly contribute to its development.
22

33
## Getting Started
4-
This project utilizes three branches for the development: the **main** branch, which hosts the latest development, and t**wo additional branches for each release**.
5-
These release branches follow a specific naming format: YYYYx, where "YYYY" represents the year, and "x" is an increasing letter. Thus, they help to keep working on minor updates and bug fixes on the supported versions (N & N-1) of each workbench.
4+
This project utilizes three branches for the development: the **main** branch, which hosts the latest development, and **two additional branches for each release**.
5+
These release branches follow a specific naming format: YYYYx, where "YYYY" represents the year, and "x" is an increasing letter. Thus, they help to keep working on minor updates and bug fixes on the supported versions (N & N-1) of each workbench.
66

77
## Architecture
88
The structure of the notebook's build chain is derived from the parent image. To better comprehend this concept, refer to the following graph.
@@ -19,30 +19,30 @@ Detailed instructions on how developers can contribute to this project can be fo
1919
## Workbench ImageStreams
2020

2121
ODH supports multiple out-of-the-box pre-built workbench images ([provided in this repository](https://github.com/opendatahub-io/notebooks)). For each of those workbench images, there is a dedicated ImageStream object definition. This ImageStream object references the actual image tag(s) and contains additional metadata that describe the workbench image.
22-
22+
2323
### **Annotations**
2424

2525
Aside from the general ImageStream config values, there are additional annotations that can be provided in the workbench ImageStream definition. This additional data is leveraged further by the [odh-dashboard](https://github.com/opendatahub-io/odh-dashboard/).
2626

27-
### **ImageStream-specific annotations**
28-
The following labels and annotations are specific to the particular workbench image. They are provided in their respective sections in the `metadata` section.
27+
### **ImageStream-specific annotations**
28+
The following labels and annotations are specific to the particular workbench image. They are provided in their respective sections in the `metadata` section.
2929
```yaml
3030
metadata:
3131
labels:
3232
...
3333
annotations:
3434
...
3535
```
36-
### **Available labels**
37-
- **`opendatahub.io/notebook-image:`** - a flag that determines whether the ImageStream references a workbench image that is meant be shown in the UI
36+
### **Available labels**
37+
- **`opendatahub.io/notebook-image:`** - a flag that determines whether the ImageStream references a workbench image that is meant be shown in the UI
3838
### **Available annotations**
3939
- **`opendatahub.io/notebook-image-url:`** - a URL reference to the source of the particular workbench image
4040
- **`opendatahub.io/notebook-image-name:`** - a desired display name string for the particular workbench image (used in the UI)
41-
- **`opendatahub.io/notebook-image-desc:`** - a desired description string of the of the particular workbench image (used in the UI)
41+
- **`opendatahub.io/notebook-image-desc:`** - a desired description string of the particular workbench image (used in the UI)
4242
- **`opendatahub.io/notebook-image-order:`** - an index value for the particular workbench ImageStream (used by the UI to list available workbench images in a specific order)
4343
- **`opendatahub.io/recommended-accelerators`** - a string that represents the list of recommended hardware accelerators for the particular workbench ImageStream (used in the UI)
4444

45-
### **Tag-specific annotations**
45+
### **Tag-specific annotations**
4646
One ImageStream can reference multiple image tags. The following annotations are specific to a particular workbench image tag and are provided in its `annotations:` section.
4747
```yaml
4848
spec:
@@ -54,17 +54,19 @@ spec:
5454
name: image-repository/tag
5555
name: tag-name
5656
```
57-
### **Available annotations**
58-
- **`opendatahub.io/notebook-software:`** - a string that represents the technology stack included within the workbench image. Each technology in the list is described by its name and the version used (e.g. `'[{"name":"CUDA","version":"11.8"},{"name":"Python","version":"v3.9"}]`')
59-
- **`opendatahub.io/notebook-python-dependencies:`** - a string that represents the list of Python libraries included within the workbench image. Each library is described by its name and currently used version (e.g. `'[{"name":"Numpy","version":"1.24"},{"name":"Pandas","version":"1.5"}]'`)
60-
- **`openshift.io/imported-from:`** - a reference to the image repository where the workbench image was obtained (e.g. `quay.io/repository/opendatahub/workbench-images`)
61-
- **`opendatahub.io/workbench-image-recommended:`** - a flag that allows the ImageStream tag to be marked as Recommended (used by the UI to distinguish which tags are recommended for use, e.g., when the workbench image offers multiple tags to choose from)
57+
### **Available per-tag annotations**
58+
- **`opendatahub.io/notebook-software:`** - a string that represents the technology stack included within the workbench image. Each technology in the list is described by its name and the version used (e.g. `'[{"name":"CUDA","version":"11.8"},{"name":"Python","version":"v3.9"}]`')
59+
- **`opendatahub.io/notebook-python-dependencies:`** - a string that represents the list of Python libraries included within the workbench image. Each library is described by its name and currently used version (e.g. `'[{"name":"Numpy","version":"1.24"},{"name":"Pandas","version":"1.5"}]'`)
60+
- **`openshift.io/imported-from:`** - a reference to the image repository where the workbench image was obtained (e.g. `quay.io/repository/opendatahub/workbench-images`)
61+
- **`opendatahub.io/workbench-image-recommended:`** - a flag that allows the ImageStream tag to be marked as Recommended (used by the UI to distinguish which tags are recommended for use, e.g., when the workbench image offers multiple tags to choose from)
62+
- **`opendatahub.io/image-tag-outdated:`** - a flag that determines whether the image stream will be hidden from the list of available image versions in the workbench spawner dialog. Workbenches previously started with this image will continue to function.
63+
- **`opendatahub.io/notebook-build-commit:`** - the commit hash of the notebook image build that was used to create the image. This is shown in Dashboard webui starting with RHOAI 2.22.
6264

63-
### **ImageStream definitions for the supported out-of-the-box images in ODH**
65+
### **ImageStream definitions for the supported out-of-the-box images in ODH**
6466

6567
The ImageStream definitions of the out-of-the-box workbench images for ODH can be found [here](https://github.com/opendatahub-io/notebooks/tree/main/manifests).
6668

67-
### **Example ImageStream object definition**
69+
### **Example ImageStream object definition**
6870

6971
An exemplary, non-functioning ImageStream object definition that uses all the aforementioned annotations is provided below.
7072

@@ -128,7 +130,7 @@ The Openshift CI is also configured to run the unit and integration tests:
128130
129131
```
130132
tests:
131-
- as: notebooks-e2e-tests
133+
- as: notebooks-e2e-tests
132134
steps:
133135
test:
134136
- as: ${NOTEBOOK_IMAGE_NAME}-e2e-tests
@@ -149,7 +151,7 @@ This GitHub action is configured to be triggered on a weekly basis, specifically
149151
This GitHub action is configured to be triggered on a daily basis and synchronizes the selected projects from their upstream repositories to their downstream counterparts.
150152
151153
### **Digest Updater workflow on the manifests** [[Link]](https://github.com/opendatahub-io/odh-manifests/blob/master/.github/workflows/notebooks-digest-updater-upstream.yaml)
152-
154+
153155
This GitHub action is designed to be triggered on a weekly basis, specifically every Friday at 12:00 AM UTC. Its primary purpose is to automate the process of updating the SHA digest of the notebooks. It achieves this by fetching the new SHA values from the quay.io registry and updating the [param.env](https://github.com/opendatahub-io/odh-manifests/blob/master/notebook-images/base/params.env) file, which is hosted on the odh-manifest repository. By automatically updating the SHA digest, this action ensures that the notebooks remain synchronized with the latest changes.
154156
155157
### **Digest Updater workflow on the live-builder** [[Link]](https://gitlab.cee.redhat.com/data-hub/rhods-live-builder/-/blob/main/.gitlab/notebook-sha-digest-updater.yml)
@@ -159,6 +161,6 @@ This GitHub action works with the same logic as the above and is designed to be
159161
160162
### **Quay security scan** [[Link]](https://github.com/opendatahub-io/notebooks/blob/main/.github/workflows/sec-scan.yml)
161163
162-
This GitHub action is designed to be triggered on a weekly basis. It generates a summary of security vulnerabilities reported by [Quay](https://quay.io/) for the latest images built for different versions of notebooks.
163-
164+
This GitHub action is designed to be triggered on a weekly basis. It generates a summary of security vulnerabilities reported by [Quay](https://quay.io/) for the latest images built for different versions of notebooks.
165+
164166
[Previous Page](https://github.com/opendatahub-io/notebooks/wiki/Workbenches) | [Next Page](https://github.com/opendatahub-io/notebooks/wiki/User-Guide)

examples/README.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Examples
2+
3+
## JupyterLab with Elyra
4+
5+
This Workbench image installs JupyterLab and the ODH-Elyra extension.
6+
7+
The main difference between the [upstream Elyra](https://github.com/elyra-ai/elyra) and the [ODH-Elyra fork](https://github.com/opendatahub-io/elyra) is that the fork implements Argo Pipelines support, which is required for executing pipelines in OpenDataHub/OpenShift AI.
8+
Specifically, the fork already includes the changes from [elyra-ai/elyra #3273](https://github.com/elyra-ai/elyra/pull/3273), which is still pending upstream.
9+
10+
### Design
11+
12+
The workbench is based on a Source-to-Image (S2I) UBI9 Python 3.11 image.
13+
This means—besides having Python 3.11 installed—that it also has the following
14+
* Python virtual environment at `/opt/app-root` is activated by default
15+
* `HOME` directory is set to `/opt/app-root/src`
16+
* port 8888 is `EXPOSE`D by default
17+
18+
These characteristics are required for OpenDataHub workbenches to function.
19+
20+
#### Integration with OpenDataHub Notebook Controller and Notebook Dashboard
21+
22+
#### OpenDataHub Dashboard
23+
24+
Dashboard automatically populates an environment variable named `NOTEBOOK_ARGS` when starting a container from this image.
25+
This variable contains configurations that are necessary to integrate with Dashboard regarding launching the Workbench and logging off.
26+
27+
Reference: https://github.com/opendatahub-io/odh-dashboard/blob/95d80a0cccd5053dc0ca372effcdcd8183a0d5b8/frontend/src/api/k8s/notebooks.ts#L143-L149
28+
29+
Furthermore, when configuring a workbench, the default Persistent Volume Claim (PVC) is created and volume is mounted at `/opt/app-root/src` in the workbench container.
30+
This means that changing the user's `HOME` directory from the expected default is inadvisable.
31+
It further means that whatever the original content of `/opt/app-root/src` in the image may be, it will be shadowed by the PVC.
32+
33+
##### OpenDataHub Notebook Controller
34+
35+
During the Notebook Custom Resource (CR) creation, the mutating webhook in Notebook Controller is triggered.
36+
This webhook is responsible for configuring OAuth Proxy, certificate bundles, pipeline runtime, runtime images, and maybe more.
37+
It also creates a service and OpenShift route to make the Workbench reachable from the outside of the cluster.
38+
39+
**OAuth Proxy** is configured to connect to port 8888 of the workbench container (discussed above) and listen for incoming connections on port 8443.
40+
41+
Reference: https://github.com/opendatahub-io/kubeflow/blob/eacf63cdaed4db766a6503aa413e388e1d2721ef/components/odh-notebook-controller/controllers/notebook_webhook.go#L114-L121
42+
43+
**Certificate bundles** are added as a file-mounted configmap at `/etc/pki/tls/custom-certs/ca-bundle.crt`.
44+
This is a nonstandard location, so it is necessary to also add environment variables that instruct various software to reference this bundle during operation.
45+
46+
Reference:
47+
* https://github.com/opendatahub-io/kubeflow/blob/eacf63cdaed4db766a6503aa413e388e1d2721ef/components/odh-notebook-controller/controllers/notebook_webhook.go#L598
48+
* https://github.com/opendatahub-io/kubeflow/blob/eacf63cdaed4db766a6503aa413e388e1d2721ef/components/odh-notebook-controller/controllers/notebook_webhook.go#L601-L607
49+
50+
**Pipeline runtime configuration** is obtained from a Data Science Pipeline Application (DSPA) CR.
51+
The DSPA CR is first located in the same project where the workbench is being started, a secret with the connection data is created, and then this secret is mounted.
52+
The secret is mounted under `/opt/app-root/runtimes/`.
53+
54+
Reference: https://github.com/opendatahub-io/kubeflow/blob/eacf63cdaed4db766a6503aa413e388e1d2721ef/components/odh-notebook-controller/controllers/notebook_dspa_secret.go#L42C28-L42C50
55+
56+
IMPORTANT: the `setup-elyra.sh` script in this repo relies on this location.
57+
58+
**Runtime images** are processed very similarly to the DSPA configuration.
59+
First, image stream resources are examined, and then a configmap is created and mounted to every newly started workbench.
60+
The mount location is under `/opt/app-root/pipeline-runtimes/`.
61+
62+
Reference: https://github.com/opendatahub-io/kubeflow/blob/eacf63cdaed4db766a6503aa413e388e1d2721ef/components/odh-notebook-controller/controllers/notebook_runtime.go#L25C19-L25C51
63+
64+
IMPORTANT: the `setup-elyra.sh` script in this repo again relies on this location.
65+
66+
### Build
67+
68+
```shell
69+
podman build -f examples/jupyterlab-with-elyra/Dockerfile -t quay.io/your-username/jupyterlab-with-elyra:latest .
70+
podman push quay.io/your-username/jupyterlab-with-elyra:latest
71+
```
72+
73+
### Deploy
74+
75+
Open the `Settings > Workbench images` page in OpenDataHub Dashboard.
76+
Click on the `Import new image` button and add the image you have just pushed.
77+
The `Image location` field should be set to `quay.io/your-username/jupyterlab-with-elyra:latest`, or wherever the image is pushed and available for the cluster to pull.
78+
Values of other fields do not matter for functionality, but they let you keep better track of previously imported images.
79+
80+
There is a special ODH Dashboard feature that alerts you when you are using a workbench image that lists the `elyra` instead of `odh-elyra` package.
81+
This code will have to be updated when `elyra` also gains support for Argo Pipelines, but for now it does the job.
82+
83+
Reference: https://github.com/opendatahub-io/odh-dashboard/blob/2ced77737a1b1fc24b94acac41245da8b29468a4/frontend/src/concepts/pipelines/elyra/utils.ts#L152-L162
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
########
2+
# base #
3+
########
4+
5+
# https://catalog.redhat.com/software/containers/registry/registry.access.redhat.com/repository/ubi9/python-311
6+
FROM registry.access.redhat.com/ubi9/python-311:latest
7+
# Subsequent code may leverages the folloving definitions from the base image:
8+
# ENV APP_ROOT=/opt/app-root
9+
# ENV HOME="${APP_ROOT}/src"
10+
# ENV PYTHON_VERSION=3.11
11+
# ENV PYTHONUNBUFFERED=1
12+
# ENV PYTHONIOENCODING=UTF-8
13+
# ENV PIP_NO_CACHE_DIR=off
14+
# ENV BASH_ENV="${APP_ROOT}/bin/activate"
15+
# ENV ENV="${APP_ROOT}/bin/activate"
16+
17+
# OS packages needs to be installed as root
18+
USER root
19+
20+
# Install useful OS packages
21+
RUN dnf install -y mesa-libGL skopeo && dnf clean all && rm -rf /var/cache/yum
22+
23+
# Other apps and tools shall be installed as default user
24+
# - Kuberneres requires using numeric IDs for the final USER command
25+
# - Openshift's SCC restricted-v2 policy runs images under random UID and GID of 0
26+
USER 1001:0
27+
WORKDIR /opt/app-root
28+
29+
ARG JUPYTER_REUSABLE_UTILS=jupyter/utils
30+
ARG MINIMAL_SOURCE_CODE=jupyter/minimal/ubi9-python-3.11
31+
ARG DATASCIENCE_SOURCE_CODE=jupyter/datascience/ubi9-python-3.11
32+
33+
# Emplace and activate our entrypoint script
34+
COPY ${MINIMAL_SOURCE_CODE}/start-notebook.sh /opt/app-root/bin/
35+
ENTRYPOINT ["/opt/app-root/bin/start-notebook.sh"]
36+
# Copy JupyterLab config from utils directory
37+
COPY ${JUPYTER_REUSABLE_UTILS} /opt/app-root/bin/utils/
38+
# Copy Elyra setup script and various utils where start-notebook.sh expects it
39+
COPY ${DATASCIENCE_SOURCE_CODE}/setup-elyra.sh ${DATASCIENCE_SOURCE_CODE}/utils /opt/app-root/bin/utils/
40+
41+
# Install Python packages and Jupyterlab extensions
42+
# https://www.docker.com/blog/introduction-to-heredocs-in-dockerfiles/
43+
44+
COPY <<EOF requirements.txt
45+
--index-url https://pypi.org/simple
46+
47+
# JupyterLab
48+
jupyterlab==4.2.7
49+
jupyter-bokeh~=4.0.5
50+
jupyter-server~=2.15.0
51+
jupyter-server-proxy~=4.4.0
52+
jupyter-server-terminals~=0.5.3
53+
jupyterlab-git~=0.50.1
54+
jupyterlab-lsp~=5.1.0
55+
jupyterlab-widgets~=3.0.13
56+
jupyter-resource-usage~=1.1.1
57+
nbdime~=4.0.2
58+
nbgitpuller~=1.2.2
59+
60+
# Elyra
61+
odh-elyra==4.2.1
62+
kfp~=2.12.1
63+
64+
# Miscellaneous datascience packages
65+
matplotlib~=3.10.1
66+
numpy~=2.2.3
67+
# ...
68+
EOF
69+
70+
RUN echo "Installing software and packages" && \
71+
pip install -r requirements.txt && \
72+
rm -f ./Pipfile.lock && \
73+
# Prepare directories for elyra runtime configuration
74+
mkdir /opt/app-root/runtimes && \
75+
mkdir /opt/app-root/pipeline-runtimes && \
76+
# Remove default Elyra runtime-images
77+
rm /opt/app-root/share/jupyter/metadata/runtime-images/*.json && \
78+
# Replace Notebook's launcher, "(ipykernel)" with Python's version 3.x.y
79+
sed -i -e "s/Python.*/$(python --version | cut -d '.' -f-2)\",/" /opt/app-root/share/jupyter/kernels/python3/kernel.json && \
80+
# Copy jupyter configuration
81+
cp /opt/app-root/bin/utils/jupyter_server_config.py /opt/app-root/etc/jupyter && \
82+
# Disable announcement plugin of jupyterlab
83+
jupyter labextension disable "@jupyterlab/apputils-extension:announcements" && \
84+
# Fix permissions to support pip in Openshift environments
85+
chmod -R g+w /opt/app-root/lib/python3.11/site-packages && \
86+
fix-permissions /opt/app-root -P
87+
88+
# Switch dir to $HOME
89+
WORKDIR /opt/app-root/src

0 commit comments

Comments
 (0)