Documentation
¶
Overview ¶
build_gate_image_resolver.go implements the Build Gate image catalog resolver.
The resolver selects runtime images for Build Gate containers when Stack Gate is enabled. It loads rules from multiple sources with precedence ordering:
- Default gates catalog (gates/gates.yaml) - lowest precedence
- Mig-level image overrides - highest precedence
Resolution uses "most specific match wins" semantics:
- Tool-specific rules (specificity 3) beat tool-agnostic rules (specificity 2)
- Same-specificity ties with different images are configuration errors
gate_docker.go implements the Docker-based GateExecutor.
This executor is the canonical source of gate validation results: it runs a language-specific image with the workspace mounted at /workspace, captures logs and resource usage, and returns BuildGateStageMetadata. Concerns are split across sibling files: mounts (gate_docker_mounts.go), log streaming (container_log_streamer.go + gate_docker_logs.go), env-driven resource limits (gate_docker_env.go), and result normalization (gate_docker_metadata.go). Stack detection + image resolution live in gate_plan_resolver.go.
Index ¶
- Constants
- Variables
- func SeedInDirFromStaging(manifest contracts.StepManifest, stagingDir, inDir string) error
- func SeedOutDirFromStaging(manifest contracts.StepManifest, stagingDir, outDir string) error
- func SeedTmpDirFromStaging(manifest contracts.StepManifest, stagingDir, tmpDir string) error
- func WithExecutionLogWriter(ctx context.Context, w io.Writer) context.Context
- func WithGateContainerLabels(ctx context.Context, labels map[string]string) context.Context
- func WithGateRuntimeImageObserver(ctx context.Context, obs GateRuntimeImageObserver) context.Context
- func WithGateShareDir(ctx context.Context, shareDir string) context.Context
- type ContainerHandle
- type ContainerMount
- type ContainerResourceUsage
- type ContainerResult
- type ContainerRuntime
- type ContainerRuntimeOptions
- type ContainerSpec
- type DiffGenerator
- type GateExecutor
- type GateRuntimeImageObserver
- type PatchStats
- type Request
- type Result
- type Runner
- type StageTiming
- type WorkspaceHydrator
Constants ¶
const ( // GateWorkspaceOutDir is a workspace-local host directory mounted // into gate containers as /out for deterministic artifact collection. GateWorkspaceOutDir = ".ploy-gate-out" )
Variables ¶
var ErrGateFailed = errors.New("build gate failed")
ErrGateFailed is returned when the pre-mig Build Gate fails.
Functions ¶
func SeedInDirFromStaging ¶
func SeedInDirFromStaging(manifest contracts.StepManifest, stagingDir, inDir string) error
SeedInDirFromStaging copies materialized Hydra in entry content from the staging directory into inDir so that the single /in mount can expose both pre-seeded content and runtime-provided cross-phase files.
func SeedOutDirFromStaging ¶
func SeedOutDirFromStaging(manifest contracts.StepManifest, stagingDir, outDir string) error
SeedOutDirFromStaging copies materialized Hydra out entry content from the staging directory into outDir so that the single /out mount covers both pre-seeded content and container writes.
func SeedTmpDirFromStaging ¶
func SeedTmpDirFromStaging(manifest contracts.StepManifest, stagingDir, tmpDir string) error
SeedTmpDirFromStaging copies materialized Hydra tmp entry content from the staging directory into tmpDir so that the single /tmp mount exposes all tmp files while keeping them outside durable repo artifacts.
func WithExecutionLogWriter ¶
WithExecutionLogWriter stores an optional live log sink in context so lower-level executors (for example gate runtime) can stream container output through the standard node log uploader path.
func WithGateContainerLabels ¶
WithGateContainerLabels attaches container labels to gate execution context. Labels are copied and merged with existing gate labels in the context.
func WithGateRuntimeImageObserver ¶
func WithGateRuntimeImageObserver(ctx context.Context, obs GateRuntimeImageObserver) context.Context
WithGateRuntimeImageObserver attaches an observer to the context used for gate execution. The observer is called with the resolved runtime image before container execution starts.
Types ¶
type ContainerHandle ¶
type ContainerHandle string
ContainerHandle identifies a prepared container by its ID.
type ContainerMount ¶
ContainerMount describes a host path mount.
type ContainerResourceUsage ¶
type ContainerResourceUsage struct {
CPUConsumedNs int64
DiskConsumedBytes int64
MemConsumedBytes int64
}
ContainerResourceUsage captures per-job container resource consumption.
type ContainerResult ¶
type ContainerResult struct {
ExitCode int
StartedAt time.Time
CompletedAt time.Time
ContainerID string
InspectJSON []byte
}
ContainerResult captures container exit metadata.
type ContainerRuntime ¶
type ContainerRuntime interface {
Create(ctx context.Context, spec ContainerSpec) (ContainerHandle, error)
Start(ctx context.Context, handle ContainerHandle) error
Wait(ctx context.Context, handle ContainerHandle) (ContainerResult, error)
Logs(ctx context.Context, handle ContainerHandle) ([]byte, error)
Remove(ctx context.Context, handle ContainerHandle) error
}
ContainerRuntime executes containers.
func NewContainerRuntime ¶
func NewContainerRuntime(opts ContainerRuntimeOptions) (ContainerRuntime, error)
NewContainerRuntime constructs a Docker-backed container runtime. It uses client.FromEnv to read DOCKER_HOST and related environment variables, and WithAPIVersionNegotiation to auto-negotiate API version with the daemon.
type ContainerRuntimeOptions ¶
type ContainerRuntimeOptions struct {
// PullImage controls whether the runtime refreshes the image before container
// creation.
PullImage bool
// Network is optional Docker network name (empty => default bridge).
Network string
// RegistryAuthConfigFile is a Docker auth config JSON file path
// (DOCKER_AUTH_CONFIG format). When set, each image pull reads current
// credentials from this file.
RegistryAuthConfigFile string
// RegistryAuthRefreshSocket is an optional Unix socket owned by the host.
// When set, an auth failure on image pull asks the host to refresh registry
// auth before retrying the same pull once.
RegistryAuthRefreshSocket string
// RegistryAuthConfigJSON is a Docker auth config JSON payload (DOCKER_AUTH_CONFIG
// format). When set, image pulls use matching registry credentials.
RegistryAuthConfigJSON string
}
ContainerRuntimeOptions holds configuration for Docker runtime.
type ContainerSpec ¶
type ContainerSpec struct {
Image string
Command []string
WorkingDir string
Env map[string]string
Mounts []ContainerMount
Labels map[string]string
// Optional resource limits (0 => unlimited)
LimitNanoCPUs int64
LimitMemoryBytes int64
// Optional disk limit for writable layer (bytes; 0 => unlimited).
// When set, Docker runtime may pass a storage option (driver dependent).
LimitDiskBytes int64
// Optional raw storage size option string passed to Docker (e.g., "10G").
// Set only when the operator provided PLOY_BUILDGATE_LIMIT_DISK_SPACE.
StorageSizeOpt string
}
ContainerSpec describes a container execution request.
type DiffGenerator ¶
DiffGenerator generates diffs between states.
func NewFilesystemDiffGenerator ¶
func NewFilesystemDiffGenerator() DiffGenerator
NewFilesystemDiffGenerator creates a DiffGenerator backed by a temporary git index snapshot.
type GateExecutor ¶
type GateExecutor interface {
Execute(ctx context.Context, spec *contracts.StepGateSpec, workspace string) (*contracts.BuildGateStageMetadata, error)
}
GateExecutor validates build artifacts. The primary implementation is gateExecutor (gate_docker.go) which runs validation containers locally via the container runtime.
func NewGateExecutor ¶
func NewGateExecutor(rt ContainerRuntime) GateExecutor
NewGateExecutor constructs a GateExecutor that uses the provided ContainerRuntime to run build commands.
type GateRuntimeImageObserver ¶
GateRuntimeImageObserver is a hook that is called once the gate runtime image is resolved (after stack detection / stack gate checks), and before the gate container is started.
type PatchStats ¶
PatchStats holds line-level statistics derived from a unified diff.
func CountPatchStats ¶
func CountPatchStats(patchBytes []byte) PatchStats
CountPatchStats parses a unified diff and returns file and line delta counts. It counts `+` lines (excluding `+++ ` file headers) as additions and `-` lines (excluding `--- ` file headers) as removals. Each `diff --*` header marks one changed file.
type Request ¶
type Request struct {
// RunID threads the workflow run identifier for correlation/labels.
// Container labels and telemetry use this value via LabelRunID.
RunID types.RunID
// JobID threads the workflow job identifier for correlation/labels.
// Container labels and telemetry use this value via LabelJobID.
JobID types.JobID
Manifest contracts.StepManifest
Workspace string
OutDir string
// InDir is an optional directory mounted at /in for cross-phase inputs.
InDir string
// shared inputs/outputs across job stages.
ShareDir string
// TmpDir is an optional per-job directory seeded from Manifest.Tmp and
// mounted at /tmp for writable, non-artifact temporary files.
TmpDir string
// StagingDir is an optional path to a directory containing pre-materialized
// Hydra resources. Each In/Out/Home/Tmp entry is mounted from StagingDir/<shortHash>.
StagingDir string
}
Request describes a step execution request.
type Result ¶
type Result struct {
ExitCode int
// Docker container identity and inspect output when a container was run.
ContainerID string
ContainerInspectJSON []byte
// Per-stage timings captured during execution.
Timings StageTiming
Gate *contracts.BuildGateStageMetadata
ContainerResources *ContainerResourceUsage
}
Result contains the outcome of a step execution.
func RunGateOnly ¶
RunGateOnly executes only the gate validation phase without container execution. This helper allows the node agent orchestration layer to reuse gate logic for post-mig gates without invoking a mig container.
Execution stages:
- Hydration — Prepare the workspace via WorkspaceHydrator when configured.
- Build Gate — Run static validation using GateExecutor when enabled.
Unlike Runner.Run, this function:
- Does NOT create or start any containers.
- Does NOT generate diffs.
- Returns immediately after gate validation (pass or fail).
The returned Result contains:
- Gate metadata (if gate was executed).
- Timings for hydration and gate phases only.
- ExitCode is always 0 (no container was executed).
On gate failure, returns ErrGateFailed so callers can detect failures.
type Runner ¶
type Runner struct {
Workspace WorkspaceHydrator
Containers ContainerRuntime
Gate GateExecutor
LogWriter io.Writer // Optional: streams logs to server as gzipped chunks.
}
Runner executes workflow steps.
Execution Stages (Pre-mig Gate per Call) ¶
Runner.Run processes each step call through the following stages in order:
Hydration — Prepare the workspace by fetching repository sources via WorkspaceHydrator. Errors here abort the run immediately.
Pre-mig Build Gate — When Gate is enabled (Manifest.Gate.Enabled), run static validation on the workspace before executing the mig container. If the gate fails, Runner.Run returns ErrGateFailed without executing container stages.
Container Execution — Create, start, and wait on the container via ContainerRuntime. Logs are forwarded to LogWriter if present. Container cleanup is owned by node-runtime pre-claim disk-pressure flow.
Gate Ownership Contract ¶
Runner supports an optional pre-mig gate when Manifest.Gate.Enabled=true. This capability exists for direct invocations (e.g., standalone testing) where Runner manages its own gate lifecycle.
However, nodeagent step execution MUST pass manifests with Gate.Enabled=false. The nodeagent orchestration layer owns all gate lifecycle management via the gate job chain, which handles:
- A single pre-run gate before the step loop begins.
- Per-step post-mig gates after each container execution.
Passing Gate.Enabled=true from nodeagent would cause duplicate pre-mig gates (one from the nodeagent, one from Runner.Run) and break the single-gate- per-run invariant. The nodeagent is the authoritative gate orchestrator.
type StageTiming ¶
type StageTiming struct {
HydrationDuration types.Duration
ExecutionDuration types.Duration
GateDuration types.Duration
DiffDuration types.Duration
PublishDuration types.Duration
TotalDuration types.Duration
}
StageTiming captures duration of each execution stage.
type WorkspaceHydrator ¶
type WorkspaceHydrator interface {
Hydrate(ctx context.Context, manifest contracts.StepManifest, workspace string) error
}
WorkspaceHydrator prepares a workspace for execution.
func NewFilesystemWorkspaceHydrator ¶
func NewFilesystemWorkspaceHydrator(fetcher hydration.GitFetcher) (WorkspaceHydrator, error)
NewFilesystemWorkspaceHydrator creates a new workspace hydrator backed by the given fetcher.
Source Files
¶
- build_gate_image_resolver.go
- container_docker.go
- container_docker_auth.go
- container_docker_auth_refresh.go
- container_docker_stats.go
- container_log_streamer.go
- container_spec.go
- diff.go
- gate_docker.go
- gate_docker_env.go
- gate_docker_logs.go
- gate_docker_metadata.go
- gate_docker_mounts.go
- gate_only.go
- gate_plan_command_selector.go
- gate_plan_resolver.go
- gate_plan_stack_context.go
- gate_runtime_image_observer.go
- gate_share_dir_context.go
- hydrator.go
- interfaces.go
- java_tool_cache_mounts.go
- log_writer_context.go
- runner.go
- runner_gate_stage.go
- stack_match.go