Documentation
¶
Overview ¶
Package emulator provides first-class support for cloud-API emulators — long-running container services (Floci, MiniStack, k3s, OpenBao, …) that stand in for AWS, GCP, Azure, Kubernetes, and select backing services during local development and testing.
A driver is a built-in emulator product: it supplies container defaults (image, ports, services) and turns a live container endpoint into a connection Profile (env vars, kubeconfig, Terraform provider fragment).
This core package is driver-agnostic: the concrete drivers live in the pkg/emulator/driver subpackage (and their profile builders in pkg/emulator/target), registering into this package's registry via RegisterDriver at init. Importing pkg/emulator/driver is what populates the registry.
Index ¶
- Constants
- func Drivers() []string
- func InstanceDataDir(stack, name string) (string, error)
- func LookupInstanceDataDir(stack, name string) string
- func RegisterDriver(d EmulatorDriver)
- func RegisterProfileResolver(r ProfileResolver)
- func ResolveYAMLFunc(atmosConfig *schema.AtmosConfiguration, args, currentStack string, ...) (any, error)
- type ContainerDefaults
- type EmulatorDriver
- type Endpoint
- type Manager
- func (m *Manager) Down(ctx context.Context, stack, name string) error
- func (m *Manager) Exec(ctx context.Context, stack, name string, command []string) error
- func (m *Manager) Kubeconfig(ctx context.Context, stack, name string) ([]byte, error)
- func (m *Manager) Logs(ctx context.Context, stack, name string, follow bool) error
- func (m *Manager) Ps(ctx context.Context, stack string) ([]Status, error)
- func (m *Manager) Reset(ctx context.Context, spec *Spec, stack, name string) error
- func (m *Manager) Resolve(ctx context.Context, spec *Spec, stack, name string) (Endpoint, Profile, error)
- func (m *Manager) Up(ctx context.Context, spec *Spec, stack, name string, env map[string]string) (Endpoint, error)
- func (m *Manager) VaultToken(ctx context.Context, stack, name string) (string, error)
- type Profile
- type ProfileResolver
- type RootlessConfig
- type RootlessOverrider
- type Spec
- func (s *Spec) ContainerPorts() ([]schema.ContainerPort, error)
- func (s *Spec) DataDir() (string, error)
- func (s *Spec) DefaultCommand() ([]string, error)
- func (s *Spec) DefaultEnv() (map[string]string, error)
- func (s *Spec) EffectiveHealthCheck() (*container.HealthCheck, error)
- func (s *Spec) EffectiveRestart() (*container.RestartPolicy, error)
- func (s *Spec) HostRuntime() bool
- func (s *Spec) Image() (string, error)
- func (s *Spec) PersistEnabled() bool
- func (s *Spec) Privileged() (bool, error)
- func (s *Spec) ResolvedDriver() (EmulatorDriver, error)
- func (s *Spec) RootlessOverride() (RootlessConfig, error)
- func (s *Spec) Target() (string, error)
- func (s *Spec) Validate() error
- type Status
Constants ¶
const ( TargetAWS = "aws" TargetGCP = "gcp" TargetAzure = "azure" TargetKubernetes = "kubernetes" TargetVault = "vault" TargetRegistry = "registry" TargetGit = "git" )
Emulator targets — what an emulator emulates. Derived from a driver's Target().
Variables ¶
This section is empty.
Functions ¶
func InstanceDataDir ¶
InstanceDataDir returns (creating it if needed) the host directory that backs an emulator instance's persisted state, under the XDG cache. It honors ATMOS_XDG_CACHE_HOME / XDG_CACHE_HOME. The returned directory is bind-mounted onto the driver's in-container data dir when persistence is enabled.
func LookupInstanceDataDir ¶
LookupInstanceDataDir resolves the host directory backing an emulator instance's persisted state WITHOUT creating it. Used by `reset`, which removes the directory.
func RegisterDriver ¶
func RegisterDriver(d EmulatorDriver)
RegisterDriver adds a built-in driver to the registry. Called from the driver subpackage's init(). Last registration wins, allowing override in tests.
func RegisterProfileResolver ¶
func RegisterProfileResolver(r ProfileResolver)
RegisterProfileResolver registers the process-wide emulator profile resolver used by the `!emulator` YAML function. Called at init by pkg/component/emulator.
func ResolveYAMLFunc ¶
func ResolveYAMLFunc(atmosConfig *schema.AtmosConfiguration, args, currentStack string, stackInfo *schema.ConfigAndStacksInfo) (any, error)
ResolveYAMLFunc evaluates `!emulator <ref> <key>` where args is the string after the tag. <ref> is the emulator component name (resolved in currentStack); <key> is one of: endpoint|url, host, port, region, project, kubeconfig, or env.<VAR>.
Types ¶
type ContainerDefaults ¶
type ContainerDefaults struct {
// Image is the default container image, e.g. "floci/floci:latest".
Image string
// Ports are the default container ports the emulator listens on.
Ports []int
// Services are the default emulated services (informational; may drive env).
Services []string
// Env are default container environment variables.
Env map[string]string
// Privileged runs the container in privileged mode. It is a driver property,
// not user config: some emulators (k3s, which runs a nested Kubernetes) only
// function privileged.
Privileged bool
// Command is the default container command/args (e.g. k3s must run `server`).
Command []string
// DataDir is the in-container path where the emulator persists its state
// (e.g. "/data" for floci, "/var/lib/registry" for the registry). When
// persistence is enabled (the default), the manager bind-mounts a host
// directory under the XDG cache onto this path so state survives `down`/`up`.
// Empty means the driver has no persistent state, so persistence is a no-op.
DataDir string
// HealthCheck is the driver's default container health check, so the emulator
// is readiness-aware out of the box (and `up` can gate on it). The component's
// `container.healthcheck` overrides it; nil means the driver ships no default
// (e.g. vault, whose readiness is handled by its bootstrap). The shape mirrors
// the container kind's healthcheck, reusing schema.ContainerHealthCheck.
HealthCheck *schema.ContainerHealthCheck
// Restart is the driver's default container restart policy. The component's
// `container.restart` overrides it; nil means no default (runtime default `no`).
Restart *schema.ContainerRestart
}
ContainerDefaults are the built-in container defaults a driver supplies. Every field is overridable in the component's `container:` block (the hooks model).
type EmulatorDriver ¶
type EmulatorDriver interface {
// Name is the driver identifier used as `driver:` in component config.
Name() string
// Target is what the driver emulates (aws|gcp|azure|kubernetes|vault|registry).
Target() string
// Defaults are the built-in container defaults (overridable in `container:`).
Defaults() ContainerDefaults
// Profile turns a live endpoint into a connection profile.
Profile(ep *Endpoint) Profile
}
EmulatorDriver is a built-in emulator product (floci, k3s, openbao, …).
func ResolveDriver ¶
func ResolveDriver(name string) (EmulatorDriver, error)
ResolveDriver returns the built-in driver registered for the given name.
type Endpoint ¶
type Endpoint struct {
// Target is what the emulator emulates: aws|gcp|azure|kubernetes|vault|registry.
Target string
// Host is the host the emulator is reachable on (typically "localhost").
Host string
// Ports maps a container port to its live host port.
Ports map[int]int
// Region is the cloud region (aws/gcp/azure), when configured.
Region string
// Project is the GCP project, when configured.
Project string
// Services are the enabled emulated services (informational; drives env/endpoints).
Services []string
}
Endpoint is the live connection info for a running emulator container, resolved from the runtime's reported port bindings.
func (*Endpoint) Authority ¶
Authority returns the live "host:port" (no scheme) for the primary host port, or "" when no port is bound. Used by targets whose env vars want a bare host:port (GCP emulator hosts, Azure endpoints, registries).
func (*Endpoint) HostPort ¶
HostPort returns the live host port bound to the given container port, and whether a binding exists.
func (*Endpoint) PrimaryHostPort ¶
PrimaryHostPort returns the live host port bound to the lowest-numbered container port — the conventional "primary" endpoint for single-port emulators (e.g. Floci/LocalStack on 4566).
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager operates emulator containers over the container component lifecycle, using ComponentType "emulator" so discovery, labels, and naming are shared with the container kind. It does not process stacks; callers pass a resolved Spec.
func NewManager ¶
NewManager returns a Manager that detects the container runtime using the given preference ("docker"|"podman"|"") and Podman auto-start setting.
func (*Manager) Exec ¶
Exec runs a command in the emulator container (interactive; defaults to a shell).
func (*Manager) Kubeconfig ¶
Kubeconfig harvests the admin kubeconfig from a running kubernetes-target emulator (k3s) and rewrites its server URL to the live host port so it works from the host. The embedded CA and client credentials are preserved verbatim — that kubeconfig IS the credential.
It polls until the kubeconfig is readable (k3s writes it shortly after the API port opens) or the timeout elapses, so callers invoked immediately after `emulator up` do not lose the readiness race.
func (*Manager) Ps ¶
Ps lists emulator containers (by canonical labels). When stack is non-empty it returns only that stack's emulators; an empty stack returns every emulator across all stacks (used by `atmos emulator list` without `--stack`).
func (*Manager) Reset ¶
Reset stops and removes the emulator's container, then wipes its persisted state directory under the XDG cache. The next `up` starts a fresh instance. The data directory is derived from stack+name alone, so reset works without resolving the driver or a running container.
func (*Manager) Resolve ¶
func (m *Manager) Resolve(ctx context.Context, spec *Spec, stack, name string) (Endpoint, Profile, error)
Resolve discovers the running emulator and builds its connection profile. It is the seam consumed by auth identities and the !emulator YAML function.
func (*Manager) Up ¶
func (m *Manager) Up(ctx context.Context, spec *Spec, stack, name string, env map[string]string) (Endpoint, error)
Up reconciles the emulator's long-lived container and returns its live endpoint. Host ports are auto-assigned (0) unless pinned, so concurrent emulators do not collide; the live ports are read back from the runtime.
type Profile ¶
type Profile struct {
// Env is the SDK / Terraform / VAULT_ADDR / registry environment.
Env map[string]string
// Kubeconfig holds a materialized kubeconfig for kubernetes targets.
Kubeconfig []byte
// ResolverURL is the base endpoint for Atmos's internal AWS SDK (aws only).
ResolverURL string
// Provider is a Terraform provider-config fragment (endpoints + skip-flags +
// creds) consumed by the provider-config contributor.
Provider map[string]any
}
Profile is what a driver advertises for a live emulator. Consumers subscribe to the parts they need: auth identities take Env (and, for kubernetes, Kubeconfig); the AWS resolver takes ResolverURL; the provider-config contributor takes Provider.
type ProfileResolver ¶
type ProfileResolver func(atmosConfig *schema.AtmosConfiguration, ref, currentStack string, stackInfo *schema.ConfigAndStacksInfo) (*Endpoint, *Profile, error)
ProfileResolver resolves a running emulator's live endpoint and connection profile for the `!emulator` YAML function, by component reference and stack.
It is implemented ABOVE this layer (it needs stack processing and the container runtime) and registered at init via RegisterProfileResolver, keeping pkg/emulator free of any stack-processing import (no cycle).
type RootlessConfig ¶
RootlessConfig is the run-args/command a driver substitutes under a rootless runtime, and whether such an override applies.
type RootlessOverrider ¶
type RootlessOverrider interface {
// RootlessOverride returns the run-args (e.g. an entrypoint override) and the
// container command to use under a rootless runtime, and whether such an
// override exists (false → the rootful defaults are used in all runtimes).
RootlessOverride() (runArgs, command []string, ok bool)
}
RootlessOverrider is an optional driver interface for emulators whose container must run differently under a rootless runtime. For example, k3s needs a cgroup-nesting entrypoint and the kubelet `KubeletInUserNamespace` feature flag that rootful runtimes don't require. The manager calls RootlessOverride only when it detects a rootless runtime; otherwise the driver's default (rootful) command runs. Drivers without a rootless variant simply don't implement it.
type Spec ¶
type Spec struct {
// Driver is the built-in driver kind, e.g. "floci/aws".
Driver string
// Cloud is the explicit target; optional, derived from the driver when empty.
Cloud string
// Region is the cloud region (aws/gcp/azure).
Region string
// Project is the GCP project.
Project string
// Services are the emulated services to enable (informational; may drive env).
Services []string
// Ephemeral, when set true, runs the emulator without persisting state: no
// host directory is bind-mounted onto the driver's data dir, so all state is
// lost on `down`. It is tri-state: nil (the default) means persist. The CLI
// `--ephemeral` flag forces a throwaway instance for a single `up`.
Ephemeral *bool
// Container holds image/ports/mounts/env overrides for the emulator container.
Container *schema.ContainerRunStep
}
Spec is the resolved, per-instance emulator component configuration, parsed from the (merged, templated) component section. The nested `container:` block reuses the container kind's ContainerRunStep so emulator and container config stay consistent. These are first-class component sections (siblings of `metadata`/`env`/`composition`), NOT nested under `vars`.
func FromComponentSection ¶
FromComponentSection decodes a resolved component section into a Spec, reading the first-class top-level keys `driver`, `cloud`, `region`, `project`, `services`, and the nested `container:` block.
func (*Spec) ContainerPorts ¶
func (s *Spec) ContainerPorts() ([]schema.ContainerPort, error)
ContainerPorts returns the effective container ports to publish: the explicit `container.ports` when set, otherwise the driver's default ports. Host ports are left at 0 (auto-assigned) unless explicitly pinned.
func (*Spec) DataDir ¶
DataDir returns the driver's in-container persistence path (e.g. "/app/data"). An empty string means the driver has no persistent state, so persistence is a no-op for it.
func (*Spec) DefaultCommand ¶
DefaultCommand returns the driver's default container command/args (e.g. k3s must run `server`). It is empty for emulators that use the image's entrypoint.
func (*Spec) DefaultEnv ¶
DefaultEnv returns the driver's default container environment variables (e.g. k3s requires a K3S_TOKEN to start). The resolved profile/component env is layered over these by the manager.
func (*Spec) EffectiveHealthCheck ¶
func (s *Spec) EffectiveHealthCheck() (*container.HealthCheck, error)
EffectiveHealthCheck returns the runtime health check for the emulator: the component's `container.healthcheck` when set, otherwise the driver's default (nil → no health check). It reuses the container kind's mapping so the Compose `test` form and disable semantics are identical across kinds.
func (*Spec) EffectiveRestart ¶
func (s *Spec) EffectiveRestart() (*container.RestartPolicy, error)
EffectiveRestart returns the runtime restart policy for the emulator: the component's `container.restart` when set, otherwise the driver's default (nil → the runtime default of `no`).
func (*Spec) HostRuntime ¶
HostRuntime reports whether the emulator container needs access to the host container runtime (Docker-out-of-Docker), set via `container.runtime.host: true`. Used, for example, by the MiniStack driver's EKS service to spawn a k3s sibling.
func (*Spec) Image ¶
Image returns the effective container image: the explicit `container.image` when set, otherwise the driver's default image.
func (*Spec) PersistEnabled ¶
PersistEnabled reports whether the emulator should persist state across `down`/`up`. Persistence is on by default; only an explicit `ephemeral: true` (or the `--ephemeral` CLI flag) disables it.
func (*Spec) Privileged ¶
Privileged reports whether the emulator container must run in privileged mode. This is a driver property (e.g. k3s runs a nested Kubernetes), not user config.
func (*Spec) ResolvedDriver ¶
func (s *Spec) ResolvedDriver() (EmulatorDriver, error)
Driver resolves the registered driver for this spec.
func (*Spec) RootlessOverride ¶
func (s *Spec) RootlessOverride() (RootlessConfig, error)
RootlessOverride returns the rootless run-args/command for the spec's driver when it defines one (e.g. k3s needs a cgroup-nesting entrypoint). Drivers without a rootless variant return Applies=false, so the rootful defaults are used in all runtimes.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package driver holds the built-in emulator drivers (floci, k3s, openbao, …).
|
Package driver holds the built-in emulator drivers (floci, k3s, openbao, …). |
|
Package target holds the per-target connection-profile builders for emulator drivers: each turns a live emulator Endpoint into a Profile (SDK env vars, a Terraform provider fragment, or a kubeconfig placeholder).
|
Package target holds the per-target connection-profile builders for emulator drivers: each turns a live emulator Endpoint into a Profile (SDK env vars, a Terraform provider fragment, or a kubeconfig placeholder). |