bridge

package
v0.8.67 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package bridge implements the PTY multiplexing between the in-container tmux session and N connected API clients.

In v1 the bridge is a thin wrapper over container primitives: tmux inside, docker exec / API for PTY plumbing outside. The public API contract is the stable surface; the bridge implementation is replaceable.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HostMaxClientSize

func HostMaxClientSize(ctx context.Context, tmuxSession string) (rows, cols uint16, ok bool)

HostMaxClientSize is MaxClientSize for a tmux session on the daemon host.

func MaxClientSize

func MaxClientSize(ctx context.Context, dockerBin, container, tmuxSession string) (rows, cols uint16, ok bool)

MaxClientSize returns the largest size (per axis) among the tmux clients already attached to the session, querying via a throwaway `docker exec`. It's used to size a *sizeless* attach (a client that sent no resize — automation, a status poller) so it matches the real interactive client instead of coming up at creack/pty's 0x0 default. A 0x0 client, under `window-size latest`, becomes the "latest" client and collapses the shared window to tmux's 80x24 fallback — which is exactly the resize bug. Matching the largest existing client makes a sizeless attach harmless (it can't shrink the window) and even pulls the window toward the real client's dimensions.

ok is false when there are no attached clients yet (the very first connect) or the query fails; callers should then fall back to the PTY default.

Types

type PTYSession

type PTYSession struct {
	// contains filtered or unexported fields
}

PTYSession is one PTY-backed `docker exec` attached to the in-container tmux session. Each connected client gets its own PTYSession; tmux's native multi- attach gives them a shared screen.

func AttachToHostTmux

func AttachToHostTmux(ctx context.Context, tmuxSession string, rows, cols uint16, te TermEnv) (*PTYSession, error)

AttachToHostTmux attaches (creating if absent) to a tmux session on the daemon host — the operator host-terminal equivalent of AttachToTmux. te carries the client's terminal identity; see TermEnv.

func AttachToTmux

func AttachToTmux(ctx context.Context, dockerBin, container, tmuxSession string, rows, cols uint16, te TermEnv) (*PTYSession, error)

AttachToTmux starts `docker exec -it <container> tmux attach-session -t <session>` against a host PTY and returns the session. Caller should Copy() to bridge bytes between the PTY and a client transport (e.g., a websocket), and Close() when the client disconnects.

rows/cols, when non-zero, size the PTY at creation. This matters: without an initial size the docker exec PTY (and the tmux client that runs in it) come up at creack/pty's 80x24 default, the agent renders its TUI at that size, and the SIGWINCH that arrives from the client's first resize envelope races the agent's initial render. Sizing up-front eliminates the race.

te carries the client's terminal identity; see TermEnv.

func ExecPTY

func ExecPTY(ctx context.Context, dockerBin, container string, cmd []string, rows, cols uint16, te TermEnv) (*PTYSession, error)

ExecPTY starts `docker exec -it <container> <cmd...>` against a host PTY and returns the session, sized to rows/cols when both are non-zero. It generalizes AttachToTmux for the SSH façade, which bridges an SSH session channel to an arbitrary in-container command (a login shell, or `bash -lc <exec>`).

func HostPTY

func HostPTY(ctx context.Context, cmd []string, rows, cols uint16, te TermEnv) (*PTYSession, error)

HostPTY starts cmd directly on the daemon host against a PTY — the operator host-terminal path (no container). Mirrors ExecPTY without the docker wrapper. This runs UNCONTAINED on the daemon host; it is gated to operators only and must never be reachable by an island token (see internal/api/tokenauth.go).

func (*PTYSession) Close

func (s *PTYSession) Close() error

Close terminates the underlying docker exec and releases the PTY.

func (*PTYSession) Read

func (s *PTYSession) Read(p []byte) (int, error)

Read reads from the PTY (container output → client).

func (*PTYSession) Resize

func (s *PTYSession) Resize(rows, cols uint16) error

Resize tells the PTY about a new window size.

func (*PTYSession) Wait

func (s *PTYSession) Wait() int

Wait reaps the underlying `docker exec` and returns its exit code. Call it after the PTY hits EOF (the in-container process exited). A signal/abnormal exit reports 1. Safe on a nil session.

func (*PTYSession) Write

func (s *PTYSession) Write(p []byte) (int, error)

Write writes to the PTY (client input → container).

type TermEnv added in v0.8.62

type TermEnv struct {
	Term      string // client's $TERM, e.g. "xterm-256color"
	ColorTerm string // client's $COLORTERM, e.g. "truecolor"
}

TermEnv carries the CLIENT terminal's identity into the container, so the in-island tmux can decide what the OUTER terminal actually supports.

Without this the island sees only the DAEMON's TERM (docker exec propagates the docker CLI's environment, not the end user's), which is identical for every connected client and says nothing about any of them. That is why image/tmux.conf's capability lines had drifted to matching `,*:` — there was no per-client signal to match on — and why a terminal that genuinely can't handle RGB/sync/extkeys was being told to emit them anyway.

Both fields are best-effort and may be empty (automation, a non-TTY client, or an older dejima client that doesn't send them); empty means "say nothing", which leaves the container's own defaults in place.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL