client

package
v1.3.4 Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2026 License: Apache-2.0 Imports: 45 Imported by: 0

Documentation

Overview

Package client - a High-level Incus API wrapper with resource management and parallel execution.

This package provides a compose-spec friendly interface for managing Incus resources: instances, networks, volumes, profiles, and images.

It also adds support for container image building by using `podman`.

Package client provides a high-level wrapper around the Incus client library.

This package abstracts the complexities of interacting with Incus servers and provides a compose-spec friendly interface for managing instances, networks, volumes, and projects.

For detailed documentation, see: https://github.com/lxc/incus-compose/tree/main/docs/architecture/client

Index

Constants

View Source
const (
	SeverityError = slog.LevelError
	SeverityWarn  = slog.LevelWarn
)

Severity of an error, defaults to SeverityError.

View Source
const (
	HealthStatusUnknown   = shared.HealthStatusUnknown
	HealthStatusHealthy   = shared.HealthStatusHealthy
	HealthStatusUnhealthy = shared.HealthStatusUnhealthy
	HealthStatusStopped   = shared.HealthStatusStopped

	HealthKeyPrefix = shared.HealthKeyPrefix

	// HealthStatusKey is the instance config key used to store health status.
	HealthStatusKey = shared.HealthStatusKey

	// HealthStoppedKey when "true" means healthchecking is stopped.
	HealthStoppedKey = shared.HealthStoppedKey
)

Health check status constants written to HealthConfigKey by ic-healthd. Re-exported from the shared package for backward compatibility with existing client.Health* references.

View Source
const (
	PriorityProject  = 1 << 8  // Infrastructure (created first, deleted last)
	PriorityProfile  = 1 << 9  // Base config
	PriorityImage    = 1 << 10 // Images (own batch for parallel downloads)
	PriorityNetwork  = 1 << 11 // Networks
	PriorityVolume   = 1 << 12 // Storage
	PriorityInstance = 1 << 13 // Instance depends on everything above
)

Resource creation priorities using powers of 2 for clear separation. Lower priority values are created first and deleted last.

View Source
const (
	InstanceDeviceTypeProxy = "proxy"
	InstanceDeviceTypeDisk  = "disk"
	InstanceDeviceTypeNic   = "nic"
	InstanceDeviceTypeTmpfs = "tmpfs"
)

Device type constants.

View Source
const BackupVolumePrefix = "ic-backup-"

BackupVolumePrefix is the prefix for backup volumes: %prefix-%project

View Source
const DefaultCacheProject = "incus-compose-cache"

DefaultCacheProject is the Incus project images are cached in.

View Source
const DefaultLockVolume = "ic-image-lock"

DefaultLockVolume is the storage volume holding the per-alias image locks.

View Source
const DefaultSystemProject = "incus-client"

DefaultSystemProject is the Incus project the library runs its own instances in.

View Source
const MaxIncusNameLen = 63

MaxIncusNameLen is the maximum length for Incus instance names. Incus allows up to 63 characters (DNS hostname limit).

View Source
const OCIUserKey = "user.incus-compose.oci.user"

OCIUserKey holds an image's own USER when it names a user instead of numbering one, which only the image's /etc/passwd can resolve.

View Source
const PrefetchVolumeServiceKey = "user.label.incus-compose.service"

PrefetchVolumeServiceKey holds the service a volume belongs to, spelled as the instances spell their own labels.

View Source
const TempInstanceKey = "user.incus-compose.temp"

TempInstanceKey marks an instance incus-compose created to read an image with.

Variables

View Source
var (
	// ErrUnsupportedAction indicates the resource does not support the action.
	ErrUnsupportedAction = NewError("resource does not support action")

	// ErrUnknown indicates an unknown error occurred.
	ErrUnknown = NewError("unknown")

	// ErrRunning indicates a command on a running instance.
	ErrRunning = NewError("resource is already running").WithSeverity(SeverityWarn)

	// ErrNotRunning indicates a command on a not running instance.
	ErrNotRunning = NewError("resource is not running").WithSeverity(SeverityWarn)

	// ErrPaused indicates a command on an already paused instance.
	ErrPaused = NewError("resource is already paused").WithSeverity(SeverityWarn)

	// ErrNotPaused indicates a command on an instance that is not paused.
	ErrNotPaused = NewError("resource is not paused").WithSeverity(SeverityWarn)

	// ErrUnknownConfig indicates an unknown config for a resource.
	ErrUnknownConfig = NewError("unknown config for resource")

	// ErrNilPointer indicates something is a nil pointer.
	ErrNilPointer = NewError("found a nil pointer")

	// ErrOperation is returned within an operation.
	ErrOperation = NewError("in an operation")

	// ErrBadDeviceConfig indicates a bad device config.
	ErrBadDeviceConfig = NewError("bad config for device")

	// ErrDependencyNotEnsured indicates a dependency is not ensured.
	ErrDependencyNotEnsured = NewError("dependency not ensured")

	// ErrDisconnected indicates an operation was attempted on a disconnected client.
	ErrDisconnected = NewError("client is not connected")

	// ErrConnectionFailed indicates a connection attempt failed.
	ErrConnectionFailed = NewError("connection failed")

	// ErrServerNotListening indicates the Incus server has no core.https_address
	// set. incus-compose copies cached images between projects using pull mode,
	// which needs the server reachable over the network.
	ErrServerNotListening = NewError("the incus server is not listening on the network (core.https_address is not set); incus-compose needs it for image caching, set it with `incus config set core.https_address=:8443`, see https://github.com/lxc/incus-compose/blob/main/docs/getting-started.md")

	// ErrServerTooOld indicates the Incus server has no oci_network_config API,
	// which every compose network attachment needs.
	ErrServerTooOld = NewError("the incus server has no oci_network_config API, incus-compose needs Incus 7.0.1 (LTS) or 7.2 and newer")

	// ErrAborted indicates an operation was aborted (e.g., by BeforeAny hook).
	ErrAborted = NewError("operation aborted")

	// ErrNotFound indicates a resource was not found.
	ErrNotFound = NewError("resource not found")

	// ErrNotEnsured indicates an operation requires the resource to be ensured first.
	ErrNotEnsured = NewError("resource not ensured").WithSeverity(SeverityWarn)

	// ErrImageRequired indicates an instance requires an image.
	ErrImageRequired = NewError("instances without an image are not yet supported")

	// ErrUnknownResource indicates an unknown resource kind.
	ErrUnknownResource = NewError("unknown resource kind")

	// ErrInvalidFormat indicates invalid format or syntax.
	ErrInvalidFormat = NewError("invalid format")

	// ErrImageSource indicates an image source error.
	ErrImageSource = NewError("image source error")

	// ErrNoPlatform indicates a multi-arch image carries no manifest for the
	// architecture it was asked for.
	ErrNoPlatform = NewError("image has no manifest for the architecture")

	// ErrPlatformConflict indicates two services want one image reference for
	// different architectures.
	ErrPlatformConflict = NewError("image wanted for two architectures")

	// ErrNoSuchUser indicates a user or group name the image does not define.
	ErrNoSuchUser = NewError("no such user or group in the image")

	// ErrDeviceConflict indicates a device name conflict.
	ErrDeviceConflict = NewError("device conflict")

	// ErrVolumeMismatch indicates volume configuration mismatch.
	ErrVolumeMismatch = NewError("volume configuration mismatch")

	// ErrVolumeInUse indicates a volume that still has users, which for one
	// several instances share is every delete but the last.
	ErrVolumeInUse = NewError("volume still in use")

	// ErrCreate indicates a resource creation error.
	ErrCreate = NewError("create failed")

	// ErrDelete indicates a resource deletion error.
	ErrDelete = NewError("delete failed")

	// ErrBackupFailed indicates a backup failed.
	ErrBackupFailed = NewError("backup failed")

	// ErrBackupNotFound indicates a backup volume or restore point is missing.
	ErrBackupNotFound = NewError("backup not found")

	// ErrRestoreFailed indicates a restore failed.
	ErrRestoreFailed = NewError("restore failed")
)
View Source
var ErrDNSWatcher = NewError("DNSWatcher")

ErrDNSWatcher is used as wrapper to indicate an error happened in the DNSWatcher.

