Skip to content

Commit 018dfd3

Browse files
author
Alan Christie
committed
fix: Changes for cluster-wide operator
BREAKING CHANGE
1 parent 8a35f49 commit 018dfd3

27 files changed

+129
-136
lines changed

.github/workflows/build-latest.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ jobs:
3030
steps:
3131
- name: Checkout
3232
uses: actions/checkout@v2
33-
- name: Set up Python 3.9
33+
- name: Set up Python 3.10
3434
uses: actions/setup-python@v2
3535
with:
36-
python-version: 3.9
36+
python-version: '3.10'
3737
- name: Install dependencies
3838
run: |
3939
python -m pip install --upgrade pip

.github/workflows/build.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ jobs:
3232
steps:
3333
- name: Checkout
3434
uses: actions/checkout@v2
35-
- name: Set up Python 3.9
35+
- name: Set up Python 3.10
3636
uses: actions/setup-python@v2
3737
with:
38-
python-version: 3.9
38+
python-version: '3.10'
3939
- name: Install dependencies
4040
run: |
4141
python -m pip install --upgrade pip

README.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,37 +62,37 @@ is automatically built and pushed to Docker Hub using GitHub Actions.
6262
You can build the image yourself using docker-compose.
6363
The following will build an operator image with the tag `19.0.0-alpha.1`: -
6464

65-
$ export IMAGE_TAG=19.0.0-alpha.1
66-
$ docker-compose build
65+
export IMAGE_TAG=19.0.0-alpha.1
66+
docker-compose build
6767

6868
## Deploying into the Data Manager API
6969
We use [Ansible] 3 and community modules in [Ansible Galaxy] as the deployment
7070
mechanism, using the `operator` Ansible role in this repository and a
7171
Kubernetes config (KUBECONFIG). All of this is done via a suitable Python
7272
environment using the requirements in the root of the project...
7373

74-
$ python -m venv ~/.venv/data-manager-jupyter-operator
75-
$ source ~/.venv/data-manager-jupyter-operator/bin/activate
76-
$ pip install --upgrade pip
77-
$ pip install -r requirements.txt
78-
$ ansible-galaxy install -r requirements.yaml
74+
python -m venv ~/.venv/data-manager-jupyter-operator
75+
source ~/.venv/data-manager-jupyter-operator/bin/activate
76+
pip install --upgrade pip
77+
pip install -r requirements.txt
78+
ansible-galaxy install -r requirements.yaml
7979

8080
Set your KUBECONFIG for the cluster and verify its right: -
8181

82-
$ export KUBECONFIG=~/k8s-config/local-config
83-
$ kubectl get no
82+
export KUBECONFIG=~/k8s-config/local-config
83+
kubectl get no
8484
[...]
8585

8686
Now, create a parameter file (i.e. `parameters.yaml`) based on the project's
8787
`example-parameters.yaml`, setting values for the operator that match your
8888
needs. Then deploy, using Ansible, from the root of the project: -
8989

90-
$ export PARAMS=parameters
91-
$ ansible-playbook -e @${PARAMS}.yaml site.yaml
90+
export PARAMS=parameters
91+
ansible-playbook -e @${PARAMS}.yaml site.yaml
9292

9393
To remove the operator (assuming there are no operator-derived instances)...
9494

95-
$ ansible-playbook -e @${PARAMS}.yaml -e jo_state=absent site.yaml
95+
ansible-playbook -e @${PARAMS}.yaml -e jo_state=absent site.yaml
9696

9797
> The current Data Manager API assumes that once an Application (operator)
9898
has been installed it is not removed. So, removing the operator here
@@ -105,9 +105,9 @@ are held in this repository.
105105

106106
To deploy: -
107107

108-
$ export KUBECONFIG=~/k8s-config/config-aws-im-main-eks
109-
$ export PARAMS=staging
110-
$ ansible-playbook -e @${PARAMS}-parameters.yaml site.yaml
108+
export KUBECONFIG=~/k8s-config/config-aws-im-main-eks
109+
export PARAMS=staging
110+
ansible-playbook -e @${PARAMS}-parameters.yaml site.yaml
111111

