apiVersion: apps/v1 kind: Deployment metadata: name: openclaw namespace: openclaw labels: app.kubernetes.io/name: openclaw spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: openclaw template: metadata: labels: app.kubernetes.io/name: openclaw spec: serviceAccountName: openclaw initContainers: - name: secret-injector image: default-route-openshift-image-registry.apps.lab.apilab.us/openclaw/openclaw:latest command: ["/bin/sh", "-c"] args: - | set -e JS=/home/node/.openclaw/openclaw.json GATEWAY_TOKEN=$(cat /run/secrets/gateway-token/token) HOOKS_TOKEN=$(cat /run/secrets/hooks-token/token) TELEGRAM_BOT_TOKEN=$(cat /run/secrets/telegram-bot-token/token) # Bootstrap a minimal config if none exists yet if [ ! -f $JS ]; then node /app/openclaw.mjs onboard --non-interactive --accept-risk \ --gateway-port 18789 --gateway-bind lan \ --skip-daemon --skip-channels --skip-skills --skip-health --skip-ui fi # Patch openclaw.json with tokens sourced from OCP secrets node -e " const fs = require('fs'); const gatewayToken = '$GATEWAY_TOKEN'; const hooksToken = '$HOOKS_TOKEN'; const telegramBotToken = '$TELEGRAM_BOT_TOKEN'; const d = JSON.parse(fs.readFileSync('$JS', 'utf8')); // Gateway token (env var) d.gateway = d.gateway || {}; d.gateway.token = gatewayToken; // Hooks token + mappings (idempotent) if (!d.hooks || !d.hooks.token) { d.hooks = { enabled: true, path: '/hooks', token: hooksToken, allowRequestSessionKey: false, mappings: [ { id: 'ocp-alerts', match: { path: '/ocp-alerts' }, action: 'agent', name: 'OCP Alerts', sessionKey: 'hook:ocp-alerts', messageTemplate: 'You are an OCP cluster alert analyst for a Single Node OpenShift lab. An alert has fired. Compose a brief narrative notification and reply with ONLY the notification text — no preamble, no markdown, no tool calls.\n\nAlert details:\n- Name: {{groupLabels.alertname}}\n- Namespace: {{commonLabels.namespace}}\n- Severity: {{commonLabels.severity}}\n- Status: {{status}}\n- Summary: {{commonAnnotations.summary}}\n\nRules:\n1. If alertname contains \'Watchdog\': reply NO_REPLY and nothing else.\n2. Classify and write one of:\n - ACTIONABLE firing: \"🔴 [pod/component] is [what\'s wrong] in [namespace]. [One sentence likely cause]. Would you like me to take action?\"\n - RESOLVED: \"✅ Good news — [what] in [namespace] has resolved.\"\n - INFORMATIONAL: \"â„šī¸ Heads up — [brief narrative].\"\n3. Plain text only. No bullet points. No markdown. Under 3 sentences.', deliver: true, allowUnsafeExternalContent: true, channel: 'telegram', to: '6479169830', model: 'haiku', timeoutSeconds: 60 } ] }; } // Telegram bot token d.channels = d.channels || {}; d.channels.telegram = d.channels.telegram || {}; d.channels.telegram.botToken = telegramBotToken; d.channels.telegram.enabled = true; fs.writeFileSync('$JS', JSON.stringify(d, null, 2)); " echo "secret-injector: openclaw.json patched from OCP secrets" volumeMounts: - name: home mountPath: /home/node env: - name: TZ value: "Australia/Sydney" resources: requests: cpu: "10m" memory: "32Mi" limits: cpu: "100m" memory: "64Mi" securityContext: runAsUser: 1000950000 runAsNonRoot: true allowPrivilegeEscalation: false readOnlyRootFilesystem: false containers: - name: openclaw image: default-route-openshift-image-registry.apps.lab.apilab.us/openclaw/openclaw:latest imagePullPolicy: Always command: ["/bin/sh", "-c"] args: - | set -e if [ ! -f ~/.openclaw/openclaw.json ]; then node /app/openclaw.mjs onboard --non-interactive --accept-risk \ --gateway-port 18789 --gateway-bind lan \ --skip-daemon --skip-channels --skip-skills --skip-health --skip-ui fi exec node /app/openclaw.mjs gateway --port 18789 --bind lan ports: - name: gateway containerPort: 18789 protocol: TCP env: - name: PATH value: /home/node/.openclaw/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - name: HOME value: /home/node - name: NPM_CONFIG_CACHE value: /tmp/npm-cache - name: XDG_CACHE_HOME value: /tmp - name: TZ value: "Australia/Sydney" - name: NODE_OPTIONS value: "--dns-result-order=ipv4first --no-network-family-autoselection --import /home/node/canvas-patch.mjs" - name: OPENCLAW_GATEWAY_TOKEN valueFrom: secretKeyRef: name: gateway-token key: token - name: GITHUB_TOKEN valueFrom: secretKeyRef: name: github key: pat - name: DISCORD_BOT_TOKEN valueFrom: secretKeyRef: name: discord key: token - name: MINIMAX_TOKEN valueFrom: secretKeyRef: name: minimax key: token volumeMounts: - name: home mountPath: /home/node - name: tmp mountPath: /tmp volumes: - name: home persistentVolumeClaim: claimName: openclaw-home - name: tmp emptyDir: {}