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
- func GenerateMagicValue(ref MagicRef) (string, error)
- func HasErrors(fs []Finding) bool
- func NormalizeComponentID(service string) string
- func ParseMagicName(name string, components map[string]bool) (MagicRef, *Finding)
- func ScanMagicReferences(content string, services []string) ([]MagicRef, []Finding)
- type Dependency
- type Finding
- type HealthFlags
- type Input
- type LimitFlags
- type MagicRef
- type MagicType
- type MountPlan
- type Plan
- type Policy
- type Result
- type ServiceExtensions
- type ServicePlan
- type Severity
- type VolumeExtensions
Constants ¶
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" 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 ¶
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 NormalizeComponentID ¶
NormalizeComponentID converts a compose service name to its magic <ID> (§4.1): uppercase, non-alphanumerics replaced by underscores.
func ParseMagicName ¶
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 ¶
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 ¶
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).
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
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 ¶
Result carries the loaded project, the execution plan and every finding. Plan is nil when findings contain at least one error.
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.
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.