Documentation
¶
Overview ¶
Package exec provides WebSocket-based remote command execution in workspace pods. It bridges WebSocket connections from clients to Kubernetes exec streams, enabling interactive terminal sessions within running workspace containers.
Package exec provides a WebSocket-to-Kubernetes-exec bridge for terminal sessions.
Index ¶
- func AgentOwnerMiddleware(instance string, keys func(context.Context) ([][]byte, error), hop *OwnerHop, ...) http.Handler
- func ClaimTier1Session(namespace, name string, cancel func()) (func(), bool)
- func ContextWithPod(ctx context.Context, name string) context.Context
- func DisplayOwnerMiddleware(store *display.Store, instance string, hop *OwnerHop, next http.Handler) http.Handler
- func Handler(opts *Options) http.HandlerFunc
- func ParseTCPPort(raw string) (int, error)
- func SSHConsoleInUse(namespace, name string) bool
- func SSHHandler(opts *SSHOptions) http.HandlerFunc
- func ScreenshotHandler(opts *Options) http.HandlerFunc
- func SerialConsoleInUse(namespace, name string) bool
- func TCPHandler(opts *TCPOptions) http.HandlerFunc
- func TCPInUse(namespace, name string, port int) bool
- func TakeOverSSHConsole(namespace, name string) bool
- func TakeOverSerialConsole(namespace, name string) bool
- func TakeOverTCP(namespace, name string, port int) bool
- func TakeOverTier1(namespace, name string) bool
- func TakeOverVNC(namespace, name string) bool
- func Tier1InUse(namespace, name string) bool
- func VMConsoleHandler(opts *Options) http.HandlerFunc
- func VMVNCHandler(opts *Options) http.HandlerFunc
- func VNCInUse(namespace, name string) bool
- type Options
- type OwnerHop
- type RevalidateFunc
- type SSHOptions
- type SharedDisplay
- type TCPOptions
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AgentOwnerMiddleware ¶ added in v0.10.0
func AgentOwnerMiddleware(instance string, keys func(context.Context) ([][]byte, error), hop *OwnerHop, next http.Handler) http.Handler
AgentOwnerMiddleware routes lifecycle calls only to a cryptographically authenticated issuer. Forward resolves pod identity through Kubernetes, preserves credentials for reauthorization, and bounds forwarding to one hop.
func ClaimTier1Session ¶ added in v0.5.0
ClaimTier1Session registers a new Tier 1 transport session for the workspace. It returns a release function and true on success, or nil and false if the slot is already taken.
func ContextWithPod ¶ added in v0.10.0
ContextWithPod sets the server-resolved target for Deployment-backed scratch workspaces. A client query parameter must never select a different pod.
func DisplayOwnerMiddleware ¶ added in v0.6.0
func DisplayOwnerMiddleware(store *display.Store, instance string, hop *OwnerHop, next http.Handler) http.Handler
DisplayOwnerMiddleware forwards Goa display membership/control requests (everything under /v1/workspaces/{name}/display except the /display/ws stream, which forwards itself) to the replica owning the workspace's display, whenever an owner is known. The membership registry is in-memory per replica, so a join on one pod and a stream attach on another would otherwise diverge into 404s; routing every call to the owner keeps the one registry coherent. With no owner known yet, any replica may answer — the stream attach that follows creates the generation on the same pod.
func Handler ¶
func Handler(opts *Options) http.HandlerFunc
Handler creates an HTTP handler that upgrades to WebSocket and bridges to pod exec. The handler expects path parameters: namespace, name (workspace name). Query parameters: shell (optional, auto-detected if not provided), cols, rows.
func ParseTCPPort ¶ added in v0.6.0
ParseTCPPort validates the ?port= query: 1-65535, no names, no ranges. The editor/admin gate on the route is the authorization; this is the syntax.
func SSHConsoleInUse ¶ added in v0.4.0
SSHConsoleInUse reports whether an SSH bridge is currently active for the workspace.
func SSHHandler ¶ added in v0.4.0
func SSHHandler(opts *SSHOptions) http.HandlerFunc
SSHHandler creates an HTTP handler that upgrades to WebSocket and bridges to the guest's sshd over the workspace's masqueraded port. The client authentic with the private key matching one of the public keys the controller seeded into the guest's cloud-init (SshKey CRs).
The target is the workspace Service's endpoints address:port — the virt-launcher pod IP where KubeVirt's masquerade DNATs to the guest — which bypasses the Service ClusterIP (VM Services do not DNAT correctly under the launcher's iptables; the pod IP path works cross-node). Guest sshd host keys are self-generated and rotate per image rebuild, so no host key verification is possible; the session is carried over the authenticated WS + TLS to the API instead.
func ScreenshotHandler ¶ added in v0.6.0
func ScreenshotHandler(opts *Options) http.HandlerFunc
ScreenshotHandler returns an HTTP handler serving a one-shot PNG of the VM display: GET /v1/workspaces/{name}/vnc/screenshot?namespace=...
It dials the same KubeVirt VMI VNC subresource as the interactive bridge but holds only the capture lease (display.AcquireCapture), so a thumbnail never evicts the viewer or the seat holder — and a held console answers 409 instead of stealing the session. The RFB handshake advertises Raw only, so no pseudo-encoding acks or payloads are involved.
func SerialConsoleInUse ¶ added in v0.4.0
SerialConsoleInUse reports whether a serial console bridge is currently active for the workspace.
func TCPHandler ¶ added in v0.6.0
func TCPHandler(opts *TCPOptions) http.HandlerFunc
TCPHandler upgrades to WebSocket and bridges raw binary frames to guest TCP port ?port=N on the workspace's VM. VM workspaces only.
The target is the launcher pod IP (from the workspace Service Endpoints) dialled at the requested port — the same masquerade path the SSH bridge uses, minus the SSH protocol: every client binary frame is written to TCP and every TCP byte is returned as a binary frame. Text frames are rejected. Requires editor/admin (enforced by the route's requireEditorAccess).
func TCPInUse ¶ added in v0.6.0
TCPInUse reports whether a TCP bridge holds (namespace, name, port).
func TakeOverSSHConsole ¶ added in v0.4.0
TakeOverSSHConsole force-ends the active SSH bridge for the workspace, if any.
func TakeOverSerialConsole ¶ added in v0.4.0
TakeOverSerialConsole force-ends the active serial console bridge for the workspace, if any, so the caller can open a fresh session. It returns whether a session was active.
func TakeOverTCP ¶ added in v0.6.0
TakeOverTCP force-ends the TCP bridge for (namespace, name, port), if any.
func TakeOverTier1 ¶ added in v0.5.0
TakeOverTier1 force-ends the active Tier 1 transport session for the workspace, if any, so the caller can open a fresh session. It returns whether a session was active.
func TakeOverVNC ¶ added in v0.5.0
TakeOverVNC force-ends the active VNC bridge for the workspace, if any, so the caller can open a fresh session. It returns whether a session was active.
func Tier1InUse ¶ added in v0.5.0
Tier1InUse reports whether either interactive display transport is in use.
func VMConsoleHandler ¶ added in v0.4.0
func VMConsoleHandler(opts *Options) http.HandlerFunc
VMConsoleHandler creates an HTTP handler that upgrades the client connection to a WebSocket and bridges it to the KubeVirt VMI serial console subresource. The VMI name equals the workspace name. The console is a raw serial stream: no shell is spawned — the guest image must run a getty on the console for a login prompt to appear.
func VMVNCHandler ¶ added in v0.4.0
func VMVNCHandler(opts *Options) http.HandlerFunc
VMVNCHandler returns an HTTP handler that upgrades the client connection to a WebSocket and bridges it to the KubeVirt VMI VNC subresource. The VMI name equals the workspace name. The socket carries the raw RFB (VNC) byte stream; the client side is expected to run a noVNC RFB client on top. KubeVirt's VNC console is single-session: while another session is active the dial fails with "Active VNC connection. Request denied."
Types ¶
type Options ¶
type Options struct {
// RESTConfig is the Kubernetes REST config for SPDY exec connections.
RESTConfig *rest.Config
// Clientset is the Kubernetes clientset for pod exec requests.
Clientset kubernetes.Interface
Display *display.Store
// Sessions is the shared-display membership registry. When set, the shared
// display route registers/unregisters participants here; it must be the same
// instance backing the Goa display service.
Sessions *display.Sessions
// route (plan E: opt-in until acceptance passes). When set, the route
// answers 404 like an unknown capability.
SharedDisplayDisabled bool
// Revalidate re-checks the credential that authorised an open stream. When
// it reports a revoked credential the stream is ended with a
// closeCodeCredentialRevoked close frame.
Revalidate RevalidateFunc
// RevalidateInterval is how often Revalidate runs for an open stream.
RevalidateInterval time.Duration
}
Options configures the exec handler.
type OwnerHop ¶ added in v0.6.0
type OwnerHop struct {
// contains filtered or unexported fields
}
OwnerHop forwards a shared-display request to the replica that owns the workspace's display generation, so any API pod can answer while exactly one pod dials the VM's VNC console. The owner identity never comes from the caller: it is read from the lease annotation the owning replica wrote, and resolved to a pod IP through the Kubernetes API. The forwarded request keeps the client's credentials, so the owning pod re-authorizes it like any direct request.
func NewOwnerHop ¶ added in v0.6.0
func NewOwnerHop(clientset kubernetes.Interface) *OwnerHop
NewOwnerHop returns an OwnerHop resolving owner pod names against the API's own namespace (from the service account, defaulting to the deployment's namespace when running off-cluster).
type RevalidateFunc ¶ added in v0.11.0
RevalidateFunc re-checks the credential that authorised a stream. It returns auth.ErrCredentialRevoked once the credential is no longer usable.
type SSHOptions ¶ added in v0.4.0
type SSHOptions struct {
// Clientset is used to resolve the workspace Service endpoints (the
// launcher pod IP:port that masquerade forwards to the guest sshd).
Clientset kubernetes.Interface
// Revalidate re-checks the credential that authorised an open stream. When
// it reports a revoked credential the stream is ended with a
// closeCodeCredentialRevoked close frame.
Revalidate RevalidateFunc
// RevalidateInterval is how often Revalidate runs for an open stream.
RevalidateInterval time.Duration
}
SSHOptions configures the SSH bridge handler.
type SharedDisplay ¶ added in v0.6.0
type SharedDisplay struct {
// contains filtered or unexported fields
}
SharedDisplay serves the shared-display WebSocket route GET /v1/workspaces/{name}/display/ws. The route must have been authorized (editor/admin + namespace access) and confirmed VM-only before Handle runs. role=controller (query) joins as the controlling participant, whose input is gated by the display control lease; anything else joins as a view-only observer. No viewer accepts role=controller while another controller exists.
func NewSharedDisplay ¶ added in v0.6.0
func NewSharedDisplay(opts *Options) *SharedDisplay
NewSharedDisplay creates the shared-display route runtime.
func (*SharedDisplay) Handle ¶ added in v0.6.0
func (s *SharedDisplay) Handle(w http.ResponseWriter, r *http.Request)
Handle upgrades the client to a WebSocket and serves it an RFB shared-display stream. It blocks until disconnect, broker shutdown or cancellation.
type TCPOptions ¶ added in v0.6.0
type TCPOptions struct {
// Clientset resolves the workspace Service endpoints to the launcher pod
// IP where masquerade forwards guest ports.
Clientset kubernetes.Interface
// Revalidate re-checks the credential that authorised an open stream. When
// it reports a revoked credential the stream is ended with a
// closeCodeCredentialRevoked close frame.
Revalidate RevalidateFunc
// RevalidateInterval is how often Revalidate runs for an open stream.
RevalidateInterval time.Duration
}
TCPOptions configures the generic TCP bridge.