319 lines
10 KiB
Nix
319 lines
10 KiB
Nix
{
|
||
description = "kupyter – rootless Kubernetes dev shell";
|
||
|
||
inputs = {
|
||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||
flake-utils.url = "github:numtide/flake-utils";
|
||
};
|
||
|
||
outputs =
|
||
{
|
||
self,
|
||
nixpkgs,
|
||
flake-utils,
|
||
}:
|
||
flake-utils.lib.eachDefaultSystem (
|
||
system:
|
||
let
|
||
pkgs = import nixpkgs { inherit system; };
|
||
|
||
get-all = pkgs.writeShellApplication {
|
||
name = "get-all";
|
||
runtimeInputs = [ pkgs.kubectl ];
|
||
text = ''kubectl get pods -A'';
|
||
};
|
||
|
||
cluster-start = pkgs.writeShellApplication {
|
||
name = "cluster-start";
|
||
runtimeInputs = [
|
||
pkgs.kind
|
||
pkgs.kubectl
|
||
];
|
||
text = ''
|
||
kind create cluster --name kupyter --wait 60s
|
||
kubectl config use-context kind-kupyter
|
||
echo "✓ Cluster ready"
|
||
kubectl cluster-info
|
||
'';
|
||
};
|
||
|
||
cluster-stop = pkgs.writeShellApplication {
|
||
name = "cluster-stop";
|
||
runtimeInputs = [ pkgs.kind ];
|
||
text = ''
|
||
kind delete cluster --name kupyter
|
||
rm -f .kubeconfig
|
||
echo "✓ Cluster deleted, kubeconfig cleared"
|
||
'';
|
||
};
|
||
|
||
tls-init = pkgs.writeShellApplication {
|
||
name = "tls-init";
|
||
runtimeInputs = [
|
||
pkgs.openssl
|
||
pkgs.kubectl
|
||
];
|
||
text = ''
|
||
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
||
-keyout tls.key \
|
||
-out tls.crt \
|
||
-subj "/CN=jupyterhub.local/O=kupyter"
|
||
|
||
kubectl create namespace jupyterhub --dry-run=client -o yaml | kubectl apply -f -
|
||
|
||
kubectl create secret tls jupyterhub-tls \
|
||
--cert=tls.crt \
|
||
--key=tls.key \
|
||
--namespace jupyterhub
|
||
echo "✓ TLS secret stored in jupyterhub namespace"
|
||
'';
|
||
};
|
||
|
||
helm-repos = pkgs.writeShellApplication {
|
||
name = "helm-repos";
|
||
runtimeInputs = [ pkgs.kubernetes-helm ];
|
||
text = ''
|
||
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
|
||
helm repo add jupyterhub https://hub.jupyter.org/helm-chart/
|
||
helm repo add bitnami https://charts.bitnami.com/bitnami
|
||
helm repo add ngshare https://libretexts.github.io/ngshare-helm-repo/
|
||
helm repo add prometheus https://prometheus-community.github.io/helm-charts
|
||
helm repo update
|
||
echo "✓ all helm repos added and updated"
|
||
'';
|
||
};
|
||
|
||
ingress-install = pkgs.writeShellApplication {
|
||
name = "ingress-install";
|
||
runtimeInputs = [
|
||
pkgs.kubernetes-helm
|
||
pkgs.kubectl
|
||
];
|
||
text = ''
|
||
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
|
||
--namespace ingress-nginx \
|
||
--create-namespace \
|
||
--set controller.service.type=NodePort \
|
||
--set controller.service.nodePorts.http=30080 \
|
||
--set controller.service.nodePorts.https=30443
|
||
echo "✓ ingress-nginx installed"
|
||
kubectl get pods -n ingress-nginx
|
||
'';
|
||
};
|
||
|
||
jupyterhub-install = pkgs.writeShellApplication {
|
||
name = "jupyterhub-install";
|
||
runtimeInputs = [
|
||
pkgs.kubernetes-helm
|
||
pkgs.kubectl
|
||
];
|
||
text = ''
|
||
kubectl create namespace jupyterhub --dry-run=client -o yaml | kubectl apply -f -
|
||
|
||
kubectl create configmap hub-logos \
|
||
--from-file=jupyterhub-80.png=./kupyter-notebook/logo.png \
|
||
--from-file=jupyterhub.svg=./kupyter-notebook/logo.svg \
|
||
--namespace jupyterhub \
|
||
--dry-run=client -o yaml | kubectl apply -f -
|
||
|
||
helm upgrade --install jupyterhub jupyterhub/jupyterhub \
|
||
--namespace jupyterhub \
|
||
--values config.yaml
|
||
|
||
kubectl apply -f jupyterhub-ingress.yaml
|
||
echo "✓ jupyterhub installing"
|
||
kubectl get pods -n jupyterhub
|
||
'';
|
||
};
|
||
|
||
db-install = pkgs.writeShellApplication {
|
||
name = "db-install";
|
||
runtimeInputs = [
|
||
pkgs.kubernetes-helm
|
||
pkgs.kubectl
|
||
];
|
||
text = ''
|
||
helm upgrade --install jupyterhub-db bitnami/postgresql \
|
||
--namespace jupyterhub \
|
||
--set auth.username=jupyterhub \
|
||
--set auth.password=jupyterhub \
|
||
--set auth.database=jupyterhub
|
||
echo "✓ postgres installing"
|
||
kubectl get pods -n jupyterhub
|
||
'';
|
||
};
|
||
|
||
notebook-build = pkgs.writeShellApplication {
|
||
name = "notebook-build";
|
||
runtimeInputs = [
|
||
pkgs.podman
|
||
pkgs.kind
|
||
];
|
||
text = ''
|
||
podman build -t kupyter-notebook:latest ./kupyter-notebook
|
||
podman save kupyter-notebook:latest -o /tmp/kupyter-notebook.tar
|
||
kind load image-archive /tmp/kupyter-notebook.tar --name kupyter
|
||
rm /tmp/kupyter-notebook.tar
|
||
echo "✓ image built and loaded into cluster"
|
||
'';
|
||
};
|
||
|
||
hub-build = pkgs.writeShellApplication {
|
||
name = "hub-build";
|
||
runtimeInputs = [
|
||
pkgs.podman
|
||
pkgs.kind
|
||
];
|
||
text = ''
|
||
podman build -t kupyter-hub:latest -f Dockerfile.hub .
|
||
podman save kupyter-hub:latest -o /tmp/kupyter-hub.tar
|
||
kind load image-archive /tmp/kupyter-hub.tar --name kupyter
|
||
rm /tmp/kupyter-hub.tar
|
||
echo "✓ hub image built and loaded"
|
||
'';
|
||
};
|
||
|
||
ngshare-install = pkgs.writeShellApplication {
|
||
name = "ngshare-install";
|
||
runtimeInputs = [
|
||
pkgs.kubernetes-helm
|
||
pkgs.kubectl
|
||
];
|
||
text = ''
|
||
helm upgrade --install ngshare ngshare/ngshare \
|
||
--namespace jupyterhub \
|
||
--set ngshare.token=822235aaaf83f0232c799fe948cbb1594b01d7d7b11af051871cc2d3fcb08fe8 \
|
||
--set ngshare.hub_api_token=822235aaaf83f0232c799fe948cbb1594b01d7d7b11af051871cc2d3fcb08fe8 \
|
||
--set ngshare.admins="admin,ngshare-setup" \
|
||
--values ngshare-values.yaml
|
||
|
||
echo "Waiting for ngshare..."
|
||
kubectl wait pod \
|
||
--for=condition=ready \
|
||
--selector=app.kubernetes.io/name=ngshare \
|
||
--namespace jupyterhub \
|
||
--timeout=120s
|
||
|
||
echo "✓ ngshare installed"
|
||
kubectl get pods -n jupyterhub
|
||
'';
|
||
};
|
||
|
||
ngshare-courses = pkgs.writeShellApplication {
|
||
name = "ngshare-courses";
|
||
runtimeInputs = [ pkgs.kubectl ];
|
||
text = ''
|
||
HUB_POD=$(kubectl get pod -n jupyterhub -l component=hub -o name)
|
||
|
||
kubectl exec -n jupyterhub "$HUB_POD" -- curl -s -X POST \
|
||
"http://ngshare.jupyterhub.svc.cluster.local:8080/services/ngshare/course/Programmieren" \
|
||
-d "instructors=[\"instructor-Prog\"]" \
|
||
-H "Authorization: token setuptoken123456789012345678901234567890123456789012345678901234"
|
||
|
||
kubectl exec -n jupyterhub "$HUB_POD" -- curl -s -X POST \
|
||
"http://ngshare.jupyterhub.svc.cluster.local:8080/services/ngshare/course/Signale" \
|
||
-d "instructors=[\"instructor-Sig\"]" \
|
||
-H "Authorization: token setuptoken123456789012345678901234567890123456789012345678901234"
|
||
|
||
echo "✓ courses created"
|
||
'';
|
||
};
|
||
|
||
monitoring-install = pkgs.writeShellApplication {
|
||
name = "monitoring-install";
|
||
runtimeInputs = [
|
||
pkgs.kubernetes-helm
|
||
pkgs.kubectl
|
||
];
|
||
text = ''
|
||
helm upgrade --install kube-prometheus-stack prometheus/kube-prometheus-stack \
|
||
--namespace monitoring \
|
||
--create-namespace \
|
||
--wait
|
||
kubectl apply -f ./jupyterhub-monitor.yaml
|
||
echo "✓ monitoring installed"
|
||
kubectl get pods -n monitoring
|
||
'';
|
||
};
|
||
|
||
rebuild-all = pkgs.writeShellApplication {
|
||
name = "rebuild-all";
|
||
runtimeInputs = [
|
||
pkgs.kind
|
||
pkgs.kubectl
|
||
pkgs.kubernetes-helm
|
||
pkgs.podman
|
||
];
|
||
text = ''
|
||
cluster-stop
|
||
cluster-start
|
||
tls-init
|
||
helm-repos
|
||
ingress-install
|
||
hub-build
|
||
notebook-build
|
||
db-install
|
||
ngshare-install
|
||
jupyterhub-install
|
||
monitoring-install
|
||
echo "Waiting for hub to be ready..."
|
||
kubectl wait pod \
|
||
--for=condition=ready \
|
||
--selector=component=hub \
|
||
--namespace jupyterhub \
|
||
--timeout=300s
|
||
ngshare-courses
|
||
'';
|
||
};
|
||
|
||
in
|
||
{
|
||
devShells.default = pkgs.mkShell {
|
||
name = "kupyter";
|
||
|
||
packages = [
|
||
get-all
|
||
cluster-start
|
||
cluster-stop
|
||
tls-init
|
||
helm-repos
|
||
ingress-install
|
||
jupyterhub-install
|
||
notebook-build
|
||
db-install
|
||
ngshare-install
|
||
ngshare-courses
|
||
hub-build
|
||
monitoring-install
|
||
rebuild-all
|
||
pkgs.openssl
|
||
pkgs.kubectl
|
||
pkgs.kubernetes-helm
|
||
pkgs.podman
|
||
pkgs.kind
|
||
];
|
||
|
||
shellHook = ''
|
||
export KUBECONFIG="$(pwd)/.kubeconfig"
|
||
export KIND_EXPERIMENTAL_PROVIDER=podman
|
||
|
||
echo ""
|
||
echo " kupyter dev shell"
|
||
echo " KUBECONFIG → $(pwd)/.kubeconfig (session-local)"
|
||
echo " runtime → podman (rootless)"
|
||
echo ""
|
||
echo " cluster-start # create cluster"
|
||
echo " cluster-stop # delete cluster + wipe kubeconfig"
|
||
echo " tls-init # generate self-signed cert"
|
||
echo " helm-repos # add and update helm repos"
|
||
echo " ingress-install # install nginx ingress"
|
||
echo " notebook-build # build and load notebook image"
|
||
echo " jupyterhub-install # install jupyterhub"
|
||
echo " get-all # show all pods"
|
||
echo ""
|
||
'';
|
||
};
|
||
}
|
||
);
|
||
}
|