Skip to content
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 .github/workflows/conventional-commits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ name: Conventional Commits

on:
pull_request:
types: [opened, reopened, synchronized]
types: [opened, reopened, synchronize]

jobs:
commits:
Expand Down
199 changes: 199 additions & 0 deletions .github/workflows/deploy-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
#
# Copyright 2026 The OKDP Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# End-to-end install validation for the sandbox deployment.
#
# Spins up a throwaway Kind cluster, installs Flux and the KuboCD controller,
# then applies the contexts and releases from clusters/sandbox/ exactly as the
# README instructs and waits until every KuboCD Release reaches READY.
#
# Unlike the package CI in OKDP/platform-packages, this workflow builds nothing:
# it deploys the already-published packages (quay.io/okdp/platform-packages/<pkg>)
# straight from the manifests, so it validates the deployment layer, not packages.
#
# NOTE: the releases reference quay.io/okdp/platform-packages/<pkg> (no version
# suffix), which only exists once OKDP/platform-packages#19 has merged and
# republished. Until then this workflow is expected to fail.

name: Deploy validation (sandbox e2e)

on:
pull_request:
paths:
- "clusters/**"
- ".github/workflows/deploy-validation.yml"
push:
branches: [main]
paths:
- "clusters/**"
workflow_dispatch:

defaults:
run:
shell: bash

jobs:
deploy-validation:
# A larger runner gives the full platform room to schedule; on a small runner
# the capacity escape-hatch below turns "insufficient cpu/memory" into a pass.
runs-on: ubuntu-latest
steps:

- name: Checkout repo ⚡️
uses: actions/checkout@v4

- name: Free up disk space 📦
uses: okdp/gh-workflows/.github/actions/free-disk-space@v1

- name: Set up Kind cluster 📦
uses: okdp/gh-workflows/.github/actions/setup-kind@v1

- name: Setup Flux CLI 🛠️
uses: fluxcd/flux2/action@main
with:
version: "2.7.5"

- name: Deploy Flux (basic mode) 🚀
run: flux install

- name: Wait until Flux controllers are ready ⌛
run: |
kubectl wait --for=condition=ready pod -l app=source-controller -n flux-system --timeout=300s

- name: Verify Flux installation ✅
run: |
flux version
kubectl -n flux-system get pods

- name: Bootstrap the KuboCD controller 🛠️
run: kubectl apply -f clusters/sandbox/flux/kubocd.yaml

- name: Wait until the KuboCD controller is ready ⌛
run: |
# HelmRelease "Ready" implies the controller is rolled out and its CRDs
# (Context, Release) are registered, which the next steps need.
kubectl wait --for=condition=Ready helmrelease/kubocd-controller \
-n flux-system --timeout=600s
kubectl -n kubocd get pods

- name: Apply the platform contexts 🚀
run: |
# Order is immaterial: precedence is resolved by defaultContexts in
# kubocd.yaml. The NN- filename prefixes only order this glob apply.
kubectl apply -f clusters/sandbox/contexts/

- name: Apply the platform releases 🚀
run: |
kubectl apply -f clusters/sandbox/releases/

- name: Wait for all releases to become READY ✅
run: |
echo "**************************************** Storage Classes ****************************************"
kubectl get sc
kubectl get events -A -w >/tmp/kubectl-events.log 2>&1 &
EVENTS_PID=$!
trap 'kill $EVENTS_PID 2>/dev/null || true' EXIT

# Poll release phase explicitly; more stable than kubectl wait for this CRD.
timeout_secs=1200
interval_secs=15
elapsed=0
ready=0

while [ "$elapsed" -lt "$timeout_secs" ]; do
echo "Wait until all KuboCD releases are ready ..."
echo "************************************** Releases status **************************************"
kubectl get release -A || true
echo "**************************************** Pods status ****************************************"
kubectl get po -A || true
echo "**************************************** PVC status ****************************************"
kubectl get pvc -A || true
echo "**************************************** Pending Pods ****************************************"
kubectl get pods -A --field-selector=status.phase=Pending \
-o custom-columns=NS:.metadata.namespace,NAME:.metadata.name --no-headers \
| xargs -r -n2 sh -c 'echo "Pending Pod: $0/$1 ==="; kubectl describe pod -n "$0" "$1"; echo'

echo "**************************************** Unhealthy Pods ****************************************"
kubectl get pods -A --no-headers \
| awk '$4 ~ /CrashLoopBackOff|Error|ImagePullBackOff|CreateContainerConfigError|CreateContainerError/ {print $1, $2}' \
| while read -r ns pod; do
[ -n "$ns" ] || continue
[ -n "$pod" ] || continue
echo "Unhealthy Pod: $ns/$pod ==="
kubectl describe pod -n "$ns" "$pod" || true
containers="$(
kubectl get pod -n "$ns" "$pod" -o jsonpath='{range .spec.initContainers[*]}{.name}{"\n"}{end}{range .spec.containers[*]}{.name}{"\n"}{end}' 2>/dev/null || true
)"
for c in $containers; do
echo "--- logs current: $ns/$pod container=$c ---"
kubectl logs -n "$ns" "$pod" -c "$c" --tail=200 || true
echo "--- logs previous: $ns/$pod container=$c ---"
kubectl logs -n "$ns" "$pod" -c "$c" --previous --tail=200 || true
done
echo
done

not_ready="$(kubectl get release -A -o jsonpath='{range .items[?(@.status.phase!="READY")]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}' 2>/dev/null || true)"

if [ -z "$not_ready" ]; then
echo "All releases are READY."
ready=1
break
fi

echo "Releases not ready yet:"
echo "$not_ready"

scheduling_errors="$(
kubectl get events -A --field-selector reason=FailedScheduling --no-headers 2>/dev/null \
| grep -E 'Insufficient (cpu|memory)' || true
)"

if [ -n "$scheduling_errors" ]; then
echo "Detected insufficient CPU or memory in Kubernetes scheduling events."
echo "Treating this as a CI capacity limitation and exiting successfully."
echo "$scheduling_errors"
exit 0
fi

sleep "$interval_secs"
elapsed=$((elapsed + interval_secs))
done

if [ "$ready" -eq 1 ]; then
exit 0
fi

echo "Timed out waiting for READY releases after ${timeout_secs}s"
kubectl get release -A
kubectl get helmrelease -A || true
kubectl get jobs -A || true
echo "Last events log lines:"
tail -n 200 /tmp/kubectl-events.log || true

scheduling_errors="$(
kubectl get events -A --field-selector reason=FailedScheduling --no-headers 2>/dev/null \
| grep -E 'Insufficient (cpu|memory)' || true
)"

if [ -n "$scheduling_errors" ]; then
echo "Detected insufficient CPU or memory in Kubernetes scheduling events."
echo "Treating this as a CI capacity limitation and exiting successfully."
echo "$scheduling_errors"
exit 0
fi

