From 3b6005b4fdd6910db777c52dd3aa64495dc8cdd4 Mon Sep 17 00:00:00 2001 From: fchinembiri Date: Thu, 23 Apr 2026 22:14:31 +0200 Subject: [PATCH] Restructure k8s manifests for GitOps alignment in k8s/base/ --- apps/web/src/MapComponent.tsx | 46 +++++++++++++++++++---- k8s/{ => base}/10-redis.yaml | 0 k8s/{ => base}/20-minio.yaml | 0 k8s/{ => base}/25-tiler.yaml | 0 k8s/{ => base}/26-tiler-ingress.yaml | 0 k8s/{ => base}/40-web.yaml | 0 k8s/{ => base}/60-ingress-minio.yaml | 0 k8s/{ => base}/80-api.yaml | 0 k8s/{ => base}/90-worker.yaml | 0 k8s/{ => base}/geocrop-tiler-rewrite.yaml | 0 k8s/{ => base}/geocrop-web-ingress.yaml | 0 k8s/base/kustomization.yaml | 18 +++++++++ terraform/main.tf | 12 +++++- terraform/terraform.tfstate | 37 +++++++++++++++++- 14 files changed, 102 insertions(+), 11 deletions(-) rename k8s/{ => base}/10-redis.yaml (100%) rename k8s/{ => base}/20-minio.yaml (100%) rename k8s/{ => base}/25-tiler.yaml (100%) rename k8s/{ => base}/26-tiler-ingress.yaml (100%) rename k8s/{ => base}/40-web.yaml (100%) rename k8s/{ => base}/60-ingress-minio.yaml (100%) rename k8s/{ => base}/80-api.yaml (100%) rename k8s/{ => base}/90-worker.yaml (100%) rename k8s/{ => base}/geocrop-tiler-rewrite.yaml (100%) rename k8s/{ => base}/geocrop-web-ingress.yaml (100%) create mode 100644 k8s/base/kustomization.yaml diff --git a/apps/web/src/MapComponent.tsx b/apps/web/src/MapComponent.tsx index d39408f..822a038 100644 --- a/apps/web/src/MapComponent.tsx +++ b/apps/web/src/MapComponent.tsx @@ -26,13 +26,15 @@ const DW_CLASSES = [ interface MapComponentProps { onCoordsSelected: (lat: number, lon: number) => void; resultUrl?: string; + baselineUrl?: string; // New: Immediate Dynamic World baseline roi?: { lat: number, lon: number, radius_m: number }; } -const MapComponent: React.FC = ({ onCoordsSelected, resultUrl, roi }) => { +const MapComponent: React.FC = ({ onCoordsSelected, resultUrl, baselineUrl, roi }) => { const mapRef = useRef(null); const mapInstance = useRef(null); const [activeResultLayer, setActiveResultLayer] = useState | null>(null); + const [activeBaselineLayer, setActiveBaselineLayer] = useState | null>(null); useEffect(() => { if (!mapRef.current) return; @@ -62,17 +64,40 @@ const MapComponent: React.FC = ({ onCoordsSelected, resultUrl }; }, []); - // Handle Result Layer and Zoom + // Handle Baseline Layer (Instant Feedback) + useEffect(() => { + if (!mapInstance.current || !baselineUrl) return; + + if (activeBaselineLayer) { + mapInstance.current.removeLayer(activeBaselineLayer); + } + + const newBaseline = new TileLayer({ + source: new XYZ({ + url: `${TITILER_ENDPOINT}/cog/tiles/{z}/{x}/{y}?url=${baselineUrl}`, + }), + opacity: 0.7, // Slightly transparent to differentiate from prediction + }); + + // Insert baseline below the prediction layer if it exists + const layers = mapInstance.current.getLayers(); + if (activeResultLayer) { + layers.insertAt(1, newBaseline); + } else { + mapInstance.current.addLayer(newBaseline); + } + + setActiveBaselineLayer(newBaseline); + }, [baselineUrl]); + + // Handle Result Layer (ML Prediction) useEffect(() => { if (!mapInstance.current || !resultUrl) return; - // Remove existing result layer if any if (activeResultLayer) { mapInstance.current.removeLayer(activeResultLayer); } - // Add new result layer - // Format: TITILER/cog/tiles/{z}/{x}/{y}?url=S3_URL const newLayer = new TileLayer({ source: new XYZ({ url: `${TITILER_ENDPOINT}/cog/tiles/{z}/{x}/{y}?url=${resultUrl}`, @@ -96,18 +121,18 @@ const MapComponent: React.FC = ({ onCoordsSelected, resultUrl
- {/* Map Legend */} + {/* Legend & Controls Overlay */}

Class Legend

{DW_CLASSES.map(cls => ( @@ -122,6 +147,11 @@ const MapComponent: React.FC = ({ onCoordsSelected, resultUrl {cls.name}
))} + +
+ {activeBaselineLayer && !activeResultLayer && "⏳ Loading ML inference..."} + {activeResultLayer && "✅ ML prediction active"} +
); diff --git a/k8s/10-redis.yaml b/k8s/base/10-redis.yaml similarity index 100% rename from k8s/10-redis.yaml rename to k8s/base/10-redis.yaml diff --git a/k8s/20-minio.yaml b/k8s/base/20-minio.yaml similarity index 100% rename from k8s/20-minio.yaml rename to k8s/base/20-minio.yaml diff --git a/k8s/25-tiler.yaml b/k8s/base/25-tiler.yaml similarity index 100% rename from k8s/25-tiler.yaml rename to k8s/base/25-tiler.yaml diff --git a/k8s/26-tiler-ingress.yaml b/k8s/base/26-tiler-ingress.yaml similarity index 100% rename from k8s/26-tiler-ingress.yaml rename to k8s/base/26-tiler-ingress.yaml diff --git a/k8s/40-web.yaml b/k8s/base/40-web.yaml similarity index 100% rename from k8s/40-web.yaml rename to k8s/base/40-web.yaml diff --git a/k8s/60-ingress-minio.yaml b/k8s/base/60-ingress-minio.yaml similarity index 100% rename from k8s/60-ingress-minio.yaml rename to k8s/base/60-ingress-minio.yaml diff --git a/k8s/80-api.yaml b/k8s/base/80-api.yaml similarity index 100% rename from k8s/80-api.yaml rename to k8s/base/80-api.yaml diff --git a/k8s/90-worker.yaml b/k8s/base/90-worker.yaml similarity index 100% rename from k8s/90-worker.yaml rename to k8s/base/90-worker.yaml diff --git a/k8s/geocrop-tiler-rewrite.yaml b/k8s/base/geocrop-tiler-rewrite.yaml similarity index 100% rename from k8s/geocrop-tiler-rewrite.yaml rename to k8s/base/geocrop-tiler-rewrite.yaml diff --git a/k8s/geocrop-web-ingress.yaml b/k8s/base/geocrop-web-ingress.yaml similarity index 100% rename from k8s/geocrop-web-ingress.yaml rename to k8s/base/geocrop-web-ingress.yaml diff --git a/k8s/base/kustomization.yaml b/k8s/base/kustomization.yaml new file mode 100644 index 0000000..ab10c76 --- /dev/null +++ b/k8s/base/kustomization.yaml @@ -0,0 +1,18 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - gitea.yaml + - jupyter.yaml + - mlflow.yaml + - postgres-postgis.yaml + - 10-redis.yaml + - 20-minio.yaml + - 25-tiler.yaml + - 26-tiler-ingress.yaml + - 40-web.yaml + - 80-api.yaml + - 90-worker.yaml + - geocrop-web-ingress.yaml + - geocrop-tiler-rewrite.yaml + - 60-ingress-minio.yaml diff --git a/terraform/main.tf b/terraform/main.tf index 8f58db9..e79faf3 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -11,11 +11,19 @@ provider "kubernetes" { config_path = "/etc/rancher/k3s/k3s.yaml" } +# Core application namespace resource "kubernetes_namespace" "geocrop" { metadata { name = "geocrop" } } -# Note: Resource quotas are intentionally omitted here and will be managed dynamically -# based on cluster telemetry to allow MLflow and Argo to consume available resources. +# GitOps management namespace +resource "kubernetes_namespace" "argocd" { + metadata { + name = "argocd" + } +} + +# Note: Resource quotas are intentionally omitted for now +# to allow heavy MLOps processes (Jupyter/MLflow) to use available cluster RAM. diff --git a/terraform/terraform.tfstate b/terraform/terraform.tfstate index b829918..e204f4f 100644 --- a/terraform/terraform.tfstate +++ b/terraform/terraform.tfstate @@ -1,10 +1,45 @@ { "version": 4, "terraform_version": "1.14.9", - "serial": 1, + "serial": 2, "lineage": "80e41663-9b90-f349-cc6c-be6879179605", "outputs": {}, "resources": [ + { + "mode": "managed", + "type": "kubernetes_namespace", + "name": "argocd", + "provider": "provider[\"registry.terraform.io/hashicorp/kubernetes\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "argocd", + "metadata": [ + { + "annotations": {}, + "generate_name": "", + "generation": 0, + "labels": {}, + "name": "argocd", + "resource_version": "3078893", + "uid": "9e556e04-d31e-4f3f-9968-abe3fa1d9362" + } + ], + "timeouts": null, + "wait_for_default_service_account": null + }, + "sensitive_attributes": [], + "identity_schema_version": 1, + "identity": { + "api_version": "v1", + "kind": "Namespace", + "name": "argocd" + }, + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiZGVsZXRlIjozMDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjAifQ==" + } + ] + }, { "mode": "managed", "type": "kubernetes_namespace",