util

package
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: Aug 13, 2026 License: GPL-3.0 Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const (
	OptionsKeyGeneric = "com.docker.network.generic"
)

Variables

View Source
var (
	// ErrIPAM indicates an unsupported IPAM driver was used
	ErrIPAM = errors.New("only the null IPAM driver is supported")
	// ErrBridgeRequired indicates a network bridge was not provided for network creation
	ErrBridgeRequired = errors.New("bridge required (mode=bridge)")
	// ErrNotBridge indicates that the provided network interface is not a bridge
	ErrNotBridge = errors.New("network interface is not a bridge")
	// ErrBridgeUsed indicates that a bridge is already in use
	ErrBridgeUsed = errors.New("bridge already in use by Docker")
	// ErrInvalidMode indicates an unsupported value was passed for the `mode` option
	ErrInvalidMode = errors.New("invalid mode (must be 'bridge' or 'macvlan')")
	// ErrParentRequired indicates `parent` was not provided when mode=macvlan
	ErrParentRequired = errors.New("parent required (mode=macvlan)")
	// ErrParentInvalid indicates the parent interface cannot host macvlan children
	ErrParentInvalid = errors.New("parent interface is unsuitable for macvlan (bridge or macvlan)")
	// ErrParentDown indicates the parent interface is administratively down
	ErrParentDown = errors.New("parent interface is down")
	// ErrModeMismatch indicates an option that doesn't apply to the chosen mode was set
	ErrModeMismatch = errors.New("option does not apply to selected mode")
	// ErrMACAddress indicates an invalid MAC address
	ErrMACAddress = errors.New("invalid MAC address")
	// ErrNoLease indicates a DHCP lease was not obtained from dhcpcd
	ErrNoLease = errors.New("dhcpcd did not output a lease")
	// ErrNoHint indicates missing state from the CreateEndpoint stage in Join
	ErrNoHint = errors.New("missing CreateEndpoint hints")
	// ErrNotVEth indicates a host link was unexpectedly not a veth interface
	ErrNotVEth = errors.New("host link is not a veth interface")
	// ErrNoContainer indicates a container was unexpectedly not found
	ErrNoContainer = errors.New("couldn't find container by endpoint on the network")
	// ErrNoSandbox indicates missing state from the Join stage
	ErrNoSandbox = errors.New("missing joined endpoint state")
)

Functions

func AwaitCondition

func AwaitCondition(ctx context.Context, cond func() (bool, error), interval time.Duration) error

AwaitCondition polls cond every interval until it returns ok=true, an error, or ctx is cancelled. The poll runs synchronously in the caller's goroutine: a previous async-poller form leaked a goroutine on every ctx-cancel because it kept calling cond forever (typically Docker NetworkInspect, ~10/s/leaked-goroutine). cond is expected to be reasonably fast or to honor ctx itself; we don't try to interrupt it.

func AwaitContainerInspect

func AwaitContainerInspect(ctx context.Context, docker ContainerInspector, id string, interval time.Duration) (container.InspectResponse, error)

AwaitContainerInspect polls docker.ContainerInspect until it succeeds, ctx is cancelled, or interval-paced retries exhaust. Synchronous for the same reason as AwaitNetNS — the previous async form leaked a poller goroutine on ctx-cancel that kept hitting the Docker API forever.

