diff --git a/cluster_analytics/src/cluster_analytics.py b/cluster_analytics/src/cluster_analytics.py index ba0be9745..4cb90eb15 100644 --- a/cluster_analytics/src/cluster_analytics.py +++ b/cluster_analytics/src/cluster_analytics.py @@ -21,11 +21,11 @@ def build_argparser(): # WebUI is disabled by default, can be enabled via flag parser.add_argument("--webui", action="store_true", default=False, - help="enable WebUI on port 5000 (default: disabled, can be enabled via flag)") + help="enable WebUI on port 9443 (default: disabled, can be enabled via flag)") parser.add_argument("--no-webui", dest="webui", action="store_false", help="disable WebUI") - parser.add_argument("--webui-port", type=int, default=5000, - help="WebUI port (default: 5000)") + parser.add_argument("--webui-port", type=int, default=9443, + help="WebUI port (default: 9443)") parser.add_argument("--webui-certfile", help="path to SSL certificate file for HTTPS WebUI (required when WebUI is enabled)") parser.add_argument("--webui-keyfile", diff --git a/cluster_analytics/src/cluster_analytics_context.py b/cluster_analytics/src/cluster_analytics_context.py index 761597d7b..8908688a4 100644 --- a/cluster_analytics/src/cluster_analytics_context.py +++ b/cluster_analytics/src/cluster_analytics_context.py @@ -89,7 +89,7 @@ def __init__(self, config_path=None): self.ARCHIVE_TIME_THRESHOLD = archival_config.get('archive_time_threshold', 5.0) class ClusterAnalyticsContext: - def __init__(self, broker, broker_auth, cert, root_cert, enable_webui=True, webui_port=5000, webui_certfile=None, webui_keyfile=None): + def __init__(self, broker, broker_auth, cert, root_cert, enable_webui=True, webui_port=9443, webui_certfile=None, webui_keyfile=None): self.config = ClusterAnalyticsConfig() self.webui_port = webui_port self.webui_certfile = webui_certfile diff --git a/cluster_analytics/tools/webui/README.md b/cluster_analytics/tools/webui/README.md index 8c08f152d..79c895996 100644 --- a/cluster_analytics/tools/webui/README.md +++ b/cluster_analytics/tools/webui/README.md @@ -17,7 +17,7 @@ cd /path/to/scenescape SUPASS=admin123 make demo ``` -After enabling, access the WebUI at: **https://localhost:5000** +After enabling, access the WebUI at: **https://localhost:9443** ## ⚠️ Important Note @@ -38,7 +38,7 @@ The WebUI is **disabled by default** in `docker-compose.yml`. To enable it, **un # ... other config ... # Uncomment the following lines to enable WebUI: ports: # ✅ Uncomment this line - - "5000:5000" # ✅ Uncomment this line + - "9443:9443" # ✅ Uncomment this line ``` 2. **Uncomment the WebUI command flags:** @@ -77,7 +77,7 @@ If you want to **disable** the WebUI again, **comment out** these lines in `dock ```yaml # ports: - # - "5000:5000" # ❌ Port not exposed + # - "9443:9443" # ❌ Port not exposed ``` 2. **Comment out the WebUI command flags:** @@ -118,22 +118,22 @@ docker compose logs cluster-analytics | grep -i webui # Expected output: # "WebUI initialized successfully" -# "WebUI server started on https://0.0.0.0:5000" +# "WebUI server started on https://0.0.0.0:9443" # Test WebUI endpoint -curl -k https://localhost:5000 +curl -k https://localhost:9443 ``` ## 🌐 Accessing the WebUI -- **URL**: https://localhost:5000 +- **URL**: https://localhost:9443 - **Protocol**: HTTPS only (uses SSL certificates) ## 🛠️ Troubleshooting **WebUI not accessible?** -- Ensure port 5000 is not blocked by firewall +- Ensure port 9443 is not blocked by firewall - Check that SSL certificates are properly mounted - Verify the `--webui` flag is uncommented in docker-compose.yml diff --git a/cluster_analytics/tools/webui/web_ui.py b/cluster_analytics/tools/webui/web_ui.py index 1c811edca..70f615725 100644 --- a/cluster_analytics/tools/webui/web_ui.py +++ b/cluster_analytics/tools/webui/web_ui.py @@ -500,7 +500,7 @@ def updateSceneClusters(self, sceneId, clusters): # Schedule throttled update self.scheduleThrottledUpdate() - def run(self, host='0.0.0.0', port=5000, debug=False, certfile=None, keyfile=None): + def run(self, host='0.0.0.0', port=9443, debug=False, certfile=None, keyfile=None): """Run the Flask-SocketIO server with HTTPS.""" if not certfile or not keyfile: raise ValueError("SSL certificate and key files are required for HTTPS") @@ -515,7 +515,7 @@ def run(self, host='0.0.0.0', port=5000, debug=False, certfile=None, keyfile=Non keyfile=keyfile ) - def runInThread(self, host='0.0.0.0', port=5000, certfile=None, keyfile=None): + def runInThread(self, host='0.0.0.0', port=9443, certfile=None, keyfile=None): """Run the Flask-SocketIO server in a separate thread using eventlet with HTTPS.""" if not certfile or not keyfile: raise ValueError("SSL certificate and key files are required for HTTPS") diff --git a/kubernetes/Makefile b/kubernetes/Makefile index 35f111447..f7e0ccc2e 100644 --- a/kubernetes/Makefile +++ b/kubernetes/Makefile @@ -4,6 +4,9 @@ IMAGE=scenescape-manager CAMCALIBIMAGE=scenescape-camcalibration CONTROLLERIMAGE=scenescape-controller +# optional image for cluster analytics component +CLUSTERANALYTICSIMAGE=scenescape-cluster-analytics + VERSION:=$(shell cat ../version.txt) NAMESPACE=scenescape WORKINGDIR=$(shell dirname $(shell pwd)) @@ -151,6 +154,10 @@ push: docker tag $(ORGANIZATION)$(CONTROLLERIMAGE):$(VERSION) $(REGISTRY)/$(CONTROLLERIMAGE):$(VERSION) docker push $(REGISTRY)/$(CONTROLLERIMAGE):$(VERSION) +push-all: push + docker tag $(ORGANIZATION)$(CLUSTERANALYTICSIMAGE):$(VERSION) $(REGISTRY)/$(CLUSTERANALYTICSIMAGE):$(VERSION) + docker push $(REGISTRY)/$(CLUSTERANALYTICSIMAGE):$(VERSION) + # generate Chart.yaml with appropriate version.txt chart.yaml: sed -e "s|{VERSION}|$(VERSION)|g" template/Chart.template > scenescape-chart/Chart.yaml diff --git a/kubernetes/scenescape-chart/templates/cluster-analytics/deployment.yaml b/kubernetes/scenescape-chart/templates/cluster-analytics/deployment.yaml new file mode 100644 index 000000000..a61db86c0 --- /dev/null +++ b/kubernetes/scenescape-chart/templates/cluster-analytics/deployment.yaml @@ -0,0 +1,71 @@ + +# SPDX-FileCopyrightText: (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +{{- if .Values.clusterAnalytics.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-cluster-analytics + labels: + app: {{ .Release.Name }}-cluster-analytics +spec: + replicas: 1 + selector: + matchLabels: + app: {{ .Release.Name }}-cluster-analytics + template: + metadata: + labels: + app: {{ .Release.Name }}-cluster-analytics + spec: + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + containers: + - name: cluster-analytics + image: {{ .Values.repository }}/{{ .Values.clusterAnalytics.image }}:{{ .Chart.AppVersion }} + args: + - "--broker" + - "broker.{{ .Release.Namespace }}.svc.cluster.local" + - "--brokerauth" + - "/run/secrets/controller.auth" + {{- if .Values.clusterAnalytics.webUI.enabled }} + - "--webui" + - "--webui-certfile" + - "/run/secrets/certs/scenescape-web.crt" + - "--webui-keyfile" + - "/run/secrets/certs/scenescape-web.key" + ports: + - containerPort: 9443 + {{- end }} + securityContext: + {{ include "defaultContainerSecurityContext" . | indent 12 }} + runAsUser: 1000 + runAsGroup: 1000 + volumeMounts: + - name: certs + mountPath: /run/secrets/certs/scenescape-ca.pem + subPath: scenescape-ca.pem + readOnly: true + - name: controller-auth + mountPath: /run/secrets/controller.auth + subPath: controller.auth + readOnly: true + {{- if .Values.clusterAnalytics.webUI.enabled }} + - name: certs + mountPath: /run/secrets/certs/scenescape-web.crt + subPath: scenescape-web.crt + readOnly: true + - name: certs + mountPath: /run/secrets/certs/scenescape-web.key + subPath: scenescape-web.key + readOnly: true + {{- end }} + volumes: + - name: controller-auth + secret: + secretName: {{ .Release.Name }}-controller.auth + {{- include "certs_volume" . | nindent 8 }} +{{- end }} diff --git a/kubernetes/scenescape-chart/templates/cluster-analytics/service.yaml b/kubernetes/scenescape-chart/templates/cluster-analytics/service.yaml new file mode 100644 index 000000000..408fba12d --- /dev/null +++ b/kubernetes/scenescape-chart/templates/cluster-analytics/service.yaml @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: (C) 2025 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +--- +{{- if .Values.clusterAnalytics.enabled }} +{{- if .Values.clusterAnalytics.webUI.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: cluster-analytics + annotations: {{- toYaml .Values.service.annotations | nindent 4 }} +spec: + selector: + app: {{ .Release.Name }}-cluster-analytics + ports: + - name: "9443" + protocol: TCP + port: 9443 + targetPort: 9443 +{{- if .Values.loadBalancer.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: cluster-analytics-lb + annotations: {{- toYaml .Values.loadBalancer.annotations | nindent 4 }} +spec: + type: LoadBalancer + selector: + app: {{ .Release.Name }}-cluster-analytics + ports: + - name: "9443" + protocol: TCP + port: 9443 + targetPort: 9443 + externalTrafficPolicy: {{ .Values.loadBalancer.externalTrafficPolicy }} + {{- if (default .Values.loadBalancer.loadBalancerIP false) }} + loadBalancerIP: {{ .Values.loadBalancer.loadBalancerIP }} + {{- end }} +{{- end }} +{{- if .Values.nodePort.enabled }} +--- +apiVersion: v1 +kind: Service +metadata: + name: cluster-analytics-np + annotations: {{- toYaml .Values.nodePort.annotations | nindent 4 }} +spec: + type: NodePort + selector: + app: {{ .Release.Name }}-cluster-analytics + ports: + - name: "9443" + protocol: TCP + port: 9443 +{{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes/scenescape-chart/values.yaml b/kubernetes/scenescape-chart/values.yaml index 5c42d4566..fd1297983 100644 --- a/kubernetes/scenescape-chart/values.yaml +++ b/kubernetes/scenescape-chart/values.yaml @@ -28,27 +28,33 @@ initModels: limits: memory: "2Gi" cpu: "1000m" + ntpserv: image: dockurr/chrony ntpServers: "0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org,3.pool.ntp.org" + broker: image: eclipse-mosquitto tag: "2.0.22" uid: 1000 gid: 1000 + pgserver: image: postgres tag: 17.6 repository: "docker.io" storage: 500Mi password: "" + web: image: scenescape-manager + scene: image: scenescape-controller + camcalibration: image: scenescape-camcalibration -# percebro - deprecated # TODO update kubeclient code to restore the dynamic camera calibration + kubeclient: enabled: true image: scenescape-manager @@ -56,6 +62,7 @@ kubeclient: repository: docker.io image: intel/dlstreamer-pipeline-server tag: "3.1.0-ubuntu24" + retail: repository: docker.io/intel/dlstreamer-pipeline-server pullPolicy: IfNotPresent @@ -67,6 +74,7 @@ retail: files: - apriltag-cam1.ts - apriltag-cam2.ts + queuing: repository: docker.io/intel/dlstreamer-pipeline-server pullPolicy: IfNotPresent @@ -78,17 +86,26 @@ queuing: files: - qcam1.ts - qcam2.ts + mediaserver: image: bluenviron/mediamtx tag: "1.14.0" + video: image: scenescape # models storage size storage: 50Gi storageClassName: "" + vdms: enabled: true +clusterAnalytics: + enabled: false + image: scenescape-cluster-analytics + webUI: + enabled: false + # media folder pvc details media: storage: 500Mi @@ -99,12 +116,6 @@ datasets: storage: 500Mi storageClassName: "" -# videos -videos: - storage: 2Gi - storageClassName: "" - -# sample_data sampleData: source: https://raw.githubusercontent.com/open-edge-platform/scenescape sourceDir: sample_data @@ -142,16 +153,6 @@ migrations: storage: 100Mi storageClassName: "" -# controller -controller: - storage: 500Mi - storageClassName: "" - -# user-access-config -userAccessConfig: - storage: 50Mi - storageClassName: "" - # PVC pvc: storageClassName: "" @@ -189,9 +190,6 @@ mqttService: annotations: {} nodePort: 31883 -camcalibrationService: - annotations: {} - # Other parameters certdomain: "" supass: "" diff --git a/sample_data/docker-compose-dl-streamer-example.yml b/sample_data/docker-compose-dl-streamer-example.yml index 84e2c0335..fc2152278 100644 --- a/sample_data/docker-compose-dl-streamer-example.yml +++ b/sample_data/docker-compose-dl-streamer-example.yml @@ -447,7 +447,7 @@ services: networks: scenescape: # ports: - # - "5000:5000" + # - "9443:9443" command: > --broker broker.scenescape.intel.com --brokerauth /run/secrets/controller.auth