moby--moby/libnetwork/endpoint.go

141 lines
2.9 KiB
Go
Raw Normal View History

package libnetwork
import (
"github.com/docker/libnetwork/sandbox"
"github.com/docker/libnetwork/types"
)
// Endpoint represents a logical connection between a network and a sandbox.
type Endpoint interface {
// A system generated id for this endpoint.
ID() string
// Name returns the name of this endpoint.
Name() string
// Network returns the name of the network to which this endpoint is attached.
Network() string
// Join creates a new sandbox for the given container ID and populates the
// network resources allocated for the endpoint and joins the sandbox to
// the endpoint. It returns the sandbox key to the caller
Join(containerID string) (string, error)
// Leave removes the sandbox associated with container ID and detaches
// the network resources populated in the sandbox
Leave(containerID string) error
// SandboxInfo returns the sandbox information for this endpoint.
SandboxInfo() *sandbox.Info
// Delete and detaches this endpoint from the network.
Delete() error
}
type endpoint struct {
name string
id types.UUID
network *network
sandboxInfo *sandbox.Info
sandBox sandbox.Sandbox
containerID string
}
func (ep *endpoint) ID() string {
return string(ep.id)
}
func (ep *endpoint) Name() string {
return ep.name
}
func (ep *endpoint) Network() string {
return ep.network.name
}
func (ep *endpoint) SandboxInfo() *sandbox.Info {
if ep.sandboxInfo == nil {
return nil
}
return ep.sandboxInfo.GetCopy()
}
func (ep *endpoint) Join(containerID string) (string, error) {
if containerID == "" {
return "", InvalidContainerIDError(containerID)
}
if ep.containerID != "" {
return "", ErrInvalidJoin
}
sboxKey := sandbox.GenerateKey(containerID)
sb, err := ep.network.ctrlr.sandboxAdd(sboxKey)
if err != nil {
return "", err
}
defer func() {
if err != nil {
ep.network.ctrlr.sandboxRm(sboxKey)
}
}()
sinfo := ep.SandboxInfo()
if sinfo != nil {
for _, i := range sinfo.Interfaces {
err = sb.AddInterface(i)
if err != nil {
return "", err
}
}
err = sb.SetGateway(sinfo.Gateway)
if err != nil {
return "", err
}
err = sb.SetGatewayIPv6(sinfo.GatewayIPv6)
if err != nil {
return "", err
}
}
ep.containerID = containerID
return sb.Key(), nil
}
func (ep *endpoint) Leave(containerID string) error {
if ep.containerID == "" || containerID == "" || ep.containerID != containerID {
return InvalidContainerIDError(containerID)
}
ep.network.ctrlr.sandboxRm(sandbox.GenerateKey(containerID))
ep.containerID = ""
return nil
}
func (ep *endpoint) Delete() error {
var err error
n := ep.network
n.Lock()
_, ok := n.endpoints[ep.id]
if !ok {
n.Unlock()
return &UnknownEndpointError{name: ep.name, id: string(ep.id)}
}
delete(n.endpoints, ep.id)
n.Unlock()
defer func() {
if err != nil {
n.Lock()
n.endpoints[ep.id] = ep
n.Unlock()
}
}()
err = n.driver.DeleteEndpoint(n.id, ep.id)
return err
}