compose

package
v0.0.0-...-c875e56 Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package compose parses, validates and transforms the Docker Compose subset of compose-spec.md. Everything here is pure: same file + same variables + same policy produce exactly the same plan and findings (INV-011, INV-014) — which is what makes the whole pipeline unit-testable without a server.

Index

Constants

View Source
const (
	CodeParseError                 = "compose_parse_error"
	CodeVersionIgnored             = "compose_version_ignored"
	CodeKeyIgnored                 = "compose_key_ignored"
	CodeContainerNameIgnored       = "compose_container_name_ignored"
	CodeSwarmKeyRejected           = "compose_swarm_key_rejected"
	CodeNetworkModeHostRejected    = "compose_network_mode_host_rejected"
	CodeNetworkModeRejected        = "compose_network_mode_rejected"
	CodeHostNamespaceRejected      = "compose_host_namespace_rejected"
	CodePrivilegedDenied           = "compose_privileged_denied"
	CodeBindMountDenied            = "compose_bind_mount_denied"
	CodeExternalObjectRejected     = "compose_external_object_rejected"
	CodeIncludeRejected            = "compose_include_rejected"
	CodePlatformUnsupported        = "compose_platform_unsupported"
	CodeInvalidServiceName         = "compose_invalid_service_name"
	CodeReservedLabel              = "compose_reserved_label"
	CodePathTraversal              = "compose_path_traversal"
	CodeConflictingLimits          = "compose_conflicting_limits"
	CodeDependencyCycle            = "compose_dependency_cycle"
	CodeDependencyNeedsHealthcheck = "compose_dependency_needs_healthcheck"
	CodeRequiredVariableMissing    = "compose_required_variable_missing"
	CodePreviewSeedInvalid         = "compose_preview_seed_invalid"
	CodeVariableUndefined          = "compose_variable_undefined"
	CodeSharedVariableMissing      = "compose_shared_variable_missing"
	CodeMagicVariableInvalidType   = "compose_magic_variable_invalid_type"
	CodeMagicVariableUnknownComp   = "compose_magic_variable_unknown_component"
	CodeStorageExtensionConflict   = "compose_storage_extension_conflict"
	CodeAccessPublicRouteInvalid   = "compose_access_public_route_invalid"
	CodeRoutablePortUnresolved     = "compose_routable_port_unresolved"
	CodeDomainConflict             = "compose_domain_conflict"
	CodeOneshotWithoutExclude      = "compose_oneshot_without_exclude"
	CodeZeroDowntimeIneligible     = "compose_zero_downtime_ineligible"
	CodeFileContentTooLarge        = "compose_file_content_too_large"
	CodeHookOnOneShot              = "compose_hook_on_one_shot"
	CodeHookWithoutHealthcheck     = "compose_hook_without_healthcheck"
)

Stable finding codes (compose-spec §11) — consumed by the API in details[].

Variables

This section is empty.

Functions

func GenerateMagicValue

func GenerateMagicValue(ref MagicRef) (string, error)

GenerateMagicValue produces the value of a credential-type reference with a CSPRNG (§4.2). FQDN/URL types are resolved from domains by the engine, never generated here.

func HasErrors

func HasErrors(fs []Finding) bool

HasErrors reports whether at least one finding blocks the operation.

func NormalizeComponentID

func NormalizeComponentID(service string) string

NormalizeComponentID converts a compose service name to its magic <ID> (§4.1): uppercase, non-alphanumerics replaced by underscores.

func ParseMagicName

func ParseMagicName(name string, components map[string]bool) (MagicRef, *Finding)

ParseMagicName parses one SERVICE_* variable name. components are the normalized IDs of the stack's services — needed to split the ID from an optional trailing port on FQDN/URL variants (§4.1–4.2).

func ScanMagicReferences

func ScanMagicReferences(content string, services []string) ([]MagicRef, []Finding)

ScanMagicReferences finds every SERVICE_* reference of a compose file and parses them against the stack's services. Each distinct name is returned once, sorted — determinism again (INV-011).

Types

type Dependency

type Dependency struct {
	Service   string
	Condition string
}

Dependency is one edge of the ordering plan (§2.6).

type Finding

type Finding struct {
	Code     string   `json:"code"`
	Severity Severity `json:"severity"`
	Service  string   `json:"service,omitempty"`
	Path     string   `json:"path,omitempty"`
	Message  string   `json:"message"`
}