View Source
var WellKnownRegistries = map[string]string{
	"ghcr.io":             "https://ghcr.io",
	"docker.io":           "https://docker.io",
	"mcr.microsoft.com":   "https://mcr.microsoft.com",
	"quay.io":             "https://quay.io",
	"registry.gitlab.com": "https://registry.gitlab.com",
	"codeberg.org":        "https://codeberg.org",
}

WellKnownRegistries maps well-known OCI registry domains to their server URLs. An image from one of these resolves without an `incus remote add` step.

Functions

func BackupDeleteManifest added in v1.3.0

func BackupDeleteManifest(ctx context.Context, bc *Client, cfg BackupConfig) error

BackupDeleteManifest removes one run's manifest from the manifest volume.

func BackupDeleteSnapshot added in v1.3.0

func BackupDeleteSnapshot(ctx context.Context, bc *Client, pool string, volume string, snapshot string) error

BackupDeleteSnapshot removes one restore point from a backup volume.

func BackupSnapshots added in v1.3.0

func BackupSnapshots(ctx context.Context, bc *Client, pool string, volume string) ([]string, error)

BackupSnapshots returns the restore points a backup volume holds. A volume that is not there yet reads as none, which is what an unbacked-up volume is.

func BackupVolumeUsage added in v1.3.0

func BackupVolumeUsage(ctx context.Context, bc *Client, pool string, volume string) (int64, error)

BackupVolumeUsage returns the bytes a backup volume occupies. The restore points on it share that space, so it is not a per-timestamp figure.

func BackupWriteManifest added in v1.3.0

func BackupWriteManifest(ctx context.Context, bc *Client, cfg BackupConfig, data []byte) error

BackupWriteManifest writes one run's manifest into the manifest volume.

func ByKind

func ByKind[T Resource](resources []Resource, kind Kind) ([]T, error)

ByKind filters resources by kind and returns them as the specified type.

func DNSmasqParse

func DNSmasqParse(raw string) (map[string][]string, map[string][]string, string)

DNSmasqParse parses a raw.dnsmasq value into its three parts: address records as a service->[]IP map, cname records as a target->[]alias map, and any other lines (e.g. user-supplied raw.dnsmasq content) verbatim.

func DialRemote added in v1.2.0

func DialRemote(path string, remote string) (*iclient.Connection, error)

DialRemote connects to a remote of the Incus CLI configuration at path. An empty path is the default location, an empty remote the default remote.

func RandString

func RandString(n int) string

RandString is a helper that creates a random string for the given size (n). It is from https://stackoverflow.com/a/31832326 -- RandStringBytesMaskImprSrcSB.

func RunAction

func RunAction(ctx context.Context, r Resource, action Action, opts ...Option) error

RunAction runs a action on a resource.

func SanitizeIncusName

func SanitizeIncusName(name string, maxLength int) string

SanitizeIncusName converts a string to a valid Incus instance name. Converts to lowercase, replaces special chars and underscores with hyphens. Names exceeding maxLength are replaced with a 32-char hex hash for DNS compatibility; -1 means the Incus limit.

func SanitizeNetworkName

func SanitizeNetworkName(projectName, prefix, networkName string) string

SanitizeNetworkName generates a network interface name from project and network name. Returns a deterministic, unique name that fits within Linux interface name limits.

func SanitizeProjectName

func SanitizeProjectName(name string) string

SanitizeProjectName converts a string to a valid Incus project name. Replaces underscores with hyphens and removes special characters via slug.

func SupportsAction

func SupportsAction(r Resource, action Action) bool

SupportsAction returns if the Resource supports the action.

Types

type Action

type Action string

Action identifies a resource action.

const (
	ActionEnsure  Action = "ensure"
	ActionDelete  Action = "delete"
	ActionStart   Action = "start"
	ActionStop    Action = "stop"
	ActionPause   Action = "pause"
	ActionUnpause Action = "unpause"
	ActionBackup  Action = "backup"
	ActionRestore Action = "restore"
)

Action constants for resource actions.

type BackupAble added in v1.3.0

type BackupAble interface {
	BackupEntry(cfg BackupConfig, backupProject string) BackupVolume
	Backup(ctx context.Context, opts ...Option) error
}

BackupAble is implemented by resources that can be backed up.

type BackupConfig added in v1.3.0

type BackupConfig struct {
	MetaVolume string `json:"meta_volume" mapstructure:"meta_volume"`
	Timestamp  string `json:"timestamp"`
	Name       string `json:"name"`
	Pool       string `json:"pool"`
}

BackupConfig holds backup configuration from x-incus-compose.backup.

type BackupVolume added in v1.3.0

type BackupVolume struct {
	Source VolumeInfos `json:"source"`
	Backup VolumeInfos `json:"backup"`
}

BackupVolume represents a single volume in a backup run.

type BaseResource

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

BaseResource provides common fields for all Incus resources.

func NewBaseResource

func NewBaseResource(kind Kind, name string, priority int) *BaseResource

NewBaseResource creates a new BaseResource.

func (*BaseResource) Kind

func (r *BaseResource) Kind() Kind

Kind returns the resource kind.

func (*BaseResource) Name

func (r *BaseResource) Name() string

Name returns the resource name.

func (*BaseResource) Priority

func (r *BaseResource) Priority() int

Priority returns the resource priority.

type BuildConfig

type BuildConfig struct {
	// Context is the build context directory (absolute path).
	Context string

	// Dockerfile is an optional path to the Containerfile/Dockerfile, passed to
	// the builder verbatim, so a relative path resolves against the process
	// working directory rather than Context. Empty means the builder uses its
	// default (Containerfile or Dockerfile in Context).
	Dockerfile string

	// DockerfileInline is inline Dockerfile content from compose build.dockerfile_inline.
	DockerfileInline string

	// Target is the Dockerfile stage to build.
	Target string

	// Platform is the OCI platform to build for, for example linux/amd64.
	Platform string

	// Args are build-time variables (--build-arg).
	Args map[string]string

	// NoCache disables layer caching during the build as well as caching
	// the resulting image on the server.
	NoCache bool

	// Pull always attempts to pull a newer version of the base image.
	Pull bool
}

BuildConfig holds the parameters read from a compose service's build: block.

type BuildInfo

type BuildInfo struct {
	// Mode controls rebuild behavior.
	Mode BuildMode

	// PreferredBuilder is the container builder binary name or absolute path.
	// Empty means auto-detect (tries podman, then docker).
	PreferredBuilder string
}

BuildInfo carries the rebuild mode and optional builder selection for ActionEnsure.

type BuildMode

type BuildMode int

BuildMode controls how build-configured images are treated during Ensure.

const (
	// BuildAuto builds the image only when it is missing (default).
	BuildAuto BuildMode = iota
	// BuildForce rebuilds the image even if an existing one is present.
	BuildForce
	// BuildNever never builds; returns an error if the image is missing.
	BuildNever
)

type Client

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

Client wraps a project-scoped Incus client with resource management.

func NewOfflineClient

func NewOfflineClient(ctx context.Context, projectName string) *Client

NewOfflineClient creates a disconnected project client for resource planning. It can create in-memory resources, but cannot run Incus operations.

func (*Client) AddHookAfter

func (c *Client) AddHookAfter(hook func(ctx context.Context, action Action, r Resource, args Options, err error) error)

AddHookAfter adds a hook that will be executed after any action (LIFO order).

func (*Client) AddHookBefore

func (c *Client) AddHookBefore(hook func(ctx context.Context, action Action, r Resource, args Options, err error) error)

AddHookBefore adds a hook that will be executed before any action. You may use it for abort control.

func (*Client) AddHookConnected

func (c *Client) AddHookConnected(hook func(err error) error)

AddHookConnected adds a hook that will be executed when the client connects (FIFO order).

func (*Client) AddHookDone

func (c *Client) AddHookDone(hook func(err error) error)

AddHookDone adds a hook that will be executed when the client's work is complete (LIFO order).

func (*Client) Clone

func (c *Client) Clone() *Client

Clone returns a copy of the client, where you can add independent hooks and resources. Resources are NOT shared.

func (*Client) Config

func (c *Client) Config() ClientConfig

Config returns a copy of the clients config.

func (*Client) Connection

func (c *Client) Connection() (*iclient.Connection, error)

