fix: phase 0 quick wins — safety, naming, and portability
- Add helm.sh/resource-policy: keep to PVC (prevent data loss on uninstall) - Add fail guard for empty name value in Helm templates - Fix Makefile IMAGE_NAME from antigravity to devcontainer - Pin busybox:1.37, homeassistant:v6.7.1, playwright:v0.0.68 (was latest/stable) - Set imagePullPolicy: IfNotPresent on pinned sidecars - Remove fetch/sequentialthinking from .mcp.json (sidecars removed from chart) - Default storage.className to empty (use cluster default, was ceph-filesystem) - Default Happy Coder URLs to empty (was private farh.net endpoints) - Broaden githubRepo schema to accept GitLab/Gitea URLs - Add unknown IDE warning before VSCode fallback - Add mkdir -p before credential file write (fix fresh PVC boot) - Guard app user existence in cont-init-user.sh - Add NOTES.txt post-install template with port-forward and secret hints - Add standard app.kubernetes.io/* labels and separate selectorLabels Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -22,14 +22,6 @@
|
||||
"pgtuner": {
|
||||
"type": "sse",
|
||||
"url": "http://localhost:8085/sse"
|
||||
},
|
||||
"fetch": {
|
||||
"type": "sse",
|
||||
"url": "http://localhost:8082/sse"
|
||||
},
|
||||
"sequentialthinking": {
|
||||
"type": "sse",
|
||||
"url": "http://localhost:8083/sse"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Variables
|
||||
REGISTRY ?= ghcr.io/cpfarhood
|
||||
IMAGE_NAME ?= antigravity
|
||||
IMAGE_NAME ?= devcontainer
|
||||
IMAGE_TAG ?= latest
|
||||
FULL_IMAGE = $(REGISTRY)/$(IMAGE_NAME):$(IMAGE_TAG)
|
||||
|
||||
@@ -29,15 +29,15 @@ run:
|
||||
-e HAPPY_EXPERIMENTAL="true" \
|
||||
-v $(PWD)/home:/home \
|
||||
-v $(PWD)/workspace:/workspace \
|
||||
--name antigravity \
|
||||
--name devcontainer \
|
||||
$(FULL_IMAGE)
|
||||
@echo "Access at http://localhost:5800"
|
||||
|
||||
# Stop the running container
|
||||
stop:
|
||||
@echo "Stopping antigravity container..."
|
||||
docker stop antigravity || true
|
||||
docker rm antigravity || true
|
||||
@echo "Stopping devcontainer..."
|
||||
docker stop devcontainer || true
|
||||
docker rm devcontainer || true
|
||||
|
||||
# Clean up local volumes
|
||||
clean: stop
|
||||
@@ -81,7 +81,7 @@ helm-port-forward:
|
||||
|
||||
# Show help
|
||||
help:
|
||||
@echo "Antigravity Dev Container Makefile"
|
||||
@echo "Dev Container Makefile"
|
||||
@echo ""
|
||||
@echo "Usage: make [target]"
|
||||
@echo ""
|
||||
@@ -101,7 +101,7 @@ help:
|
||||
@echo ""
|
||||
@echo "Variables:"
|
||||
@echo " REGISTRY - Docker registry (default: ghcr.io/cpfarhood)"
|
||||
@echo " IMAGE_NAME - Image name (default: antigravity)"
|
||||
@echo " IMAGE_NAME - Image name (default: devcontainer)"
|
||||
@echo " IMAGE_TAG - Image tag (default: latest)"
|
||||
@echo " RELEASE_NAME - Helm release name (default: mydev)"
|
||||
@echo " NAMESPACE - Kubernetes namespace (default: default)"
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
Dev Container "{{ .Values.name }}" has been deployed.
|
||||
|
||||
{{- if ne (.Values.ide.type | default "vscode") "none" }}
|
||||
|
||||
Access the IDE:
|
||||
kubectl port-forward deployment/{{ include "devcontainer.fullname" . }} 5800:5800 -n {{ .Release.Namespace }}
|
||||
Then open: http://localhost:5800
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.ssh.enabled }}
|
||||
|
||||
SSH access:
|
||||
kubectl port-forward deployment/{{ include "devcontainer.fullname" . }} 2222:22 -n {{ .Release.Namespace }}
|
||||
Then: ssh -p 2222 user@localhost
|
||||
{{- end }}
|
||||
|
||||
Useful commands:
|
||||
Logs: kubectl logs -f deployment/{{ include "devcontainer.fullname" . }} -n {{ .Release.Namespace }}
|
||||
Shell: kubectl exec -it deployment/{{ include "devcontainer.fullname" . }} -n {{ .Release.Namespace }} -- bash
|
||||
|
||||
{{- if not (lookup "v1" "Secret" .Release.Namespace (include "devcontainer.envSecretName" .)) }}
|
||||
|
||||
Optional: Create a secret for GITHUB_TOKEN, VNC_PASSWORD, etc:
|
||||
kubectl create secret generic {{ include "devcontainer.envSecretName" . }} \
|
||||
--from-literal=GITHUB_TOKEN=ghp_xxx \
|
||||
--from-literal=VNC_PASSWORD=changeme \
|
||||
-n {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
|
||||
Note: The PVC "{{ include "devcontainer.pvcName" . }}" is protected from deletion on helm uninstall.
|
||||
To remove it manually: kubectl delete pvc {{ include "devcontainer.pvcName" . }} -n {{ .Release.Namespace }}
|
||||
@@ -2,6 +2,9 @@
|
||||
Resource name prefix: devcontainer-{name}
|
||||
*/}}
|
||||
{{- define "devcontainer.fullname" -}}
|
||||
{{- if not .Values.name }}
|
||||
{{- fail "values.name is required and must not be empty" }}
|
||||
{{- end }}
|
||||
{{- printf "devcontainer-%s" .Values.name }}
|
||||
{{- end }}
|
||||
|
||||
@@ -25,6 +28,18 @@ Common labels
|
||||
{{- define "devcontainer.labels" -}}
|
||||
app: devcontainer
|
||||
instance: {{ .Values.name }}
|
||||
app.kubernetes.io/name: devcontainer
|
||||
app.kubernetes.io/instance: {{ .Values.name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels — keep narrow since changing these requires recreating the Deployment
|
||||
*/}}
|
||||
{{- define "devcontainer.selectorLabels" -}}
|
||||
app: devcontainer
|
||||
instance: {{ .Values.name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
|
||||
@@ -8,7 +8,7 @@ spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "devcontainer.labels" . | nindent 6 }}
|
||||
{{- include "devcontainer.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
@@ -23,7 +23,7 @@ spec:
|
||||
{{- if and .Values.ide.type (eq .Values.ide.type "antigravity") }}
|
||||
initContainers:
|
||||
- name: setup-userdata
|
||||
image: busybox:latest
|
||||
image: busybox:1.37
|
||||
command: ['sh', '-c']
|
||||
args:
|
||||
- |
|
||||
@@ -169,7 +169,7 @@ spec:
|
||||
{{- if .Values.mcp.sidecars.homeassistant.enabled }}
|
||||
- name: homeassistant-mcp
|
||||
image: "{{ .Values.mcp.sidecars.homeassistant.image.repository }}:{{ .Values.mcp.sidecars.homeassistant.image.tag }}"
|
||||
imagePullPolicy: Always
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["fastmcp", "run", "--transport", "sse", "--host", "0.0.0.0", "--port", "{{ .Values.mcp.sidecars.homeassistant.port }}"]
|
||||
ports:
|
||||
- name: homeassistant
|
||||
@@ -203,7 +203,7 @@ spec:
|
||||
{{- if .Values.mcp.sidecars.pgtuner.enabled }}
|
||||
- name: pgtuner-mcp
|
||||
image: "{{ .Values.mcp.sidecars.pgtuner.image.repository }}:{{ .Values.mcp.sidecars.pgtuner.image.tag }}"
|
||||
imagePullPolicy: Always
|
||||
imagePullPolicy: Always # pgtuner uses `latest` tag (no versioned releases available)
|
||||
command: ["python", "-m", "pgtuner_mcp", "--mode", "sse", "--host", "0.0.0.0", "--port", "{{ .Values.mcp.sidecars.pgtuner.port }}"]
|
||||
ports:
|
||||
- name: pgtuner
|
||||
@@ -237,7 +237,7 @@ spec:
|
||||
{{- if .Values.mcp.sidecars.playwright.enabled }}
|
||||
- name: playwright-mcp
|
||||
image: "{{ .Values.mcp.sidecars.playwright.image.repository }}:{{ .Values.mcp.sidecars.playwright.image.tag }}"
|
||||
imagePullPolicy: Always
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["node"]
|
||||
args:
|
||||
- cli.js
|
||||
|
||||
@@ -2,12 +2,16 @@ apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "devcontainer.pvcName" . }}
|
||||
annotations:
|
||||
helm.sh/resource-policy: keep
|
||||
labels:
|
||||
{{- include "devcontainer.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteMany
|
||||
{{- if .Values.storage.className }}
|
||||
storageClassName: {{ .Values.storage.className }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.storage.size }}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"githubRepo": {
|
||||
"type": "string",
|
||||
"description": "GitHub repository URL to clone",
|
||||
"pattern": "^https://github\\.com/.+/.+$"
|
||||
"pattern": "^https?://.+/.+/.+$"
|
||||
},
|
||||
"ide": {
|
||||
"type": "object",
|
||||
@@ -108,7 +108,7 @@
|
||||
"description": "Storage class name (must support ReadWriteMany)"
|
||||
}
|
||||
},
|
||||
"required": ["size", "className"]
|
||||
"required": ["size"]
|
||||
},
|
||||
"resources": {
|
||||
"type": "object",
|
||||
@@ -143,12 +143,10 @@
|
||||
"properties": {
|
||||
"serverUrl": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"description": "Happy Coder server URL"
|
||||
},
|
||||
"webappUrl": {
|
||||
"type": "string",
|
||||
"format": "uri",
|
||||
"description": "Happy Coder webapp URL"
|
||||
},
|
||||
"homeDir": {
|
||||
@@ -161,7 +159,7 @@
|
||||
"description": "Enable experimental Happy features"
|
||||
}
|
||||
},
|
||||
"required": ["serverUrl", "webappUrl", "homeDir", "experimental"]
|
||||
"required": ["homeDir", "experimental"]
|
||||
},
|
||||
"mcp": {
|
||||
"type": "object",
|
||||
|
||||
+5
-5
@@ -45,7 +45,7 @@ user:
|
||||
# Storage configuration
|
||||
storage:
|
||||
size: 32Gi
|
||||
className: ceph-filesystem
|
||||
className: "" # Empty string uses the cluster's default StorageClass (must support ReadWriteMany)
|
||||
|
||||
# Resource allocation
|
||||
resources:
|
||||
@@ -70,8 +70,8 @@ clusterAccess: none
|
||||
|
||||
# Happy Coder AI assistant configuration
|
||||
happy:
|
||||
serverUrl: "https://happy.farh.net"
|
||||
webappUrl: "https://happy-coder.farh.net"
|
||||
serverUrl: ""
|
||||
webappUrl: ""
|
||||
homeDir: "/config/userdata/.happy"
|
||||
experimental: "true"
|
||||
|
||||
@@ -115,7 +115,7 @@ mcp:
|
||||
enabled: false # Requires HOMEASSISTANT_URL and HOMEASSISTANT_TOKEN
|
||||
image:
|
||||
repository: ghcr.io/homeassistant-ai/ha-mcp
|
||||
tag: stable
|
||||
tag: v6.7.1
|
||||
port: 8087
|
||||
resources:
|
||||
requests:
|
||||
@@ -145,7 +145,7 @@ mcp:
|
||||
enabled: true
|
||||
image:
|
||||
repository: mcr.microsoft.com/playwright/mcp
|
||||
tag: latest
|
||||
tag: v0.0.68
|
||||
port: 8086
|
||||
resources:
|
||||
requests:
|
||||
|
||||
@@ -2,5 +2,9 @@
|
||||
# Fix the app user (UID 1000) created by baseimage-gui at runtime.
|
||||
# baseimage-gui sets shell=/sbin/nologin and home=/dev/null, which
|
||||
# prevents VSCode from opening terminals.
|
||||
usermod -s /bin/bash app
|
||||
usermod -d /config/userdata app
|
||||
if id app >/dev/null 2>&1; then
|
||||
usermod -s /bin/bash app
|
||||
usermod -d /config/userdata app
|
||||
else
|
||||
echo "WARNING: 'app' user not found, skipping usermod" >&2
|
||||
fi
|
||||
|
||||
@@ -22,6 +22,7 @@ if [ -n "$GITHUB_TOKEN" ]; then
|
||||
|
||||
# Create or update the credentials file
|
||||
CREDENTIALS_FILE="/config/userdata/.git-credentials"
|
||||
mkdir -p "$(dirname "$CREDENTIALS_FILE")"
|
||||
|
||||
# Support multiple git hosting providers
|
||||
# GitHub supports both oauth2 and token as username
|
||||
@@ -51,6 +52,7 @@ else
|
||||
|
||||
# Create an empty credentials file with proper permissions
|
||||
CREDENTIALS_FILE="/config/userdata/.git-credentials"
|
||||
mkdir -p "$(dirname "$CREDENTIALS_FILE")"
|
||||
touch "$CREDENTIALS_FILE"
|
||||
chmod 600 "$CREDENTIALS_FILE"
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@ case "$IDE" in
|
||||
exec sleep infinity
|
||||
;;
|
||||
*)
|
||||
if [ "$IDE" != "vscode" ]; then
|
||||
echo "WARNING: Unknown IDE value '$IDE', defaulting to VSCode"
|
||||
fi
|
||||
echo "Opening VSCode in: $WORKSPACE_DIR"
|
||||
exec code --new-window --wait "$WORKSPACE_DIR"
|
||||
;;
|
||||
|
||||
Reference in New Issue
Block a user