agentapi

package
v2.35.1 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2026 License: AGPL-3.0 Imports: 60 Imported by: 0

Documentation

Index

Constants

View Source
const BuildDurationMetricName = "template_workspace_build_duration_seconds"

BuildDurationMetricName is the short name for the end-to-end workspace build duration histogram. The full metric name is prefixed with the namespace "coderd_".

Variables

View Source
var ErrBatchSizeExceeded = xerrors.New("boundary logs batch size exceeded")

ErrBatchSizeExceeded matches any BatchSizeExceededError via errors.Is.

Functions

func WithAPIVersion added in v2.8.0

func WithAPIVersion(ctx context.Context, version string) context.Context

Types

type API

API implements the DRPC agent API interface from agent/proto. This struct is instantiated once per agent connection and kept alive for the duration of the session.

func New

func New(opts Options, workspace database.Workspace, agent database.WorkspaceAgent) *API

func (*API) Serve

func (a *API) Serve(ctx context.Context, l net.Listener) error

func (*API) Server

func (a *API) Server(ctx context.Context) (*drpcserver.Server, error)

type AnnouncementBannerAPI added in v2.12.0

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

func (*AnnouncementBannerAPI) GetAnnouncementBanners added in v2.12.0

func (*AnnouncementBannerAPI) GetServiceBanner deprecated added in v2.12.0

Deprecated: GetServiceBanner has been deprecated in favor of GetAnnouncementBanners.

type AppsAPI

type AppsAPI struct {
	AgentID                  uuid.UUID
	AgentFn                  func(context.Context) (database.WorkspaceAgent, error)
	Database                 database.Store
	Log                      slog.Logger
	Workspace                *CachedWorkspaceFields
	PublishWorkspaceUpdateFn func(context.Context, uuid.UUID, wspubsub.WorkspaceEventKind) error
	NotificationsEnqueuer    notifications.Enqueuer
	Clock                    quartz.Clock
}

func (*AppsAPI) UpdateAppStatus added in v2.31.1

type BatchSizeExceededError added in v2.35.0

type BatchSizeExceededError struct {
	BatchSize int
	MaxSize   int
}

BatchSizeExceededError is returned when a ReportBoundaryLogs request exceeds maxBoundaryLogsPerBatch. Match it with errors.As for the sizes, or errors.Is(err, ErrBatchSizeExceeded) for the category.

func (BatchSizeExceededError) Error added in v2.35.0

func (e BatchSizeExceededError) Error() string

func (BatchSizeExceededError) Is added in v2.35.0

func (BatchSizeExceededError) Is(target error) bool

type BoundaryLogsAPI added in v2.30.0

type BoundaryLogsAPI struct {
	Log                  slog.Logger
	Database             database.Store
	AgentID              uuid.UUID
	WorkspaceID          uuid.UUID
	OwnerID              uuid.UUID
	TemplateID           uuid.UUID
	TemplateVersionID    uuid.UUID
	BoundaryUsageTracker *boundaryusage.Tracker
	// contains filtered or unexported fields
}

func (*BoundaryLogsAPI) ReportBoundaryLogs added in v2.30.0

type CachedWorkspaceFields added in v2.29.0

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

CachedWorkspaceFields contains workspace data that is safe to cache for the duration of an agent connection. These fields are used to reduce database calls in high-frequency operations like stats reporting and metadata updates. Prebuild workspaces should not be cached using this struct within the API struct, however some of these fields for a workspace can be updated live so there is a routine in the API for refreshing the workspace on a timed interval.

IMPORTANT: ACL fields (GroupACL, UserACL) are NOT cached because they can be modified in the database and we must use fresh data for authorization checks.

func (*CachedWorkspaceFields) AsWorkspaceIdentity added in v2.29.0

func (cws *CachedWorkspaceFields) AsWorkspaceIdentity() (database.WorkspaceIdentity, bool)

Returns the Workspace, true, unless the workspace has not been cached (nuked or was a prebuild).

func (*CachedWorkspaceFields) Clear added in v2.29.0

func (cws *CachedWorkspaceFields) Clear()

func (*CachedWorkspaceFields) ContextInject added in v2.30.0

func (cws *CachedWorkspaceFields) ContextInject(ctx context.Context) (context.Context, error)

ContextInject attempts to inject the rbac object for the cached workspace fields into the given context, either returning the wrapped context or the original.

func (*CachedWorkspaceFields) TaskID added in v2.32.0

func (cws *CachedWorkspaceFields) TaskID() uuid.NullUUID

func (*CachedWorkspaceFields) UpdateValues added in v2.29.0

func (cws *CachedWorkspaceFields) UpdateValues(ws database.Workspace)

type ConnLogAPI added in v2.25.0

type ConnLogAPI struct {
	AgentID          uuid.UUID
	AgentName        string
	ConnectionLogger *atomic.Pointer[connectionlog.ConnectionLogger]
	Workspace        *CachedWorkspaceFields
	Database         database.Store
	Log              slog.Logger
}

func (*ConnLogAPI) ReportConnection added in v2.25.0