Finding is one validation outcome. Message is generic and never contains a secret (INV-003); Path is the YAML path (e.g. services.app.deploy.replicas).

func (Finding) String

func (f Finding) String() string

type HealthFlags

type HealthFlags struct {
	Test          []string
	Interval      time.Duration
	Timeout       time.Duration
	StartPeriod   time.Duration
	StartInterval time.Duration
	Retries       uint64
	Disable       bool
}

HealthFlags maps compose healthcheck to docker create flags (§7.1), defaults filled.

type Input

type Input struct {
	Content   string
	StackUUID string
	Variables map[string]string
	Policy    Policy
	// Raw enables the raw compose mode (§9): transformations that rename or
	// rewrite are skipped, security boundaries stay.
	Raw bool
}

Input is everything the pipeline needs. Variables are the RESOLVED stack variables (shared scopes and magic variables already merged by the caller, compose-spec §3.2): this package never talks to the database.

type LimitFlags

type LimitFlags struct {
	Memory            int64
	MemoryReservation int64
	MemorySwap        int64
	CPUs              float64
	CPUShares         int64
	CPUSet            string
	Pids              int64
}

LimitFlags are the normalized resource limits (§8.5) — deploy.resources and legacy keys reduced to one set of docker create flags.

type MagicRef

type MagicRef struct {
	// Name is the full variable name as referenced.
	Name string
	Type MagicType
	// ID is the component identifier ([A-Z0-9_]+). The same ID means the
	// same value across the whole stack (§4.1).
	ID string
	// Length is the generation length (§4.2); 0 for FQDN/URL.
	Length int
	// Port is the internal port for FQDN/URL variants (§4.2); 0 if absent.
	Port int
	// Credential marks the types stored is_secret = true (§4.3).
	Credential bool
}

MagicRef is one parsed SERVICE_* reference.

type MagicType

type MagicType string

MagicType is a supported <TYPE> (§4.2).

const (
	MagicFQDN                MagicType = "FQDN"
	MagicURL                 MagicType = "URL"
	MagicUser                MagicType = "USER"
	MagicPassword            MagicType = "PASSWORD"
	MagicPasswordWithSymbols MagicType = "PASSWORDWITHSYMBOLS"
	MagicBase64              MagicType = "BASE64"
	MagicRealBase64          MagicType = "REALBASE64"
	MagicHex                 MagicType = "HEX"
)

Magic value placeholders substituted at deploy time (compose-spec).

type MountPlan

type MountPlan struct {
	Type     string // volume | bind | tmpfs
	Source   string // docker volume name, or host path for binds
	Target   string
	ReadOnly bool
	// Ext carries the managed file/directory extensions (§5.1), nil if none.
	Ext *VolumeExtensions
}

MountPlan is one container mount after rewriting (§2.4).

type Plan

type Plan struct {
	StackUUID string
	// NetworkName is the isolated bridge network of the stack (§2.1).
	NetworkName string
	// ExtraNetworks are the additional file-declared networks, prefixed
	// (§2.1): docker name -> declared name.
	ExtraNetworks map[string]string
	// Volumes maps declared named volumes to their docker names (§2.4).
	Volumes map[string]string
	// SeedVolumes maps the docker name of a volume declaring
	// `x-akerdock: preview_seed: clone` to its DECLARED name (ADR-029): a
	// preview deployment seeds it, still empty, from the production volume
	// `<app-uuid>_<declared>` before the mounting service first starts.
	SeedVolumes map[string]string
	// ExternalVolumes maps `external: true` volumes to their real docker
	// names: mounted verbatim, never created, never prefixed. This is how an
	// adopted stack keeps its data across the normalizing redeployment
	// (§20.7, INV-008).
	ExternalVolumes map[string]string
	// Services in topological start order (§2.6).
	Services []ServicePlan
	// Canonical is the transformed compose, traced in deployment logs (§2).
	Canonical string
}

Plan is the deterministic execution plan of a stack (compose-spec §2): what the deployment engine creates on the server, in which order, under which names. Same file + same input = same plan (INV-011, INV-014).

type Policy

