Documentation
¶
Overview ¶
Package dockerexec is the write-plane exec wrapper: it shells out to `docker compose` with STATIC ARGV only — never a shell, never string interpolation, always a `--` terminator before service names (plan §3, §5.6). It enforces the global one-docker-child semaphore and the ≥1 GB write-plane gate, and reaps the whole process group on context cancellation.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrBusy = errors.New("dockerexec: another docker operation is in progress")
ErrBusy is returned when the one-docker-child semaphore could not be acquired.
var ErrWritePlaneDisabled = errors.New("dockerexec: write plane disabled (host below the 1 GB resource gate)")
ErrWritePlaneDisabled is returned when the host is below the §0 resource gate.
Functions ¶
func WritePlaneGate ¶
WritePlaneGate decides whether the write plane is armed from the host's total RAM. memTotal==0 means unknown (non-Linux dev) → armed, with a caveat note.
Types ¶
type Job ¶
type Job struct {
Project string
Dir string
ConfigFiles []string
EnvFile string // optional 0600 --env-file rendered from the env store
Action []string // e.g. ["up","-d","--force-recreate"]
Service string // optional; appended after a "--" terminator
}
Job is one `docker compose` invocation. Project/Dir/ConfigFiles come from the app's compose labels; they are passed as discrete argv elements (no shell), so they cannot inject commands.
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner executes Jobs under the gate + semaphore.
func (*Runner) Run ¶
Run executes the job, invoking onLine for each (truncated) output line. It acquires the semaphore (blocking on ctx), and on ctx cancellation kills the whole process group and reaps it. Returns the command error (incl. non-zero exit) or a gate/semaphore error.
func (*Runner) RunHeld ¶
RunHeld is Run for a caller that ALREADY HOLDS the one-docker-child semaphore (the self-healing supervisor, which acquires it non-blocking via its safety gate so it never queues a docker child). It must not be called without holding the semaphore.
func (*Runner) RunInternal ¶
RunInternal runs a Mooring-OWNED infrastructure job (bringing up the embedded read-only socket-proxy) REGARDLESS of the §0 write-plane resource gate — the read plane must come up even on a sub-1 GB box. It is NOT for app workloads: the caller passes a fixed, embedded, Mooring-authored compose (never operator input), so it bypasses the RAM gate while keeping the static-argv discipline, the one-docker-child semaphore, and process-group reaping. It acquires the semaphore (blocking on ctx) like Run.
func (*Runner) WriteAllowed ¶
WriteAllowed reports whether the write plane is armed, and why not if not.
type Semaphore ¶
type Semaphore struct {
// contains filtered or unexported fields
}
Semaphore caps concurrent `docker` children at 1 across the whole process (poller stats go through the proxy and don't count; only exec children do). Remediation/scale-up use TryAcquire (never queue — queuing children IS the OOM vector, plan §4).
func NewSemaphore ¶
func NewSemaphore() *Semaphore
NewSemaphore returns the global one-docker-child semaphore.
func (*Semaphore) TryAcquire ¶
TryAcquire grabs the slot without blocking; false means held.