Documentation
¶
Index ¶
- Constants
- Variables
- func ValidateAgentdDelivery(image, amd64, arm64 string) error
- func ValidateAgentdSidecar(sidecarEnabled bool, agentdImage string) error
- func ValidateOpencodeDelivery(image, amd64, arm64 string) error
- type AgentdDeliveryConfig
- type BinaryPins
- type CachedOrgStatusClient
- type FailureClass
- type HostResolver
- type OpencodeDeliveryConfig
- type OrgStatusClient
- type OrgStatusLogger
- type PodObservation
- type RecoveryPolicy
- type WorkspaceReconciler
Constants ¶
const ( LabelApp = "app" LabelComponent = "component" LabelWorkspace = "llmsafespaces.dev/workspace" LabelRuntime = "runtime" LabelTenant = "llmsafespaces.dev/tenant" AppName = "llmsafespaces" ComponentWorkspace = "workspace" )
Labels applied to workspace pods.
const ( // AgentdPinsConfigMapName caches the last successfully resolved pins // per digest so a controller restart during a registry outage does // not brick startup. AgentdPinsConfigMapName = "llmsafespaces-agentd-pins" )
const ( // OpencodePinsConfigMapName caches the last successfully resolved // opencode pins per digest so a controller restart during a registry // outage does not brick startup. OpencodePinsConfigMapName = "llmsafespaces-opencode-pins" )
const ( // SidecarRestartMarkerEnv wires LLMSAFESPACES_RESTART_MARKER_PATH on // both containers so the sidecar's and the supervisor's marker writes // land on one cross-uid-readable file (0640 + shared gid 1000). SidecarRestartMarkerEnv = agentd.SidecarRestartMarkerPath )
const WorkspaceFinalizer = "workspace.llmsafespaces.dev/finalizer"
Variables ¶
ErrAgentdPinsUnavailable wraps every agentd resolution failure where the registry was unreachable AND no usable cache existed. Callers can errors.Is this to offer the manual-pin hint.
ErrOpencodePinsUnavailable wraps every opencode resolution failure where the registry was unreachable AND no usable cache existed. Callers can errors.Is this to offer the manual-pin hint.
Functions ¶
func ValidateAgentdDelivery ¶ added in v0.15.8
ValidateAgentdDelivery is the exported startup guard used by controller main. Wraps validateAgentdDeliveryConfig.
func ValidateAgentdSidecar ¶ added in v0.18.0
ValidateAgentdSidecar is the exported startup guard used by controller main. Wraps validateAgentdSidecarConfig.
func ValidateOpencodeDelivery ¶ added in v0.25.5
ValidateOpencodeDelivery is the exported startup guard used by controller main. Wraps validateOpencodeDeliveryConfig.
Types ¶
type AgentdDeliveryConfig ¶ added in v0.15.8
AgentdDeliveryConfig is the #863 overlay-delivery configuration passed from controller main (flags) to the reconciler. Zero value = legacy baked-in mode.
type BinaryPins ¶ added in v0.25.5
BinaryPins are the resolved per-arch binary sha256s of one overlay artifact.
func ResolveOpencodePinsWithCache ¶ added in v0.25.5
func ResolveOpencodePinsWithCache(ctx context.Context, image, flagAMD64, flagARM64 string) (BinaryPins, error)
ResolveOpencodePinsWithCache is the opencode startup entrypoint used by controller main. validateOpencodeDeliveryConfig has already run.
func ResolvePinsWithCache ¶ added in v0.15.10
func ResolvePinsWithCache(ctx context.Context, image, flagAMD64, flagARM64 string) (BinaryPins, error)
ResolvePinsWithCache is the agentd startup entrypoint used by controller main. validateAgentdDeliveryConfig has already run.
type CachedOrgStatusClient ¶
type CachedOrgStatusClient struct {
// contains filtered or unexported fields
}
CachedOrgStatusClient is an OrgStatusClient backed by the API service's internal org-status endpoint with a per-org TTL cache.
Cache semantics (D20):
- On a fresh cache hit (< TTL): return the cached status, no fetch.
- On a stale entry (>= TTL) or cache miss: attempt a fetch.
- Fetch success: update the cache and return the new status.
- Fetch failure + prior entry: serve the STALE cached status so a transient API outage does not flip the controller into fail-open and leave suspended orgs running. This is the "30s cache absorbs transient failures" guarantee.
- Fetch failure + no entry: return ok=false (fail open — D20: an unwarranted suspension is more disruptive than leaving a pod running).
Concurrency: each orgID has its own entry guarded by a mutex, so concurrent refreshes for the SAME org are deduplicated (only one in-flight fetch per org) while different orgs refresh in parallel. The mutex is held for the duration of the fetch, bounding concurrent same-org fetches to one.
func NewCachedOrgStatusClient ¶
func NewCachedOrgStatusClient(baseURL, token string, ttl time.Duration, logger OrgStatusLogger) *CachedOrgStatusClient
NewCachedOrgStatusClient constructs the client. baseURL is the API service root (e.g. http://llmsafespaces-api.llmsafespaces.svc:8080); leave empty to disable org-suspension (the reconciler then never org-suspends). token, when non-empty, is sent as X-Internal-Token. ttl is the cache freshness window (production: 30s). logger may be nil.
func (*CachedOrgStatusClient) GetOrgStatus ¶
GetOrgStatus implements OrgStatusClient. See CachedOrgStatusClient docs for the cache + fail-open contract.
type FailureClass ¶
type FailureClass string
const ( FailureClassNone FailureClass = "" FailureClassInfrastructure FailureClass = "Infrastructure" FailureClassResource FailureClass = "Resource" FailureClassProcess FailureClass = "Process" FailureClassConfiguration FailureClass = "Configuration" )
type HostResolver ¶
HostResolver resolves a hostname to a list of IP strings. Tests inject a stub via WorkspaceReconciler.HostResolver to avoid hitting real DNS; production uses net.DefaultResolver via defaultHostResolver.
type OpencodeDeliveryConfig ¶ added in v0.25.5
type OpencodeDeliveryConfig struct {
Image string
BinarySHA256AMD64 string
BinarySHA256ARM64 string
}
OpencodeDeliveryConfig is the design 0053 §4.2 overlay-delivery configuration passed from controller main (flags) to the reconciler. Zero value = opencode stays baked into runtimes/base (S1 default).
type OrgStatusClient ¶
type OrgStatusClient interface {
GetOrgStatus(ctx context.Context, orgID string) (status string, ok bool)
}
OrgStatusClient reports an org's operational status. ok is false when the status could not be determined (API unreachable and no cached value); callers MUST fail open in that case (D20). ok is true whenever a value — fresh or stale — is available.
The interface lets tests inject a fake without an HTTP server.
type OrgStatusLogger ¶
type OrgStatusLogger interface {
Info(msg string, keysAndValues ...any)
Error(err error, msg string, keysAndValues ...any)
}
OrgStatusLogger is the minimal logging surface CachedOrgStatusClient uses. controller-runtime's logr.Logger satisfies it; nil disables logging.
type PodObservation ¶
type RecoveryPolicy ¶
type WorkspaceReconciler ¶
type WorkspaceReconciler struct {
client.Client
Scheme *runtime.Scheme
// HostResolver is used by the per-workspace NetworkPolicy generator
// (network_policy.go) to resolve declared FQDNs to /32 ipBlocks at
// reconcile time. Tests inject a stub; production uses
// defaultHostResolver (net.DefaultResolver) when nil.
HostResolver HostResolver
// InferenceRelayURL is the self-hosted relay URL for free-tier inference
// (Epic 42 InferenceRelay fleet). When set, workspace pods route opencode
// free-tier provider requests through this URL for IP distribution. When
// empty (the chart default), opencode uses its default gateway
// (opencode.ai/zen/v1) directly with the built-in `public` key.
InferenceRelayURL string
// OrgStatusClient, when non-nil AND the workspace belongs to an org
// (Spec.Owner.OrgID != ""), is consulted on every Active reconcile to drive
// D20 org-level suspension: if the org is suspended, the workspace
// transitions Active → Suspending (pod killed, PVC retained). The client is
// nil when --api-service-url is unset, disabling the feature. Lookups are
// cached (30s TTL); a lookup failure fails open (workspace keeps running).
OrgStatusClient OrgStatusClient
// DefaultRuntimeClass is the container runtime class applied to all
// workspace pods (Epic 51 S51.1). Typically "gvisor" for production
// multi-tenant deployments to provide kernel-level isolation against
// container escape. Empty means use the default (runc). Set via
// --default-runtime-class controller flag, sourced from Helm
// .Values.gvisor.defaultRuntimeClass (only set when .Values.gvisor.enabled
// is true). Individual workspaces can override via spec.runtimeClass for
// compatibility opt-out (admin-gated).
DefaultRuntimeClass string
// APIServiceURL is the in-cluster URL of the API service, used by the
// workspace init container's bootstrap subcommand (Epic 35 US-35.4) to
// fetch decrypted credentials via POST /internal/v1/pod-bootstrap. Same
// value as --api-service-url (also used for OrgStatusClient). When empty,
// the bootstrap subcommand degrades gracefully (empty secrets, pod boots
// without credentials; live /reload-secrets push handles delivery).
APIServiceURL string
// PreviewOriginBaseDomain (Epic 66 Phase 1): when non-empty, workspace
// pods receive PREVIEW_ORIGIN_BASE_DOMAIN so agentd's dev_preview_url
// MCP tool emits the per-workspace-origin bootstrap URL instead of the
// path-based URL. Sourced from the same previewOrigin.baseDomain chart
// value the API consumes — one flag enables the deployment-wide mode.
// Empty = path-based dev preview (unchanged behavior).
PreviewOriginBaseDomain string
// #863 agentd overlay delivery. When AgentdImage is set, buildPod pins a
// digest-addressed image volume into every workspace pod and the
// entrypoint verifies the binary's sha256 against the per-arch pins
// before exec. All three fields must be set together (validated at
// startup by validateAgentdDeliveryConfig). Empty AgentdImage = legacy
// mode (binary baked into runtimes/base; no volume, mount, or env).
AgentdImage string
AgentdBinarySHA256AMD64 string
AgentdBinarySHA256ARM64 string
// Design 0053 §4.2 opencode overlay delivery. When OpencodeImage is
// set, buildPod pins a digest-addressed image volume into every
// workspace pod (RO mount at /opencode on the workspace container
// only) and the supervisor verifies the binary's sha256 against the
// per-arch pins before spawn. All three fields must be set together
// (validated at startup by validateOpencodeDeliveryConfig). Empty
// OpencodeImage = baked-in mode (opencode stays in runtimes/base; S1
// default — the feature is opt-in and inert until the base strip).
OpencodeImage string
OpencodeBinarySHA256AMD64 string
OpencodeBinarySHA256ARM64 string
// AgentdSidecarEnabled (design 0051 US-2, chart-gated, default
// false): when true, buildPod appends the native agentd sidecar and
// switches the main container to supervise-opencode mode. Requires
// AgentdImage (validated at startup) — the sidecar runs the same
// digest-pinned delivery artifact.
AgentdSidecarEnabled bool
// Recorder emits Kubernetes events on the Workspace (agentd verify
// failures). Injected from mgr.GetEventRecorderFor() in production;
// a FakeRecorder in tests.
Recorder record.EventRecorder
// contains filtered or unexported fields
}
func (*WorkspaceReconciler) SetupWithManager ¶
func (r *WorkspaceReconciler) SetupWithManager(mgr ctrl.Manager) error
Source Files
¶
- agentd_overlay.go
- agentd_pins.go
- agentd_sidecar.go
- boot_failure.go
- classification.go
- constants.go
- health.go
- helpers.go
- metrics_wiring.go
- network_policy.go
- opencode_overlay.go
- opencode_pins.go
- org_status_client.go
- org_suspend.go
- overlay_pins.go
- phase_active.go
- phase_creating.go
- phase_pending.go
- phase_suspend.go
- phase_terminating.go
- platform_init.go
- pod_builder.go
- pvc.go
- reconciler.go
- recovery.go
- recovery_policy.go
- runtime_resolver.go
- secrets.go
- suspend_request.go