master
Marius Ensrud 4 months ago
parent b6caa6e7d4
commit 313ae786c3
No known key found for this signature in database

@ -0,0 +1,13 @@
# Patterns to ignore when building packages.
.DS_Store
*.swp
*.bak
*.tmp
*.orig
*~
.git
.gitignore
.project
.idea
*.tmproj
.vscode

@ -0,0 +1,18 @@
apiVersion: v2
name: openclaw-mission-control
description: Mission Control web UI for managing OpenClaw projects and workspaces
type: application
version: 0.1.0
appVersion: "latest"
keywords:
- openclaw
- mission-control
- ai
- project-management
home: https://github.com/openclaw/openclaw
sources:
- https://github.com/openclaw/openclaw
maintainers:
- name: Openclaw Team
url: https://docs.clawd.bot
icon: https://github.com/openclaw/openclaw/raw/main/README-header.png

@ -0,0 +1,23 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- if .Values.ingress.domain }}
http{{ if .Values.ingress.tls.enabled }}s{{ end }}://{{ .Values.ingress.domain }}
{{- else }}
{{- range .Values.ingress.hosts }}
http{{ if $.Values.ingress.tls.enabled }}s{{ end }}://{{ .host }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "openclaw-mission-control.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "openclaw-mission-control.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else }}
kubectl --namespace {{ .Release.Namespace }} port-forward svc/{{ include "openclaw-mission-control.fullname" . }} 4000:{{ .Values.service.port }}
echo "Visit http://127.0.0.1:4000"
{{- end }}
2. To connect to an OpenClaw gateway, set the OPENCLAW_GATEWAY_URL environment variable:
helm upgrade {{ .Release.Name }} openclaw-mission-control --set env.OPENCLAW_GATEWAY_URL=ws://your-openclaw-service:18789

@ -0,0 +1,82 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "openclaw-mission-control.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "openclaw-mission-control.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "openclaw-mission-control.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "openclaw-mission-control.labels" -}}
helm.sh/chart: {{ include "openclaw-mission-control.chart" . }}
{{ include "openclaw-mission-control.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "openclaw-mission-control.selectorLabels" -}}
app.kubernetes.io/name: {{ include "openclaw-mission-control.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "openclaw-mission-control.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "openclaw-mission-control.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create the image name
*/}}
{{- define "openclaw-mission-control.image" -}}
{{- if .Values.image.registry }}
{{- printf "%s/%s:%s" .Values.image.registry .Values.image.repository (.Values.image.tag | default .Chart.AppVersion) }}
{{- else }}
{{- printf "%s:%s" .Values.image.repository (.Values.image.tag | default .Chart.AppVersion) }}
{{- end }}
{{- end }}
{{/*
Create the name of the env secret to use
*/}}
{{- define "openclaw-mission-control.envSecretName" -}}
{{- if .Values.envSecret.existingSecret }}
{{- .Values.envSecret.existingSecret }}
{{- else }}
{{- printf "%s-env" (include "openclaw-mission-control.fullname" .) }}
{{- end }}
{{- end }}

@ -0,0 +1,102 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "openclaw-mission-control.fullname" . }}
labels:
{{- include "openclaw-mission-control.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
strategy:
type: Recreate
selector:
matchLabels:
{{- include "openclaw-mission-control.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- if .Values.envSecret.create }}
annotations:
checksum/env-secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- end }}
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "openclaw-mission-control.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "openclaw-mission-control.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: mission-control
image: {{ include "openclaw-mission-control.image" . }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
{{- range $key, $value := .Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- with .Values.extraEnv }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- if or .Values.envSecret.create .Values.envSecret.existingSecret }}
envFrom:
- secretRef:
name: {{ include "openclaw-mission-control.envSecretName" . }}
{{- end }}
ports:
- name: http
containerPort: 4000
protocol: TCP
volumeMounts:
- name: data
mountPath: /app/data
- name: workspace
mountPath: /app/workspace
{{- if .Values.livenessProbe.enabled }}
livenessProbe:
{{- omit .Values.livenessProbe "enabled" | toYaml | nindent 12 }}
{{- end }}
{{- if .Values.readinessProbe.enabled }}
readinessProbe:
{{- omit .Values.readinessProbe "enabled" | toYaml | nindent 12 }}
{{- end }}
{{- if .Values.startupProbe.enabled }}
startupProbe:
{{- omit .Values.startupProbe "enabled" | toYaml | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
volumes:
- name: data
{{- if .Values.persistence.data.enabled }}
persistentVolumeClaim:
claimName: {{ include "openclaw-mission-control.fullname" . }}-data
{{- else }}
emptyDir: {}
{{- end }}
- name: workspace
{{- if .Values.persistence.workspace.enabled }}
persistentVolumeClaim:
claimName: {{ include "openclaw-mission-control.fullname" . }}-workspace
{{- else }}
emptyDir: {}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

@ -0,0 +1,62 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "openclaw-mission-control.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- $domain := .Values.ingress.domain -}}
{{- $tlsEnabled := .Values.ingress.tls.enabled -}}
{{- $tlsSecretName := .Values.ingress.tls.secretName | default (printf "%s-tls" $fullName) -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "openclaw-mission-control.labels" . | nindent 4 }}
annotations:
{{- if and $tlsEnabled .Values.ingress.tls.certManager.enabled }}
cert-manager.io/cluster-issuer: {{ .Values.ingress.tls.certManager.issuer | quote }}
{{- end }}
{{- with .Values.ingress.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if $tlsEnabled }}
tls:
- hosts:
{{- if $domain }}
- {{ $domain | quote }}
{{- end }}
{{- range .Values.ingress.hosts }}
- {{ .host | quote }}
{{- end }}
secretName: {{ $tlsSecretName }}
{{- end }}
rules:
{{- if $domain }}
- host: {{ $domain | quote }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- end }}
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}

@ -0,0 +1,51 @@
{{- if .Values.persistence.data.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "openclaw-mission-control.fullname" . }}-data
labels:
{{- include "openclaw-mission-control.labels" . | nindent 4 }}
{{- with .Values.persistence.data.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
accessModes:
- {{ .Values.persistence.data.accessMode }}
{{- if .Values.persistence.data.storageClass }}
storageClassName: {{ .Values.persistence.data.storageClass }}
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.data.size }}
{{- with .Values.persistence.data.selector }}
selector:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
---
{{- if .Values.persistence.workspace.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "openclaw-mission-control.fullname" . }}-workspace
labels:
{{- include "openclaw-mission-control.labels" . | nindent 4 }}
{{- with .Values.persistence.workspace.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
accessModes:
- {{ .Values.persistence.workspace.accessMode }}
{{- if .Values.persistence.workspace.storageClass }}
storageClassName: {{ .Values.persistence.workspace.storageClass }}
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.workspace.size }}
{{- with .Values.persistence.workspace.selector }}
selector:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

@ -0,0 +1,13 @@
{{- if .Values.envSecret.create -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "openclaw-mission-control.envSecretName" . }}
labels:
{{- include "openclaw-mission-control.labels" . | nindent 4 }}
type: Opaque
stringData:
{{- range $key, $value := .Values.envSecret.data }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- end }}

@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "openclaw-mission-control.fullname" . }}
labels:
{{- include "openclaw-mission-control.labels" . | nindent 4 }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "openclaw-mission-control.selectorLabels" . | nindent 4 }}

