6711ac030f
Image 0.3.9 baked socktop 1.60.1 because CI's registry layer cache reused the apt-install layer from before the 1.60.2 release. 1.60.1 has no --no-kill flag, so the restricted shell's invocation parsed it as the positional websocket URL, breaking (and on overwrite, corrupting) the local profile. Pinning the package version busts the cache and ties the installed binary to the flags the restricted shell uses. Also point the manifest's webterm container at the current tag so a manual kubectl apply cannot roll the image back to 0.2.2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
199 lines
6.5 KiB
YAML
199 lines
6.5 KiB
YAML
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: socktop-webterm
|
|
labels:
|
|
app: socktop-webterm
|
|
spec:
|
|
replicas: 3
|
|
selector:
|
|
matchLabels:
|
|
app: socktop-webterm
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: socktop-webterm
|
|
spec:
|
|
# Use standard pod networking
|
|
hostNetwork: false
|
|
dnsPolicy: ClusterFirst
|
|
|
|
# Security context for the pod
|
|
securityContext:
|
|
runAsUser: 100
|
|
runAsGroup: 101
|
|
fsGroup: 101
|
|
|
|
# Init container to set up configuration
|
|
initContainers:
|
|
- name: init-config
|
|
image: gt.wittyoneoff.com/jason/socktop-webterm:0.2.2
|
|
imagePullPolicy: Always
|
|
command: ["/bin/bash", "-c"]
|
|
args:
|
|
- |
|
|
set -e
|
|
echo "Setting up configuration directories..."
|
|
mkdir -p /var/lib/socktop/.config/socktop/certs
|
|
mkdir -p /var/lib/socktop/.config/alacritty
|
|
|
|
if [ -f "/home/socktop/.config/socktop/profiles.json" ]; then
|
|
cp /home/socktop/.config/socktop/profiles.json /var/lib/socktop/.config/socktop/profiles.json
|
|
echo "Copied profiles.json"
|
|
fi
|
|
|
|
if [ -f "/home/socktop/.config/alacritty/alacritty.toml" ]; then
|
|
cp /home/socktop/.config/alacritty/alacritty.toml /var/lib/socktop/.config/alacritty/alacritty.toml
|
|
echo "Copied alacritty.toml"
|
|
fi
|
|
|
|
if [ -f "/home/socktop/.config/alacritty/catppuccin-frappe.toml" ]; then
|
|
cp /home/socktop/.config/alacritty/catppuccin-frappe.toml /var/lib/socktop/.config/alacritty/catppuccin-frappe.toml
|
|
echo "Copied catppuccin-frappe.toml"
|
|
fi
|
|
|
|
if [ -d "/home/socktop/.config/socktop/certs" ]; then
|
|
cp /home/socktop/.config/socktop/certs/*.pem /var/lib/socktop/.config/socktop/certs/ 2>/dev/null || true
|
|
echo "Copied certificates"
|
|
fi
|
|
|
|
# Fix paths in profiles.json
|
|
if [ -f "/var/lib/socktop/.config/socktop/profiles.json" ]; then
|
|
sed -i 's|/home/socktop/.config/socktop/rpi-|/var/lib/socktop/.config/socktop/certs/rpi-|g' /var/lib/socktop/.config/socktop/profiles.json
|
|
echo "Updated certificate paths"
|
|
fi
|
|
|
|
echo "Configuration setup complete"
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /home/socktop/.config/socktop/profiles.json
|
|
subPath: profiles.json
|
|
- name: config
|
|
mountPath: /home/socktop/.config/alacritty/alacritty.toml
|
|
subPath: alacritty.toml
|
|
- name: config
|
|
mountPath: /home/socktop/.config/alacritty/catppuccin-frappe.toml
|
|
subPath: catppuccin-frappe.toml
|
|
- name: certs
|
|
mountPath: /home/socktop/.config/socktop/certs
|
|
readOnly: true
|
|
- name: socktop-home
|
|
mountPath: /var/lib/socktop
|
|
securityContext:
|
|
runAsUser: 100
|
|
runAsGroup: 101
|
|
|
|
containers:
|
|
- name: webterm
|
|
image: gt.wittyoneoff.com/jason/socktop-webterm:0.3.10
|
|
imagePullPolicy: Always
|
|
|
|
command: ["/docker-entrypoint.sh"]
|
|
args:
|
|
[
|
|
"webterm-server",
|
|
"--host",
|
|
"0.0.0.0",
|
|
"--port",
|
|
"8082",
|
|
"--command",
|
|
"/usr/local/bin/session-shell.sh",
|
|
]
|
|
|
|
ports:
|
|
- name: http
|
|
containerPort: 8082
|
|
protocol: TCP
|
|
- name: agent
|
|
containerPort: 3001
|
|
protocol: TCP
|
|
|
|
env:
|
|
- name: TERM
|
|
value: "xterm-256color"
|
|
- name: TZ
|
|
value: "America/New_York"
|
|
- name: RUST_LOG
|
|
value: "info"
|
|
# Disable socktop's local process-kill feature for every socktop
|
|
# launched anywhere under this pod, regardless of command line.
|
|
# The restricted shell also passes --no-kill, but this is the layer
|
|
# a visitor cannot route around (no way to unset env from the
|
|
# restricted shell).
|
|
- name: SOCKTOP_NO_KILL
|
|
value: "1"
|
|
|
|
resources:
|
|
limits:
|
|
cpu: "2000m"
|
|
memory: "1Gi"
|
|
requests:
|
|
cpu: "500m"
|
|
memory: "256Mi"
|
|
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 8082
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 30
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 8082
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
timeoutSeconds: 3
|
|
failureThreshold: 3
|
|
|
|
volumeMounts:
|
|
- name: config
|
|
mountPath: /home/socktop/.config/socktop/profiles.json
|
|
subPath: profiles.json
|
|
- name: config
|
|
mountPath: /home/socktop/.config/alacritty/alacritty.toml
|
|
subPath: alacritty.toml
|
|
- name: config
|
|
mountPath: /home/socktop/.config/alacritty/catppuccin-frappe.toml
|
|
subPath: catppuccin-frappe.toml
|
|
- name: certs
|
|
mountPath: /home/socktop/.config/socktop/certs
|
|
readOnly: true
|
|
- name: socktop-home
|
|
mountPath: /var/lib/socktop
|
|
|
|
# webterm-server runs as in-container root holding ONLY
|
|
# CAP_SETUID/CAP_SETGID (everything else dropped, no privilege
|
|
# escalation), so it can drop each websocket session to the
|
|
# unprivileged `demo` user via session-shell.sh. The kernel then
|
|
# refuses any signal a session aims at the server, the agent
|
|
# (running as `socktop`), or another session's UID — the kill
|
|
# feature's UI gating stops being the only line of defense.
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
add:
|
|
- SETUID
|
|
- SETGID
|
|
readOnlyRootFilesystem: false
|
|
runAsUser: 0
|
|
runAsGroup: 0
|
|
|
|
volumes:
|
|
- name: config
|
|
configMap:
|
|
name: socktop-webterm-config
|
|
- name: certs
|
|
secret:
|
|
secretName: socktop-webterm-certs
|
|
optional: true
|
|
- name: socktop-home
|
|
emptyDir: {}
|
|
|
|
restartPolicy: Always
|