Restructure k8s manifests for GitOps alignment in k8s/base/
This commit is contained in:
parent
79093f7d3c
commit
3b6005b4fd
|
|
@ -26,13 +26,15 @@ const DW_CLASSES = [
|
||||||
interface MapComponentProps {
|
interface MapComponentProps {
|
||||||
onCoordsSelected: (lat: number, lon: number) => void;
|
onCoordsSelected: (lat: number, lon: number) => void;
|
||||||
resultUrl?: string;
|
resultUrl?: string;
|
||||||
|
baselineUrl?: string; // New: Immediate Dynamic World baseline
|
||||||
roi?: { lat: number, lon: number, radius_m: number };
|
roi?: { lat: number, lon: number, radius_m: number };
|
||||||
}
|
}
|
||||||
|
|
||||||
const MapComponent: React.FC<MapComponentProps> = ({ onCoordsSelected, resultUrl, roi }) => {
|
const MapComponent: React.FC<MapComponentProps> = ({ onCoordsSelected, resultUrl, baselineUrl, roi }) => {
|
||||||
const mapRef = useRef<HTMLDivElement>(null);
|
const mapRef = useRef<HTMLDivElement>(null);
|
||||||
const mapInstance = useRef<Map | null>(null);
|
const mapInstance = useRef<Map | null>(null);
|
||||||
const [activeResultLayer, setActiveResultLayer] = useState<TileLayer<XYZ> | null>(null);
|
const [activeResultLayer, setActiveResultLayer] = useState<TileLayer<XYZ> | null>(null);
|
||||||
|
const [activeBaselineLayer, setActiveBaselineLayer] = useState<TileLayer<XYZ> | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!mapRef.current) return;
|
if (!mapRef.current) return;
|
||||||
|
|
@ -62,17 +64,40 @@ const MapComponent: React.FC<MapComponentProps> = ({ 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(() => {
|
useEffect(() => {
|
||||||
if (!mapInstance.current || !resultUrl) return;
|
if (!mapInstance.current || !resultUrl) return;
|
||||||
|
|
||||||
// Remove existing result layer if any
|
|
||||||
if (activeResultLayer) {
|
if (activeResultLayer) {
|
||||||
mapInstance.current.removeLayer(activeResultLayer);
|
mapInstance.current.removeLayer(activeResultLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new result layer
|
|
||||||
// Format: TITILER/cog/tiles/{z}/{x}/{y}?url=S3_URL
|
|
||||||
const newLayer = new TileLayer({
|
const newLayer = new TileLayer({
|
||||||
source: new XYZ({
|
source: new XYZ({
|
||||||
url: `${TITILER_ENDPOINT}/cog/tiles/{z}/{x}/{y}?url=${resultUrl}`,
|
url: `${TITILER_ENDPOINT}/cog/tiles/{z}/{x}/{y}?url=${resultUrl}`,
|
||||||
|
|
@ -96,18 +121,18 @@ const MapComponent: React.FC<MapComponentProps> = ({ onCoordsSelected, resultUrl
|
||||||
<div style={{ position: 'relative', width: '100%', height: '100vh' }}>
|
<div style={{ position: 'relative', width: '100%', height: '100vh' }}>
|
||||||
<div ref={mapRef} style={{ width: '100%', height: '100%' }} />
|
<div ref={mapRef} style={{ width: '100%', height: '100%' }} />
|
||||||
|
|
||||||
{/* Map Legend */}
|
{/* Legend & Controls Overlay */}
|
||||||
<div style={{
|
<div style={{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
bottom: '30px',
|
bottom: '30px',
|
||||||
right: '20px',
|
right: '20px',
|
||||||
background: 'rgba(255, 255, 255, 0.9)',
|
background: 'rgba(255, 255, 255, 0.9)',
|
||||||
padding: '10px',
|
padding: '12px',
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
boxShadow: '0 2px 10px rgba(0,0,0,0.2)',
|
boxShadow: '0 2px 10px rgba(0,0,0,0.2)',
|
||||||
zIndex: 1000,
|
zIndex: 1000,
|
||||||
fontSize: '12px',
|
fontSize: '12px',
|
||||||
maxWidth: '150px'
|
maxWidth: '180px'
|
||||||
}}>
|
}}>
|
||||||
<h4 style={{ margin: '0 0 8px 0', fontSize: '13px', borderBottom: '1px solid #ddd', paddingBottom: '3px' }}>Class Legend</h4>
|
<h4 style={{ margin: '0 0 8px 0', fontSize: '13px', borderBottom: '1px solid #ddd', paddingBottom: '3px' }}>Class Legend</h4>
|
||||||
{DW_CLASSES.map(cls => (
|
{DW_CLASSES.map(cls => (
|
||||||
|
|
@ -122,6 +147,11 @@ const MapComponent: React.FC<MapComponentProps> = ({ onCoordsSelected, resultUrl
|
||||||
<span>{cls.name}</span>
|
<span>{cls.name}</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
<div style={{ marginTop: '10px', fontSize: '11px', color: '#666', fontStyle: 'italic' }}>
|
||||||
|
{activeBaselineLayer && !activeResultLayer && "⏳ Loading ML inference..."}
|
||||||
|
{activeResultLayer && "✅ ML prediction active"}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -11,11 +11,19 @@ provider "kubernetes" {
|
||||||
config_path = "/etc/rancher/k3s/k3s.yaml"
|
config_path = "/etc/rancher/k3s/k3s.yaml"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Core application namespace
|
||||||
resource "kubernetes_namespace" "geocrop" {
|
resource "kubernetes_namespace" "geocrop" {
|
||||||
metadata {
|
metadata {
|
||||||
name = "geocrop"
|
name = "geocrop"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Note: Resource quotas are intentionally omitted here and will be managed dynamically
|
# GitOps management namespace
|
||||||
# based on cluster telemetry to allow MLflow and Argo to consume available resources.
|
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.
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,45 @@
|
||||||
{
|
{
|
||||||
"version": 4,
|
"version": 4,
|
||||||
"terraform_version": "1.14.9",
|
"terraform_version": "1.14.9",
|
||||||
"serial": 1,
|
"serial": 2,
|
||||||
"lineage": "80e41663-9b90-f349-cc6c-be6879179605",
|
"lineage": "80e41663-9b90-f349-cc6c-be6879179605",
|
||||||
"outputs": {},
|
"outputs": {},
|
||||||
"resources": [
|
"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",
|
"mode": "managed",
|
||||||
"type": "kubernetes_namespace",
|
"type": "kubernetes_namespace",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue