bridge

package
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Nov 8, 2026 License: AGPL-3.0 Imports: 24 Imported by: 0

Documentation

Overview

Package bridge provides a gRPC client for the workspace container bridge service. Each bot container runs a gRPC server listening on a Unix domain socket. This client wraps the generated gRPC stubs with connection pooling and a simplified API for callers.

Index

Constants

View Source
const (
	WorkspaceBackendContainer = "container"
	WorkspaceBackendRemote    = "remote"
	ToolsProxyAddr            = "127.0.0.1:18732"
	ToolsProxyHTTPURL         = "http://" + ToolsProxyAddr + "/mcp"
)

Variables

View Source
var (
	ErrNotFound    = errors.New("not found")
	ErrUnavailable = errors.New("unavailable")
	ErrBadRequest  = errors.New("invalid argument")
	ErrForbidden   = errors.New("permission denied")
)

Functions

func WithWorkspaceTarget

func WithWorkspaceTarget(ctx context.Context, targetID string) context.Context

func WorkspaceTargetFromContext

func WorkspaceTargetFromContext(ctx context.Context) string

Types

type Client

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

Client wraps a gRPC connection to a single MCP container.

func Dial

func Dial(ctx context.Context, target string) (*Client, error)

Dial creates a new Client connected to the given gRPC target. For UDS use "unix:///path/to/sock", for TCP use "host:port".

func DialTLS

func DialTLS(_ context.Context, target string, tlsOpts *TLSOptions) (*Client, error)

DialTLS dials with optional mTLS. A nil TLS config or UDS target uses the local trust model; TCP targets use strict mTLS when configured.

func NewClientFromConn

func NewClientFromConn(conn *grpc.ClientConn) *Client

NewClientFromConn wraps an existing gRPC connection into a Client. Intended for testing with in-process transports such as bufconn.

func (*Client) Close

func (c *Client) Close() error

func (*Client) DeleteFile

func (c *Client) DeleteFile(ctx context.Context, path string, recursive bool) error

func (*Client) DialContext

func (c *Client) DialContext(ctx context.Context, network, address string) (net.Conn, error)

func (*Client) Exec

func (c *Client) Exec(ctx context.Context, command, workDir string, timeout int32) (*ExecResult, error)

Exec runs a command and collects all output. For streaming, use ExecStream.

func (*Client) ExecStream

func (c *Client) ExecStream(ctx context.Context, command, workDir string, timeout int32) (*ExecStream, error)

ExecStream returns a bidirectional stream for interactive exec. Caller can send stdin data and receive stdout/stderr in real-time.

func (*Client) ExecStreamPTY

func (c *Client) ExecStreamPTY(ctx context.Context, command, workDir string, cols, rows uint32) (*ExecStream, error)

ExecStreamPTY opens a bidirectional PTY exec stream. The command runs inside a pseudo-terminal with the given initial size.

func (*Client) ExecStreamPTYWithOptions

func (c *Client) ExecStreamPTYWithOptions(ctx context.Context, command, workDir string, cols, rows uint32, opts ExecOptions) (*ExecStream, error)

func (*Client) ExecStreamWithEnv

func (c *Client) ExecStreamWithEnv(ctx context.Context, command, workDir string, timeout int32, env []string) (*ExecStream, error)

ExecStreamWithEnv returns a bidirectional exec stream with additional env.

func (*Client) ExecStreamWithOptions

func (c *Client) ExecStreamWithOptions(ctx context.Context, command, workDir string, timeout int32, opts ExecOptions) (*ExecStream, error)

ExecStreamWithOptions returns a bidirectional exec stream with environment controls.

func (*Client) ExecWithEnv

func (c *Client) ExecWithEnv(ctx context.Context, command, workDir string, timeout int32, env []string) (*ExecResult, error)

ExecWithEnv runs a command with additional environment variables.

func (*Client) ExecWithOptions

func (c *Client) ExecWithOptions(ctx context.Context, command, workDir string, timeout int32, stdinData []byte, opts ExecOptions) (*ExecResult, error)

func (*Client) ExecWithStdin

func (c *Client) ExecWithStdin(ctx context.Context, command, workDir string, timeout int32, stdinData []byte) (*ExecResult, error)

ExecWithStdin runs a command with optional stdin data.

func (*Client) ExecWithStdinEnv

func (c *Client) ExecWithStdinEnv(ctx context.Context, command, workDir string, timeout int32, stdinData []byte, env []string) (*ExecResult, error)

ExecWithStdinEnv runs a command with optional stdin data and additional environment variables.

func (*Client) ListDir

func (c *Client) ListDir(ctx context.Context, path string, recursive bool, offset, limit, collapseThreshold int32) (*ListDirResult, error)

func (*Client) ListDirAll

func (c *Client) ListDirAll(ctx context.Context, path string, recursive bool) ([]*pb.FileEntry, error)

ListDirAll lists all entries without pagination (offset=0, limit=0, no collapsing).

func (*Client) ListDirBounded

func (c *Client) ListDirBounded(ctx context.Context, path string, recursive bool, maxEntries int32) ([]*pb.FileEntry, error)

ListDirBounded lists at most maxEntries entries. The bridge stops traversing once the bound is exceeded and fails with a resource-exhausted error, so server-side memory stays bounded before collection. Callers with a hard ceiling use this instead of judging an unbounded listing after the fact.

func (*Client) Mkdir

func (c *Client) Mkdir(ctx context.Context, path string) error

func (*Client) ReadFile

func (c *Client) ReadFile(ctx context.Context, path string, lineOffset, nLines int32) (*pb.ReadFileResponse, error)

func (*Client) ReadRaw

