providersdk

package
v0.1.54 Latest Latest
Warning

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

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

Documentation

Overview

pkg/providersdk/availability.go

Package providersdk defines small interfaces and types for interacting with provider instances (Docker hosts, Hyper-V hosts, etc).

This is intended as a reusable SDK surface:

  • "provider instance" is configuration (where/how to connect)
  • "driver" is code for a provider kind (docker, hyperv, ...)
  • optional capability interfaces describe what a kind can do (VMs, containers, guest operations, exec, resizing, ...).

Higher-level orchestration (pooling, caching, policy reconciliation) belongs elsewhere.

pkg/providersdk/networkrange.go

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ResolveSecretRef

func ResolveSecretRef(_ context.Context, ref SecretRef) (string, error)

ResolveSecretRef resolves a secret reference to its current secret value.

Supported forms:

  • env:NAME

Types

type AllocationResult added in v0.1.40

type AllocationResult struct {
	Properties      map[string]any
	GuestCredential *GuestCredential
	AppliedPackages []resourcepack.AppliedPackage
}

AllocationResult separates safe properties, which may be persisted on a resource, from an ephemeral credential that must never enter resource metadata or the durable store.

type AvailabilityReporter added in v0.1.37

type AvailabilityReporter interface {
	Availability(ctx context.Context) (*ResourceAvailability, error)
}

AvailabilityReporter is an optional provider capability for reporting current resource headroom before a Create is attempted. Not every driver implements it — callers that care must type-assert, the same pattern as GuestPersonalizer.

type CapacityError added in v0.1.39

type CapacityError struct {
	RequestedMemoryMB int64
	AvailableMemoryMB int64
}

CapacityError indicates the host does not currently have enough available capacity (e.g. memory) to satisfy a Create request. Provider-neutral: any driver can return one, not just Hyper-V, which aliases this type — see pkg/providersdk/providers/hyperv/driver.go.

func (*CapacityError) Error added in v0.1.39

func (e *CapacityError) Error() string

func (*CapacityError) ErrorType added in v0.1.39

func (e *CapacityError) ErrorType() string

ErrorType implements ErrorTyper.

type Driver

type Driver interface {
	// Type returns the provider type identifier (e.g. "docker", "hyperv").
	Type() Type

	// Create provisions a new resource from the given configuration.
	// The config is the driver's own typed struct, already unmarshaled.
	Create(ctx context.Context, cfg any) (*Resource, error)

	// Read returns the current status of a resource.
	Read(ctx context.Context, id string) (*ResourceStatus, error)

	// Update performs an operation on an existing resource. What "update"
	// means depends on the resource type: exec a command in a container,
	// set permissions on a share, attach a node to a network, etc.
	Update(ctx context.Context, id string, op Operation) (*Result, error)

	// Delete destroys a resource and cleans up associated state.
	//
	// Delete must be idempotent for missing provider resources: if the resource
	// is already gone, return nil. Boxy may retry cleanup after partially
	// completed state updates.
	Delete(ctx context.Context, id string) error

	// Allocate is called when a resource transitions from ready to allocated
	// (i.e., when it is assigned to a sandbox). It performs allocation-time
	// work such as generating credentials or injecting SSH keys.
	//
	// Returns additional Properties to merge into the resource.
	// Returns nil, nil if no allocation work is needed.
	Allocate(ctx context.Context, id string) (map[string]any, error)
}

Driver is the CRUD interface that every provider driver implements.

A driver is a thin adapter between Boxy and the underlying infrastructure (Docker, Hyper-V, VMware, etc.). It uses its native mechanism for all operations — the same client that creates resources also reads, updates, and deletes them.

Create and Delete manage resource lifecycle. Read checks current state. Update performs post-creation operations through the driver's native mechanism (docker exec, PowerShell Direct, VMware Tools, SSH, etc.).

type ErrorTyper added in v0.1.39

type ErrorTyper interface {
	ErrorType() string // e.g. "capacity"
}

