|
@@ -5,6 +5,8 @@ import (
|
|
|
"path/filepath"
|
|
|
|
|
|
"github.com/docker/docker/pkg/etchosts"
|
|
|
+ "github.com/docker/libnetwork/netutils"
|
|
|
+ "github.com/docker/libnetwork/pkg/options"
|
|
|
"github.com/docker/libnetwork/sandbox"
|
|
|
"github.com/docker/libnetwork/types"
|
|
|
)
|
|
@@ -23,11 +25,11 @@ type Endpoint interface {
|
|
|
// 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, options ...JoinOption) (*ContainerData, error)
|
|
|
+ Join(containerID string, options ...EndpointOption) (*ContainerData, error)
|
|
|
|
|
|
// Leave removes the sandbox associated with container ID and detaches
|
|
|
// the network resources populated in the sandbox
|
|
|
- Leave(containerID string, options ...LeaveOption) error
|
|
|
+ Leave(containerID string, options ...EndpointOption) error
|
|
|
|
|
|
// SandboxInfo returns the sandbox information for this endpoint.
|
|
|
SandboxInfo() *sandbox.Info
|
|
@@ -36,43 +38,39 @@ type Endpoint interface {
|
|
|
Delete() error
|
|
|
}
|
|
|
|
|
|
+// EndpointOption is a option setter function type used to pass varios options to Network
|
|
|
+// and Endpoint interfaces methods. The various setter functions of type EndpointOption are
|
|
|
+// provided by libnetwork, they look like <Create|Join|Leave>Option[...](...)
|
|
|
+type EndpointOption func(ep *endpoint)
|
|
|
+
|
|
|
// ContainerData is a set of data returned when a container joins an endpoint.
|
|
|
type ContainerData struct {
|
|
|
SandboxKey string
|
|
|
HostsPath string
|
|
|
}
|
|
|
|
|
|
-// JoinOption is a option setter function type used to pass varios options to
|
|
|
-// endpoint Join method. The various setter functions of type JoinOption are
|
|
|
-// provided by libnetwork, they look like JoinOption[...](...)
|
|
|
-type JoinOption func(ep *endpoint)
|
|
|
-
|
|
|
-// LeaveOption is a option setter function type used to pass varios options to
|
|
|
-// endpoint Leave method. The various setter functions of type LeaveOption are
|
|
|
-// provided by libnetwork, they look like LeaveOptionXXXX(...)
|
|
|
-type LeaveOption func(ep *endpoint)
|
|
|
-
|
|
|
type containerConfig struct {
|
|
|
- Hostname string
|
|
|
- Domainname string
|
|
|
+ hostName string
|
|
|
+ domainName string
|
|
|
generic map[string]interface{}
|
|
|
}
|
|
|
|
|
|
type containerInfo struct {
|
|
|
- ID string
|
|
|
- Config containerConfig
|
|
|
- Data ContainerData
|
|
|
+ id string
|
|
|
+ config containerConfig
|
|
|
+ data ContainerData
|
|
|
}
|
|
|
|
|
|
type endpoint struct {
|
|
|
- name string
|
|
|
- id types.UUID
|
|
|
- network *network
|
|
|
- sandboxInfo *sandbox.Info
|
|
|
- sandBox sandbox.Sandbox
|
|
|
- container *containerInfo
|
|
|
- generic map[string]interface{}
|
|
|
- context map[string]interface{}
|
|
|
+ name string
|
|
|
+ id types.UUID
|
|
|
+ network *network
|
|
|
+ sandboxInfo *sandbox.Info
|
|
|
+ sandBox sandbox.Sandbox
|
|
|
+ container *containerInfo
|
|
|
+ exposedPorts []netutils.TransportPort
|
|
|
+ generic map[string]interface{}
|
|
|
+ context map[string]interface{}
|
|
|
}
|
|
|
|
|
|
const prefix = "/var/lib/docker/network/files"
|
|
@@ -96,19 +94,6 @@ func (ep *endpoint) SandboxInfo() *sandbox.Info {
|
|
|
return ep.sandboxInfo.GetCopy()
|
|
|
}
|
|
|
|
|
|
-// EndpointOption is a option setter function type used to pass various options to
|
|
|
-// CreateEndpoint method. The various setter functions of type EndpointOption are
|
|
|
-// provided by libnetwork, they look like EndpointOptionXXXX(...)
|
|
|
-type EndpointOption func(ep *endpoint)
|
|
|
-
|
|
|
-// EndpointOptionGeneric function returns an option setter for a Generic option defined
|
|
|
-// in a Dictionary of Key-Value pair
|
|
|
-func EndpointOptionGeneric(generic map[string]interface{}) EndpointOption {
|
|
|
- return func(ep *endpoint) {
|
|
|
- ep.generic = generic
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
func (ep *endpoint) processOptions(options ...EndpointOption) {
|
|
|
for _, opt := range options {
|
|
|
if opt != nil {
|
|
@@ -143,7 +128,7 @@ func createHostsFile(path string) error {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
-func (ep *endpoint) Join(containerID string, options ...JoinOption) (*ContainerData, error) {
|
|
|
+func (ep *endpoint) Join(containerID string, options ...EndpointOption) (*ContainerData, error) {
|
|
|
var err error
|
|
|
|
|
|
if containerID == "" {
|
|
@@ -161,10 +146,10 @@ func (ep *endpoint) Join(containerID string, options ...JoinOption) (*ContainerD
|
|
|
}
|
|
|
}()
|
|
|
|
|
|
- ep.processJoinOptions(options...)
|
|
|
+ ep.processOptions(options...)
|
|
|
|
|
|
- ep.container.Data.HostsPath = prefix + "/" + containerID + "/hosts"
|
|
|
- err = createHostsFile(ep.container.Data.HostsPath)
|
|
|
+ ep.container.data.HostsPath = prefix + "/" + containerID + "/hosts"
|
|
|
+ err = createHostsFile(ep.container.data.HostsPath)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
@@ -186,7 +171,7 @@ func (ep *endpoint) Join(containerID string, options ...JoinOption) (*ContainerD
|
|
|
}()
|
|
|
|
|
|
n := ep.network
|
|
|
- err = n.driver.Join(n.id, ep.id, sboxKey, ep.container.Config.generic)
|
|
|
+ err = n.driver.Join(n.id, ep.id, sboxKey, ep.container.config.generic)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
@@ -211,28 +196,28 @@ func (ep *endpoint) Join(containerID string, options ...JoinOption) (*ContainerD
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- ep.container.ID = containerID
|
|
|
- ep.container.Data.SandboxKey = sb.Key()
|
|
|
+ ep.container.id = containerID
|
|
|
+ ep.container.data.SandboxKey = sb.Key()
|
|
|
|
|
|
- cData := ep.container.Data
|
|
|
+ cData := ep.container.data
|
|
|
return &cData, nil
|
|
|
}
|
|
|
|
|
|
-func (ep *endpoint) Leave(containerID string, options ...LeaveOption) error {
|
|
|
- if ep.container == nil || ep.container.ID == "" ||
|
|
|
- containerID == "" || ep.container.ID != containerID {
|
|
|
+func (ep *endpoint) Leave(containerID string, options ...EndpointOption) error {
|
|
|
+ if ep.container == nil || ep.container.id == "" ||
|
|
|
+ containerID == "" || ep.container.id != containerID {
|
|
|
return InvalidContainerIDError(containerID)
|
|
|
}
|
|
|
|
|
|
- n := ep.network
|
|
|
- ep.processLeaveOptions(options...)
|
|
|
+ ep.processOptions(options...)
|
|
|
|
|
|
+ n := ep.network
|
|
|
err := n.driver.Leave(n.id, ep.id, ep.context)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- ep.network.ctrlr.sandboxRm(ep.container.Data.SandboxKey)
|
|
|
+ ep.network.ctrlr.sandboxRm(ep.container.data.SandboxKey)
|
|
|
ep.container = nil
|
|
|
ep.context = nil
|
|
|
return nil
|
|
@@ -266,9 +251,9 @@ func (ep *endpoint) Delete() error {
|
|
|
func (ep *endpoint) buildHostsFiles() error {
|
|
|
var extraContent []etchosts.Record
|
|
|
|
|
|
- name := ep.container.Config.Hostname
|
|
|
- if ep.container.Config.Domainname != "" {
|
|
|
- name = name + "." + ep.container.Config.Domainname
|
|
|
+ name := ep.container.config.hostName
|
|
|
+ if ep.container.config.domainName != "" {
|
|
|
+ name = name + "." + ep.container.config.domainName
|
|
|
}
|
|
|
|
|
|
IP := ""
|
|
@@ -277,56 +262,64 @@ func (ep *endpoint) buildHostsFiles() error {
|
|
|
IP = ep.sandboxInfo.Interfaces[0].Address.IP.String()
|
|
|
}
|
|
|
|
|
|
- return etchosts.Build(ep.container.Data.HostsPath, IP, ep.container.Config.Hostname,
|
|
|
- ep.container.Config.Domainname, extraContent)
|
|
|
+ return etchosts.Build(ep.container.data.HostsPath, IP, ep.container.config.hostName,
|
|
|
+ ep.container.config.domainName, extraContent)
|
|
|
+}
|
|
|
+
|
|
|
+// EndpointOptionGeneric function returns an option setter for a Generic option defined
|
|
|
+// in a Dictionary of Key-Value pair
|
|
|
+func EndpointOptionGeneric(generic map[string]interface{}) EndpointOption {
|
|
|
+ return func(ep *endpoint) {
|
|
|
+ for k, v := range generic {
|
|
|
+ ep.generic[k] = v
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// JoinOptionHostname function returns an option setter for hostname option to
|
|
|
// be passed to endpoint Join method.
|
|
|
-func JoinOptionHostname(name string) JoinOption {
|
|
|
+func JoinOptionHostname(name string) EndpointOption {
|
|
|
return func(ep *endpoint) {
|
|
|
- ep.container.Config.Hostname = name
|
|
|
+ ep.container.config.hostName = name
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// JoinOptionDomainname function returns an option setter for domainname option to
|
|
|
// be passed to endpoint Join method.
|
|
|
-func JoinOptionDomainname(name string) JoinOption {
|
|
|
+func JoinOptionDomainname(name string) EndpointOption {
|
|
|
return func(ep *endpoint) {
|
|
|
- ep.container.Config.Domainname = name
|
|
|
+ ep.container.config.domainName = name
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// JoinOptionGeneric function returns an option setter for Generic configuration
|
|
|
-// that is not managed by libNetwork but can be used by the Drivers during the call to
|
|
|
-// endpoint join method. Container Labels are a good example.
|
|
|
-func JoinOptionGeneric(generic map[string]interface{}) JoinOption {
|
|
|
+// CreateOptionPortMapping function returns an option setter for the container exposed
|
|
|
+// ports option to be passed to network.CreateEndpoint() method.
|
|
|
+func CreateOptionPortMapping(portBindings []netutils.PortBinding) EndpointOption {
|
|
|
return func(ep *endpoint) {
|
|
|
- ep.container.Config.generic = generic
|
|
|
+ // Store endpoint label
|
|
|
+ ep.generic[options.PortMap] = portBindings
|
|
|
+ // Extract exposed ports as this is the only concern of libnetwork endpoint
|
|
|
+ ep.exposedPorts = make([]netutils.TransportPort, 0, len(portBindings))
|
|
|
+ for _, b := range portBindings {
|
|
|
+ ep.exposedPorts = append(ep.exposedPorts, netutils.TransportPort{Proto: b.Proto, Port: b.Port})
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func (ep *endpoint) processJoinOptions(options ...JoinOption) {
|
|
|
- for _, opt := range options {
|
|
|
- if opt != nil {
|
|
|
- opt(ep)
|
|
|
- }
|
|
|
+// JoinOptionGeneric function returns an option setter for Generic configuration
|
|
|
+// that is not managed by libNetwork but can be used by the Drivers during the call to
|
|
|
+// endpoint join method. Container Labels are a good example.
|
|
|
+func JoinOptionGeneric(generic map[string]interface{}) EndpointOption {
|
|
|
+ return func(ep *endpoint) {
|
|
|
+ ep.container.config.generic = generic
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// LeaveOptionGeneric function returns an option setter for Generic configuration
|
|
|
// that is not managed by libNetwork but can be used by the Drivers during the call to
|
|
|
// endpoint leave method. Container Labels are a good example.
|
|
|
-func LeaveOptionGeneric(context map[string]interface{}) JoinOption {
|
|
|
+func LeaveOptionGeneric(context map[string]interface{}) EndpointOption {
|
|
|
return func(ep *endpoint) {
|
|
|
ep.context = context
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-func (ep *endpoint) processLeaveOptions(options ...LeaveOption) {
|
|
|
- for _, opt := range options {
|
|
|
- if opt != nil {
|
|
|
- opt(ep)
|
|
|
- }
|
|
|
- }
|
|
|
-}
|