mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Vendor-in 2baa2ddc78b42f011f55633282ac63a72e1b09c1 for userns support
Changes include : * libnetwork support for userns * driver api change to have 1 interface per endpoint Signed-off-by: Madhu Venugopal <madhu@docker.com>
This commit is contained in:
parent
d25dada639
commit
d0e0c13b60
25 changed files with 490 additions and 246 deletions
|
@ -580,13 +580,11 @@ func (container *Container) buildEndpointInfo(ep libnetwork.Endpoint, networkSet
|
||||||
return networkSettings, nil
|
return networkSettings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ifaceList := epInfo.InterfaceList()
|
iface := epInfo.Iface()
|
||||||
if len(ifaceList) == 0 {
|
if iface == nil {
|
||||||
return networkSettings, nil
|
return networkSettings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
iface := ifaceList[0]
|
|
||||||
|
|
||||||
ones, _ := iface.Address().Mask.Size()
|
ones, _ := iface.Address().Mask.Size()
|
||||||
networkSettings.IPAddress = iface.Address().IP.String()
|
networkSettings.IPAddress = iface.Address().IP.String()
|
||||||
networkSettings.IPPrefixLen = ones
|
networkSettings.IPPrefixLen = ones
|
||||||
|
@ -597,24 +595,6 @@ func (container *Container) buildEndpointInfo(ep libnetwork.Endpoint, networkSet
|
||||||
networkSettings.GlobalIPv6PrefixLen = onesv6
|
networkSettings.GlobalIPv6PrefixLen = onesv6
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ifaceList) == 1 {
|
|
||||||
return networkSettings, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
networkSettings.SecondaryIPAddresses = make([]network.Address, 0, len(ifaceList)-1)
|
|
||||||
networkSettings.SecondaryIPv6Addresses = make([]network.Address, 0, len(ifaceList)-1)
|
|
||||||
for _, iface := range ifaceList[1:] {
|
|
||||||
ones, _ := iface.Address().Mask.Size()
|
|
||||||
addr := network.Address{Addr: iface.Address().IP.String(), PrefixLen: ones}
|
|
||||||
networkSettings.SecondaryIPAddresses = append(networkSettings.SecondaryIPAddresses, addr)
|
|
||||||
|
|
||||||
if iface.AddressIPv6().IP.To16() != nil {
|
|
||||||
onesv6, _ := iface.AddressIPv6().Mask.Size()
|
|
||||||
addrv6 := network.Address{Addr: iface.AddressIPv6().IP.String(), PrefixLen: onesv6}
|
|
||||||
networkSettings.SecondaryIPv6Addresses = append(networkSettings.SecondaryIPv6Addresses, addrv6)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return networkSettings, nil
|
return networkSettings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -820,9 +820,9 @@ func (daemon *Daemon) Shutdown() error {
|
||||||
}
|
}
|
||||||
group.Wait()
|
group.Wait()
|
||||||
|
|
||||||
// trigger libnetwork GC only if it's initialized
|
// trigger libnetwork Stop only if it's initialized
|
||||||
if daemon.netController != nil {
|
if daemon.netController != nil {
|
||||||
daemon.netController.GC()
|
daemon.netController.Stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ clone git github.com/tchap/go-patricia v2.1.0
|
||||||
clone git golang.org/x/net 3cffabab72adf04f8e3b01c5baf775361837b5fe https://github.com/golang/net.git
|
clone git golang.org/x/net 3cffabab72adf04f8e3b01c5baf775361837b5fe https://github.com/golang/net.git
|
||||||
|
|
||||||
#get libnetwork packages
|
#get libnetwork packages
|
||||||
clone git github.com/docker/libnetwork 3e31cead05cba8ec20241630d051e6d73765b3a2
|
clone git github.com/docker/libnetwork 2baa2ddc78b42f011f55633282ac63a72e1b09c1
|
||||||
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
||||||
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
|
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
|
||||||
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4
|
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
*.so
|
*.so
|
||||||
|
|
||||||
# Folders
|
# Folders
|
||||||
|
integration-tmp/
|
||||||
_obj
|
_obj
|
||||||
_test
|
_test
|
||||||
|
|
||||||
|
|
25
vendor/src/github.com/docker/libnetwork/Makefile
vendored
25
vendor/src/github.com/docker/libnetwork/Makefile
vendored
|
@ -1,4 +1,4 @@
|
||||||
.PHONY: all all-local build build-local check check-code check-format run-tests check-local install-deps coveralls circle-ci
|
.PHONY: all all-local build build-local check check-code check-format run-tests check-local integration-tests install-deps coveralls circle-ci
|
||||||
SHELL=/bin/bash
|
SHELL=/bin/bash
|
||||||
build_image=libnetwork-build
|
build_image=libnetwork-build
|
||||||
dockerargs = --privileged -v $(shell pwd):/go/src/github.com/docker/libnetwork -w /go/src/github.com/docker/libnetwork
|
dockerargs = --privileged -v $(shell pwd):/go/src/github.com/docker/libnetwork -w /go/src/github.com/docker/libnetwork
|
||||||
|
@ -7,8 +7,15 @@ docker = docker run --rm -it ${dockerargs} ${container_env} ${build_image}
|
||||||
ciargs = -e "COVERALLS_TOKEN=$$COVERALLS_TOKEN" -e "INSIDECONTAINER=-incontainer=true"
|
ciargs = -e "COVERALLS_TOKEN=$$COVERALLS_TOKEN" -e "INSIDECONTAINER=-incontainer=true"
|
||||||
cidocker = docker run ${ciargs} ${dockerargs} golang:1.4
|
cidocker = docker run ${ciargs} ${dockerargs} golang:1.4
|
||||||
|
|
||||||
all: ${build_image}.created
|
all: ${build_image}.created build check integration-tests
|
||||||
${docker} ./wrapmake.sh all-local
|
|
||||||
|
integration-tests:
|
||||||
|
@if [ ! -d ./integration-tmp ]; then \
|
||||||
|
mkdir -p ./integration-tmp; \
|
||||||
|
git clone https://github.com/sstephenson/bats.git ./integration-tmp/bats; \
|
||||||
|
./integration-tmp/bats/install.sh ./integration-tmp; \
|
||||||
|
fi
|
||||||
|
@./integration-tmp/bin/bats ./test/integration/dnet
|
||||||
|
|
||||||
all-local: check-local build-local
|
all-local: check-local build-local
|
||||||
|
|
||||||
|
@ -19,13 +26,16 @@ ${build_image}.created:
|
||||||
touch ${build_image}.created
|
touch ${build_image}.created
|
||||||
|
|
||||||
build: ${build_image}.created
|
build: ${build_image}.created
|
||||||
${docker} ./wrapmake.sh build-local
|
@echo "Building code... "
|
||||||
|
@${docker} ./wrapmake.sh build-local
|
||||||
|
@echo "Done building code"
|
||||||
|
|
||||||
build-local:
|
build-local:
|
||||||
$(shell which godep) go build -tags libnetwork_discovery ./...
|
@$(shell which godep) go build -tags libnetwork_discovery ./...
|
||||||
|
@$(shell which godep) go build -o ./cmd/dnet/dnet ./cmd/dnet
|
||||||
|
|
||||||
check: ${build_image}.created
|
check: ${build_image}.created
|
||||||
${docker} ./wrapmake.sh check-local
|
@${docker} ./wrapmake.sh check-local
|
||||||
|
|
||||||
check-code:
|
check-code:
|
||||||
@echo "Checking code... "
|
@echo "Checking code... "
|
||||||
|
@ -76,4 +86,5 @@ coveralls:
|
||||||
# The following target is a workaround for this
|
# The following target is a workaround for this
|
||||||
|
|
||||||
circle-ci:
|
circle-ci:
|
||||||
@${cidocker} make install-deps check-local coveralls
|
@${cidocker} make install-deps build-local check-local coveralls
|
||||||
|
make integration-tests
|
||||||
|
|
|
@ -249,6 +249,9 @@ func (sc *sandboxCreate) parseOptions() []libnetwork.SandboxOption {
|
||||||
if sc.UseDefaultSandbox {
|
if sc.UseDefaultSandbox {
|
||||||
setFctList = append(setFctList, libnetwork.OptionUseDefaultSandbox())
|
setFctList = append(setFctList, libnetwork.OptionUseDefaultSandbox())
|
||||||
}
|
}
|
||||||
|
if sc.UseExternalKey {
|
||||||
|
setFctList = append(setFctList, libnetwork.OptionUseExternalKey())
|
||||||
|
}
|
||||||
if sc.DNS != nil {
|
if sc.DNS != nil {
|
||||||
for _, d := range sc.DNS {
|
for _, d := range sc.DNS {
|
||||||
setFctList = append(setFctList, libnetwork.OptionDNS(d))
|
setFctList = append(setFctList, libnetwork.OptionDNS(d))
|
||||||
|
|
|
@ -57,6 +57,7 @@ type sandboxCreate struct {
|
||||||
DNS []string `json:"dns"`
|
DNS []string `json:"dns"`
|
||||||
ExtraHosts []extraHost `json:"extra_hosts"`
|
ExtraHosts []extraHost `json:"extra_hosts"`
|
||||||
UseDefaultSandbox bool `json:"use_default_sandbox"`
|
UseDefaultSandbox bool `json:"use_default_sandbox"`
|
||||||
|
UseExternalKey bool `json:"use_external_key"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// endpointJoin represents the expected body of the "join endpoint" or "leave endpoint" http request messages
|
// endpointJoin represents the expected body of the "join endpoint" or "leave endpoint" http request messages
|
||||||
|
|
|
@ -115,7 +115,7 @@ func lookupContainerID(cli *NetworkCli, cnNameID string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupSandboxID(cli *NetworkCli, containerID string) (string, error) {
|
func lookupSandboxID(cli *NetworkCli, containerID string) (string, error) {
|
||||||
obj, _, err := readBody(cli.call("GET", fmt.Sprintf("/sandboxes?container-id=%s", containerID), nil, nil))
|
obj, _, err := readBody(cli.call("GET", fmt.Sprintf("/sandboxes?partial-container-id=%s", containerID), nil, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -360,12 +360,17 @@ func (cli *NetworkCli) CmdServiceDetach(chain string, args ...string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sandboxID, err := lookupSandboxID(cli, containerID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
serviceID, err := lookupServiceID(cli, nn, sn)
|
serviceID, err := lookupServiceID(cli, nn, sn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, err = readBody(cli.call("DELETE", "/services/"+serviceID+"/backend/"+containerID, nil, nil))
|
_, _, err = readBody(cli.call("DELETE", "/services/"+serviceID+"/backend/"+sandboxID, nil, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,7 @@ func (c *Config) ProcessOptions(options ...Option) {
|
||||||
|
|
||||||
// IsValidName validates configuration objects supported by libnetwork
|
// IsValidName validates configuration objects supported by libnetwork
|
||||||
func IsValidName(name string) bool {
|
func IsValidName(name string) bool {
|
||||||
if name == "" || strings.Contains(name, ".") {
|
if strings.TrimSpace(name) == "" || strings.Contains(name, ".") {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -65,6 +65,9 @@ import (
|
||||||
// NetworkController provides the interface for controller instance which manages
|
// NetworkController provides the interface for controller instance which manages
|
||||||
// networks.
|
// networks.
|
||||||
type NetworkController interface {
|
type NetworkController interface {
|
||||||
|
// ID provides an unique identity for the controller
|
||||||
|
ID() string
|
||||||
|
|
||||||
// ConfigureNetworkDriver applies the passed options to the driver instance for the specified network type
|
// ConfigureNetworkDriver applies the passed options to the driver instance for the specified network type
|
||||||
ConfigureNetworkDriver(networkType string, options map[string]interface{}) error
|
ConfigureNetworkDriver(networkType string, options map[string]interface{}) error
|
||||||
|
|
||||||
|
@ -99,8 +102,8 @@ type NetworkController interface {
|
||||||
// SandboxByID returns the Sandbox which has the passed id. If not found, a types.NotFoundError is returned.
|
// SandboxByID returns the Sandbox which has the passed id. If not found, a types.NotFoundError is returned.
|
||||||
SandboxByID(id string) (Sandbox, error)
|
SandboxByID(id string) (Sandbox, error)
|
||||||
|
|
||||||
// GC triggers immediate garbage collection of resources which are garbage collected.
|
// Stop network controller
|
||||||
GC()
|
Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkWalker is a client provided function which will be used to walk the Networks.
|
// NetworkWalker is a client provided function which will be used to walk the Networks.
|
||||||
|
@ -122,11 +125,13 @@ type endpointTable map[string]*endpoint
|
||||||
type sandboxTable map[string]*sandbox
|
type sandboxTable map[string]*sandbox
|
||||||
|
|
||||||
type controller struct {
|
type controller struct {
|
||||||
networks networkTable
|
id string
|
||||||
drivers driverTable
|
networks networkTable
|
||||||
sandboxes sandboxTable
|
drivers driverTable
|
||||||
cfg *config.Config
|
sandboxes sandboxTable
|
||||||
store datastore.DataStore
|
cfg *config.Config
|
||||||
|
store datastore.DataStore
|
||||||
|
extKeyListener net.Listener
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +143,7 @@ func New(cfgOptions ...config.Option) (NetworkController, error) {
|
||||||
cfg.ProcessOptions(cfgOptions...)
|
cfg.ProcessOptions(cfgOptions...)
|
||||||
}
|
}
|
||||||
c := &controller{
|
c := &controller{
|
||||||
|
id: stringid.GenerateRandomID(),
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
networks: networkTable{},
|
networks: networkTable{},
|
||||||
sandboxes: sandboxTable{},
|
sandboxes: sandboxTable{},
|
||||||
|
@ -159,9 +165,17 @@ func New(cfgOptions ...config.Option) (NetworkController, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := c.startExternalKeyListener(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *controller) ID() string {
|
||||||
|
return c.id
|
||||||
|
}
|
||||||
|
|
||||||
func (c *controller) validateHostDiscoveryConfig() bool {
|
func (c *controller) validateHostDiscoveryConfig() bool {
|
||||||
if c.cfg == nil || c.cfg.Cluster.Discovery == "" || c.cfg.Cluster.Address == "" {
|
if c.cfg == nil || c.cfg.Cluster.Discovery == "" || c.cfg.Cluster.Address == "" {
|
||||||
return false
|
return false
|
||||||
|
@ -204,11 +218,11 @@ func (c *controller) ConfigureNetworkDriver(networkType string, options map[stri
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver, capability driverapi.Capability) error {
|
func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver, capability driverapi.Capability) error {
|
||||||
c.Lock()
|
|
||||||
if !config.IsValidName(networkType) {
|
if !config.IsValidName(networkType) {
|
||||||
c.Unlock()
|
|
||||||
return ErrInvalidName(networkType)
|
return ErrInvalidName(networkType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.Lock()
|
||||||
if _, ok := c.drivers[networkType]; ok {
|
if _, ok := c.drivers[networkType]; ok {
|
||||||
c.Unlock()
|
c.Unlock()
|
||||||
return driverapi.ErrActiveRegistration(networkType)
|
return driverapi.ErrActiveRegistration(networkType)
|
||||||
|
@ -414,7 +428,7 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if sb.osSbox == nil {
|
if sb.osSbox == nil && !sb.config.useExternalKey {
|
||||||
if sb.osSbox, err = osl.NewSandbox(sb.Key(), !sb.config.useDefaultSandBox); err != nil {
|
if sb.osSbox, err = osl.NewSandbox(sb.Key(), !sb.config.useDefaultSandBox); err != nil {
|
||||||
return nil, fmt.Errorf("failed to create new osl sandbox: %v", err)
|
return nil, fmt.Errorf("failed to create new osl sandbox: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -514,6 +528,7 @@ func (c *controller) isDriverGlobalScoped(networkType string) (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *controller) GC() {
|
func (c *controller) Stop() {
|
||||||
|
c.stopExternalKeyListener()
|
||||||
osl.GC()
|
osl.GC()
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,18 +45,16 @@ type Driver interface {
|
||||||
|
|
||||||
// EndpointInfo provides a go interface to fetch or populate endpoint assigned network resources.
|
// EndpointInfo provides a go interface to fetch or populate endpoint assigned network resources.
|
||||||
type EndpointInfo interface {
|
type EndpointInfo interface {
|
||||||
// Interfaces returns a list of interfaces bound to the endpoint.
|
// Interface returns the interface bound to the endpoint.
|
||||||
// If the list is not empty the driver is only expected to consume the interfaces.
|
// If the value is not nil the driver is only expected to consume the interface.
|
||||||
// It is an error to try to add interfaces to a non-empty list.
|
// It is an error to try to add interface if the passed down value is non-nil
|
||||||
// If the list is empty the driver is expected to populate with 0 or more interfaces.
|
// If the value is nil the driver is expected to add an interface
|
||||||
Interfaces() []InterfaceInfo
|
Interface() InterfaceInfo
|
||||||
|
|
||||||
// AddInterface is used by the driver to add an interface to the interface list.
|
// AddInterface is used by the driver to add an interface for the endpoint.
|
||||||
// This method will return an error if the driver attempts to add interfaces
|
// This method will return an error if the driver attempts to add interface
|
||||||
// if the Interfaces() method returned a non-empty list.
|
// if the Interface() method returned a non-nil value.
|
||||||
// ID field need only have significance within the endpoint so it can be a simple
|
AddInterface(mac net.HardwareAddr, ipv4 net.IPNet, ipv6 net.IPNet) error
|
||||||
// monotonically increasing number
|
|
||||||
AddInterface(ID int, mac net.HardwareAddr, ipv4 net.IPNet, ipv6 net.IPNet) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// InterfaceInfo provides a go interface for drivers to retrive
|
// InterfaceInfo provides a go interface for drivers to retrive
|
||||||
|
@ -70,10 +68,6 @@ type InterfaceInfo interface {
|
||||||
|
|
||||||
// AddressIPv6 returns the IPv6 address.
|
// AddressIPv6 returns the IPv6 address.
|
||||||
AddressIPv6() net.IPNet
|
AddressIPv6() net.IPNet
|
||||||
|
|
||||||
// ID returns the numerical id of the interface and has significance only within
|
|
||||||
// the endpoint.
|
|
||||||
ID() int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// InterfaceNameInfo provides a go interface for the drivers to assign names
|
// InterfaceNameInfo provides a go interface for the drivers to assign names
|
||||||
|
@ -81,18 +75,14 @@ type InterfaceInfo interface {
|
||||||
type InterfaceNameInfo interface {
|
type InterfaceNameInfo interface {
|
||||||
// SetNames method assigns the srcName and dstPrefix for the interface.
|
// SetNames method assigns the srcName and dstPrefix for the interface.
|
||||||
SetNames(srcName, dstPrefix string) error
|
SetNames(srcName, dstPrefix string) error
|
||||||
|
|
||||||
// ID returns the numerical id that was assigned to the interface by the driver
|
|
||||||
// CreateEndpoint.
|
|
||||||
ID() int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// JoinInfo represents a set of resources that the driver has the ability to provide during
|
// JoinInfo represents a set of resources that the driver has the ability to provide during
|
||||||
// join time.
|
// join time.
|
||||||
type JoinInfo interface {
|
type JoinInfo interface {
|
||||||
// InterfaceNames returns a list of InterfaceNameInfo go interface to facilitate
|
// InterfaceName returns a InterfaceNameInfo go interface to facilitate
|
||||||
// setting the names for the interfaces.
|
// setting the names for the interface.
|
||||||
InterfaceNames() []InterfaceNameInfo
|
InterfaceName() InterfaceNameInfo
|
||||||
|
|
||||||
// SetGateway sets the default IPv4 gateway when a container joins the endpoint.
|
// SetGateway sets the default IPv4 gateway when a container joins the endpoint.
|
||||||
SetGateway(net.IP) error
|
SetGateway(net.IP) error
|
||||||
|
@ -102,7 +92,7 @@ type JoinInfo interface {
|
||||||
|
|
||||||
// AddStaticRoute adds a routes to the sandbox.
|
// AddStaticRoute adds a routes to the sandbox.
|
||||||
// It may be used in addtion to or instead of a default gateway (as above).
|
// It may be used in addtion to or instead of a default gateway (as above).
|
||||||
AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP, interfaceID int) error
|
AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// DriverCallback provides a Callback interface for Drivers into LibNetwork
|
// DriverCallback provides a Callback interface for Drivers into LibNetwork
|
||||||
|
|
|
@ -32,7 +32,6 @@ const (
|
||||||
vethLen = 7
|
vethLen = 7
|
||||||
containerVethPrefix = "eth"
|
containerVethPrefix = "eth"
|
||||||
maxAllocatePortAttempts = 10
|
maxAllocatePortAttempts = 10
|
||||||
ifaceID = 1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -883,8 +882,8 @@ func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo,
|
||||||
return errors.New("invalid endpoint info passed")
|
return errors.New("invalid endpoint info passed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(epInfo.Interfaces()) != 0 {
|
if epInfo.Interface() != nil {
|
||||||
return errors.New("non empty interface list passed to bridge(local) driver")
|
return errors.New("non-nil interface passed to bridge(local) driver")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the network handler and make sure it exists
|
// Get the network handler and make sure it exists
|
||||||
|
@ -1070,7 +1069,7 @@ func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo,
|
||||||
endpoint.addrv6 = ipv6Addr
|
endpoint.addrv6 = ipv6Addr
|
||||||
}
|
}
|
||||||
|
|
||||||
err = epInfo.AddInterface(ifaceID, endpoint.macAddress, *ipv4Addr, *ipv6Addr)
|
err = epInfo.AddInterface(endpoint.macAddress, *ipv4Addr, *ipv6Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1244,14 +1243,10 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
|
||||||
return EndpointNotFoundError(eid)
|
return EndpointNotFoundError(eid)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, iNames := range jinfo.InterfaceNames() {
|
iNames := jinfo.InterfaceName()
|
||||||
// Make sure to set names on the correct interface ID.
|
err = iNames.SetNames(endpoint.srcName, containerVethPrefix)
|
||||||
if iNames.ID() == ifaceID {
|
if err != nil {
|
||||||
err = iNames.SetNames(endpoint.srcName, containerVethPrefix)
|
return err
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = jinfo.SetGateway(network.bridge.gatewayIPv4)
|
err = jinfo.SetGateway(network.bridge.gatewayIPv4)
|
||||||
|
|
|
@ -65,13 +65,10 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
|
||||||
return fmt.Errorf("could not set mac address to the container interface: %v", err)
|
return fmt.Errorf("could not set mac address to the container interface: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, iNames := range jinfo.InterfaceNames() {
|
if iNames := jinfo.InterfaceName(); iNames != nil {
|
||||||
// Make sure to set names on the correct interface ID.
|
err = iNames.SetNames(name2, "eth")
|
||||||
if iNames.ID() == 1 {
|
if err != nil {
|
||||||
err = iNames.SetNames(name2, "eth")
|
return err
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,10 +51,10 @@ func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo,
|
||||||
id: eid,
|
id: eid,
|
||||||
}
|
}
|
||||||
|
|
||||||
if epInfo != nil && (len(epInfo.Interfaces()) > 0) {
|
if epInfo != nil && epInfo.Interface() != nil {
|
||||||
addr := epInfo.Interfaces()[0].Address()
|
addr := epInfo.Interface().Address()
|
||||||
ep.addr = &addr
|
ep.addr = &addr
|
||||||
ep.mac = epInfo.Interfaces()[0].MacAddress()
|
ep.mac = epInfo.Interface().MacAddress()
|
||||||
n.addEndpoint(ep)
|
n.addEndpoint(ep)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo,
|
||||||
|
|
||||||
ep.mac = netutils.GenerateMACFromIP(ep.addr.IP)
|
ep.mac = netutils.GenerateMACFromIP(ep.addr.IP)
|
||||||
|
|
||||||
err = epInfo.AddInterface(1, ep.mac, *ep.addr, net.IPNet{})
|
err = epInfo.AddInterface(ep.mac, *ep.addr, net.IPNet{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not add interface to endpoint info: %v", err)
|
return fmt.Errorf("could not add interface to endpoint info: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,13 +48,12 @@ type CreateEndpointRequest struct {
|
||||||
NetworkID string
|
NetworkID string
|
||||||
// The ID of the endpoint for later reference.
|
// The ID of the endpoint for later reference.
|
||||||
EndpointID string
|
EndpointID string
|
||||||
Interfaces []*EndpointInterface
|
Interface *EndpointInterface
|
||||||
Options map[string]interface{}
|
Options map[string]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EndpointInterface represents an interface endpoint.
|
// EndpointInterface represents an interface endpoint.
|
||||||
type EndpointInterface struct {
|
type EndpointInterface struct {
|
||||||
ID int
|
|
||||||
Address string
|
Address string
|
||||||
AddressIPv6 string
|
AddressIPv6 string
|
||||||
MacAddress string
|
MacAddress string
|
||||||
|
@ -63,12 +62,11 @@ type EndpointInterface struct {
|
||||||
// CreateEndpointResponse is the response to the CreateEndpoint action.
|
// CreateEndpointResponse is the response to the CreateEndpoint action.
|
||||||
type CreateEndpointResponse struct {
|
type CreateEndpointResponse struct {
|
||||||
Response
|
Response
|
||||||
Interfaces []*EndpointInterface
|
Interface *EndpointInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface is the representation of a linux interface.
|
// Interface is the representation of a linux interface.
|
||||||
type Interface struct {
|
type Interface struct {
|
||||||
ID int
|
|
||||||
Address *net.IPNet
|
Address *net.IPNet
|
||||||
AddressIPv6 *net.IPNet
|
AddressIPv6 *net.IPNet
|
||||||
MacAddress net.HardwareAddr
|
MacAddress net.HardwareAddr
|
||||||
|
@ -118,16 +116,15 @@ type StaticRoute struct {
|
||||||
Destination string
|
Destination string
|
||||||
RouteType int
|
RouteType int
|
||||||
NextHop string
|
NextHop string
|
||||||
InterfaceID int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// JoinResponse is the response to a JoinRequest.
|
// JoinResponse is the response to a JoinRequest.
|
||||||
type JoinResponse struct {
|
type JoinResponse struct {
|
||||||
Response
|
Response
|
||||||
InterfaceNames []*InterfaceName
|
InterfaceName *InterfaceName
|
||||||
Gateway string
|
Gateway string
|
||||||
GatewayIPv6 string
|
GatewayIPv6 string
|
||||||
StaticRoutes []StaticRoute
|
StaticRoutes []StaticRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
// LeaveRequest describes the API for detaching an endpoint from a sandbox.
|
// LeaveRequest describes the API for detaching an endpoint from a sandbox.
|
||||||
|
|
|
@ -71,16 +71,17 @@ func (d *driver) DeleteNetwork(nid string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo, epOptions map[string]interface{}) error {
|
func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo, epOptions map[string]interface{}) error {
|
||||||
|
var reqIface *api.EndpointInterface
|
||||||
|
|
||||||
if epInfo == nil {
|
if epInfo == nil {
|
||||||
return fmt.Errorf("must not be called with nil EndpointInfo")
|
return fmt.Errorf("must not be called with nil EndpointInfo")
|
||||||
}
|
}
|
||||||
|
|
||||||
reqIfaces := make([]*api.EndpointInterface, len(epInfo.Interfaces()))
|
iface := epInfo.Interface()
|
||||||
for i, iface := range epInfo.Interfaces() {
|
if iface != nil {
|
||||||
addr4 := iface.Address()
|
addr4 := iface.Address()
|
||||||
addr6 := iface.AddressIPv6()
|
addr6 := iface.AddressIPv6()
|
||||||
reqIfaces[i] = &api.EndpointInterface{
|
reqIface = &api.EndpointInterface{
|
||||||
ID: iface.ID(),
|
|
||||||
Address: addr4.String(),
|
Address: addr4.String(),
|
||||||
AddressIPv6: addr6.String(),
|
AddressIPv6: addr6.String(),
|
||||||
MacAddress: iface.MacAddress().String(),
|
MacAddress: iface.MacAddress().String(),
|
||||||
|
@ -89,7 +90,7 @@ func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo,
|
||||||
create := &api.CreateEndpointRequest{
|
create := &api.CreateEndpointRequest{
|
||||||
NetworkID: nid,
|
NetworkID: nid,
|
||||||
EndpointID: eid,
|
EndpointID: eid,
|
||||||
Interfaces: reqIfaces,
|
Interface: reqIface,
|
||||||
Options: epOptions,
|
Options: epOptions,
|
||||||
}
|
}
|
||||||
var res api.CreateEndpointResponse
|
var res api.CreateEndpointResponse
|
||||||
|
@ -97,25 +98,26 @@ func (d *driver) CreateEndpoint(nid, eid string, epInfo driverapi.EndpointInfo,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ifaces, err := parseInterfaces(res)
|
inIface, err := parseInterface(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(reqIfaces) > 0 && len(ifaces) > 0 {
|
if reqIface != nil && inIface != nil {
|
||||||
// We're not supposed to add interfaces if there already are
|
// We're not supposed to add interface if there is already
|
||||||
// some. Attempt to roll back
|
// one. Attempt to roll back
|
||||||
return errorWithRollback("driver attempted to add more interfaces", d.DeleteEndpoint(nid, eid))
|
return errorWithRollback("driver attempted to add interface ignoring the one provided", d.DeleteEndpoint(nid, eid))
|
||||||
}
|
}
|
||||||
for _, iface := range ifaces {
|
|
||||||
|
if inIface != nil {
|
||||||
var addr4, addr6 net.IPNet
|
var addr4, addr6 net.IPNet
|
||||||
if iface.Address != nil {
|
if inIface.Address != nil {
|
||||||
addr4 = *(iface.Address)
|
addr4 = *(inIface.Address)
|
||||||
}
|
}
|
||||||
if iface.AddressIPv6 != nil {
|
if inIface.AddressIPv6 != nil {
|
||||||
addr6 = *(iface.AddressIPv6)
|
addr6 = *(inIface.AddressIPv6)
|
||||||
}
|
}
|
||||||
if err := epInfo.AddInterface(iface.ID, iface.MacAddress, addr4, addr6); err != nil {
|
if err := epInfo.AddInterface(inIface.MacAddress, addr4, addr6); err != nil {
|
||||||
return errorWithRollback(fmt.Sprintf("failed to AddInterface %v: %s", iface, err), d.DeleteEndpoint(nid, eid))
|
return errorWithRollback(fmt.Sprintf("failed to AddInterface %v: %s", inIface, err), d.DeleteEndpoint(nid, eid))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -165,18 +167,13 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expect each interface ID given by CreateEndpoint to have an
|
ifaceName := res.InterfaceName
|
||||||
// entry at that index in the names supplied here. In other words,
|
if ifaceName == nil {
|
||||||
// if you supply 0..n interfaces with IDs 0..n above, you should
|
return fmt.Errorf("no interface name information received")
|
||||||
// supply the names in the same order.
|
}
|
||||||
ifaceNames := res.InterfaceNames
|
|
||||||
for _, iface := range jinfo.InterfaceNames() {
|
if iface := jinfo.InterfaceName(); iface != nil {
|
||||||
i := iface.ID()
|
if err := iface.SetNames(ifaceName.SrcName, ifaceName.DstPrefix); err != nil {
|
||||||
if i >= len(ifaceNames) || i < 0 {
|
|
||||||
return fmt.Errorf("no correlating interface %d in supplied interface names", i)
|
|
||||||
}
|
|
||||||
supplied := ifaceNames[i]
|
|
||||||
if err := iface.SetNames(supplied.SrcName, supplied.DstPrefix); err != nil {
|
|
||||||
return errorWithRollback(fmt.Sprintf("failed to set interface name: %s", err), d.Leave(nid, eid))
|
return errorWithRollback(fmt.Sprintf("failed to set interface name: %s", err), d.Leave(nid, eid))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,7 +201,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, route := range routes {
|
for _, route := range routes {
|
||||||
if jinfo.AddStaticRoute(route.Destination, route.RouteType, route.NextHop, route.InterfaceID) != nil {
|
if jinfo.AddStaticRoute(route.Destination, route.RouteType, route.NextHop) != nil {
|
||||||
return errorWithRollback(fmt.Sprintf("failed to set static route: %v", route), d.Leave(nid, eid))
|
return errorWithRollback(fmt.Sprintf("failed to set static route: %v", route), d.Leave(nid, eid))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +226,7 @@ func parseStaticRoutes(r api.JoinResponse) ([]*types.StaticRoute, error) {
|
||||||
var routes = make([]*types.StaticRoute, len(r.StaticRoutes))
|
var routes = make([]*types.StaticRoute, len(r.StaticRoutes))
|
||||||
for i, inRoute := range r.StaticRoutes {
|
for i, inRoute := range r.StaticRoutes {
|
||||||
var err error
|
var err error
|
||||||
outRoute := &types.StaticRoute{InterfaceID: inRoute.InterfaceID, RouteType: inRoute.RouteType}
|
outRoute := &types.StaticRoute{RouteType: inRoute.RouteType}
|
||||||
|
|
||||||
if inRoute.Destination != "" {
|
if inRoute.Destination != "" {
|
||||||
if outRoute.Destination, err = toAddr(inRoute.Destination); err != nil {
|
if outRoute.Destination, err = toAddr(inRoute.Destination); err != nil {
|
||||||
|
@ -250,13 +247,13 @@ func parseStaticRoutes(r api.JoinResponse) ([]*types.StaticRoute, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseInterfaces validates all the parameters of an Interface and returns them.
|
// parseInterfaces validates all the parameters of an Interface and returns them.
|
||||||
func parseInterfaces(r api.CreateEndpointResponse) ([]*api.Interface, error) {
|
func parseInterface(r api.CreateEndpointResponse) (*api.Interface, error) {
|
||||||
var (
|
var outIf *api.Interface
|
||||||
Interfaces = make([]*api.Interface, len(r.Interfaces))
|
|
||||||
)
|
inIf := r.Interface
|
||||||
for i, inIf := range r.Interfaces {
|
if inIf != nil {
|
||||||
var err error
|
var err error
|
||||||
outIf := &api.Interface{ID: inIf.ID}
|
outIf = &api.Interface{}
|
||||||
if inIf.Address != "" {
|
if inIf.Address != "" {
|
||||||
if outIf.Address, err = toAddr(inIf.Address); err != nil {
|
if outIf.Address, err = toAddr(inIf.Address); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -272,9 +269,9 @@ func parseInterfaces(r api.CreateEndpointResponse) ([]*api.Interface, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Interfaces[i] = outIf
|
|
||||||
}
|
}
|
||||||
return Interfaces, nil
|
|
||||||
|
return outIf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toAddr(ipAddr string) (*net.IPNet, error) {
|
func toAddr(ipAddr string) (*net.IPNet, error) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package libnetwork
|
package libnetwork
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"container/heap"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
@ -49,7 +50,7 @@ type endpoint struct {
|
||||||
name string
|
name string
|
||||||
id string
|
id string
|
||||||
network *network
|
network *network
|
||||||
iFaces []*endpointInterface
|
iface *endpointInterface
|
||||||
joinInfo *endpointJoinInfo
|
joinInfo *endpointJoinInfo
|
||||||
sandboxID string
|
sandboxID string
|
||||||
exposedPorts []types.TransportPort
|
exposedPorts []types.TransportPort
|
||||||
|
@ -67,7 +68,7 @@ func (ep *endpoint) MarshalJSON() ([]byte, error) {
|
||||||
epMap := make(map[string]interface{})
|
epMap := make(map[string]interface{})
|
||||||
epMap["name"] = ep.name
|
epMap["name"] = ep.name
|
||||||
epMap["id"] = ep.id
|
epMap["id"] = ep.id
|
||||||
epMap["ep_iface"] = ep.iFaces
|
epMap["ep_iface"] = ep.iface
|
||||||
epMap["exposed_ports"] = ep.exposedPorts
|
epMap["exposed_ports"] = ep.exposedPorts
|
||||||
epMap["generic"] = ep.generic
|
epMap["generic"] = ep.generic
|
||||||
epMap["sandbox"] = ep.sandboxID
|
epMap["sandbox"] = ep.sandboxID
|
||||||
|
@ -86,12 +87,7 @@ func (ep *endpoint) UnmarshalJSON(b []byte) (err error) {
|
||||||
ep.id = epMap["id"].(string)
|
ep.id = epMap["id"].(string)
|
||||||
|
|
||||||
ib, _ := json.Marshal(epMap["ep_iface"])
|
ib, _ := json.Marshal(epMap["ep_iface"])
|
||||||
var ifaces []endpointInterface
|
json.Unmarshal(ib, ep.iface)
|
||||||
json.Unmarshal(ib, &ifaces)
|
|
||||||
ep.iFaces = make([]*endpointInterface, 0)
|
|
||||||
for _, iface := range ifaces {
|
|
||||||
ep.iFaces = append(ep.iFaces, &iface)
|
|
||||||
}
|
|
||||||
|
|
||||||
tb, _ := json.Marshal(epMap["exposed_ports"])
|
tb, _ := json.Marshal(epMap["exposed_ports"])
|
||||||
var tPorts []types.TransportPort
|
var tPorts []types.TransportPort
|
||||||
|
@ -289,10 +285,25 @@ func (ep *endpoint) Join(sbox Sandbox, options ...EndpointOption) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sb.Lock()
|
||||||
|
heap.Push(&sb.endpoints, ep)
|
||||||
|
sb.Unlock()
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
for i, e := range sb.getConnectedEndpoints() {
|
||||||
|
if e == ep {
|
||||||
|
sb.Lock()
|
||||||
|
heap.Remove(&sb.endpoints, i)
|
||||||
|
sb.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
if err = sb.populateNetworkResources(ep); err != nil {
|
if err = sb.populateNetworkResources(ep); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,13 +311,7 @@ func (ep *endpoint) hasInterface(iName string) bool {
|
||||||
ep.Lock()
|
ep.Lock()
|
||||||
defer ep.Unlock()
|
defer ep.Unlock()
|
||||||
|
|
||||||
for _, iface := range ep.iFaces {
|
return ep.iface != nil && ep.iface.srcName == iName
|
||||||
if iface.srcName == iName {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *endpoint) Leave(sbox Sandbox, options ...EndpointOption) error {
|
func (ep *endpoint) Leave(sbox Sandbox, options ...EndpointOption) error {
|
||||||
|
@ -463,8 +468,8 @@ func (ep *endpoint) getFirstInterfaceAddress() net.IP {
|
||||||
ep.Lock()
|
ep.Lock()
|
||||||
defer ep.Unlock()
|
defer ep.Unlock()
|
||||||
|
|
||||||
if len(ep.iFaces) != 0 && ep.iFaces[0] != nil {
|
if ep.iface != nil {
|
||||||
return ep.iFaces[0].addr.IP
|
return ep.iface.addr.IP
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -10,9 +10,11 @@ import (
|
||||||
|
|
||||||
// EndpointInfo provides an interface to retrieve network resources bound to the endpoint.
|
// EndpointInfo provides an interface to retrieve network resources bound to the endpoint.
|
||||||
type EndpointInfo interface {
|
type EndpointInfo interface {
|
||||||
// InterfaceList returns an interface list which were assigned to the endpoint
|
// Iface returns InterfaceInfo, go interface that can be used
|
||||||
// by the driver. This can be used after the endpoint has been created.
|
// to get more information on the interface which was assigned to
|
||||||
InterfaceList() []InterfaceInfo
|
// the endpoint by the driver. This can be used after the
|
||||||
|
// endpoint has been created.
|
||||||
|
Iface() InterfaceInfo
|
||||||
|
|
||||||
// Gateway returns the IPv4 gateway assigned by the driver.
|
// Gateway returns the IPv4 gateway assigned by the driver.
|
||||||
// This will only return a valid value if a container has joined the endpoint.
|
// This will only return a valid value if a container has joined the endpoint.
|
||||||
|
@ -39,7 +41,6 @@ type InterfaceInfo interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type endpointInterface struct {
|
type endpointInterface struct {
|
||||||
id int
|
|
||||||
mac net.HardwareAddr
|
mac net.HardwareAddr
|
||||||
addr net.IPNet
|
addr net.IPNet
|
||||||
addrv6 net.IPNet
|
addrv6 net.IPNet
|
||||||
|
@ -50,7 +51,6 @@ type endpointInterface struct {
|
||||||
|
|
||||||
func (epi *endpointInterface) MarshalJSON() ([]byte, error) {
|
func (epi *endpointInterface) MarshalJSON() ([]byte, error) {
|
||||||
epMap := make(map[string]interface{})
|
epMap := make(map[string]interface{})
|
||||||
epMap["id"] = epi.id
|
|
||||||
epMap["mac"] = epi.mac.String()
|
epMap["mac"] = epi.mac.String()
|
||||||
epMap["addr"] = epi.addr.String()
|
epMap["addr"] = epi.addr.String()
|
||||||
epMap["addrv6"] = epi.addrv6.String()
|
epMap["addrv6"] = epi.addrv6.String()
|
||||||
|
@ -69,7 +69,6 @@ func (epi *endpointInterface) UnmarshalJSON(b []byte) (err error) {
|
||||||
if err := json.Unmarshal(b, &epMap); err != nil {
|
if err := json.Unmarshal(b, &epMap); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
epi.id = int(epMap["id"].(float64))
|
|
||||||
|
|
||||||
mac, _ := net.ParseMAC(epMap["mac"].(string))
|
mac, _ := net.ParseMAC(epMap["mac"].(string))
|
||||||
epi.mac = mac
|
epi.mac = mac
|
||||||
|
@ -128,51 +127,42 @@ func (ep *endpoint) DriverInfo() (map[string]interface{}, error) {
|
||||||
return driver.EndpointOperInfo(nid, epid)
|
return driver.EndpointOperInfo(nid, epid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *endpoint) InterfaceList() []InterfaceInfo {
|
func (ep *endpoint) Iface() InterfaceInfo {
|
||||||
ep.Lock()
|
ep.Lock()
|
||||||
defer ep.Unlock()
|
defer ep.Unlock()
|
||||||
|
|
||||||
iList := make([]InterfaceInfo, len(ep.iFaces))
|
if ep.iface != nil {
|
||||||
|
return ep.iface
|
||||||
for i, iface := range ep.iFaces {
|
|
||||||
iList[i] = iface
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return iList
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *endpoint) Interfaces() []driverapi.InterfaceInfo {
|
func (ep *endpoint) Interface() driverapi.InterfaceInfo {
|
||||||
ep.Lock()
|
ep.Lock()
|
||||||
defer ep.Unlock()
|
defer ep.Unlock()
|
||||||
|
|
||||||
iList := make([]driverapi.InterfaceInfo, len(ep.iFaces))
|
if ep.iface != nil {
|
||||||
|
return ep.iface
|
||||||
for i, iface := range ep.iFaces {
|
|
||||||
iList[i] = iface
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return iList
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *endpoint) AddInterface(id int, mac net.HardwareAddr, ipv4 net.IPNet, ipv6 net.IPNet) error {
|
func (ep *endpoint) AddInterface(mac net.HardwareAddr, ipv4 net.IPNet, ipv6 net.IPNet) error {
|
||||||
ep.Lock()
|
ep.Lock()
|
||||||
defer ep.Unlock()
|
defer ep.Unlock()
|
||||||
|
|
||||||
iface := &endpointInterface{
|
iface := &endpointInterface{
|
||||||
id: id,
|
|
||||||
addr: *types.GetIPNetCopy(&ipv4),
|
addr: *types.GetIPNetCopy(&ipv4),
|
||||||
addrv6: *types.GetIPNetCopy(&ipv6),
|
addrv6: *types.GetIPNetCopy(&ipv6),
|
||||||
}
|
}
|
||||||
iface.mac = types.GetMacCopy(mac)
|
iface.mac = types.GetMacCopy(mac)
|
||||||
|
|
||||||
ep.iFaces = append(ep.iFaces, iface)
|
ep.iface = iface
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (epi *endpointInterface) ID() int {
|
|
||||||
return epi.id
|
|
||||||
}
|
|
||||||
|
|
||||||
func (epi *endpointInterface) MacAddress() net.HardwareAddr {
|
func (epi *endpointInterface) MacAddress() net.HardwareAddr {
|
||||||
return types.GetMacCopy(epi.mac)
|
return types.GetMacCopy(epi.mac)
|
||||||
}
|
}
|
||||||
|
@ -191,24 +181,22 @@ func (epi *endpointInterface) SetNames(srcName string, dstPrefix string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *endpoint) InterfaceNames() []driverapi.InterfaceNameInfo {
|
func (ep *endpoint) InterfaceName() driverapi.InterfaceNameInfo {
|
||||||
ep.Lock()
|
ep.Lock()
|
||||||
defer ep.Unlock()
|
defer ep.Unlock()
|
||||||
|
|
||||||
iList := make([]driverapi.InterfaceNameInfo, len(ep.iFaces))
|
if ep.iface != nil {
|
||||||
|
return ep.iface
|
||||||
for i, iface := range ep.iFaces {
|
|
||||||
iList[i] = iface
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return iList
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *endpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP, interfaceID int) error {
|
func (ep *endpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP) error {
|
||||||
ep.Lock()
|
ep.Lock()
|
||||||
defer ep.Unlock()
|
defer ep.Unlock()
|
||||||
|
|
||||||
r := types.StaticRoute{Destination: destination, RouteType: routeType, NextHop: nextHop, InterfaceID: interfaceID}
|
r := types.StaticRoute{Destination: destination, RouteType: routeType, NextHop: nextHop}
|
||||||
|
|
||||||
if routeType == types.NEXTHOP {
|
if routeType == types.NEXTHOP {
|
||||||
// If the route specifies a next-hop, then it's loosely routed (i.e. not bound to a particular interface).
|
// If the route specifies a next-hop, then it's loosely routed (i.e. not bound to a particular interface).
|
||||||
|
@ -223,14 +211,12 @@ func (ep *endpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *endpoint) addInterfaceRoute(route *types.StaticRoute) error {
|
func (ep *endpoint) addInterfaceRoute(route *types.StaticRoute) error {
|
||||||
for _, iface := range ep.iFaces {
|
ep.Lock()
|
||||||
if iface.id == route.InterfaceID {
|
defer ep.Unlock()
|
||||||
iface.routes = append(iface.routes, route.Destination)
|
|
||||||
return nil
|
iface := ep.iface
|
||||||
}
|
iface.routes = append(iface.routes, route.Destination)
|
||||||
}
|
return nil
|
||||||
return types.BadRequestErrorf("Interface with ID %d doesn't exist.",
|
|
||||||
route.InterfaceID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *endpoint) Sandbox() Sandbox {
|
func (ep *endpoint) Sandbox() Sandbox {
|
||||||
|
|
|
@ -305,7 +305,6 @@ func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoi
|
||||||
}
|
}
|
||||||
|
|
||||||
ep := &endpoint{name: name,
|
ep := &endpoint{name: name,
|
||||||
iFaces: []*endpointInterface{},
|
|
||||||
generic: make(map[string]interface{})}
|
generic: make(map[string]interface{})}
|
||||||
ep.id = stringid.GenerateRandomID()
|
ep.id = stringid.GenerateRandomID()
|
||||||
ep.network = n
|
ep.network = n
|
||||||
|
@ -409,7 +408,7 @@ func (n *network) isGlobalScoped() (bool, error) {
|
||||||
func (n *network) updateSvcRecord(ep *endpoint, isAdd bool) {
|
func (n *network) updateSvcRecord(ep *endpoint, isAdd bool) {
|
||||||
n.Lock()
|
n.Lock()
|
||||||
var recs []etchosts.Record
|
var recs []etchosts.Record
|
||||||
for _, iface := range ep.InterfaceList() {
|
if iface := ep.Iface(); iface != nil {
|
||||||
if isAdd {
|
if isAdd {
|
||||||
n.svcRecords[ep.Name()] = iface.Address().IP
|
n.svcRecords[ep.Name()] = iface.Address().IP
|
||||||
n.svcRecords[ep.Name()+"."+n.name] = iface.Address().IP
|
n.svcRecords[ep.Name()+"."+n.name] = iface.Address().IP
|
||||||
|
|
|
@ -157,30 +157,43 @@ func (n *networkNamespace) NeighborOptions() NeighborOptionSetter {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mountNetworkNamespace(basePath string, lnPath string) error {
|
||||||
|
if err := syscall.Mount(basePath, lnPath, "bind", syscall.MS_BIND, ""); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := loopbackUp(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSandboxForExternalKey returns sandbox object for the supplied path
|
||||||
|
func GetSandboxForExternalKey(basePath string, key string) (Sandbox, error) {
|
||||||
|
var err error
|
||||||
|
if err = createNamespaceFile(key); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
n := &networkNamespace{path: basePath}
|
||||||
|
n.InvokeFunc(func() {
|
||||||
|
err = mountNetworkNamespace(basePath, key)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &networkNamespace{path: key}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func reexecCreateNamespace() {
|
func reexecCreateNamespace() {
|
||||||
if len(os.Args) < 2 {
|
if len(os.Args) < 2 {
|
||||||
log.Fatal("no namespace path provided")
|
log.Fatal("no namespace path provided")
|
||||||
}
|
}
|
||||||
|
if err := mountNetworkNamespace("/proc/self/ns/net", os.Args[1]); err != nil {
|
||||||
if err := syscall.Mount("/proc/self/ns/net", os.Args[1], "bind", syscall.MS_BIND, ""); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := loopbackUp(); err != nil {
|
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createNetworkNamespace(path string, osCreate bool) error {
|
func createNetworkNamespace(path string, osCreate bool) error {
|
||||||
runtime.LockOSThread()
|
|
||||||
defer runtime.UnlockOSThread()
|
|
||||||
|
|
||||||
origns, err := netns.Get()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer origns.Close()
|
|
||||||
|
|
||||||
if err := createNamespaceFile(path); err != nil {
|
if err := createNamespaceFile(path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,3 +6,7 @@ package osl
|
||||||
// and waits for it.
|
// and waits for it.
|
||||||
func GC() {
|
func GC() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSandboxForExternalKey(path string, key string) (Sandbox, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,10 @@ func NewSandbox(key string, osCreate bool) (Sandbox, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSandboxForExternalKey(path string, key string) (Sandbox, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GC triggers garbage collection of namespace path right away
|
// GC triggers garbage collection of namespace path right away
|
||||||
// and waits for it.
|
// and waits for it.
|
||||||
func GC() {
|
func GC() {
|
||||||
|
|
104
vendor/src/github.com/docker/libnetwork/sandbox.go
vendored
104
vendor/src/github.com/docker/libnetwork/sandbox.go
vendored
|
@ -32,6 +32,8 @@ type Sandbox interface {
|
||||||
// Refresh leaves all the endpoints, resets and re-apply the options,
|
// Refresh leaves all the endpoints, resets and re-apply the options,
|
||||||
// re-joins all the endpoints without destroying the osl sandbox
|
// re-joins all the endpoints without destroying the osl sandbox
|
||||||
Refresh(options ...SandboxOption) error
|
Refresh(options ...SandboxOption) error
|
||||||
|
// SetKey updates the Sandbox Key
|
||||||
|
SetKey(key string) error
|
||||||
// Delete destroys this container after detaching it from all connected endpoints.
|
// Delete destroys this container after detaching it from all connected endpoints.
|
||||||
Delete() error
|
Delete() error
|
||||||
}
|
}
|
||||||
|
@ -102,6 +104,7 @@ type containerConfig struct {
|
||||||
resolvConfPathConfig
|
resolvConfPathConfig
|
||||||
generic map[string]interface{}
|
generic map[string]interface{}
|
||||||
useDefaultSandBox bool
|
useDefaultSandBox bool
|
||||||
|
useExternalKey bool
|
||||||
prio int // higher the value, more the priority
|
prio int // higher the value, more the priority
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,8 +244,14 @@ func (sb *sandbox) getConnectedEndpoints() []*endpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *sandbox) updateGateway(ep *endpoint) error {
|
func (sb *sandbox) updateGateway(ep *endpoint) error {
|
||||||
sb.osSbox.UnsetGateway()
|
sb.Lock()
|
||||||
sb.osSbox.UnsetGatewayIPv6()
|
osSbox := sb.osSbox
|
||||||
|
sb.Unlock()
|
||||||
|
if osSbox == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
osSbox.UnsetGateway()
|
||||||
|
osSbox.UnsetGatewayIPv6()
|
||||||
|
|
||||||
if ep == nil {
|
if ep == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -252,24 +261,66 @@ func (sb *sandbox) updateGateway(ep *endpoint) error {
|
||||||
joinInfo := ep.joinInfo
|
joinInfo := ep.joinInfo
|
||||||
ep.Unlock()
|
ep.Unlock()
|
||||||
|
|
||||||
if err := sb.osSbox.SetGateway(joinInfo.gw); err != nil {
|
if err := osSbox.SetGateway(joinInfo.gw); err != nil {
|
||||||
return fmt.Errorf("failed to set gateway while updating gateway: %v", err)
|
return fmt.Errorf("failed to set gateway while updating gateway: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sb.osSbox.SetGatewayIPv6(joinInfo.gw6); err != nil {
|
if err := osSbox.SetGatewayIPv6(joinInfo.gw6); err != nil {
|
||||||
return fmt.Errorf("failed to set IPv6 gateway while updating gateway: %v", err)
|
return fmt.Errorf("failed to set IPv6 gateway while updating gateway: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sb *sandbox) SetKey(basePath string) error {
|
||||||
|
var err error
|
||||||
|
if basePath == "" {
|
||||||
|
return types.BadRequestErrorf("invalid sandbox key")
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Lock()
|
||||||
|
if sb.osSbox != nil {
|
||||||
|
sb.Unlock()
|
||||||
|
return types.ForbiddenErrorf("failed to set sandbox key : already assigned")
|
||||||
|
}
|
||||||
|
sb.Unlock()
|
||||||
|
osSbox, err := osl.GetSandboxForExternalKey(basePath, sb.Key())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sb.Lock()
|
||||||
|
sb.osSbox = osSbox
|
||||||
|
sb.Unlock()
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
sb.Lock()
|
||||||
|
sb.osSbox = nil
|
||||||
|
sb.Unlock()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for _, ep := range sb.getConnectedEndpoints() {
|
||||||
|
if err = sb.populateNetworkResources(ep); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
|
func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
|
||||||
|
sb.Lock()
|
||||||
|
if sb.osSbox == nil {
|
||||||
|
sb.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
sb.Unlock()
|
||||||
|
|
||||||
ep.Lock()
|
ep.Lock()
|
||||||
joinInfo := ep.joinInfo
|
joinInfo := ep.joinInfo
|
||||||
ifaces := ep.iFaces
|
i := ep.iface
|
||||||
ep.Unlock()
|
ep.Unlock()
|
||||||
|
|
||||||
for _, i := range ifaces {
|
if i != nil {
|
||||||
var ifaceOptions []osl.IfaceOption
|
var ifaceOptions []osl.IfaceOption
|
||||||
|
|
||||||
ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().Address(&i.addr), sb.osSbox.InterfaceOptions().Routes(i.routes))
|
ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().Address(&i.addr), sb.osSbox.InterfaceOptions().Routes(i.routes))
|
||||||
|
@ -292,7 +343,6 @@ func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.Lock()
|
sb.Lock()
|
||||||
heap.Push(&sb.endpoints, ep)
|
|
||||||
highEp := sb.endpoints[0]
|
highEp := sb.endpoints[0]
|
||||||
sb.Unlock()
|
sb.Unlock()
|
||||||
if ep == highEp {
|
if ep == highEp {
|
||||||
|
@ -305,24 +355,28 @@ func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *sandbox) clearNetworkResources(ep *endpoint) error {
|
func (sb *sandbox) clearNetworkResources(ep *endpoint) error {
|
||||||
|
sb.Lock()
|
||||||
for _, i := range sb.osSbox.Info().Interfaces() {
|
osSbox := sb.osSbox
|
||||||
// Only remove the interfaces owned by this endpoint from the sandbox.
|
sb.Unlock()
|
||||||
if ep.hasInterface(i.SrcName()) {
|
if osSbox != nil {
|
||||||
if err := i.Remove(); err != nil {
|
for _, i := range osSbox.Info().Interfaces() {
|
||||||
log.Debugf("Remove interface failed: %v", err)
|
// Only remove the interfaces owned by this endpoint from the sandbox.
|
||||||
|
if ep.hasInterface(i.SrcName()) {
|
||||||
|
if err := i.Remove(); err != nil {
|
||||||
|
log.Debugf("Remove interface failed: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ep.Lock()
|
ep.Lock()
|
||||||
joinInfo := ep.joinInfo
|
joinInfo := ep.joinInfo
|
||||||
ep.Unlock()
|
ep.Unlock()
|
||||||
|
|
||||||
// Remove non-interface routes.
|
// Remove non-interface routes.
|
||||||
for _, r := range joinInfo.StaticRoutes {
|
for _, r := range joinInfo.StaticRoutes {
|
||||||
if err := sb.osSbox.RemoveStaticRoute(r); err != nil {
|
if err := osSbox.RemoveStaticRoute(r); err != nil {
|
||||||
log.Debugf("Remove route failed: %v", err)
|
log.Debugf("Remove route failed: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,6 +724,14 @@ func OptionUseDefaultSandbox() SandboxOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OptionUseExternalKey function returns an option setter for using provided namespace
|
||||||
|
// instead of creating one.
|
||||||
|
func OptionUseExternalKey() SandboxOption {
|
||||||
|
return func(sb *sandbox) {
|
||||||
|
sb.config.useExternalKey = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// OptionGeneric function returns an option setter for Generic configuration
|
// OptionGeneric 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
|
// that is not managed by libNetwork but can be used by the Drivers during the call to
|
||||||
// net container creation method. Container Labels are a good example.
|
// net container creation method. Container Labels are a good example.
|
||||||
|
|
185
vendor/src/github.com/docker/libnetwork/sandbox_externalkey.go
vendored
Normal file
185
vendor/src/github.com/docker/libnetwork/sandbox_externalkey.go
vendored
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
package libnetwork
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/docker/pkg/reexec"
|
||||||
|
"github.com/docker/libnetwork/types"
|
||||||
|
"github.com/opencontainers/runc/libcontainer"
|
||||||
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type setKeyData struct {
|
||||||
|
ContainerID string
|
||||||
|
Key string
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
reexec.Register("libnetwork-setkey", processSetKeyReexec)
|
||||||
|
}
|
||||||
|
|
||||||
|
const udsBase = "/var/lib/docker/network/files/"
|
||||||
|
const success = "success"
|
||||||
|
|
||||||
|
// processSetKeyReexec is a private function that must be called only on an reexec path
|
||||||
|
// It expects 3 args { [0] = "libnetwork-setkey", [1] = <container-id>, [2] = <controller-id> }
|
||||||
|
// It also expects libcontainer.State as a json string in <stdin>
|
||||||
|
// Refer to https://github.com/opencontainers/runc/pull/160/ for more information
|
||||||
|
func processSetKeyReexec() {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Return a failure to the calling process via ExitCode
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// expecting 3 args {[0]="libnetwork-setkey", [1]=<container-id>, [2]=<controller-id> }
|
||||||
|
if len(os.Args) < 3 {
|
||||||
|
err = fmt.Errorf("Re-exec expects 3 args, received : %d", len(os.Args))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
containerID := os.Args[1]
|
||||||
|
|
||||||
|
// We expect libcontainer.State as a json string in <stdin>
|
||||||
|
stateBuf, err := ioutil.ReadAll(os.Stdin)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var state libcontainer.State
|
||||||
|
if err = json.Unmarshal(stateBuf, &state); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controllerID := os.Args[2]
|
||||||
|
key := state.NamespacePaths[configs.NamespaceType("NEWNET")]
|
||||||
|
|
||||||
|
err = SetExternalKey(controllerID, containerID, key)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetExternalKey provides a convenient way to set an External key to a sandbox
|
||||||
|
func SetExternalKey(controllerID string, containerID string, key string) error {
|
||||||
|
keyData := setKeyData{
|
||||||
|
ContainerID: containerID,
|
||||||
|
Key: key}
|
||||||
|
|
||||||
|
c, err := net.Dial("unix", udsBase+controllerID+".sock")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
if err = sendKey(c, keyData); err != nil {
|
||||||
|
return fmt.Errorf("sendKey failed with : %v", err)
|
||||||
|
}
|
||||||
|
return processReturn(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendKey(c net.Conn, data setKeyData) error {
|
||||||
|
var err error
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
c.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
var b []byte
|
||||||
|
if b, err = json.Marshal(data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.Write(b)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func processReturn(r io.Reader) error {
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
n, err := r.Read(buf[:])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read buf in processReturn : %v", err)
|
||||||
|
}
|
||||||
|
if string(buf[0:n]) != success {
|
||||||
|
return fmt.Errorf(string(buf[0:n]))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *controller) startExternalKeyListener() error {
|
||||||
|
if err := os.MkdirAll(udsBase, 0600); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
uds := udsBase + c.id + ".sock"
|
||||||
|
l, err := net.Listen("unix", uds)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.Chmod(uds, 0600); err != nil {
|
||||||
|
l.Close()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.Lock()
|
||||||
|
c.extKeyListener = l
|
||||||
|
c.Unlock()
|
||||||
|
|
||||||
|
go c.acceptClientConnections(uds, l)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *controller) acceptClientConnections(sock string, l net.Listener) {
|
||||||
|
for {
|
||||||
|
conn, err := l.Accept()
|
||||||
|
if err != nil {
|
||||||
|
if _, err1 := os.Stat(sock); os.IsNotExist(err1) {
|
||||||
|
logrus.Warnf("Unix socket %s doesnt exist. cannot accept client connections", sock)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logrus.Errorf("Error accepting connection %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
err := c.processExternalKey(conn)
|
||||||
|
ret := success
|
||||||
|
if err != nil {
|
||||||
|
ret = err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = conn.Write([]byte(ret))
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("Error returning to the client %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *controller) processExternalKey(conn net.Conn) error {
|
||||||
|
buf := make([]byte, 1280)
|
||||||
|
nr, err := conn.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var s setKeyData
|
||||||
|
if err = json.Unmarshal(buf[0:nr], &s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var sandbox Sandbox
|
||||||
|
search := SandboxContainerWalker(&sandbox, s.ContainerID)
|
||||||
|
c.WalkSandboxes(search)
|
||||||
|
if sandbox == nil {
|
||||||
|
return types.BadRequestErrorf("no sandbox present for %s", s.ContainerID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sandbox.SetKey(s.Key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *controller) stopExternalKeyListener() {
|
||||||
|
c.extKeyListener.Close()
|
||||||
|
}
|
|
@ -266,12 +266,6 @@ type StaticRoute struct {
|
||||||
|
|
||||||
// NextHop will be resolved by the kernel (i.e. as a loose hop).
|
// NextHop will be resolved by the kernel (i.e. as a loose hop).
|
||||||
NextHop net.IP
|
NextHop net.IP
|
||||||
|
|
||||||
// InterfaceID must refer to a defined interface on the
|
|
||||||
// Endpoint to which the routes are specified. Routes specified this way
|
|
||||||
// are interpreted as directly connected to the specified interface (no
|
|
||||||
// next hop will be used).
|
|
||||||
InterfaceID int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCopy returns a copy of this StaticRoute structure
|
// GetCopy returns a copy of this StaticRoute structure
|
||||||
|
@ -279,9 +273,9 @@ func (r *StaticRoute) GetCopy() *StaticRoute {
|
||||||
d := GetIPNetCopy(r.Destination)
|
d := GetIPNetCopy(r.Destination)
|
||||||
nh := GetIPCopy(r.NextHop)
|
nh := GetIPCopy(r.NextHop)
|
||||||
return &StaticRoute{Destination: d,
|
return &StaticRoute{Destination: d,
|
||||||
RouteType: r.RouteType,
|
RouteType: r.RouteType,
|
||||||
NextHop: nh,
|
NextHop: nh,
|
||||||
InterfaceID: r.InterfaceID}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************
|
/******************************
|
||||||
|
|
Loading…
Reference in a new issue