Documentation
¶
Overview ¶
Package terminal — adapter.go provides ManagerAdapter which bridges terminal.Manager to the api.TerminalManager interface.
Package terminal manages interactive terminal sessions inside Docker containers. It provides a Manager that creates exec-based PTY sessions with ring-buffered output, and supports attach/detach, input, resize, and stop operations.
Index ¶
- Variables
- type DockerExecClient
- func (c *DockerExecClient) ExecAttach(ctx context.Context, execID string) (io.ReadWriteCloser, error)
- func (c *DockerExecClient) ExecCreate(ctx context.Context, containerID string, cmd []string, tty bool) (string, error)
- func (c *DockerExecClient) ExecResize(ctx context.Context, execID string, height, width uint) error
- type ExecClient
- type HostExecClient
- func (c *HostExecClient) ExecAttach(_ context.Context, execID string) (io.ReadWriteCloser, error)
- func (c *HostExecClient) ExecCreate(_ context.Context, dirPath string, cmd []string, _ bool) (string, error)
- func (c *HostExecClient) ExecResize(_ context.Context, execID string, height, width uint) error
- type Manager
- func (m *Manager) CreateSession(ctx context.Context, containerID string, cmd []string) (*Session, error)
- func (m *Manager) GetSession(id string) (*Session, error)
- func (m *Manager) ListSessions() []string
- func (m *Manager) Resize(ctx context.Context, id string, rows, cols uint) error
- func (m *Manager) SendInput(id string, data []byte) error
- func (m *Manager) SetIdleTimeout(d time.Duration)
- func (m *Manager) SetRingBufSize(size int)
- func (m *Manager) StopSession(id string) (string, error)
- type ManagerAdapter
- func (a *ManagerAdapter) AttachSession(sessionID string) (<-chan []byte, []byte, <-chan struct{}, error)
- func (a *ManagerAdapter) CreateSession(ctx context.Context, containerID string, cmd []string) (string, <-chan []byte, []byte, <-chan struct{}, error)
- func (a *ManagerAdapter) DetachSession(sessionID string, output <-chan []byte) error
- func (a *ManagerAdapter) Resize(ctx context.Context, sessionID string, rows, cols uint) error
- func (a *ManagerAdapter) SendInput(sessionID string, data []byte) error
- func (a *ManagerAdapter) StopSession(sessionID string) (string, error)
- type RingBuffer
- type Session
Constants ¶
This section is empty.
Variables ¶
var ErrClientNotFound = errors.New("client not found")
ErrClientNotFound is returned when a detach is attempted with an unrecognized client channel.
var ErrSessionNotFound = errors.New("session not found")
ErrSessionNotFound is returned when a session ID is not recognized.
Functions ¶
This section is empty.
Types ¶
type DockerExecClient ¶
type DockerExecClient struct {
// contains filtered or unexported fields
}
DockerExecClient implements ExecClient using the Docker SDK. It wraps the Docker exec API (docker exec) to create interactive processes inside running containers. This is separate from container.Client which handles container lifecycle (docker create/start/stop/rm).
func NewDockerExecClient ¶
func NewDockerExecClient() (*DockerExecClient, error)
NewDockerExecClient creates a new DockerExecClient backed by the Docker SDK.
func (*DockerExecClient) ExecAttach ¶ added in v0.2.0
func (c *DockerExecClient) ExecAttach(ctx context.Context, execID string) (io.ReadWriteCloser, error)
ExecAttach attaches to an exec process and returns an io.ReadWriteCloser over the hijacked connection.
func (*DockerExecClient) ExecCreate ¶ added in v0.2.0
func (c *DockerExecClient) ExecCreate(ctx context.Context, containerID string, cmd []string, tty bool) (string, error)
ExecCreate creates a new exec process in the container with the given command and TTY setting. The exec runs as the host user (matching the container's non-root agent user created by the entrypoint). If cmd is empty, defaults to /bin/sh.
func (*DockerExecClient) ExecResize ¶ added in v0.2.0
ExecResize changes the PTY dimensions of the exec process.
type ExecClient ¶
type ExecClient interface {
ExecCreate(ctx context.Context, targetID string, cmd []string, tty bool) (string, error)
ExecAttach(ctx context.Context, execID string) (io.ReadWriteCloser, error)
ExecResize(ctx context.Context, execID string, height, width uint) error
}
ExecClient abstracts the Docker exec operations needed by the terminal manager (docker exec), making it testable without a real Docker daemon.
This is distinct from container.DockerClient, which handles container lifecycle (docker create/start/stop/rm). ExecClient runs commands inside already-running containers for interactive PTY sessions.
type HostExecClient ¶ added in v0.2.0
type HostExecClient struct {
// contains filtered or unexported fields
}
HostExecClient implements ExecClient for running shell commands directly on the host machine. On Unix it uses creack/pty; on Windows it uses ConPTY. The containerID parameter in ExecCreate is repurposed as the working directory.
func NewHostExecClient ¶ added in v0.2.0
func NewHostExecClient() *HostExecClient
NewHostExecClient creates a new HostExecClient.
func (*HostExecClient) ExecAttach ¶ added in v0.2.0
func (c *HostExecClient) ExecAttach(_ context.Context, execID string) (io.ReadWriteCloser, error)
ExecAttach starts the exec process with a PTY and returns a ReadWriteCloser wrapping the PTY file descriptor. Close sends SIGHUP to the process group, waits briefly, then SIGKILL.
func (*HostExecClient) ExecCreate ¶ added in v0.2.0
func (c *HostExecClient) ExecCreate(_ context.Context, dirPath string, cmd []string, _ bool) (string, error)
ExecCreate creates a new exec process. The dirPath parameter is used as the working directory. The process is not started until ExecAttach is called.
func (*HostExecClient) ExecResize ¶ added in v0.2.0
ExecResize changes the PTY dimensions of the exec process.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager manages terminal sessions.
func NewManager ¶
func NewManager(client ExecClient, logger *slog.Logger) *Manager
NewManager creates a new terminal session manager.
func (*Manager) CreateSession ¶
func (m *Manager) CreateSession(ctx context.Context, containerID string, cmd []string) (*Session, error)
CreateSession starts a new interactive terminal session by creating a Docker exec with a PTY, attaching to it, and starting the read loop. If cmd is empty, the ExecClient decides the default shell.
func (*Manager) GetSession ¶
GetSession returns the session with the given ID.
func (*Manager) ListSessions ¶
ListSessions returns all active session IDs.
func (*Manager) SetIdleTimeout ¶
SetIdleTimeout sets the idle timeout for new sessions. Sessions that receive no output within this duration are automatically closed. A zero value disables the timeout.
func (*Manager) SetRingBufSize ¶
SetRingBufSize sets the ring buffer size for new sessions.
type ManagerAdapter ¶
type ManagerAdapter struct {
// contains filtered or unexported fields
}
ManagerAdapter wraps a terminal.Manager to satisfy the api.TerminalManager interface expected by the WebSocket handler.
func NewManagerAdapter ¶
func NewManagerAdapter(mgr *Manager) *ManagerAdapter
NewManagerAdapter creates a new adapter around the given Manager.
func (*ManagerAdapter) AttachSession ¶
func (a *ManagerAdapter) AttachSession(sessionID string) (<-chan []byte, []byte, <-chan struct{}, error)
AttachSession re-attaches to an existing session.
func (*ManagerAdapter) CreateSession ¶
func (a *ManagerAdapter) CreateSession(ctx context.Context, containerID string, cmd []string) (string, <-chan []byte, []byte, <-chan struct{}, error)
CreateSession creates a PTY session and immediately attaches a client channel, returning the decomposed session fields.
func (*ManagerAdapter) DetachSession ¶
func (a *ManagerAdapter) DetachSession(sessionID string, output <-chan []byte) error
DetachSession detaches a client channel from a session.
func (*ManagerAdapter) SendInput ¶
func (a *ManagerAdapter) SendInput(sessionID string, data []byte) error
SendInput writes raw bytes to the session's PTY stdin.
func (*ManagerAdapter) StopSession ¶
func (a *ManagerAdapter) StopSession(sessionID string) (string, error)
StopSession closes the exec connection and removes the session. Returns the container ID the session was running in.
type RingBuffer ¶
type RingBuffer struct {
// contains filtered or unexported fields
}
RingBuffer is a fixed-size circular byte buffer that is safe for concurrent use. When full, new writes overwrite the oldest data.
func NewRingBuffer ¶
func NewRingBuffer(size int) *RingBuffer
NewRingBuffer creates a ring buffer with the given capacity in bytes.
func (*RingBuffer) Bytes ¶
func (r *RingBuffer) Bytes() []byte
Bytes returns a copy of the buffered data in chronological order.
func (*RingBuffer) Len ¶
func (r *RingBuffer) Len() int
Len returns the number of bytes currently stored.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session represents a single interactive terminal session backed by a Docker exec instance with a PTY.
func (*Session) Attach ¶
Attach registers a new client channel that receives a copy of all subsequent output. The caller receives the current ring buffer contents followed by a live stream. Close the returned channel by calling Detach.
func (*Session) ContainerID ¶
ContainerID returns the container this session runs in.