ErrorTyper lets a driver error self-report a stable category (and, via json.Marshal on the error value itself, a JSON detail payload) for propagation across the RemoteAgent/gRPC boundary — without coupling the provider-neutral agentsdk layer to any specific driver package. Optional: errors that don't implement it just lose their type on that path, same as before this existed. See docs/superpowers/specs/2026-08-13-hyperv-create-failure-hardening-design.md.

type ExecOperation added in v0.1.34

type ExecOperation struct {
	Command         []string
	Env             map[string]string
	GuestCredential *GuestCredential
}

ExecOperation is the provider-neutral command shape used by Boxy workflows. Providers may alias or translate it into their native operation type.

type GuestAccessDetails

type GuestAccessDetails struct {
	Properties map[string]string
}

GuestAccessDetails is the safe provider-returned connection metadata for a personalized guest. These values may be persisted and surfaced to the CLI.

func (GuestAccessDetails) ToProperties

func (d GuestAccessDetails) ToProperties() map[string]any

ToProperties converts safe string properties into the model.Resource.Properties shape used by the rest of Boxy.

type GuestBootstrapCredential added in v0.1.40

type GuestBootstrapCredential struct {
	Username string
	Password string
}

GuestBootstrapCredential is the short-lived input used by a provider to authenticate to a freshly provisioned guest before rotating its password. It is never persisted in resource metadata.

type GuestBootstrapResolver added in v0.1.40

type GuestBootstrapResolver func(ctx context.Context, resourceID string) (GuestBootstrapCredential, error)

GuestBootstrapResolver supplies the server-owned bootstrap credential for a resource. Providers receive it as a callback so embedded and remote agents can use different transport implementations without changing driver APIs.

type GuestCredential added in v0.1.40

type GuestCredential struct {
	Kind string          `json:"kind"`
	Data json.RawMessage `json:"data"`
}

GuestCredential is an opaque, driver-defined credential payload. The control plane relays it without interpreting Data; Kind is advisory for clients that know how to render or persist a particular credential kind.

type GuestPersonalizationResult

type GuestPersonalizationResult struct {
	AccessDetails       GuestAccessDetails
	EphemeralCredential *GuestCredential
}

GuestPersonalizationResult is the typed result of allocation-time guest personalization. AccessDetails may be persisted; EphemeralCredential must remain process-local and be delivered to the caller exactly once.

type GuestPersonalizer

type GuestPersonalizer interface {
	PersonalizeGuest(ctx context.Context, id string) (*GuestPersonalizationResult, error)
}

GuestPersonalizer is an optional provider capability for allocation-time guest personalization with typed, safe returned access details.

type Instance

type Instance struct {
	Name   string         `json:"name" yaml:"name"`
	Type   Type           `json:"type" yaml:"type"`
	Config map[string]any `json:"config,omitempty" yaml:"config,omitempty"`
}

Instance is a configured provider — a named, typed instance with its raw config. These are declared in the boxy.yaml providers: list and passed to ValidateInstances.

type NetworkRange added in v0.1.46

type NetworkRange struct {
	// CIDR is the discovered IPv4 subnet in canonical network-address form
	// (e.g. "203.0.113.0/24").
	CIDR string `json:"cidr"`

	// Gateway is the host-side address on the switch's own interface within
	// CIDR, when known (e.g. "203.0.113.1"). Empty if undetermined.
	Gateway string `json:"gateway,omitempty"`

	// NATBacked reports whether the driver could positively confirm CIDR is
	// backed by a NAT rule (e.g. a Get-NetNat entry) rather than a plain
	// internal/private switch with no NAT. False means "not confirmed", not
	// "confirmed absent" — a driver that can't correlate NAT rules to a
	// switch at all should leave this false rather than guess.
	NATBacked bool `json:"nat_backed,omitempty"`
}

NetworkRange describes one IPv4 subnet a provider discovered bound to a named virtual switch/network on its host, as opposed to an operator-declared range in pool config. Fields are best-effort: a driver may be unable to determine Gateway or confirm NATBacked even when CIDR itself is known, so callers should not assume every field is populated.

type NetworkRangeReporter added in v0.1.46

type NetworkRangeReporter interface {
	NetworkRanges(ctx context.Context, switchName string) ([]NetworkRange, error)
}