Connection returns the Incus connection, safe for concurrent use. Every project-scoped call on it takes IncusProject.

func (*Client) Done

func (c *Client) Done() error

Done releases what the client's resources hold and fires the done hooks. Call when the client's work is complete; calling it twice is a no-op.

func (*Client) FindHealthd

func (c *Client) FindHealthd() (string, error)

FindHealthd returns the name of the healthd instance in the project, identified by user.healthcheck.daemon=true.

func (*Client) Global

func (c *Client) Global() *GlobalClient

Global returns the GlobalClient associated with this project client.

func (*Client) GlobalConnection

func (c *Client) GlobalConnection() (*iclient.Connection, error)

GlobalConnection returns the global incus connection (with the default project).

func (*Client) HealthdRunning added in v1.2.0

func (c *Client) HealthdRunning() (bool, error)

HealthdRunning reports whether the daemon watching this project is up, looking wherever the project's stored scope says it lives.

func (*Client) IgnoreError

func (c *Client) IgnoreError(iAction Action, iErr error)

IgnoreError ignores an "warning" errors for the given kind and the rest of the session.

func (*Client) IncusProject

func (c *Client) IncusProject() string

IncusProject returns the sanitized Incus project name.

func (*Client) InstanceExists

func (c *Client) InstanceExists(name string) (bool, error)

InstanceExists reports whether an instance with the given name exists in Incus.

func (*Client) IsConnected

func (c *Client) IsConnected() bool

IsConnected reports whether the project client can run Incus operations.

func (*Client) IsDebugging

func (c *Client) IsDebugging() bool

IsDebugging returns if debugging is enabled.

func (*Client) IsRemote

func (c *Client) IsRemote() bool

IsRemote returns true if connected via network (not unix socket).

func (*Client) LogDebug

func (c *Client) LogDebug(msg string, args ...any)

LogDebug logs an debug message. The `any` here is ok.

func (*Client) LogError

func (c *Client) LogError(msg string, args ...any)

LogError logs an error. The `any` here is ok.

func (*Client) LogInfo

func (c *Client) LogInfo(msg string, args ...any)

LogInfo logs an info message. The `any` here is ok.

func (*Client) LogWarn

func (c *Client) LogWarn(msg string, args ...any)

LogWarn logs an warning message. The `any` here is ok.

func (*Client) Open

func (c *Client) Open() error

Open fires the connected hooks. Call once after registering all hooks, before running any stack actions.

func (*Client) Project

func (c *Client) Project() string

Project returns the user-facing project name.

func (*Client) RegisterDNSWatcher

func (c *Client) RegisterDNSWatcher() error

RegisterDNSWatcher wires service-name DNS records into the project's managed networks via the client lifecycle hooks. On each instance create/start/stop/ delete it reads raw.dnsmasq from Incus, updates only the records for services seen in this run (identified via IncusName), preserves all other records, and writes back. Multiple projects can coexist in the same network without clobbering each other's records.

func (*Client) ResolveImageFingerprint

func (c *Client) ResolveImageFingerprint(fingerprint string) string

ResolveImageFingerprint returns the first alias name for the given fingerprint, or the fingerprint itself if no alias is found or the lookup fails.

func (*Client) Resource

func (c *Client) Resource(kind Kind, name string, config Config) (Resource, error)

Resource returns an existing resource or creates a new one. You might use a nil config for lookups.

func (*Client) Resources added in v1.3.0

func (c *Client) Resources() []Resource

Resources returns the resources this client holds right now, clones excluded. The slice is a copy; the resources in it are the live ones.

func (*Client) WarnError

func (c *Client) WarnError(f func() error, message string)

WarnError logs a warning if the given error is not nil, use in deferred for example.

type ClientConfig

type ClientConfig struct {
	// URL is the Incus server URL to connect to.
	URL string

	// Logger to use within this client.
	Logger *slog.Logger

	// Stdout is the stdout writer to use.
	Stdout io.Writer

	// Stderr is the swappable stderr writer.
	Stderr *SwapWriter

	// NetworkPrefix is the prefix for new networks (default: "ic-").
	NetworkPrefix string

	// DefaultStoragePool is the storage pool to use for volumes (default: "default").
	DefaultStoragePool string

	// DescriptionFormat is the format string for resource descriptions (default: "incus-compose: %s").
	DescriptionFormat string

	// ProvidedConnection allows injecting an existing connection (for testing).
	ProvidedConnection *iclient.Connection

	// CacheProject is the project name to use as image cache.
	// If set, the project will be created if it doesn't exist.
	CacheProject string

	// SystemProject is the project holding the instances the library runs.
	SystemProject string
}

ClientConfig holds configuration options for the Client.

type ClientOption

type ClientOption func(*ClientConfig)

ClientOption is a functional option for configuring the Client.

func ClientCacheProject

func ClientCacheProject(n string) ClientOption

ClientCacheProject sets the project name to use as image cache.

func ClientDefaultStoragePool

func ClientDefaultStoragePool(n string) ClientOption

ClientDefaultStoragePool sets the default storage pool name.

func ClientDescriptionFormat

func ClientDescriptionFormat(n string) ClientOption

ClientDescriptionFormat sets the format string for resource descriptions.

func ClientLogger

func ClientLogger(l *slog.Logger) ClientOption

ClientLogger sets the client to use within the created client.

func ClientNetworkPrefix

func ClientNetworkPrefix(n string) ClientOption

ClientNetworkPrefix sets the prefix for network names.

func ClientProvideConnection

func ClientProvideConnection(conn *iclient.Connection) ClientOption

ClientProvideConnection injects an existing Incus connection.

func ClientStderrWriter added in v1.1.0

func ClientStderrWriter(lw *SwapWriter) ClientOption

ClientStderrWriter sets the swappable writer.

func ClientStdout added in v1.1.0

func ClientStdout(w io.Writer) ClientOption

ClientStdout sets the clients stdout.

func ClientSystemProject added in v1.2.0

func ClientSystemProject(n string) ClientOption

ClientSystemProject sets the project holding the library's own instances.

func ClientURL

func ClientURL(u string) ClientOption

ClientURL sets the Incus server ClientURL.

type Config

type Config interface {
	GetConfig() any
}

Config is implemented by resource configuration types.

type DeleteAble

type DeleteAble interface {
	Delete(ctx context.Context, opts ...Option) error
}

DeleteAble is implemented by resources that can be deleted.

type EnsureAble

type EnsureAble interface {
	// Ensure fetches an existing Resource or creates a new one.
	// If a Resource with the same name exists, it is returned.
	Ensure(ctx context.Context, opts ...Option) error
}

EnsureAble is implemented by resources that can be ensured.

type EnsureProjectOption

type EnsureProjectOption func(*ensureProjectOptions)

EnsureProjectOption is a functional option for configuring project creation.

func EnsureProjectWithConfig

func EnsureProjectWithConfig(config map[string]string) EnsureProjectOption

EnsureProjectWithConfig sets configuration options to apply when creating the project. These options are merged with default features configuration.

func EnsureProjectWithCreate

func EnsureProjectWithCreate() EnsureProjectOption

EnsureProjectWithCreate enables project creation if the project doesn't exist.

func EnsureProjectWithSkipHealthd

func EnsureProjectWithSkipHealthd() EnsureProjectOption

EnsureProjectWithSkipHealthd skips as the name says any healthd calls.

type Error

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

Error is a sentinel-based error type that supports context enrichment.

func NewError

func NewError(text string) *Error

NewError creates a new sentinel error.

func (*Error) As

func (e *Error) As(target any) bool

As implements errors.As() support by copying to target if it's *Error.

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface.

func (*Error) Is

func (e *Error) Is(target error) bool

Is implements errors.Is() support by comparing sentinel pointers.

func (*Error) Severity

func (e *Error) Severity() slog.Level

Severity returns the errors severity, defaults to SeverityError.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap returns the wrapped error for errors.Unwrap() support.

func (*Error) WithAction

func (e *Error) WithAction(action Action) *Error

WithAction adds action context to the error.

func (*Error) WithKindName

func (e *Error) WithKindName(kind Kind, name string) *Error

WithKindName adds resource kind and name context to the error.

func (*Error) WithResource

func (e *Error) WithResource(resource Resource) *Error

