Documentation
¶
Index ¶
- Variables
- func GenerateAuthToken() (string, error)
- func GenerateID(nodeID string) (string, error)
- func GenerateTemplateID() (string, error)
- type BufferedNotification
- type CreateRequest
- type CreateTemplateRequest
- type Daemon
- func (d *Daemon) ConnectAgent(sbx *Sandbox) (*proxy.AgentConn, error)
- func (d *Daemon) CreateSandbox(ctx context.Context, req CreateRequest, id identity.Identity, ...) (*Sandbox, error)
- func (d *Daemon) DestroySandbox(ctx context.Context, sbx *Sandbox) error
- func (d *Daemon) HandleDisconnect(sbx *Sandbox)
- func (d *Daemon) Reload(path string) error
- func (d *Daemon) RuntimeFor(sbx *Sandbox) runtime.Runtime
- func (d *Daemon) Shutdown(ctx context.Context) error
- func (d *Daemon) Start(ctx context.Context) error
- func (d *Daemon) TemplateBackendFor(sbx *Sandbox) TemplateBackend
- func (d *Daemon) Verifier() *identity.Verifier
- type DockerTemplateBackend
- type Event
- type EventBus
- type Metrics
- type NotificationBuffer
- type Registry
- func (r *Registry) Add(sbx *Sandbox) error
- func (r *Registry) All() []*Sandbox
- func (r *Registry) AllocCPU() float64
- func (r *Registry) AllocMemory() int64
- func (r *Registry) Count() int
- func (r *Registry) CountByIdentity(identity string) int
- func (r *Registry) Get(id string) (*Sandbox, bool)
- func (r *Registry) List(id identity.Identity) []*Sandbox
- func (r *Registry) Remove(id string) bool
- type Sandbox
- func (s *Sandbox) CancelReaper()
- func (s *Sandbox) ContainerIP() string
- func (s *Sandbox) GetSession() *proxy.Session
- func (s *Sandbox) GetState() SandboxState
- func (s *Sandbox) Info() SandboxInfo
- func (s *Sandbox) MatchLabels(filters map[string]string) bool
- func (s *Sandbox) SetSession(session *proxy.Session) *proxy.Session
- func (s *Sandbox) SetState(state SandboxState)
- func (s *Sandbox) StartReaper(ttl time.Duration, destroyFn func())
- type SandboxInfo
- type SandboxState
- type SandboxStats
- type Server
- type Template
- type TemplateBackend
- type TemplateRegistry
- func (r *TemplateRegistry) Add(tpl *Template) error
- func (r *TemplateRegistry) All() []*Template
- func (r *TemplateRegistry) Count() int
- func (r *TemplateRegistry) CountByIdentity(ident string) int
- func (r *TemplateRegistry) Get(id string) (*Template, bool)
- func (r *TemplateRegistry) List(id identity.Identity) []*Template
- func (r *TemplateRegistry) MarkUsed(id string)
- func (r *TemplateRegistry) Remove(id string) (*Template, bool)
- type Tunnel
- type TunnelInfo
- type TunnelManager
Constants ¶
This section is empty.
Variables ¶
var ErrAtCapacity = fmt.Errorf("at capacity")
ErrAtCapacity indicates the sandbox limit has been reached.
var ErrIdentityQuotaExceeded = fmt.Errorf("identity quota exceeded")
ErrIdentityQuotaExceeded indicates the per-identity sandbox limit has been reached.
Functions ¶
func GenerateAuthToken ¶
GenerateAuthToken creates a random 32-byte hex token for agent authentication.
func GenerateID ¶
GenerateID creates a new sandbox ID. If nodeID is non-empty, the format is sbx-{nodeID}-{8 hex}, otherwise sbx-{8 hex}. Embedding the node ID in the sandbox ID lets a routing proxy parse the target node from the ID alone, without a lookup table.
func GenerateTemplateID ¶
GenerateTemplateID creates a new template ID in the format tpl-{8 hex chars}.
Types ¶
type BufferedNotification ¶
BufferedNotification stores a notification that arrived while disconnected.
type CreateRequest ¶
type CreateRequest struct {
Profile string `json:"profile"`
Template string `json:"template"`
Memory string `json:"memory"`
CPU float64 `json:"cpu"`
Storage string `json:"storage"` // tmpfs size for /root (e.g. "500m", "1g"). Overrides profile default.
TTL int `json:"ttl"`
Labels map[string]string `json:"labels"`
}
CreateRequest is the request body for POST /sandboxes.
type CreateTemplateRequest ¶
type CreateTemplateRequest struct {
SandboxID string `json:"sandbox_id"`
Label string `json:"label"`
}
CreateTemplateRequest is the request body for POST /templates.
type Daemon ¶
type Daemon struct {
Config config.Config
Runtimes map[string]runtime.Runtime // keyed by runtime name ("docker", "docker+gvisor", "firecracker")
Pool *pool.Manager
Registry *Registry
Templates *TemplateRegistry
TemplateBackend TemplateBackend // Default template backend (Docker).
TemplateBackends map[string]TemplateBackend // Per-runtime template backends.
Server *Server
Metrics *Metrics
Events *EventBus
Tunnels *TunnelManager
AuthLimit *rateLimiter // Rate limiter for failed auth attempts.
CreateLimit *rateLimiter // Rate limiter for sandbox creation per identity.
Log *slog.Logger
// contains filtered or unexported fields
}
Daemon is the main sandboxd service.
func (*Daemon) ConnectAgent ¶
ConnectAgent dials the agent for a sandbox.
func (*Daemon) CreateSandbox ¶
func (d *Daemon) CreateSandbox(ctx context.Context, req CreateRequest, id identity.Identity, limits identity.RequestLimits) (*Sandbox, error)
CreateSandbox creates a new sandbox from the given parameters.
func (*Daemon) DestroySandbox ¶
DestroySandbox removes a sandbox and its container.
func (*Daemon) HandleDisconnect ¶
HandleDisconnect handles a WebSocket session ending for a sandbox. If TTL > 0, the sandbox enters disconnected state with a reaper. If TTL == 0, the sandbox is destroyed.
func (*Daemon) RuntimeFor ¶
RuntimeFor returns the runtime associated with the sandbox, falling back to Docker.
func (*Daemon) Start ¶
Start initializes the daemon: initializes runtimes, starts the warm pool, and begins listening for requests.
func (*Daemon) TemplateBackendFor ¶
func (d *Daemon) TemplateBackendFor(sbx *Sandbox) TemplateBackend
TemplateBackendFor returns the template backend for the sandbox's runtime.
type DockerTemplateBackend ¶
DockerTemplateBackend implements TemplateBackend using Docker commit.
type Event ¶
type Event struct {
ID uint64 `json:"id"` // Monotonically increasing sequence number.
Type string `json:"type"` // "sandbox.created", "sandbox.destroyed", "sandbox.disconnected", "sandbox.reconnected"
SandboxID string `json:"sandbox_id"`
Identity string `json:"identity,omitempty"`
Timestamp time.Time `json:"timestamp"`
Data map[string]interface{} `json:"data,omitempty"`
}
Event represents a sandbox lifecycle event.
type EventBus ¶
type EventBus struct {
// contains filtered or unexported fields
}
EventBus manages pub/sub for sandbox lifecycle events with replay support.
Events are assigned monotonically increasing sequence IDs and stored in a ring buffer. Subscribers that reconnect can replay missed events using Since(), and the SSE endpoint supports the standard Last-Event-ID header.
func NewEventBus ¶
NewEventBus creates a new EventBus with the given ring buffer capacity. A capacity of 0 defaults to 10 000 events.
func (*EventBus) Publish ¶
Publish assigns a sequence ID to the event, stores it in the ring buffer, and fans it out to all live subscribers. Non-blocking: drops events for subscribers whose channels are full.
func (*EventBus) Seq ¶
Seq returns the current sequence number (the ID of the last published event).
func (*EventBus) Since ¶
Since returns all buffered events with ID strictly greater than afterID, ordered by ID. If afterID is 0, returns the entire buffer. Returns the events and a boolean indicating whether the requested afterID was still in the buffer (true = complete, false = some events were lost).
func (*EventBus) Subscribe ¶
Subscribe registers a new subscriber and returns a unique ID and a read-only channel. Returns "", nil if the maximum subscriber count has been reached.
func (*EventBus) Unsubscribe ¶
Unsubscribe removes a subscriber and closes its channel.
type Metrics ¶
type Metrics struct {
// contains filtered or unexported fields
}
Metrics holds all Prometheus metrics for the sandboxd daemon.
func (*Metrics) IncCreateCold ¶
func (m *Metrics) IncCreateCold()
IncCreateCold increments the cold sandbox creation counter.
func (*Metrics) IncCreateWarm ¶
func (m *Metrics) IncCreateWarm()
IncCreateWarm increments the warm sandbox creation counter.
func (*Metrics) IncDestroy ¶
func (m *Metrics) IncDestroy()
IncDestroy increments the sandbox destroy counter.
func (*Metrics) IncRequest ¶
IncRequest increments the request counter for the given method, path, and status.
type NotificationBuffer ¶
type NotificationBuffer struct {
// contains filtered or unexported fields
}
NotificationBuffer implements a two-tier buffer for notifications during disconnect. State notifications (process.exit, process.error) are stored in a non-evictable ring. Stream notifications (process.stdout, process.stderr) are stored in an evictable buffer.
func NewNotificationBuffer ¶
func NewNotificationBuffer() *NotificationBuffer
NewNotificationBuffer creates a new notification buffer.
func (*NotificationBuffer) Add ¶
func (b *NotificationBuffer) Add(method string, payload []byte)
Add adds a notification to the buffer. It categorizes based on method.
func (*NotificationBuffer) Count ¶
func (b *NotificationBuffer) Count() int
Count returns the total number of buffered notifications.
func (*NotificationBuffer) Drain ¶
func (b *NotificationBuffer) Drain() (state []BufferedNotification, stream []BufferedNotification, truncated int)
Drain returns all buffered notifications in replay order (state first, then stream) and resets the buffer. Returns the number of truncated stream messages.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry manages active sandboxes.
func (*Registry) AllocMemory ¶
AllocMemory returns the total allocated memory across all sandboxes in bytes.
func (*Registry) CountByIdentity ¶
CountByIdentity returns the number of sandboxes belonging to the given identity.
type Sandbox ¶
type Sandbox struct {
ID string `json:"id"`
ContainerID string `json:"container_id"`
Image string `json:"image"`
State SandboxState `json:"state"`
Identity identity.Identity `json:"-"`
IdentityStr string `json:"identity,omitempty"`
AgentAddr string `json:"-"`
AuthToken string `json:"-"` // Token for agent authentication.
Created time.Time `json:"created"`
TTL int `json:"ttl"`
Memory int64 `json:"-"`
CPU float64 `json:"-"`
Profile string `json:"profile,omitempty"`
Template string `json:"template,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
RuntimeName string `json:"runtime,omitempty"` // "docker" or "firecracker"
// Session tracking.
Session *proxy.Session `json:"-"`
// TTL reconnection fields.
DisconnectedAt time.Time `json:"-"`
// Notification buffer for disconnected state.
Buffer *NotificationBuffer `json:"-"`
// Agent connection kept alive during disconnect for buffering.
Agent *proxy.AgentConn `json:"-"`
// Active port tunnels keyed by container port.
Tunnels map[int]*Tunnel `json:"-"`
// contains filtered or unexported fields
}
Sandbox represents a running sandbox container.
func (*Sandbox) CancelReaper ¶
func (s *Sandbox) CancelReaper()
CancelReaper cancels the TTL reaper if one is running.
func (*Sandbox) ContainerIP ¶
ContainerIP extracts the container IP from AgentAddr (strips the :port suffix).
func (*Sandbox) GetSession ¶
GetSession atomically gets the active session.
func (*Sandbox) GetState ¶
func (s *Sandbox) GetState() SandboxState
GetState atomically gets the sandbox state.
func (*Sandbox) Info ¶
func (s *Sandbox) Info() SandboxInfo
Info returns the public API representation of the sandbox.
func (*Sandbox) MatchLabels ¶
MatchLabels returns true if the sandbox's labels match all the given filters. Thread-safe: acquires the sandbox mutex.
func (*Sandbox) SetSession ¶
SetSession atomically sets the active session, returning the old one.
func (*Sandbox) SetState ¶
func (s *Sandbox) SetState(state SandboxState)
SetState atomically sets the sandbox state.
func (*Sandbox) StartReaper ¶
StartReaper starts a goroutine that will call destroyFn after TTL expires. Returns immediately. Can be cancelled by calling CancelReaper.
type SandboxInfo ¶
type SandboxInfo struct {
ID string `json:"id"`
Image string `json:"image"`
State SandboxState `json:"state"`
Created time.Time `json:"created"`
TTL int `json:"ttl"`
Profile string `json:"profile,omitempty"`
Template string `json:"template,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
}
SandboxInfo is the JSON-serializable sandbox information returned by the API.
type SandboxState ¶
type SandboxState string
SandboxState represents the lifecycle state of a sandbox.
const ( StateCreating SandboxState = "creating" StateRunning SandboxState = "running" StateDisconnected SandboxState = "disconnected" StateStopping SandboxState = "stopping" StateStopped SandboxState = "stopped" )
type SandboxStats ¶
type SandboxStats struct {
CPUPercent float64 `json:"cpu_percent"`
MemoryUsageBytes uint64 `json:"memory_usage_bytes"`
MemoryLimitBytes uint64 `json:"memory_limit_bytes"`
MemoryPercent float64 `json:"memory_percent"`
NetworkRxBytes uint64 `json:"network_rx_bytes"`
NetworkTxBytes uint64 `json:"network_tx_bytes"`
PIDs uint64 `json:"pids"`
UptimeSeconds float64 `json:"uptime_seconds"`
}
SandboxStats is the JSON response for GET /sandboxes/{id}/stats.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server manages the HTTP listeners for the daemon.
type Template ¶
type Template struct {
ID string `json:"id"`
Label string `json:"label"`
Image string `json:"image"` // Docker image tag or snapshot path.
Backend string `json:"backend"` // "docker" or "firecracker".
Identity string `json:"identity,omitempty"`
Size int64 `json:"size"`
CreatedAt time.Time `json:"created_at"`
LastUsedAt time.Time `json:"last_used,omitempty"`
}
Template represents a saved sandbox template.
type TemplateBackend ¶
type TemplateBackend interface {
// Capture creates a template from a running sandbox, returning the
// image/snapshot reference and its size in bytes.
Capture(ctx context.Context, containerID, tag string) (ref string, size int64, err error)
// Remove deletes the underlying image or snapshot files.
Remove(ctx context.Context, ref string) error
}
TemplateBackend abstracts how templates are captured and cleaned up. The default implementation uses Docker commit; a Firecracker implementation would snapshot memory + disk state instead.
type TemplateRegistry ¶
type TemplateRegistry struct {
// contains filtered or unexported fields
}
TemplateRegistry manages template metadata in a thread-safe manner.
func NewTemplateRegistry ¶
func NewTemplateRegistry() *TemplateRegistry
NewTemplateRegistry creates a new template registry.
func (*TemplateRegistry) Add ¶
func (r *TemplateRegistry) Add(tpl *Template) error
Add registers a template. Returns an error if the ID already exists.
func (*TemplateRegistry) All ¶
func (r *TemplateRegistry) All() []*Template
All returns a snapshot of all templates in the registry.
func (*TemplateRegistry) Count ¶
func (r *TemplateRegistry) Count() int
Count returns the total number of registered templates.
func (*TemplateRegistry) CountByIdentity ¶
func (r *TemplateRegistry) CountByIdentity(ident string) int
CountByIdentity returns the number of templates belonging to the given identity.
func (*TemplateRegistry) Get ¶
func (r *TemplateRegistry) Get(id string) (*Template, bool)
Get retrieves a template by ID.
func (*TemplateRegistry) List ¶
func (r *TemplateRegistry) List(id identity.Identity) []*Template
List returns all templates matching the given identity. If the identity is empty (single-user mode), all templates are returned.
func (*TemplateRegistry) MarkUsed ¶
func (r *TemplateRegistry) MarkUsed(id string)
MarkUsed updates the LastUsedAt timestamp for a template.
type Tunnel ¶
type Tunnel struct {
SandboxID string
Port int // container port
HostPort int // allocated host port
ContainerIP string
// contains filtered or unexported fields
}
Tunnel represents an active host-port → container-port mapping.
type TunnelInfo ¶
type TunnelInfo struct {
Port int `json:"port"`
HostPort int `json:"host_port"`
URL string `json:"url"`
}
TunnelInfo is the JSON-serializable tunnel information returned by the API.
type TunnelManager ¶
type TunnelManager struct {
// contains filtered or unexported fields
}
TunnelManager manages host-port tunnels for sandboxes.
func NewTunnelManager ¶
func NewTunnelManager(portMin, portMax, maxConns int, log *slog.Logger) *TunnelManager
NewTunnelManager creates a tunnel manager.
func (*TunnelManager) Close ¶
func (tm *TunnelManager) Close(t *Tunnel)
Close shuts down a tunnel, draining active connections.
func (*TunnelManager) Expose ¶
func (tm *TunnelManager) Expose(ctx context.Context, sbx *Sandbox, containerPort int, timeout time.Duration) (*Tunnel, error)
Expose creates a tunnel from a host port to container_ip:port. It probes the container port for readiness with exponential backoff up to timeout.