func (a *ConnLogAPI) ReportConnection(ctx context.Context, req *agentproto.ReportConnectionRequest) (*emptypb.Empty, error)

type ContextAPI added in v2.35.0

type ContextAPI struct {
	AgentID uuid.UUID
	// Workspace caches workspace fields for the duration of the agent
	// connection so dbauthz can authorize against the workspace RBAC
	// object without re-fetching the workspace on every push.
	Workspace *CachedWorkspaceFields
	Log       slog.Logger
	Clock     quartz.Clock
	Database  database.Store
	// DirtyMarker hydrates chats from, and marks chats dirty against, the
	// snapshot persisted by a push. It is nil when chatd is not running,
	// in which case PushContextState stays a pure write path.
	DirtyMarker ContextDirtyMarker
}

ContextAPI implements the v2.10 PushContextState RPC. It persists the latest pushed snapshot per workspace agent across two tables (workspace_agent_context_snapshots and workspace_agent_context_resources) so later phases can hydrate chats and surface drift to the dashboard.

The handler is a pure write path: nothing else in coderd reads these rows yet. If a bug here returns errors the agent's RunPush loop backs off and the workspace keeps behaving exactly like it did before v2.10.

func (*ContextAPI) PushContextState added in v2.35.0

PushContextState persists a snapshot pushed by the workspace agent. The transaction upserts the snapshot row, upserts each resource, then deletes any resources whose source is not in the incoming set so the stored snapshot and resource table always agree. It runs at repeatable read isolation (with retries) so two concurrent pushes cannot interleave their writes; the loser of the conflict re-runs the version gate against the winner's committed state.

Returns accepted = false (without writing) when the push is a replay or out-of-order resend: the agent's per-process version counter is monotonic, and only an initial = true push from a freshly-booted agent resets that baseline. Replays and stale retransmits leave the stored state untouched.