WithResource adds resource context to the error.

func (*Error) WithSeverity

func (e *Error) WithSeverity(severity slog.Level) *Error

WithSeverity returns a new error withe given severity.

func (*Error) WithText

func (e *Error) WithText(text string) *Error

WithText adds text context to the error.

func (*Error) Wrap

func (e *Error) Wrap(wrapped error) *Error

Wrap wraps another error, preserving the sentinel identity.

type GlobalClient

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

GlobalClient provides a high-level interface to Incus operations.

func New

func New(ctx context.Context, opts ...ClientOption) *GlobalClient

New creates a new Client with the provided context and logger.

func NewTestClient

func NewTestClient(ctx context.Context) (*GlobalClient, error)

NewTestClient creates a new GlobalClient for testing.

func (*GlobalClient) AddHookAfter

func (c *GlobalClient) AddHookAfter(hook func(ctx context.Context, action Action, r Resource, args Options, err error) error)

AddHookAfter adds a hook that will be executed after any action (LIFO order).

func (*GlobalClient) AddHookBefore

func (c *GlobalClient) AddHookBefore(hook func(ctx context.Context, action Action, r Resource, args Options, err error) error)

AddHookBefore adds a hook that will be executed before any action (FIFO order). You may use it for abort control.

func (*GlobalClient) AddMissingProjectConfig added in v1.2.0

func (c *GlobalClient) AddMissingProjectConfig(name string, config map[string]string) error

AddMissingProjectConfig adds declared config keys the project does not have yet.

func (*GlobalClient) CliConfig

func (c *GlobalClient) CliConfig() *iclient.Config

CliConfig returns the CLI config for image server resolution.

func (*GlobalClient) Connect

func (c *GlobalClient) Connect() error

Connect establishes a connection to the Incus server.

func (*GlobalClient) Connection

func (c *GlobalClient) Connection() (*iclient.Connection, error)

Connection returns the connection scoped to the default project, safe for concurrent use.

func (*GlobalClient) ConnectionIPs

func (c *GlobalClient) ConnectionIPs() ([]net.IP, error)

ConnectionIPs returns the IP of the current connection, this function is cached by GlobalClient.connectionIP.

func (*GlobalClient) DeleteProject

func (c *GlobalClient) DeleteProject(name string, force bool) error

DeleteProject deletes a project and removes it from the cache.

func (*GlobalClient) EnsureProject

func (c *GlobalClient) EnsureProject(name string, opts ...EnsureProjectOption) (*Client, error)

EnsureProject ensures a project exists and returns a Client for it. Options control whether the project is created if it doesn't exist and what config to apply.

func (*GlobalClient) HTTPSAddress

func (c *GlobalClient) HTTPSAddress() (string, error)

HTTPSAddress returns the core.https_address of the incus server.

func (*GlobalClient) HasExtension added in v1.1.0

func (c *GlobalClient) HasExtension(ext string) bool

HasExtension returns whether the server has the given extension.

func (*GlobalClient) IsConnected

func (c *GlobalClient) IsConnected() bool

IsConnected returns true if the client is connected.

func (*GlobalClient) IsDebugging

func (c *GlobalClient) IsDebugging() bool

IsDebugging returns true if debug logging is enabled.

func (*GlobalClient) IsRemote

func (c *GlobalClient) IsRemote() bool

IsRemote returns true if connected via network (not unix socket).

func (*GlobalClient) LogDebug

func (c *GlobalClient) LogDebug(msg string, args ...any)

LogDebug logs a debug message. The `any` here is ok.

func (*GlobalClient) LogError

func (c *GlobalClient) LogError(msg string, args ...any)

LogError logs an error. The `any` here is ok.

func (*GlobalClient) LogInfo

func (c *GlobalClient) LogInfo(msg string, args ...any)

LogInfo logs an info message. The `any` here is ok.

func (*GlobalClient) LogWarn

func (c *GlobalClient) LogWarn(msg string, args ...any)

LogWarn logs a warning. The `any` here is ok.

func (*GlobalClient) NetworkBridgeIPs

func (c *GlobalClient) NetworkBridgeIPs(networkName string) (ipv4 []string, ipv6 []string, err error)

NetworkBridgeIPs returns the IPv4 and IPv6 bridge addresses of an Incus network. The addresses are returned without CIDR notation. Addresses for which the network config key is absent or set to "none" are omitted.

func (*GlobalClient) ProjectConfig added in v1.2.0

func (c *GlobalClient) ProjectConfig(name string) (map[string]string, error)

ProjectConfig returns the Incus project's config, empty if it does not exist.

func (*GlobalClient) ProjectsWithConfig added in v1.2.0

func (c *GlobalClient) ProjectsWithConfig(key, value string) ([]string, error)

ProjectsWithConfig returns the names of the Incus projects carrying key set to value.

func (*GlobalClient) SameHost

func (c *GlobalClient) SameHost() error

SameHost returns nil of the connected incus and the current host share the same ip else an error.

func (*GlobalClient) SetOutputHandler

func (c *GlobalClient) SetOutputHandler(handler func(action Action, r Resource, data []byte))

SetOutputHandler sets the handler for resource output (e.g., logs). The handler receives raw bytes - formatting is the caller's responsibility.

func (*GlobalClient) SetProgressHandler

func (c *GlobalClient) SetProgressHandler(handler func(action Action, r Resource, args Options, p Progress))

SetProgressHandler sets the handler for live operation progress. Pass nil to disable. Operations run in parallel, so the handler may be called concurrently and must be safe for concurrent use.

func (*GlobalClient) Stderr added in v1.1.0

func (c *GlobalClient) Stderr() io.Writer

Stderr returns this clients error output.

func (*GlobalClient) Stdout added in v1.1.0

func (c *GlobalClient) Stdout() io.Writer

Stdout returns this clients standard output.

func (*GlobalClient) SwapStderr added in v1.1.0

func (c *GlobalClient) SwapStderr(w io.Writer) io.Writer

SwapStderr redirects this client's log output to w.

func (*GlobalClient) URL

func (c *GlobalClient) URL() (*url.URL, error)

URL returns the URL of the connection.

type Image

type Image struct {
	*BaseResource

	Config ImageConfig
	// contains filtered or unexported fields
}

Image represents an OCI or native Incus image copied to the Incus image cache.

func (*Image) AddService added in v1.2.0

func (r *Image) AddService(name string, platform string) error

AddService records a compose service that uses this image. One image often serves several services, and Client.Resource hands them all the same object - which two services wanting different architectures of it cannot share.

func (*Image) Created

func (r *Image) Created() bool

Created returns true if the image was created during the last Ensure call.

func (*Image) Delete

func (r *Image) Delete(ctx context.Context, opts ...Option) error

Delete removes the per-project copy of the image from the active project, and with OptionCache the store's copy as well. The cache is only known once the image has been ensured, so an image this process never ensured keeps it.

func (*Image) Done added in v1.3.0

func (r *Image) Done() error

Done closes the image's SFTP connection and removes the instance behind it.

func (*Image) Ensure

func (r *Image) Ensure(ctx context.Context, opts ...Option) error

Ensure retrieves an existing image from cache or copies it if Create option is set. When ImageConfig.Build is set the image is built locally via podman/docker.

func (*Image) IncusName

func (r *Image) IncusName() string

IncusName returns the image alias name used in Incus.

func (*Image) IsEnsured

func (r *Image) IsEnsured() bool

IsEnsured returns true if the image has been fetched/copied to cache.

func (*Image) NativeIncus

func (r *Image) NativeIncus() bool

NativeIncus returns true if this is a native Incus image.

func (*Image) Remote

func (r *Image) Remote() string

Remote returns the image remote.

func (*Image) ResolveUser added in v1.3.0

func (r *Image) ResolveUser(ctx context.Context, user string) (*Owner, error)

ResolveUser maps a `user[:group]` value to numeric ids, reading the image's /etc/passwd and /etc/group when either side is a name.

func (*Image) SFTP added in v1.3.0

func (r *Image) SFTP(ctx context.Context) (*sftp.Client, error)

SFTP returns a connection to the image's own filesystem, opened once and closed by Done.

func (*Image) Size

func (r *Image) Size() int64