NetworkRangeReporter is an optional provider capability for discovering the real IPv4 range(s) a named switch/network has bound on the host, distinct from whatever range an operator declared in pool config. Not every driver implements it — callers that care must type-assert, the same pattern as AvailabilityReporter, ResourceLister, and GuestPersonalizer.

The intended use is a driver validating its own pool config against live host state before provisioning — not a general "hardware inventory" subsystem. A switch name that doesn't exist, or exists but has no discoverable IPv4 range (e.g. a Private switch with no host vNIC), is not itself an error: implementations should return (nil, nil) for "nothing found" and reserve a non-nil error for a query that could not be completed at all.

type Operation

type Operation interface{}

Operation is the input to Driver.Update. Each driver defines its own concrete operation types.

type OrphanedResourceError added in v0.1.39

type OrphanedResourceError struct {
	ID           string
	CauseMessage string
}

OrphanedResourceError indicates Create failed and best-effort cleanup of the partially-created resource also failed, leaving it on the underlying host outside Boxy's inventory. ID is the provider-native identifier — the same convention every successfully created Resource uses — so a caller can record a quarantined resource and retry destroying it later. CauseMessage is a plain string, not a wrapped error, so this type round-trips through json.Marshal/json.Unmarshal across the RemoteAgent/gRPC boundary (see #185) — an error interface's concrete type usually can't survive that.

func (*OrphanedResourceError) Error added in v0.1.39

func (e *OrphanedResourceError) Error() string

func (*OrphanedResourceError) ErrorType added in v0.1.39

func (e *OrphanedResourceError) ErrorType() string

ErrorType implements ErrorTyper.

type Registration

type Registration struct {
	// Type is the provider type identifier (e.g. "docker", "hyperv").
	Type Type

	// ConfigProto returns a zero-value config struct for this driver type.
	// The system unmarshals a provider instance's config YAML block into this
	// struct before calling NewDriver.
	ConfigProto func() any

	// NewDriver creates a Driver instance from a parsed config struct.
	// The cfg argument is the same type returned by ConfigProto, populated
	// by the YAML unmarshaler.
	NewDriver func(cfg any) (Driver, error)
}

Registration bundles everything a provider type contributes to the system: a config prototype for unmarshaling provider-instance config, and a factory that produces a Driver from parsed config. Pool-level create settings are decoded separately by each driver's Create method.

type Registry

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

Registry maps provider Type -> Registration.

func NewRegistry

func NewRegistry() *Registry

func (*Registry) Get

func (r *Registry) Get(t Type) (Registration, bool)

Get returns the registration for a provider type.

func (*Registry) NewDriverFromInstance added in v0.1.39

func (r *Registry) NewDriverFromInstance(instance Instance, baseDir string) (Driver, error)

NewDriverFromInstance decodes a configured provider instance and creates its driver. An instance with an empty config receives the registration's zero-value configuration. This keeps provider configuration plumbing in the provider-agnostic registry rather than duplicating it in each application entrypoint.

baseDir is passed to the decoded config's ResolveRelativePaths, if it implements RelativePathResolver — pass the directory of whatever boxy config file supplied instance, or "" if none (see RelativePathResolver's doc comment for what implementations should do with an empty baseDir).

func (*Registry) Register

func (r *Registry) Register(reg Registration) error

Register adds a provider registration. Returns an error if the type is already registered or the registration is invalid.

func (*Registry) Types

func (r *Registry) Types() []Type

Types returns all registered provider types in sorted order.

func (*Registry) ValidateInstances

func (r *Registry) ValidateInstances(_ context.Context, instances []Instance) error

ValidateInstances checks that every instance references a registered provider type and that each provider type is configured at most once. Driver lookup is keyed by provider type, so duplicate instances would otherwise be ambiguous.

type RelativePathResolver added in v0.1.42

type RelativePathResolver interface {
	ResolveRelativePaths(baseDir string)
}