func (c *Client) ReadRaw(ctx context.Context, path string) (io.ReadCloser, error)

ReadRaw streams raw file bytes. Caller must consume the returned reader.

func (*Client) Rename

func (c *Client) Rename(ctx context.Context, oldPath, newPath string) error

func (*Client) ServeReverseHTTP

func (c *Client) ServeReverseHTTP(ctx context.Context, handler http.Handler) (func(), error)

func (*Client) ServeReverseHTTPRoute

func (c *Client) ServeReverseHTTPRoute(ctx context.Context, route string, handler http.Handler) (func(), error)

func (*Client) Stat

func (c *Client) Stat(ctx context.Context, path string) (*pb.FileEntry, error)

func (*Client) WithOutgoingMetadata

func (c *Client) WithOutgoingMetadata(values map[string]string) *Client

WithOutgoingMetadata returns a non-owning view of the same gRPC connection. Every unary and streaming RPC sent through the view carries the supplied metadata. Closing the view is intentionally a no-op: the root client owns the device connection and may be shared by multiple Bot workspaces.

func (*Client) WriteFile

func (c *Client) WriteFile(ctx context.Context, path string, content []byte) error

func (*Client) WriteRaw

func (c *Client) WriteRaw(ctx context.Context, path string, r io.Reader) (int64, error)

WriteRaw writes raw bytes to a file in the container.

type ExecOptions

type ExecOptions struct {
	ReportLiveness bool
	Env            []string
	CleanEnv       bool
	UnsetEnv       []string
}

ExecOptions controls how a workspace command is launched.

Env entries are KEY=value overrides. By default the bridge preserves its process environment and appends Env, matching the historical ExecWithEnv behavior. CleanEnv starts from an empty environment instead. UnsetEnv scrubs inherited environment keys before Env is appended, so explicit Env entries remain authoritative.

type ExecResult

type ExecResult struct {
	Stdout   string
	Stderr   string
	ExitCode int32
}

ExecResult holds the output of a non-streaming exec call.

type ExecStream

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

ExecStream wraps a bidirectional exec stream.

func (*ExecStream) Close

func (s *ExecStream) Close() error

Close closes the stream.

func (*ExecStream) CloseSend added in v0.20.0

func (s *ExecStream) CloseSend() error

CloseSend half-closes the send side so the process sees stdin EOF while its output keeps streaming. Close() cancels the stream; this does not.

func (*ExecStream) Recv

func (s *ExecStream) Recv() (*pb.ExecOutput, error)

Recv receives output from the process.

func (*ExecStream) Resize

func (s *ExecStream) Resize(cols, rows uint32) error

Resize sends a terminal resize event to the running process.

func (*ExecStream) SendStdin

func (s *ExecStream) SendStdin(data []byte) error

SendStdin sends data to the process stdin.

type ListDirResult

type ListDirResult struct {
	Entries    []*pb.FileEntry
	TotalCount int32
	Truncated  bool
}

ListDirResult holds the paginated result of a directory listing.

type Pool

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

Pool manages cached gRPC clients keyed by bot ID.

func NewPool

func NewPool(dialTargetFunc func(string) string) *Pool

NewPool creates a client pool. dialTargetFunc maps bot ID to a gRPC target string (e.g. "unix:///path/sock" or "host:port").

func (*Pool) CloseAll

func (p *Pool) CloseAll()

CloseAll closes all cached clients.

func (*Pool) Get

func (p *Pool) Get(ctx context.Context, botID string) (*Client, error)

Get returns a cached client or dials a new one. Stale connections (Shutdown / TransientFailure / stuck Connecting) are evicted automatically.

func (*Pool) MCPClient

func (p *Pool) MCPClient(ctx context.Context, botID string) (*Client, error)

MCPClient implements Provider. Alias for Get.

func (*Pool) Remove

func (p *Pool) Remove(botID string)

Remove closes and removes the client for a bot.

func (*Pool) SetTLSOptions

func (p *Pool) SetTLSOptions(opts *TLSOptions)

SetTLSOptions enables strict mTLS for subsequent TCP dials (UDS targets are exempt). Call once during startup, before the pool serves traffic.

type Provider

type Provider interface {
	MCPClient(ctx context.Context, botID string) (*Client, error)
}

Provider resolves a gRPC client for a given bot container.

type TLSOptions

type TLSOptions struct {
	// ServerName 是 synthetic TLS ServerName(memoh-bridge.<instance-id>.bridge.memoh.internal)。
	// 连接目标是 PodIP(或 port-forward 的 localhost),证书校验必须用稳定名字
	// 而不是关闭 hostname verification。
	ServerName string
	// ExpectedServerURI 是 bridge server cert 必须携带的 URI SAN
	// (spiffe://memoh/instance/<instance-id>/bridge)。
	ExpectedServerURI string
	ClientCertFile    string
	ClientKeyFile     string
	// ServerCAFile 是 bridge-server CA bundle(bridge-server-ca.crt)。
	ServerCAFile string
}

TLSOptions 配置 Memoh Server → bridge 的 TCP gRPC mTLS(设计 §8.2)。 nil 表示 disabled(开源/本地默认)。strict 下握手或身份校验失败一律拒绝, 不回退明文;UDS target 不论 mode 始终走本地信任模型(insecure)。

type WorkspaceInfo

type WorkspaceInfo struct {
	Backend        string
	OS             string
	DefaultWorkDir string
	ToolsHTTPURL   string
}

type WorkspaceInfoProvider

type WorkspaceInfoProvider interface {
	WorkspaceInfo(ctx context.Context, botID string) (WorkspaceInfo, error)
}

Jump to

Keyboard shortcuts

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