Size returns the total image size in bytes as reported by the source server, or 0 when unknown. It is resolved best-effort before a download starts.

func (*Image) State added in v1.2.0

func (r *Image) State() *ImageState

State returns the image state as of the last fetch. It is replaced whole, never written into, so the result stays consistent for as long as it is held.

func (*Image) Status

func (r *Image) Status() string

Status returns the image status: "Unknown" or "Cached".

func (*Image) String

func (r *Image) String() string

String is for debugging.

type ImageConfig

type ImageConfig struct {
	// CacheClient is the project-scoped client to use as cache (for library
	// users). Takes precedence over CacheProject.
	CacheClient *Client

	// CacheProject is the project name to use as cache (for CLI users).
	// The project will be created if it doesn't exist.
	// Ignored if CacheClient is set.
	CacheProject string

	// LockVolume names the storage volume in the cache project holding the
	// per-alias locks. Empty means DefaultLockVolume.
	LockVolume string

	// Platform is the OCI platform the image is wanted for, for example
	// linux/arm64. Empty means the architecture of the server we are connected
	// to. Build.Platform takes precedence for a built image.
	Platform string

	// Build, when set, marks this image as locally built rather than pulled
	// from a registry. Ensure will shell out to podman/docker instead of
	// calling CopyImage.
	Build *BuildConfig

	// A list of service dependencies for log output.
	Services []string
}

ImageConfig contains the source and cache configuration for an image.

func (*ImageConfig) GetConfig

func (c *ImageConfig) GetConfig() any

GetConfig returns the configuration.

type ImageState added in v1.2.0

type ImageState struct {
	// IncusAlias is nil until the image is ensured.
	IncusAlias *incusApi.ImageAliasesEntry
	ETag       string

	// OCI metadata extracted from the image (empty/0 for native Incus images).
	UID uint64
	GID uint64

	// OCIUser is the image's own USER verbatim, which UID/GID cannot hold when
	// it names a user instead of numbering one.
	OCIUser string

	Entrypoint string
	Cmd        string
	Cwd        string
	Volumes    []string

	// Healthcheck is the image's own HEALTHCHECK, nil when it declares none.
	Healthcheck *ociHealthcheck

	// Size is the total image size in bytes as reported by the source server,
	// resolved best-effort before a download. 0 when unknown.
	Size int64

	// SourceFingerprint is what the source held at the last OptionResolveSource,
	// in the shape Incus fingerprints by. Empty when nothing resolved it, and
	// set means the OCI fields above came from the source rather than the image.
	SourceFingerprint string
}

ImageState is what the last fetch read back from Incus.

type Instance

type Instance struct {
	*BaseResource

	Config InstanceConfig
	// contains filtered or unexported fields
}

Instance represents an Incus container or virtual machine.

func (*Instance) Created

func (r *Instance) Created() bool

Created returns true if the instance was created during the last Ensure call.

func (*Instance) Delete

func (r *Instance) Delete(ctx context.Context, opts ...Option) error

Delete removes the instance from Incus.

func (*Instance) Ensure

func (r *Instance) Ensure(ctx context.Context, opts ...Option) error

Ensure retrieves an existing instance or creates a new one if args.Create is true.

func (*Instance) Exec added in v1.3.0

func (r *Instance) Exec(ctx context.Context, command ...string) error

Exec runs a command in the instance and waits for it to finish, discarding its output. A non-zero exit from the command itself is not an error.

func (*Instance) Frozen added in v1.3.0

func (r *Instance) Frozen() bool

Frozen returns whether the instance is paused. A frozen instance is not Running, so the two never both hold.

func (*Instance) HasState added in v1.3.0

func (r *Instance) HasState() bool

HasState returns true if the instance's runtime state was fetched.

func (*Instance) IncusName

func (r *Instance) IncusName() string

IncusName returns the sanitized instance name used in Incus.

func (*Instance) IsEnsured

func (r *Instance) IsEnsured() bool

IsEnsured returns true if the instance has been fetched/created.

func (*Instance) MarkDelete

func (r *Instance) MarkDelete()

MarkDelete marks a instance to be deleted after Ensure(), this is for down scaling instances.

func (*Instance) Pause added in v1.3.0

func (r *Instance) Pause(ctx context.Context, opts ...Option) error

Pause freezes the instance, leaving its processes in memory.

func (*Instance) PushFiles

func (r *Instance) PushFiles(ctx context.Context, sftpConn *sftp.Client) error

PushFiles pushes files into the instance over the instance's SFTP endpoint.

func (*Instance) Running

func (r *Instance) Running() bool

Running returns true if the instance is running.

func (*Instance) ServiceName

func (r *Instance) ServiceName() string

ServiceName returns the compose service name which has been set by the config.

func (*Instance) SetHealthCheckingStopped

func (r *Instance) SetHealthCheckingStopped(ctx context.Context, stopped bool) error

SetHealthCheckingStopped writes the user.healthcheck.stopped marker, which tells ic-healthd a stop was deliberate. The status is ic-healthd's alone.

func (*Instance) Start

func (r *Instance) Start(ctx context.Context, opts ...Option) error

Start starts the instance.

func (*Instance) State added in v1.2.0

func (r *Instance) State() *InstanceState

State returns the instance state as of the last fetch. It is replaced whole, never written into, so the result stays consistent for as long as it is held.

func (*Instance) Stop

func (r *Instance) Stop(ctx context.Context, opts ...Option) error

Stop stops the instance.

func (*Instance) String

func (r *Instance) String() string

String is for debugging.

func (*Instance) Unpause added in v1.3.0

func (r *Instance) Unpause(ctx context.Context, opts ...Option) error

Unpause resumes a paused instance.

func (*Instance) WaitIPs

func (r *Instance) WaitIPs(ctx context.Context, timeout time.Duration) ([]InterfaceIPs, error)