Authorization happens in dbauthz: every query in the transaction authorizes the actor (the agent's token subject) against the workspace that owns the agent.

type ContextDirtyMarker added in v2.35.0

type ContextDirtyMarker interface {
	// HydrateAndMarkChatsDirty runs inside the PushContextState
	// transaction using the supplied store. It hydrates chats for the
	// agent that have no pinned hash yet (no dirty event) and flips
	// already-pinned chats whose hash differs from aggregateHash. It
	// returns a callback that publishes the resulting dirty watch events;
	// the caller invokes it only after the transaction commits. The
	// callback is a no-op when nothing transitioned to dirty.
	HydrateAndMarkChatsDirty(ctx context.Context, tx database.Store, agentID uuid.UUID, aggregateHash []byte, snapshotError string, now time.Time) (publishDirty func(), err error)
}

ContextDirtyMarker hydrates chats from, and marks chats dirty against, a freshly persisted agent context snapshot. It is implemented by chatd and injected at coderd construction so this package neither imports the chat domain nor performs chat-authorized writes directly.

type LifecycleAPI

type LifecycleAPI struct {
	AgentFn                  func(context.Context) (database.WorkspaceAgent, error)
	WorkspaceID              uuid.UUID
	Database                 database.Store
	Log                      slog.Logger
	PublishWorkspaceUpdateFn func(context.Context, uuid.UUID, wspubsub.WorkspaceEventKind) error

	TimeNowFn func() time.Time // defaults to dbtime.Now()
	Metrics   *LifecycleMetrics
	// contains filtered or unexported fields
}

func (*LifecycleAPI) UpdateLifecycle

func (*LifecycleAPI) UpdateStartup

type LifecycleMetrics added in v2.31.1

type LifecycleMetrics struct {
	BuildDuration *prometheus.HistogramVec
}

LifecycleMetrics contains Prometheus metrics for the lifecycle API.

func NewLifecycleMetrics added in v2.31.1

func NewLifecycleMetrics(reg prometheus.Registerer) *LifecycleMetrics

NewLifecycleMetrics creates and registers all lifecycle-related Prometheus metrics.

The build duration histogram tracks the end-to-end duration from workspace build creation to agent ready, by template. It is recorded by the coderd replica handling the agent's connection when the last agent reports ready. In multi-replica deployments, each replica only has observations for agents it handles.

The "is_prebuild" label distinguishes prebuild creation (background, no user waiting) from user-initiated builds (regular workspace creation or prebuild claims).

type LogsAPI

type LogsAPI struct {
	AgentFn                           func(context.Context) (database.WorkspaceAgent, error)
	Database                          database.Store
	Log                               slog.Logger
	PublishWorkspaceUpdateFn          func(context.Context, uuid.UUID, wspubsub.WorkspaceEventKind) error
	PublishWorkspaceAgentLogsUpdateFn func(ctx context.Context, workspaceAgentID uuid.UUID, msg agentsdk.LogsNotifyMessage)

	TimeNowFn func() time.Time // defaults to dbtime.Now()
}

type ManifestAPI

type ManifestAPI struct {
	AccessURL                *url.URL
	AppHostname              string
	ExternalAuthConfigs      []*externalauth.Config
	DisableDirectConnections bool
	DerpForceWebSockets      bool
	WorkspaceID              uuid.UUID

	AgentFn   func(ctx context.Context) (database.WorkspaceAgent, error)
	Database  database.Store
	DerpMapFn func() *tailcfg.DERPMap
}

func (*ManifestAPI) GetManifest

type MetadataAPI

type MetadataAPI struct {
	AgentID   uuid.UUID
	Workspace *CachedWorkspaceFields
	Database  database.Store
	Log       slog.Logger
	Batcher   *metadatabatcher.Batcher

	TimeNowFn func() time.Time // defaults to dbtime.Now()
}

type Options

type Options struct {
	AgentID           uuid.UUID
	OwnerID           uuid.UUID
	WorkspaceID       uuid.UUID
	OrganizationID    uuid.UUID
	TemplateVersionID uuid.UUID

	AuthenticatedCtx      context.Context
	Log                   slog.Logger
	Clock                 quartz.Clock
	Database              database.Store
	NotificationsEnqueuer notifications.Enqueuer
	Pubsub                pubsub.Pubsub
	// ContextDirtyMarker is the chatd-backed hydrate/dirty fan-out invoked
	// from PushContextState. Nil when chatd is disabled.
	ContextDirtyMarker                ContextDirtyMarker
	ConnectionLogger                  *atomic.Pointer[connectionlog.ConnectionLogger]
	DerpMapFn                         func() *tailcfg.DERPMap
	TailnetCoordinator                *atomic.Pointer[tailnet.Coordinator]
	StatsReporter                     *workspacestats.Reporter
	MetadataBatcher                   *metadatabatcher.Batcher
	AppearanceFetcher                 *atomic.Pointer[appearance.Fetcher]
	PublishWorkspaceUpdateFn          func(ctx context.Context, userID uuid.UUID, event wspubsub.WorkspaceEvent)
	PublishWorkspaceAgentLogsUpdateFn func(ctx context.Context, workspaceAgentID uuid.UUID, msg agentsdk.LogsNotifyMessage)
	NetworkTelemetryHandler           func(batch []*tailnetproto.TelemetryEvent)
	BoundaryUsageTracker              *boundaryusage.Tracker
	LifecycleMetrics                  *LifecycleMetrics
	PortSharer                        *atomic.Pointer[portsharing.PortSharer]

	AccessURL                 *url.URL
	AppHostname               string
	AgentStatsRefreshInterval time.Duration
	DisableDirectConnections  bool
	DerpForceWebSockets       bool
	DerpMapUpdateFrequency    time.Duration
	ExternalAuthConfigs       []*externalauth.Config
	Experiments               codersdk.Experiments

	UpdateAgentMetricsFn func(ctx context.Context, labels prometheusmetrics.AgentMetricLabels, metrics []*agentproto.Stats_Metric)
}

type ResourcesMonitoringAPI added in v2.20.0

type ResourcesMonitoringAPI struct {
	AgentID     uuid.UUID
	WorkspaceID uuid.UUID

	Log                   slog.Logger
	Clock                 quartz.Clock
	Database              database.Store
	NotificationsEnqueuer notifications.Enqueuer

	Debounce time.Duration
	Config   resourcesmonitor.Config
	// contains filtered or unexported fields
}

func (*ResourcesMonitoringAPI) GetResourcesMonitoringConfiguration added in v2.20.0

func (*ResourcesMonitoringAPI) InitMonitors added in v2.28.0

func (a *ResourcesMonitoringAPI) InitMonitors(ctx context.Context) error

InitMonitors fetches resource monitors from the database and caches them. This must be called once after creating a ResourcesMonitoringAPI, the context should be the agent per-RPC connection context. If fetching fails with a real error (not sql.ErrNoRows), the connection should be torn down.

func (*ResourcesMonitoringAPI) PushResourcesMonitoringUsage added in v2.20.0

type ScriptsAPI added in v2.16.0

type ScriptsAPI struct {
	Database database.Store
}

type StatsAPI

type StatsAPI struct {
	AgentID                   uuid.UUID
	AgentName                 string
	Workspace                 *CachedWorkspaceFields
	Database                  database.Store
	Log                       slog.Logger
	StatsReporter             *workspacestats.Reporter
	AgentStatsRefreshInterval time.Duration
	Experiments               codersdk.Experiments

	TimeNowFn func() time.Time // defaults to dbtime.Now()
}

func (*StatsAPI) UpdateStats

type SubAgentAPI added in v2.24.0

type SubAgentAPI struct {
	OwnerID        uuid.UUID
	OrganizationID uuid.UUID
	AgentFn        func(context.Context) (database.WorkspaceAgent, error)

	Log        slog.Logger
	Clock      quartz.Clock
	Database   database.Store
	PortSharer *atomic.Pointer[portsharing.PortSharer]
}

func (*SubAgentAPI) CreateSubAgent added in v2.24.0

func (*SubAgentAPI) DeleteSubAgent added in v2.24.0

func (*SubAgentAPI) ListSubAgents added in v2.24.0

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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