exit 1
70 changes: 27 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,10 @@
[![Kubernetes](https://img.shields.io/badge/kubernetes-1.28+-blue.svg)](https://kubernetes.io/)
[![Kind](https://img.shields.io/badge/kind-latest-orange.svg)](https://kind.sigs.k8s.io/)&ensp;&ensp;
[![License Apache2](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)
<a href="https://okdp.io">
<img src="https://okdp.io/logos/okdp-notext.svg" height="20px" style="margin: 0 2px;" />
</a>

![OKDP UI Demo](https://raw.githubusercontent.com/OKDP/okdp-ui/main/docs/images/demo.gif)

OKDP Sandbox is a hands-on environment for deploying, testing, and exploring the [OKDP](https://okdp.io) ecosystem on a local Kubernetes cluster.

It provides a ready-to-use data platform environment that includes:
- Identity and access management (Keycloak)
- Object storage (SeaweedFS)
- Spark processing and monitoring (Spark Operator + Spark History Server)
- Workflow orchestration (Apache Airflow)
- Interactive data science workspaces (JupyterHub)
- Data visualization (Apache Superset)
- Platform management (OKDP Server & UI)
It provides a ready-to-use data platform environment covering identity, object storage, Spark processing, workflow orchestration, interactive notebooks, SQL querying, and visualization, running end to end on a local cluster. See [What is included](#what-is-included-in-the-sandbox) for the full component list.

## What is included in the sandbox?

Expand All @@ -33,19 +21,25 @@ The default OKDP sandbox deploys a complete local data-platform environment with
- Apache Superset for dashboards and visual analytics
- OKDP Server and OKDP UI for platform management

## Repository status
## Repository scope

This repository is now a lightweight entry point. The reusable deployment assets have been moved to dedicated repositories so they can evolve independently from the sandbox.
This repository owns the **single-cluster sandbox deployment**. It describes how to deploy the OKDP platform onto a local Kubernetes cluster and contains the deployment assets only:

The implementation assets previously owned by this repository were migrated as follows:
- `clusters/sandbox/flux/` : Flux bootstrap of the KuboCD controller (`kubocd.yaml`)
- `clusters/sandbox/releases/` : KuboCD `Release` manifests (what gets installed, which package tag, which parameters)
- `clusters/sandbox/contexts/` : the layered KuboCD `Context` files (`10-platform`, `20-provider`, `30-service`, `99-examples`)
- `docs/` : deployment guides (DNS, certificates)

| Asset | New owner | Reference |
|---|---|---|
| KuboCD packages, release definitions, context layers, package build and release automation | [`OKDP/platform-packages`](https://github.com/OKDP/platform-packages) | [`OKDP/platform-packages#1`](https://github.com/OKDP/platform-packages/pull/1), [`OKDP/okdp-sandbox#51`](https://github.com/OKDP/okdp-sandbox/issues/51) |
| Reusable utility Helm charts | [`OKDP/helm-charts-utilities`](https://github.com/OKDP/helm-charts-utilities) | [`OKDP/helm-charts-utilities#1`](https://github.com/OKDP/helm-charts-utilities/pull/1), [`OKDP/okdp-sandbox#52`](https://github.com/OKDP/okdp-sandbox/issues/52) |
| Notebooks, DAGs, and runnable examples | [`OKDP/okdp-examples`](https://github.com/OKDP/okdp-examples) | Examples repository |
The **packages themselves** (the KuboCD packages bundled as OCI artifacts) live in a dedicated repository and are consumed here from the registry. This repository never builds packages, it only deploys published ones.

As a result, this repository should no longer contain duplicated `.github/`, `clusters/`, or `packages/` directories.
| Concern | Owner |
|---|---|
| KuboCD packages (system and services), build and release automation | [`OKDP/platform-packages`](https://github.com/OKDP/platform-packages) |
| Reusable utility Helm charts | [`OKDP/helm-charts-utilities`](https://github.com/OKDP/helm-charts-utilities) |
| Notebooks, DAGs, and runnable examples | [`OKDP/okdp-examples`](https://github.com/OKDP/okdp-examples) |
| OKDP web UI | [`OKDP/okdp-ui`](https://github.com/OKDP/okdp-ui) |
| OKDP backend server (API) | [`OKDP/okdp-server`](https://github.com/OKDP/okdp-server) |
| Single-cluster sandbox deployment (this repository) | `OKDP/okdp-sandbox` |

## Prerequisites

Expand All @@ -59,17 +53,17 @@ As a result, this repository should no longer contain duplicated `.github/`, `cl
- [Docker](https://docs.docker.com/get-docker/) or a compatible container runtime
- [Kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation)
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
- [Flux CLI](https://fluxcd.io/flux/installation/)
- [Flux CLI v2.7.5](https://fluxcd.io/flux/installation/)

## Quick start

The maintained sandbox deployment files now live in [`OKDP/platform-packages`](https://github.com/OKDP/platform-packages).
The sandbox deployment files live in this repository under `clusters/sandbox/`.

### 1. Clone the platform packages repository
### 1. Clone this repository

```sh
git clone https://github.com/OKDP/platform-packages.git
cd platform-packages
git clone https://github.com/OKDP/okdp-sandbox.git
cd okdp-sandbox
```

### 2. Create Kubernetes Kind Cluster
Expand Down Expand Up @@ -213,7 +207,7 @@ kubectl wait --for=condition=ready pod -l app=source-controller -n flux-system -
> It manages platform components and applications **declaratively**, providing a higher-level CD abstraction for GitOps workflows.

```sh
kubectl apply -f kubocd.yaml
kubectl apply -f clusters/sandbox/flux/kubocd.yaml
```

#### Deploy/Upgrade OKDP platform components
Expand Down Expand Up @@ -262,10 +256,10 @@ Deploy/Upgrade the sandbox default context:


```sh
kubectl apply -f 10-platform-context.yaml
kubectl apply -f 20-provider-context.yaml
kubectl apply -f 30-service-context.yaml
kubectl apply -f 99-examples-context.yaml
kubectl apply -f clusters/sandbox/contexts/10-platform-context.yaml
kubectl apply -f clusters/sandbox/contexts/20-provider-context.yaml
kubectl apply -f clusters/sandbox/contexts/30-service-context.yaml
kubectl apply -f clusters/sandbox/contexts/99-examples-context.yaml
```

> 💡 By default, the **default Context** uses **okdp.sandbox** as the ingress domain suffix.
Expand Down Expand Up @@ -316,7 +310,7 @@ spec:
Deploy/Upgrade OKDP components:

```sh
kubectl apply -f releases/
kubectl apply -f clusters/sandbox/releases/
```

#### Verify and monitor release deployment status
Expand Down Expand Up @@ -392,16 +386,6 @@ Remove-Item "$env:TEMP\okdp-sandbox-config.yaml" -Force

</details>

## Related repositories

| Repository | Purpose |
|---|---|
| [`OKDP/platform-packages`](https://github.com/OKDP/platform-packages) | KuboCD packages, release definitions, context layers, and deployment assets |
| [`OKDP/helm-charts-utilities`](https://github.com/OKDP/helm-charts-utilities) | Reusable utility Helm charts consumed by packages and examples |
| [`OKDP/okdp-examples`](https://github.com/OKDP/okdp-examples) | Notebooks, DAGs, and data-platform examples |
| [`OKDP/okdp-ui`](https://github.com/OKDP/okdp-ui) | OKDP web UI |
| [`OKDP/okdp-server`](https://github.com/OKDP/okdp-server) | OKDP backend server |

## License

This project is licensed under the [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).
Expand Down
Loading
Loading