112112
> You will need the vault password, held in the company's KeePass under
113113
`data-manager-jupyter-operator -> Ansible Vault Password`
@@ -162,7 +162,7 @@ Data Manager's **Namespace**.
162162
Typical **Role** and **RoleBinding** definitions are provided in this
163163
repository. Once you define yours you'll just need to create them: -
164164

165-
$ kubectl create -f data-manager-rbac.yaml
165+
kubectl create -f data-manager-rbac.yaml
166166

167167
With this done the application should be visible through the Data Manager API's
168168
**/application** REST endpoint.

docker-compose.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@
55
# You can control some of the behaviour of the build
66
# with environment variables: -
77
#
8-
# - IMAGE_TAG The image version tag (default 19.0.0)
8+
# - IMAGE_TAG The image version tag (default 19.2.0)
99
#
1010
# Note: The image tag MUST use the major version of the
1111
# kubernetes package the operator is built against.
1212
# The minor/patch values are free for your use.
1313
#
1414
# i.e.: -
1515
#
16-
# IMAGE_TAG=19.0.0-alpha.1 docker-compose build
17-
# IMAGE_TAG=19.0.0-alpha.1 docker-compose push
16+
# IMAGE_TAG=19.3.0-alpha.1 docker-compose build
17+
# IMAGE_TAG=19.3.0-alpha.1 docker-compose push
1818

1919
version: '3.8'
2020

2121
services:
2222
operator:
2323
build:
2424
context: operator
25-
image: informaticsmatters/data-manager-jupyter-operator:${IMAGE_TAG:-19.0.0}
25+
image: informaticsmatters/data-manager-jupyter-operator:${IMAGE_TAG:-19.2.0}

docker-desktop-parameters.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
jo_ingress_domain: kubernetes.docker.internal
44
jo_ingress_tls_secret: data-manager-api-tls
55
jo_dmapi_namespace: data-manager-api
6-
jo_image_tag: 19.1.2
6+
jo_image_tag: 19.2.0
77
jo_namespaces: data-manager-api
88

99
jo_kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}"

integration-parameters.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
---
22

3+
jo_image_tag: 19.2.0
4+
jo_dmapi_namespace: data-manager-api-integration
5+
36
jo_ingress_domain: squonk.it
47
jo_ingress_tls_secret: data-manager-api-tls
5-
jo_dmapi_name: integration
6-
jo_image_tag: 19.0.2
78
jo_namespaces: data-manager-api-staging:data-manager-api-integration:data-manager-api-production
89

910
jo_kubeconfig: "{{ lookup('env', 'KUBECONFIG') }}"

local-parameters.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
3+
jo_image_tag: 19.2.0
4+
jo_dmapi_namespace: data-manager-api
5+
6+
# The Kubernetes config file
7+
jo_kubeconfig: ~/k8s-config/config-local

operator/Dockerfile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
FROM python:3.9.12-slim
1+
FROM python:3.10.4-slim
2+
3+
# Labels
4+
LABEL maintainer='Alan Christie <[email protected]>'
5+
6+
# Force the binary layer of the stdout and stderr streams
7+
# to be unbuffered
8+
ENV PYTHONUNBUFFERED 1
29

310
COPY requirements.txt ./
411
RUN pip install -r requirements.txt

operator/entrypoint.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
#!/usr/bin/env bash
2-
NS=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
3-
kopf run ./handlers.py --verbose --standalone --namespace=${NS} --log-format full
2+
kopf run ./handlers.py --verbose --standalone --all-namespaces --log-format full

operator/handlers.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,33 @@
44
import random
55
import os
66
import string
7-
from typing import Any, Dict
7+
from typing import Any, Dict, Optional
88

99
import kubernetes
1010
import kopf
1111

