Files
vshell/openshift
mward4 9dbe3749ba Add OpenShift manifests for in-cluster build and runtime
- build chain: project, Gitea basic-auth source secret, output ImageStream,
  BuildConfig (Docker strategy, ubuntu:24.04 base), optional base-image
  ImageStream and Docker Hub pull secret
- runtime: ServiceAccount + least-privilege SCC and its RoleBinding (VShell
  needs UID 0), PVC for config/certificate, Deployment with ImageStream
  trigger, ClusterIP Service, passthrough HTTPS Route
- all manifests verified with 'oc create --dry-run=client' against the
  OpenShift 4.22 client scheme (12/12 decode cleanly)
2026-10-05 13:25:10 -04:00
..

OpenShift manifests for VShell

Everything needed to build vshell:latest inside an OpenShift project and, if you want, to run it there. Write-tested against the OpenShift 4.22 client scheme and matching the 4.21 cluster described in /workspace/openshift-win11/FINDINGS.md.

Build (required)

File What it does
00-namespace.yaml Project vshell.
01-gitea-source-secret.yaml kubernetes.io/basic-auth secret for the private Gitea repo.
02-vshell-imagestream.yaml Output ImageStream/vshell (latest).
03-buildconfig.yaml BuildConfig/vshell — Docker strategy, git source, ubuntu:24.04 base.
04-base-imagestream.yaml Optional: keep the Ubuntu base inside the cluster instead of pulling Docker Hub on every build.
05-dockerhub-pull-secret.yaml Optional: Docker Hub credentials so base pulls are not rate limited.
oc apply -f 00-namespace.yaml

# password = the Gitea token from ~/.dsh/AGENTS.md (do not commit it into 01-*.yaml)
oc create secret generic gitea-vshell-source -n vshell \
  --type=kubernetes.io/basic-auth \
  --from-literal=username=mward4 \
  --from-literal=password=<gitea-token>

oc apply -f 02-vshell-imagestream.yaml
oc apply -f 03-buildconfig.yaml

oc start-build vshell -n vshell --follow
oc get is vshell -n vshell

The repository vendors the vendor .deb, so the build pod only needs egress to gitea.milesward.dev, registry-1.docker.io and archive.ubuntu.com (apt-get install openssl). Air-gapped clusters: import ubuntu:24.04 with 04-base-imagestream.yaml, point strategy.dockerStrategy.from at ImageStreamTag ubuntu:24.04, and add an internal apt mirror.

replicas: 1 is not a build concern but a runtime one: the daemons own fixed ports and a single host key, so never scale the Deployment.

Runtime (optional)

File What it does
runtime/00-serviceaccount.yaml ServiceAccount/vshell.
runtime/01-scc.yaml Least-privilege SCC that allows UID 0 + Role/RoleBinding so only this SA may use it.
runtime/02-pvc.yaml PersistentVolumeClaim/vshell-data for config + TLS certificate.
runtime/03-deployment.yaml Deployment, auto-updated by the image.openshift.io/triggers annotation.
runtime/04-service.yaml ClusterIP service for ports 22/21/990/80/443.
runtime/05-route.yaml HTTPS Route, passthrough termination.
oc apply -f runtime/
oc get route vshell-https -n vshell

restricted-v2 forbids UID 0, so the SCC (or oc adm policy add-scc-to-user anyuid -z vshell -n vshell) is required — VShell reads /etc/shadow through PAM, writes /var/run/*.pid and creates root-owned host keys. The custom SCC grants no extra capabilities and no host access.

The Route is passthrough because vshell-httpsd terminates TLS itself with the PKCS#12 certificate the entrypoint generated; clients therefore see a self-signed certificate until you mount a real one at $VSHELL_TLS_P12. SSH (22), explicit FTPS (21) and implicit FTPS (990) cannot go through a Route — expose the Service with a NodePort/LoadBalancer or an external load balancer.

The Deployment points VSHELL_CONFIG and VSHELL_TLS_P12 at the PVC-mounted /data, which keeps the vendor defaults and the HttpsFiles/ web assets visible. The SSH host key stays at /usr/local/etc/vshelld_hostkey unless you set HostKeyFilenames /data/vshelld_hostkey in the generated config.

Caveats

  • Builds run as root inside the build pod by default, which the Dockerfile's apt-get and dpkg -i need. Unprivileged builds (BUILD_PRIVILEGED=false) are an opt-in Developer Preview feature and would break this Dockerfile.
  • VShell runs under its 60-day evaluation license (expires 2026-12-04) until a license file is mounted and LicenseFilePath is set.
  • The image and repository are private because VShell is commercial software distributed under the VanDyke Software EULA.