type Policy struct {
	AllowPrivileged      bool
	AllowDevices         bool
	AllowSecurityOpt     bool
	AllowExternalObjects bool
	// ExtraCapAdd extends the default allowlist (NET_BIND_SERVICE, CHOWN,
	// SETUID, SETGID).
	ExtraCapAdd []string
	// AllowedBindRoots are the absolute host directories under which bind
	// mounts are allowed. Empty = every absolute bind is denied.
	AllowedBindRoots []string
}

Policy is the per-server policy for privilege-raising keys (compose-spec §1.4). The zero value is the default policy: everything denied.

type Result

type Result struct {
	Project  *types.Project
	Plan     *Plan
	Findings []Finding
}

Result carries the loaded project, the execution plan and every finding. Plan is nil when findings contain at least one error.

func Load

func Load(ctx context.Context, in Input) (*Result, error)

Load runs the full control-plane pipeline of compose-spec.md sections 1–5: raw pass (keys the schema would reject must be ignored-with-warning, not fatal), Compose Specification parse + interpolation, policy validation and deterministic transformation into a Plan.

func (*Result) HasErrors

func (r *Result) HasErrors() bool

HasErrors reports whether the compose file is deployable.

type ServiceExtensions

type ServiceExtensions struct {
	ExcludeFromHC bool
	// AccessPublicRoutes are narrow unauthenticated paths owned by this
	// routed service (ADR-049).
	AccessPublicRoutes []accessroute.Route
	// ZeroDowntime is nil when unset (default: eligible), false when the
	// stack cannot tolerate two simultaneous instances (ADR-015).
	ZeroDowntime *bool
	// Pre/PostDeploymentCommand are the stack-level hooks (deployment-engine
	// §10, applied per service): pre runs in the EXISTING container of this
	// service before any build or mutation; post runs in its CANDIDATE once
	// healthy, before its switch — a failing post never switches this service.
	PreDeploymentCommand  string
	PostDeploymentCommand string
}

ServiceExtensions are the x-akerdock keys of a service (compose-spec §5.1).

type ServicePlan

type ServicePlan struct {
	Name          string
	ContainerName string
	// CandidateName is the zero-downtime candidate (§2.2).
	CandidateName string
	// Aliases on the stack network (§2.1): short service name + prefixed.
	Aliases []string
	// ExtraNetworks this service attaches to (docker names).
	ExtraNetworks []string
	Image         string
	// Build is true when the service builds from the clone (§1.3).
	Build bool
	// BuildImage is the local image name for built services (§2.2), tag
	// applied at deploy time with the commit sha.
	BuildImage string
	Mounts     []MountPlan
	DependsOn  []Dependency
	Restart    string
	// OneShot marks restart:no jobs (§7.3) — run at their topological
	// position, success required.
	OneShot bool
	// Pre/PostCommand are the per-service hooks (x-akerdock, §10 semantics):
	// pre in the existing container before any mutation, post in the healthy
	// candidate before its switch.
	PreCommand         string
	PostCommand        string
	AccessPublicRoutes []accessroute.Route
	ExcludeFromHC      bool
	ZeroDowntimeOptOut bool
	// HasHostPorts makes the service ineligible to zero-downtime (§8.4):
	// two instances cannot bind the same host port.
	HasHostPorts bool
	// DefaultRoutePort is the first exposed port (§6) — the routing default.
	DefaultRoutePort int
	Health           *HealthFlags
	Limits           LimitFlags
	// IsDatabase/DatabaseEngine come from image detection (§10).
	IsDatabase     bool
	DatabaseEngine string
	Service        types.ServiceConfig
}

ServicePlan is one compose service, transformed. The full canonical config stays available in Service for the flags this plan does not precompute (user, working_dir, dns…): the engine reads them from there.

type Severity

type Severity string

Severity of a finding (compose-spec §11): an error blocks the deployment or the save; a warning is accepted, traced and displayed.

const (
	Error   Severity = "error"
	Warning Severity = "warning"
)

Finding severities (compose-spec §11).

type VolumeExtensions

type VolumeExtensions struct {
	IsDirectory bool
	// Content creates the host file with variable interpolation; editable in
	// the UI afterwards.
	Content  string
	FileMode string
	OwnerUID *int64
	GroupGID *int64
}

VolumeExtensions are the x-akerdock keys of one volumes[] entry (§5.1): managed file/directory creation on the host before the mount.

Jump to

Keyboard shortcuts

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