"No such container" ends the wait immediately instead of being retried. Polling for a container that has been removed can only ever end in the deadline, and callers then read that deadline as "the daemon was slow" when what actually happened is "the container is gone". Those need opposite responses: one is a fault worth counting, the other is an ordinary short-lived container. Retrying an absence spent the whole budget converting the second into the first — nine to twelve times per integration run (#401).

A NotFound arriving here means removed, not "not yet": every caller resolves the container ID from the daemon first, so it existed moments ago. The error is returned with its chain intact so callers can classify with cerrdefs.IsNotFound.

Other errors are still retried, and the last one is reported alongside the deadline — the same contract AwaitNetNS and AwaitLinkByIndex already keep. Discarding it here was why a Join timeout said only "context deadline exceeded" while its sibling failures named a missing file.

func AwaitLinkByIndex

func AwaitLinkByIndex(ctx context.Context, handle *netlink.Handle, index int, interval time.Duration) (netlink.Link, error)

AwaitLinkByIndex polls for a netlink Link by index until it appears, ctx is cancelled, or interval-paced retries exhaust. Synchronous for the same reason as AwaitNetNS; surfaces the last attempt's error for the same reason too.

func AwaitNetNS

func AwaitNetNS(ctx context.Context, path string, interval time.Duration) (netns.NsHandle, error)

AwaitNetNS polls for a netns at path until it appears, ctx is cancelled, or interval-paced retries exhaust. Synchronous to avoid leaking a poller goroutine on ctx-cancel (the previous form did, and each leaked goroutine kept hammering netns.GetFromPath forever).

On ctx expiry the returned error wraps ctx.Err() (so errors.Is against context.DeadlineExceeded keeps working) and carries the last attempt's underlying error. A bare "context deadline exceeded" hid a persistent EACCES for weeks in production — the netns open needs ptrace access to the target process, and a permission failure retried to the deadline is indistinguishable from a startup race without this (#317).

func ErrToStatus

func ErrToStatus(err error) int

ErrToStatus maps a sentinel error to its HTTP status. Validation errors (caller-supplied bad input) produce 400. Upstream-DHCP and retryable Docker-state-transition errors produce 502 / 503 / 409 so the wire shape is meaningful to non-libnetwork consumers; the libnetwork integration treats all 5xx the same so this is purely a clarity win for direct API users / logs / dashboards.

Anything not enumerated here falls through to 500 — those are either internal plumbing failures (netlink, fs) or unexpected daemon errors, where 500 is the honest answer.

func JSONErrResponse

func JSONErrResponse(w http.ResponseWriter, err error, statusCode int)

JSONErrResponse Sends an `error` as a JSON object with a `message` property. Logs at a level matching the HTTP status:

  • 5xx -> Error (we did something wrong)
  • 4xx -> Warn (caller did something wrong; not actionable for us)
  • other -> Info

A torrent of 4xx from a misconfigured client used to land at ERROR, drowning real failures (I-12 in the 2026-05-05 review).

func JSONResponse

func JSONResponse(w http.ResponseWriter, v interface{}, statusCode int)

JSONResponse Sends a JSON payload in response to a HTTP request. The payload is encoded into a buffer first so that, on encoding failure, we can still send a clean HTTP 500 instead of a garbled response with a half-flushed body and a no-op second WriteHeader call.

func ParseJSONOrErrorResponse

func ParseJSONOrErrorResponse(v interface{}, w http.ResponseWriter, r *http.Request) error

ParseJSONOrErrorResponse decodes the request body as JSON into v. On failure it ALSO writes a 400 JSON error response to w; the caller is expected to early-return on a non-nil error and not touch w again. The verbose name is deliberate: the prior name (ParseJSONBody) read as a pure parse, but the function quietly took over response writing — a future caller writing the obvious-looking

if err := ParseJSONBody(&req, w, r); err != nil {
    JSONErrResponse(w, err, ...); return
}

would double-write headers. This name makes the response-writing side-effect impossible to overlook at the call site.

func WriteAccessLog

func WriteAccessLog(w io.Writer, params handlers.LogFormatterParams)

Types

type ContainerInspector

type ContainerInspector interface {
	ContainerInspect(ctx context.Context, id string) (container.InspectResponse, error)
}

ContainerInspector is the one Docker-client method AwaitContainerInspect needs. Taking an interface (not the concrete *client.Client) lets callers inject a fake in tests; the real client satisfies it as-is.

Jump to

Keyboard shortcuts

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