1212
# Some (key) default deployment variables...
13-
_DEFAULT_IMAGE = "jupyter/minimal-notebook:notebook-6.3.0"
14-
_DEFAULT_SA = "default"
15-
_DEFAULT_CPU_LIMIT = "1"
16-
_DEFAULT_CPU_REQUEST = "10m"
17-
_DEFAULT_MEM_LIMIT = "1Gi"
18-
_DEFAULT_MEM_REQUEST = "256Mi"
19-
_DEFAULT_USER_ID = 1000
20-
_DEFAULT_GROUP_ID = 100
21-
_DEFAULT_INGRESS_PROXY_BODY_SIZE = "500m"
13+
_DEFAULT_IMAGE: str = "jupyter/minimal-notebook:notebook-6.3.0"
14+
_DEFAULT_SA: str = "default"
15+
_DEFAULT_CPU_LIMIT: str = "1"
16+
_DEFAULT_CPU_REQUEST: str = "10m"
17+
_DEFAULT_MEM_LIMIT: str = "1Gi"
18+
_DEFAULT_MEM_REQUEST: str = "256Mi"
19+
_DEFAULT_USER_ID: int = 1000
20+
_DEFAULT_GROUP_ID: int = 100
21+
_DEFAULT_INGRESS_PROXY_BODY_SIZE: str = "500m"
2222

2323
# The ingress class
24-
_INGRESS_CLASS = "nginx"
24+
_INGRESS_CLASS: str = "nginx"
2525
# The ingress domain must be provided.
26-
ingress_domain = os.environ["INGRESS_DOMAIN"]
26+
ingress_domain: str = os.environ["INGRESS_DOMAIN"]
2727
# The ingress TLS secret is optional.
2828
# If provided it is used as the Ingress secret
2929
# and cert-manager is avoided.
30-
ingress_tls_secret = os.environ.get("INGRESS_TLS_SECRET")
30+
ingress_tls_secret: Optional[str] = os.environ.get("INGRESS_TLS_SECRET")
3131
# The cert-manager issuer,
3232
# expected if a TLS certificate is not defined.
33-
ingress_cert_issuer = os.environ.get("INGRESS_CERT_ISSUER")
33+
ingress_cert_issuer: Optional[str] = os.environ.get("INGRESS_CERT_ISSUER")
3434

3535
# Application node selection
3636
_POD_NODE_SELECTOR_KEY: str = os.environ.get(
@@ -51,7 +51,7 @@
5151
# As part of the startup we erase the existing '~/.bashrc' and,
5252
# as a minimum, set a more suitable PS1 (see ch2385).
5353
# 'conda init' then puts its stuff into the same file.
54-
_NOTEBOOK_STARTUP = """#!/bin/bash
54+
_NOTEBOOK_STARTUP: str = """#!/bin/bash
5555
echo "PS1='\$(pwd) \$UID$ '" > ~/.bashrc
5656
echo "umask 0002" >> ~/.bashrc
5757
conda init
@@ -72,7 +72,7 @@
7272

7373
# The bash-profile
7474
# which simply launches the .bashrc
75-
_BASH_PROFILE = """if [ -f ~/.bashrc ]; then
75+
_BASH_PROFILE: str = """if [ -f ~/.bashrc ]; then
7676
source ~/.bashrc
7777
fi
7878
"""
@@ -81,7 +81,7 @@
8181
# A ConfigMap whose content is written into '/etc'
8282
# and copied to the $HOME/.jupyter by the notebook_startup
8383
# script (above).
84-
_NOTEBOOK_CONFIG = """{
84+
_NOTEBOOK_CONFIG: str = """{
8585
"NotebookApp": {
8686
"token": "%(token)s",
8787
"base_url": "%(base_url)s"
@@ -97,7 +97,7 @@ def configure(settings: kopf.OperatorSettings, **_: Any) -> None:
9797
settings.posting.level = logging.INFO
9898

9999

100-
@kopf.on.create("squonk.it", "v1", "jupyternotebooks", id="jupyter")
100+
@kopf.on.create("squonk.it", "v2", "jupyternotebooks", id="jupyter")
101101
def create(spec: Dict[str, Any], name: str, namespace: str, **_: Any) -> Dict[str, Any]:
102102
"""Handler for CRD create events.
103103
Here we construct the required Kubernetes objects,

0 commit comments

Comments
 (0)