Documentation
¶
Index ¶
- func CheckTarget(target container.Summary, serviceName, operation string) error
- func IsContainer(ctr container.Summary) bool
- func IsRelay(labels map[string]string) bool
- func Networks(project *types.Project, service types.ServiceConfig) []string
- type Backend
- type InfoAnswer
- type NetworkInfo
- type Service
- func (s *Service) Ensure(ctx context.Context, project *types.Project, service types.ServiceConfig, ...) error
- func (s *Service) Info(ctx context.Context, project *types.Project, service types.ServiceConfig) InfoAnswer
- func (s *Service) LinkNetworks(ctx context.Context, projectName string) ([]network.Summary, error)
- func (s *Service) Remove(ctx context.Context, projectName, serviceName string) error
- func (s *Service) RemoveLinkNetwork(ctx context.Context, n network.Summary) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CheckTarget ¶
CheckTarget refuses process-level operations on a relay container: it stands in for the provider's resource on the network, but there is no service process in it to act on.
func IsContainer ¶
IsContainer reports whether a container is a service's network relay rather than a regular instance of it: a static scratch-based binary with no shell or service process, so anything expecting one to be there — secrets/configs injection, lifecycle hooks, process-level commands — must skip it.
func IsRelay ¶
IsRelay tells, from a container's labels, whether it is a service's network relay. Relays are long-lived infrastructure standing in for a provider's resource: they never terminate on their own, so counting them among the application's containers would keep an attached `up` waiting forever.
func Networks ¶
func Networks(project *types.Project, service types.ServiceConfig) []string
Networks returns the compose network keys the relay must join: the union of the networks of every service depending on the provider service — the consumers the relay exists for — falling back to the project default.
Types ¶
type Backend ¶
type Backend interface {
// APIClient talks to the Docker daemon.
APIClient() client.APIClient
// Events receives the progress of the operations.
Events() api.EventProcessor
// IsDesktopIntegrationActive tells whether Docker Desktop is the engine.
IsDesktopIntegrationActive(ctx context.Context) (bool, error)
}
Backend is what the relay management needs from the engine.
type InfoAnswer ¶
type InfoAnswer struct {
Networks []NetworkInfo `json:"networks"`
}
InfoAnswer is the get-relay-info reply: the network the relay reaches the provider's own runtime through, with the address the HOST owns on it — its gateway. A provider running its service locally can bind that address: reachable from the relay (same-bridge local delivery), and — unlike a project's own bridge networks, which every service on them can also reach — joined by nothing else. That is isolation by network membership, not something the address alone enforces: the gateway is an address of the host itself, and a plain bind restricts by destination address, not by arrival interface, so a local container able to route to it can still reach the listener by IP. A provider keeps the endpoint relay-only by binding ONLY this address and pinning the socket to the bridge's own interface (SO_BINDTODEVICE on Linux). A single entry, or none when it could not be resolved (see ensureRelayLinkNetwork): a provider must treat that as "bind elsewhere".
type NetworkInfo ¶
type NetworkInfo struct {
// Name is the engine-level name of the dedicated relay-link network on a
// standalone engine. Under Docker Desktop it is the placeholder
// "desktop": no such network exists there, so it is only meaningful
// for logging, never as an engine-level network reference.
Name string `json:"name"`
// Gateway is the address the provider's host owns that the relay can
// reach on this network: the dedicated relay-link network's IPv4
// gateway on a standalone engine, the host's own loopback under Docker
// Desktop — whose proxy dials host-process endpoints through
// 127.0.0.1, making it factually the gateway to the host from the
// relay's vantage point. Empty when unresolved (network not created
// yet, driver without a host-owned gateway, IPv6-only).
Gateway string `json:"gateway,omitempty"`
}
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service manages the relay containers and relay link networks on a Backend.
func (*Service) Ensure ¶
func (s *Service) Ensure(ctx context.Context, project *types.Project, service types.ServiceConfig, endpoints map[int]string, networkKeys []string) error
Ensure converges the relay container standing in for a provider service that published endpoints: consumers reach the provider's resource at the compose-native address (http://<service>:<port>) through it. The relay is a regular project container (standard compose labels, canonical name, service alias on the consumers' networks) so label-driven commands treat it as the service, plus the RelayLabel identifying its role — the reconciler leaves provider services' containers alone, and process-level commands (exec) refuse it.
networkKeys (see relayNetworks) is computed by the caller under the shared project mutex: this function performs only Docker API work and must not touch project.Services, which concurrent provider runs mutate.
func (*Service) Info ¶
func (s *Service) Info(ctx context.Context, project *types.Project, service types.ServiceConfig) InfoAnswer
Info assembles the get-relay-info answer for one provider service: the dedicated relay-link network (ensureRelayLinkNetwork) — never one of the project's own bridge networks, which every other service attached to them could also reach — resolved for the address a locally-run endpoint should bind. Compose owns the platform knowledge — the provider just binds what is announced. Best-effort by design: a provider must treat a missing gateway as "bind elsewhere".
func (*Service) LinkNetworks ¶
LinkNetworks lists the relay link networks of every provider service of a project — what a `down` has to remove, since removeServiceRelay's own network cleanup only runs when a later `up` decides a relay is no longer needed, a path a full `down` never takes (the relay container itself is swept by the generic per-service container removal instead), so without this the dedicated network would outlive the relay it was created for. Looked up directly by label — not by walking project.Services and checking Provider — because a project reconstructed from live containers (getProjectWithResources, the path a `down` without an explicit compose file takes) never repopulates Provider: nothing in a container's own labels says its service declared one, so a per-service check here would silently skip every service and leak the network on every such down — the common case, not an edge one.
func (*Service) Remove ¶
Remove removes a service's relay container, if any. Called whenever an up finds the provider publishing no endpoint — whether it never did, or a relay from an earlier up is now stale — so a relay that still routes to an upstream the provider no longer serves doesn't linger.
func (*Service) RemoveLinkNetwork ¶
RemoveLinkNetwork is the single place a relay-link network is removed, shared by the up path (removeRelayLinkNetwork) and the down path (ensureRelayLinkNetworksDown). Every caller removes the relay container first, but the daemon disconnects its endpoints asynchronously, so a ContainerRemove that already returned can still race NetworkRemove: a conflict (errdefs.IsConflict) is tolerated, left for a later up/down to retry, as is the network already being gone (errdefs.IsNotFound).