@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "openclaw-mission-control.serviceAccountName" . }}
labels:
{{- include "openclaw-mission-control.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

@ -0,0 +1,162 @@
# Default values for openclaw-mission-control.
# This is a YAML-formatted file.
# Image configuration
image:
registry: ""
repository: mission-control
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
replicaCount: 1
# Service account
serviceAccount:
create: true
annotations: {}
name: ""
# Pod annotations
podAnnotations: {}
# Pod security context
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
# Container security context
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false
# Environment variables
env:
NODE_ENV: production
DATABASE_PATH: /app/data/mission-control.db
WORKSPACE_BASE_PATH: /app/workspace
PROJECTS_PATH: /app/workspace/projects
# Set this to connect to an OpenClaw gateway:
# OPENCLAW_GATEWAY_URL: ws://openclaw:18789
# Extra environment variables from secrets or configmaps
extraEnv: []
# - name: SECRET_KEY
# valueFrom:
# secretKeyRef:
# name: my-secret
# key: secret-key
# Extra environment variables from .env file style secret
envSecret:
# Create a secret from key-value pairs
create: false
# Use an existing secret
existingSecret: ""
# Secret data (only used if create is true)
data: {}
# MY_VAR: "my-value"
# Persistence for data volume (/app/data - SQLite database)
persistence:
data:
enabled: true
storageClass: ""
accessMode: ReadWriteOnce
size: 1Gi
annotations: {}
selector: {}
# Persistence for workspace volume (/app/workspace - projects)
workspace:
enabled: true
storageClass: ""
accessMode: ReadWriteOnce
size: 5Gi
annotations: {}
selector: {}
# Service configuration
service:
type: ClusterIP
port: 4000
annotations: {}
# Ingress configuration
ingress:
enabled: false
className: nginx
# Simplified domain configuration
domain: "" # e.g., "mission-control.yourdomain.com"
# TLS configuration
tls:
enabled: false
secretName: ""
certManager:
enabled: false
issuer: "letsencrypt-prod"
annotations: {}
# Advanced: Manual host configuration (overrides domain if set)
hosts: []
# Resource limits/requests
resources:
limits:
memory: 512Mi
cpu: 500m
requests:
memory: 128Mi
cpu: 100m
# Node selector
nodeSelector: {}
# Tolerations
tolerations: []
# Affinity rules
affinity: {}
# Probes
livenessProbe:
enabled: true
httpGet:
path: /
port: http
initialDelaySeconds: 15
periodSeconds: 20
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
enabled: true
httpGet:
path: /
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
startupProbe:
enabled: true
httpGet:
path: /
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 12 # 60 seconds max startup time
Loading…
Cancel
Save