WaitIPs polls the instance state until each attached NIC reports its expected global addresses (IPv4 always, IPv6 too unless the network or this NIC's own attachment disables it) or the timeout elapses. A freshly started container may not have its DHCP lease(s) yet, so this gives it time. On timeout it returns an error: DNSWatcher registers an AAAA-equivalent record for any address family it waited for, so a missing one must not pass silently.

Incus has no lifecycle event for a NIC acquiring an address, so this cannot rely on the event-driven fetch() calls alone - it re-fetches itself on an interval. The device to network map comes from the instance and does not change while we wait; only its state does, which ips() reads each round.

Those rounds read into a state of their own, so a read taken before ic-healthd reported cannot rewind the status another instance is waiting on. The instance state is published once, from the round that succeeded.

type InstanceConfig

type InstanceConfig struct {
	// ServiceName represents the compose service name.
	ServiceName string

	// Type is the instance type (container or VM).
	Type incusApi.InstanceType

	// Image is the OCI image to create the instance from.
	Image string

	// Ensured Resources that this instance depends on.
	Resources []Resource

	// Devices are devices attached before instance creation (networks, proxies).
	Devices []InstanceDevice

	// Files are files pushed into the instance after creation.
	// Map key is the target path in the instance.
	Files []InstanceFile

	// Extensions contains Incus instance configuration options.
	Extensions map[string]string

	// ExtraDevices contains additional raw device configurations.
	ExtraDevices map[string]map[string]string

	// Profiles is the instance's full Incus profile list, from
	// x-incus-compose.profiles. Same semantics as `incus launch --profile`:
	// set verbatim, not merged with the implicit "default" profile - a list
	// that omits "default" means the instance won't carry it. Nil leaves
	// Incus's own default (the "default" profile) untouched.
	Profiles []string

	// NoRootDevice takes the root disk from the instance's profile instead.
	NoRootDevice bool

	// Dependencies maps dependency Incus instance names to the required health
	// status (HealthStatusHealthy, HealthStatusStarting, HealthStatusUnhealthy).
	// Instance.Start() blocks until all dependencies reach the required status.
	Dependencies map[string]string

	// Priority if set sets the instance priority to this instead PriorityInstance.
	Priority int

	// Entrypoint overrides the image entrypoint (compose `entrypoint:`). Nil
	// means unset; a non-nil value discards the image's default command.
	Entrypoint []string

	// Command overrides the image command (compose `command:`).
	Command []string

	// NoAutoVolumes leaves the paths the image declares as volumes to Incus,
	// instead of giving each one a volume of the service's own.
	NoAutoVolumes bool

	// Owner the instance runs as. Nil resolves User, then the image.
	Owner *Owner

	// User is the compose `user:` override, `uid[:gid]` or the names the
	// image's own /etc/passwd and /etc/group give them. Ignored unless Owner
	// is nil.
	User string

	// WorkingDir is the compose `working_dir:` override of the image's WORKDIR.
	WorkingDir string
}

InstanceConfig configures instance creation.

func (*InstanceConfig) GetConfig

func (c *InstanceConfig) GetConfig() any

GetConfig returns the configuration.

type InstanceDevice

type InstanceDevice struct {
	// Name is the device name.
	Name string

	// Config holds the device configuration.
	Config InstanceDeviceConfig
}

InstanceDevice represents an instance device configuration.

func (*InstanceDevice) ToIncusDevice

func (d *InstanceDevice) ToIncusDevice() (string, map[string]string, error)

ToIncusDevice converts the device to Incus API format. Returns the device name and configuration map.

type InstanceDeviceConfig

type InstanceDeviceConfig struct {
	// DeviceType identifies the device type (nic, disk, proxy, tmpfs).
	DeviceType string

	// Network is the network resource for nic devices (compose-managed).
	Network Resource

	// NetworkName is a raw Incus network name for nic devices that reference an
	// existing bridge directly, without a compose-managed Resource.
	// Only one of Network or NetworkName should be set.
	NetworkName string

	// Proxy contains proxy device configuration.
	Proxy InstanceDeviceProxyConfig

	// Disk contains disk device configuration.
	Disk InstanceDeviceDiskConfig

	// Tmpfs contains tmpfs device configuration.
	Tmpfs InstanceDeviceTmpfsConfig

	// Extensions contains direct device configuration options. For a raw device
	// (unknown DeviceType) it holds the entire device config; for a typed device
	// it holds extra keys merged over the generated config.
	Extensions map[string]string
}

InstanceDeviceConfig configures an instance device.

type InstanceDeviceDiskConfig

type InstanceDeviceDiskConfig struct {
	StorageVolumeConfig *StorageVolumeConfig

	// Source is the volume name or host path.
	Source string

	// Path is the mount point inside the instance.
	Path string

	// Shift enables UID/GID shifting for the mount.
	Shift bool

	// ReadOnly makes the mount read-only.
	ReadOnly bool
}

InstanceDeviceDiskConfig configures a disk device (volume or bind mount).

type InstanceDeviceProxyConfig

type InstanceDeviceProxyConfig struct {
	// ListenType is the protocol type for the listen side (e.g., "tcp").
	ListenType string

	// ListenAddr is the address to listen on.
	ListenAddr string

	// ListenPort is the port to listen on.
	ListenPort uint32

	// ConnectType is the protocol type for the connect side (e.g., "tcp").
	ConnectType string

	// ConnectAddr is the address to connect to.
	ConnectAddr string

	// ConnectPort is the port to connect to.
	ConnectPort uint32

	// Nat enables NAT mode for the proxy.
	Nat bool
}

InstanceDeviceProxyConfig configures a proxy device for port forwarding.

type InstanceDeviceTmpfsConfig

type InstanceDeviceTmpfsConfig struct {
	// Path is the mount point inside the instance.
	Path string

	// Size is the optional size limit in bytes.
	Size string
}

InstanceDeviceTmpfsConfig configures a tmpfs device.

type InstanceFile

type InstanceFile struct {
	Target string

	// Give either "File", "Content" or "Reader"
	File    string
	Content io.ReadSeekCloser

	// Owner of the pushed file. Nil uses the instance's oci.uid/oci.gid.
	Owner     *Owner
	Mode      int
	NoMKDir   bool
	DirMode   int
	Overwrite bool
}

InstanceFile represents a file to push to an instance after creation.

type InstanceState added in v1.2.0

type InstanceState struct {
	// State - nil means not ensured.
	IncusInstance *incusApi.Instance
	ETag          string

	// // UID/GID from the config or extracted from container (for volume shifting).
	UID uint64
	GID uint64

	IncusInstanceState *incusApi.InstanceState
}

type InterfaceIPs

type InterfaceIPs struct {
	Network string
	IPv4s   []string
	IPv6s   []string
}

InterfaceIPs represents interface ips.

type Kind

type Kind string

Kind identifies a resource type.

const (
	KindProject       Kind = "project"
	KindProfile       Kind = "profile"
	KindImage         Kind = "image"
	KindStorageVolume Kind = "storage-volume"
	KindNetwork       Kind = "network"
	KindInstance      Kind = "instance"
)

Resource kind identifiers.

type Network

type Network struct {
	*BaseResource

	Config NetworkConfig

	// CNames is a map of cnames indexed by target.
	CNames map[string][]string
	// contains filtered or unexported fields
}

Network represents an Incus bridge network.

func (*Network) Created

func (r *Network) Created() bool

Created returns true if the network was created during the last Ensure call.

func (*Network) Delete

func (r *Network) Delete(ctx context.Context, opts ...Option) error

Delete removes the network from Incus. External networks are never deleted.

func (*Network) Ensure

func (r *Network) Ensure(ctx context.Context, opts ...Option) error

Ensure retrieves an existing network or creates a new one if args.Create is true.

func (*Network) IncusName

func (r *Network) IncusName() string

IncusName returns the sanitized network name used in Incus.

func (*Network) IsEnsured

func (r *Network) IsEnsured() bool

IsEnsured returns true if the network state has been fetched from Incus.

func (*Network) State added in v1.2.0

func (r *Network) State() *NetworkState

State returns the network state as of the last fetch. It is replaced whole, never written into, so the result stays consistent for as long as it is held.

func (*Network) String

func (r *Network) String() string

String is for debugging.

type NetworkConfig

type NetworkConfig struct {
	// Type is the network type (default: "bridge").
	Type string

	// External marks the network as externally managed.
	// External networks must already exist and won't be created or deleted.
	External bool

	// Extensions are Incus network config key-value pairs sourced from the
	// x-incus compose extension. All entries pass through verbatim to the
	// Incus network config on creation.
	Extensions map[string]string

	// OverrideName is the x-incus-compose.network override. For external networks
	// it is probed raw then sanitized before falling back to the compose name.
	OverrideName string
}

NetworkConfig configures network creation.

func (*NetworkConfig) GetConfig

func (c *NetworkConfig) GetConfig() any

GetConfig returns the configuration.

type NetworkState added in v1.2.0

type NetworkState struct {
	// IncusNetwork is nil until the network is ensured.
	IncusNetwork *incusApi.Network
	ETag         string
}

NetworkState is what the last fetch read back from Incus.

type Option

type Option func(o *Options)

Option configures action arguments.

func OptionBackup added in v1.3.0

func OptionBackup(c *Client, cfg BackupConfig) Option

OptionBackup sets options required for ActionBackup.

func OptionBuild

func OptionBuild(info BuildInfo) Option

OptionBuild sets the build info for build-configured images (for ActionEnsure).

func OptionCache added in v1.3.0

func OptionCache() Option

OptionCache deletes an image's cached copy along with the project one.

func OptionCreate

func OptionCreate() Option

OptionCreate creates resources if they don't exist (for ActionEnsure).

func OptionDependencyTimeout

func OptionDependencyTimeout(t time.Duration) Option

OptionDependencyTimeout sets the max time to wait for dependency health checks. Falls back to OptionTimeout when zero.

func OptionExternalHealthd

func OptionExternalHealthd() Option

OptionExternalHealthd indicates that we have an unmanaged healthd.

func OptionFollow

func OptionFollow() Option

OptionFollow enables continuous streaming.

func OptionForce

func OptionForce() Option

OptionForce forces deletion/stop even if resource is in use.

func OptionNoHealthd

func OptionNoHealthd() Option

OptionNoHealthd indicates that we dont use healthd features.

func OptionPull

func OptionPull() Option

OptionPull forces cached images to refresh from their source registry (for ActionEnsure).

func OptionPullMode added in v1.2.0

func OptionPullMode(m PullMode) Option

OptionPullMode sets the pull policy for images (for ActionEnsure).

func OptionResolveSource added in v1.3.0

func OptionResolveSource() Option

OptionResolveSource records what an image's source holds now in its state, for a caller deciding whether to delete what it has (for ActionEnsure).

func OptionTimeout

func OptionTimeout(t time.Duration) Option

OptionTimeout sets the timeout for actions.

func OptionVolumes added in v1.3.0

func OptionVolumes() Option

OptionVolumes deletes an instance's own volumes along with it.

type Options

type Options struct {
	// Create resources if they don't exist (for ActionEnsure).
	Create bool

	// Force deletion/stop even if resource is in use.
	Force bool

	// Volumes takes an instance's own volumes with it (for ActionDelete).
	Volumes bool

	// Cache takes an image's cached copy with it (for ActionDelete).
	Cache bool

	// Timeout for actions (0 = default).
	Timeout time.Duration

	// DependencyTimeout is the max time to wait for dependency health checks.
	// Falls back to Timeout when zero.
	DependencyTimeout time.Duration

	// Follow enables continuous streaming.
	Follow bool

	// Pull is the pull policy for images (for ActionEnsure).
	Pull PullMode

	// ResolveSource reads what an image's source holds into its state, changing
	// nothing (for ActionEnsure).
	ResolveSource bool

	// Build controls rebuild behavior for build-configured images (for ActionEnsure).
	Build BuildInfo

	// Healthd indicates that we use healthd features.
	Healthd bool

	// ExternalHealthd indicates that we have an unmanaged healthd.
	ExternalHealthd bool

	BackupClient *Client
	BackupConfig BackupConfig
}

Options holds arguments for resource actions.

func NewOptions

func NewOptions(opts ...Option) Options

NewOptions makes a ActionArgs struct from ActionO* options.

type Owner added in v1.3.0

type Owner struct {
	UID uint64
	GID uint64
}

Owner is a uid/gid pair. A nil *Owner means unset, which each config field documents its own fallback for.

type PauseAble added in v1.3.0

type PauseAble interface {
	Pause(ctx context.Context, opts ...Option) error
}

PauseAble is implemented by resources that can be paused.

type PoolRunArgs

type PoolRunArgs struct {
	// FailFast stops processing on first error (default: true).
	FailFast bool
}

PoolRunArgs contains options for WorkerPool.Run.

type Profile

type Profile struct {
	*BaseResource

	Config ProfileConfig
	// contains filtered or unexported fields
}

Profile represents an Incus profile resource.

func (*Profile) Created

func (r *Profile) Created() bool

Created returns true if the profile was created during the last Ensure call.

func (*Profile) Delete

func (r *Profile) Delete(ctx context.Context, opts ...Option) error

Delete removes the profile from Incus.

func (*Profile) Ensure

func (r *Profile) Ensure(ctx context.Context, opts ...Option) error

Ensure retrieves an existing resource or creates a new one if args.Create is true.

func (*Profile) HasDevice

func (r *Profile) HasDevice(name string) bool

HasDevice returns true if the profile has a device with the given name.

func (*Profile) IncusName

func (r *Profile) IncusName() string

IncusName returns the sanitized profile name used in Incus.

func (*Profile) IsEnsured

func (r *Profile) IsEnsured() bool

IsEnsured returns true if the profile state has been fetched from Incus.

func (*Profile) State added in v1.2.0

func (r *Profile) State() *ProfileState

State returns the profile state as of the last fetch. It is replaced whole, never written into, so the result stays consistent for as long as it is held.

func (*Profile) String

func (r *Profile) String() string

String is for debugging.

type ProfileConfig

type ProfileConfig struct {
	// SourceServer is the Incus server to copy the profile from.
	// If nil, uses the global Incus client.
	SourceServer *iclient.Connection

	// SourceProject is the project containing the source profile.
	SourceProject string

	// SourceProfile is the name of the profile to copy from.
	SourceProfile string

	// NetworkOnly copies only NIC devices from the source profile.
	NetworkOnly bool
}

ProfileConfig configures profile creation from a source profile.

func (*ProfileConfig) GetConfig

func (c *ProfileConfig) GetConfig() any

GetConfig returns the configuration.

type ProfileState added in v1.2.0

type ProfileState struct {
	// IncusProfile is nil until the profile is ensured.
	IncusProfile *incusApi.Profile
	ETag         string
}

ProfileState is what the last fetch read back from Incus.

type Progress

type Progress struct {
	// Percent is 0-100, or -1 when the operation reports no percentage.
	Percent int

	// Text is the raw status text from Incus, empty when none was reported.
	Text string
}

Progress describes the live state of a long-running resource operation.

Native Incus images report a real percentage ("rootfs: 42% (3.10MB/s)"), so Percent is set. OCI image pulls only emit status text ("Retrieving OCI image from registry"); for those Percent is -1 and only Text is meaningful, because the registry download runs as an opaque skopeo subprocess with no byte or percentage feedback.

type PullMode added in v1.2.0

type PullMode int

PullMode controls when an image is refreshed from its source.

const (
	// PullMissing contacts the source only when the store has no copy (default).
	PullMissing PullMode = iota
	// PullAlways refreshes from the source even when the store has a copy.
	PullAlways
	// PullNever never contacts the source; a store miss is an error.
	PullNever
)

type Reader

type Reader struct {
	*bytes.Reader
}

Reader wraps bytes.Reader to add a no-op Close.

func NewReaderFromBytes

func NewReaderFromBytes(b []byte) *Reader

NewReaderFromBytes returns the given ClosingBufferReader from the given bytes.

func (*Reader) Close

func (cb *Reader) Close() error

Close is a noop.

type Resource

type Resource interface {
	// Kind returns the resource type identifier (e.g., "instance", "network").
	Kind() Kind

	// Name returns the user-facing resource name.
	Name() string

	// IncusName returns the sanitized name for incus.
	IncusName() string

	// Priority returns the creation/deletion priority for dependency ordering.
	// Lower values are created first and deleted last.
	Priority() int

	// IsEnsured returns wherever the resource has been ensured.
	IsEnsured() bool

	// Created returns true if the resource was created during the last Ensure call.
	// Returns false if the resource already existed or hasn't been ensured yet.
	Created() bool
}

Resource defines the common interface for all Incus resources.

type ResourceStore

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

ResourceStore provides storage for any BasicResource type.

func (*ResourceStore) Add

func (s *ResourceStore) Add(r Resource)

Add appends a resource to the store.

func (*ResourceStore) Get

func (s *ResourceStore) Get(kind Kind, name string, incus bool) Resource

Get retrieves a resource by kind and its name. Returns nil if not found.

func (*ResourceStore) GetOrCreate added in v1.3.0

func (s *ResourceStore) GetOrCreate(kind Kind, name string, create func() (Resource, error)) (Resource, error)

GetOrCreate atomic returns or creates a resource.

func (*ResourceStore) Range added in v1.1.0

func (s *ResourceStore) Range(f func(r Resource))

Range runs a function on each resource with an active lock.

func (*ResourceStore) Remove

func (s *ResourceStore) Remove(r Resource)

Remove removes a resource from the store by kind and name.

type RestoreAble added in v1.3.0

type RestoreAble interface {
	Restore(ctx context.Context, opts ...Option) error
}

RestoreAble is implemented by resources that can be restored from a backup.

type Stack

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

Stack manages a collection of resource operations. Resources are executed in priority order with proper dependency handling.

func NewStack

func NewStack(c *Client, opts ...StackOption) *Stack

NewStack creates a new Stack for the given project.

func (*Stack) Add

func (s *Stack) Add(resources ...Resource)

Add appends resources to the stack, skipping nil and already-added pointers. Since Client.Resource() deduplicates by IncusName, pointer identity is the right key: the same resource object must not run twice in parallel.

func (*Stack) AddOrdered

func (s *Stack) AddOrdered(order []string, resources map[string][]Resource)

AddOrdered adds resources in the given order.

func (*Stack) All

func (s *Stack) All() []Resource

All returns all tasks in the stack.

func (*Stack) ForAction

func (s *Stack) ForAction(action Action) *Stack

ForAction returns a new stack with resources filtered for the given action.

func (*Stack) ForActionF

func (s *Stack) ForActionF(action Action, filter func(r Resource) bool) *Stack

ForActionF returns a new stack with resources filtered for the given action, it allows custom filtering with the filter hook.

func (*Stack) Run

func (s *Stack) Run(ctx context.Context, action Action, opts ...Option) error

Run executes all tasks in priority order. Returns aggregated errors from all failed operations.

Image tasks are executed in parallel using a worker pool. All other tasks are executed sequentially to respect potential dependencies.

func (*Stack) SetOptions

func (s *Stack) SetOptions(opts ...StackOption)

SetOptions allows you to override options for the current stack.

func (*Stack) Sort

func (s *Stack) Sort(desc bool)

Sort sets the sort order.

type StackOption

type StackOption func(*StackOptions)

StackOption configures stack options.

func StackFailFast

func StackFailFast() StackOption

StackFailFast instructs the stack to fail on first error.

func StackSortDescending

func StackSortDescending() StackOption

StackSortDescending sorts resources in descending priority order.

func StackWorkers

func StackWorkers(w int) StackOption

StackWorkers sets the number of parallel workers.

type StackOptions

type StackOptions struct {
	Workers        int
	SortDescending bool
	FailFast       bool
}

StackOptions configures stack execution.

type StackRunArgs

type StackRunArgs struct {
	Options

	// Workers is the number of parallel workers per batch (default: 4).
	Workers int
}

StackRunArgs holds arguments for Stack.Run().

type StartAble

type StartAble interface {
	Start(ctx context.Context, opts ...Option) error
}

StartAble is implemented by resources that can be started.

type StopAble

type StopAble interface {
	Stop(ctx context.Context, opts ...Option) error
}

StopAble is implemented by resources that can be stopped.

type StorageVolume

type StorageVolume struct {
	*BaseResource

	Config StorageVolumeConfig
	// contains filtered or unexported fields
}

StorageVolume represents a custom storage volume with optional UID/GID shifting. Storage volumes provide persistent storage that can be attached to instances.

func BackupManifestVolume added in v1.3.0

func BackupManifestVolume(ctx context.Context, bc *Client, cfg BackupConfig) (*StorageVolume, error)

BackupManifestVolume ensures the manifest volume exists and returns it.

func (*StorageVolume) Backup added in v1.3.0

func (r *StorageVolume) Backup(ctx context.Context, opts ...Option) error

func (*StorageVolume) BackupEntry added in v1.3.0

func (r *StorageVolume) BackupEntry(cfg BackupConfig, backupProject string) BackupVolume

func (*StorageVolume) Created

func (r *StorageVolume) Created() bool

Created returns true if the volume was created during the last Ensure call.

func (*StorageVolume) Delete

func (r *StorageVolume) Delete(ctx context.Context, opts ...Option) error

Delete removes the storage volume from Incus.

func (*StorageVolume) Ensure

func (r *StorageVolume) Ensure(ctx context.Context, opts ...Option) error

Ensure retrieves an existing storage volume or creates a new one if Create option is set.

func (*StorageVolume) IncusName

func (r *StorageVolume) IncusName() string

IncusName returns the prefixed volume name used in Incus.

func (*StorageVolume) IsEnsured

func (r *StorageVolume) IsEnsured() bool

IsEnsured returns true if the volume has been fetched/created.

func (*StorageVolume) Lock added in v1.2.0

func (r *StorageVolume) Lock(ctx context.Context, sc *sftp.Client, name string, stale time.Duration) (*VolumeLock, error)

Lock acquires the named advisory lock on the volume, blocking until it is held or ctx is done. The name may contain slashes; missing parent directories are created. A stale of 0 means the lock is never taken over and the holder does not refresh it. sc must stay open until Unlock is called - the acquire uses it, and when stale > 0 so does the heartbeat.

func (*StorageVolume) Restore added in v1.3.0

func (r *StorageVolume) Restore(ctx context.Context, opts ...Option) error

Restore rewinds the volume to the restore point named by the backup config. The instances holding it must be stopped; Incus refreshes a mounted volume without complaint and the writes already in flight are not part of the backup.

func (*StorageVolume) SFTP added in v1.2.0

func (r *StorageVolume) SFTP(ctx context.Context) (*sftp.Client, error)

SFTP returns a new SFTP connection to the volume. The caller closes it.

func (*StorageVolume) Start

func (r *StorageVolume) Start(ctx context.Context, _ ...Option) error

Start validates the storage volume.

func (*StorageVolume) State added in v1.2.0

func (r *StorageVolume) State() *StorageVolumeState

State returns the volume state as of the last fetch. It is replaced whole, never written into, so the result stays consistent for as long as it is held.

func (*StorageVolume) String

func (r *StorageVolume) String() string

String is for debugging.

type StorageVolumeConfig

type StorageVolumeConfig struct {
	// Pool is the storage pool to create the volume in.
	// Defaults to ClientProject.Config.DefaultStoragePool.
	Pool string

	// Shifted enables UID/GID shifting for the volume.
	Shifted bool

	// Owner the volume is created for. Nil resolves User, then ImageResource.
	Owner *Owner

	// User is the compose `user:` override the owning instance was given, in
	// the same form. Ignored unless Owner is nil.
	User string

	// ImageResource to take UID/GID from for shifting, only
	// needed if shifting is true.
	ImageResource Resource

	// HostPath, when set, seeds the volume with the local directory contents on first creation.
	HostPath string

	// Prefetch, when set, fills the volume on first creation with what
	// ImageResource holds at that path. Needs ImageResource.
	Prefetch string

	// Extensions contains additional volume configuration options.
	Extensions map[string]string
}

StorageVolumeConfig configures storage volume creation.

func (*StorageVolumeConfig) GetConfig

func (c *StorageVolumeConfig) GetConfig() any

GetConfig returns the configuration.

type StorageVolumeState added in v1.2.0

type StorageVolumeState struct {
	// IncusVolume is nil until the volume is ensured.
	IncusVolume *incusApi.StorageVolume
	ETag        string

	// Created reports whether that volume is one this run made.
	Created bool
}

StorageVolumeState is what the last fetch read back from Incus.

type SwapWriter added in v1.1.0

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

SwapWriter is an io.Writer whose destination can be swapped at runtime.

func NewSwapWriter added in v1.1.0

func NewSwapWriter(w io.Writer) *SwapWriter

NewSwapWriter creates a LogWriter initially writing to w.

func (*SwapWriter) Swap added in v1.1.0

func (l *SwapWriter) Swap(w io.Writer) io.Writer

Swap replaces the destination and returns the previous one.

func (*SwapWriter) Write added in v1.1.0

func (l *SwapWriter) Write(b []byte) (int, error)

type UnpauseAble added in v1.3.0

type UnpauseAble interface {
	Unpause(ctx context.Context, opts ...Option) error
}

UnpauseAble is implemented by resources that can be resumed after a pause.

type VolumeInfos added in v1.3.0

type VolumeInfos struct {
	Project string `json:"project"`
	Pool    string `json:"pool"`
	Name    string `json:"name"`
}

VolumeInfos represents either a Source or a Backup in a BackupEntry.

type VolumeLock added in v1.2.0

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

VolumeLock is an advisory lock on a file inside a StorageVolume; release it with Unlock.

func BackupLock added in v1.3.0

func BackupLock(ctx context.Context, bc *Client, sc *sftp.Client, cfg BackupConfig, stale time.Duration, lockName string) (*VolumeLock, error)

BackupLock creates backupLock which you MUST release with Unlock(). sc is owned by the caller; close it after Unlock.

func (*VolumeLock) Unlock added in v1.2.0

func (l *VolumeLock) Unlock() error

Unlock releases the lock, deleting the lock file only if it still names this holder as owner.

type WorkerPool

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

WorkerPool executes tasks concurrently with a limited number of workers.

func NewWorkerPool

func NewWorkerPool(workers int) *WorkerPool

NewWorkerPool creates a new WorkerPool with the specified number of workers.

func (*WorkerPool) Run

func (p *WorkerPool) Run(args PoolRunArgs) error

Run executes all submitted tasks using the worker pool. With FailFast it returns the first error without waiting for the remaining tasks; otherwise it waits for all tasks and returns their aggregated errors.

func (*WorkerPool) Submit

func (p *WorkerPool) Submit(fn func() error)

Submit adds a task to the pool.

Jump to

Keyboard shortcuts

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