RelativePathResolver is an optional capability for a provider Config type that has one or more filesystem path fields it wants resolved relative to the boxy config file's own directory, rather than left to resolve against whatever the process's ambient working directory happens to be. This mirrors how Boxy's own .boxy/state.json is resolved (see internal/cli/serve.go's serveStatePath) — a relative path in a config file should mean the same thing regardless of where the process was launched from.

Registry.NewDriverFromInstance calls ResolveRelativePaths (if the decoded config implements it) with baseDir before constructing the driver. baseDir is empty when no config file path is known (e.g. no --config flag, or config loaded from stdin); implementations should leave their paths untouched in that case rather than guessing a base.

Optional and type-asserted, like every other capability in this package (ResourceLister, AvailabilityReporter, GuestPersonalizer, ErrorTyper) — most provider Config types have no config-relative path fields and don't implement this. It's deliberately not the default for every path-shaped config field: docker's socket path and hyperv's VHD/template paths are real host filesystem locations an operator points at explicitly, not directories conceptually owned by the boxy config file the way devfactory's DataDir is.

type Resource

type Resource struct {
	// ID is the provider-specific resource identifier
	// (container ID, VM name, etc.).
	ID string

	// ConnectionInfo describes how to reach the resource. Keys and values
	// are driver-defined (e.g. "host", "port", "container_id").
	ConnectionInfo map[string]string

	// Metadata holds additional driver-specific data that Boxy may
	// surface but does not interpret.
	Metadata map[string]string
}

Resource is returned by Driver.Create — the driver's output after provisioning a new resource.

type ResourceAvailability added in v0.1.37

type ResourceAvailability struct {
	// MemoryMB is available memory for new resources, in megabytes.
	MemoryMB int64 `json:"memory_mb"`
}

ResourceAvailability is a driver's point-in-time view of how much of a resource it can currently hand out to a new Create request.

type ResourceLister added in v0.1.29

type ResourceLister interface {
	List(ctx context.Context) ([]ResourceStatus, error)
}

ResourceLister is an optional provider capability for enumerating every resource the driver currently manages, independent of any single resource ID. Not every driver can support this (see docker's implementation for the managed-resource tagging convention this depends on) — callers must type- assert for it rather than relying on it being part of Driver.

type ResourceStatus

type ResourceStatus struct {
	ID    string
	State string // Driver-defined: "running", "stopped", "error", etc.
}

ResourceStatus is returned by Driver.Read.

type Result

type Result struct {
	// Outputs holds key/value pairs produced by the operation
	// (e.g. generated credentials, captured stdout).
	Outputs map[string]string
}

Result is returned by Driver.Update.

type SecretRef

type SecretRef string

SecretRef is an opaque provider-managed lookup handle for a secret.

The initial built-in resolver supports env:NAME references so providers can avoid persisting raw bootstrap secrets in resource metadata.

type StreamingDriver added in v0.1.34

type StreamingDriver interface {
	UpdateStream(ctx context.Context, id string, op Operation, sink eventstream.Sink) (*Result, error)
}

StreamingDriver is an optional capability for providers that can emit live events while an operation runs. The base Driver contract remains unary so providers can opt in incrementally.

type Type

type Type string

Type identifies the provider kind (e.g. "docker", "hyperv").

Directories

Path Synopsis
Package builtins registers the built-in provider drivers with a Registry.
Package builtins registers the built-in provider drivers with a Registry.
Package guestcred contains provider-neutral primitives for generating caller-deliverable guest credentials.
Package guestcred contains provider-neutral primitives for generating caller-deliverable guest credentials.
providers
devfactory
Package devfactory provides a reference implementation of the providersdk.Driver interface.
Package devfactory provides a reference implementation of the providersdk.Driver interface.
docker
Package docker provides a providersdk.Driver backed by the local docker CLI.
Package docker provides a providersdk.Driver backed by the local docker CLI.
hyperv
Package hyperv provides a providersdk.Driver for Microsoft Hyper-V. The agent must run on the Hyper-V host with Administrator privileges; no remote connection config is needed.
Package hyperv provides a providersdk.Driver for Microsoft Hyper-V. The agent must run on the Hyper-V host with Administrator privileges; no remote connection config is needed.

Jump to

Keyboard shortcuts

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