1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/libnetwork/cmd/ovrouter/ovrouter.go
Jana Radhakrishnan 6fb69f0816 Add driver api enhancements for gossip
With the introduction of a driver generic gossip in libnetwork it is not
necessary for drivers to run their own gossip protocol (like what
overlay driver is doing currently) but instead rely on the gossip
instance run centrally in libnetwork. In order to achieve this, certain
enhancements to driver api are needed. This api aims to provide these
enhancements.

The new api provides a way for drivers to register interest on table
names of their choice by returning a list of table names of interest as
a response to CreateNetwork. By doing that they will get notified if a
CRUD operation happened on the tables of their interest, via the newly
added EventNotify call.

Drivers themselves can add entries to any table during a Join call by
invoking AddTableEntry method any number of times during the Join
call. These entries lifetime is the same as the endpoint itself. As soon
as the container leaves the endpoint, those entries added by driver
during that endpoint's Join call will be automatically removed by
libnetwork. This action may trigger notification of such deletion to all
driver instances in the cluster who have registered interest in that
table's notification.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
2016-04-18 19:55:39 -07:00

169 lines
3.8 KiB
Go

package main
import (
"fmt"
"net"
"os"
"os/signal"
"github.com/docker/docker/pkg/reexec"
"github.com/docker/libnetwork/driverapi"
"github.com/docker/libnetwork/drivers/overlay"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
)
type router struct {
d driverapi.Driver
}
type endpoint struct {
addr *net.IPNet
mac net.HardwareAddr
name string
}
func (r *router) RegisterDriver(name string, driver driverapi.Driver, c driverapi.Capability) error {
r.d = driver
return nil
}
func (ep *endpoint) Interface() driverapi.InterfaceInfo {
return nil
}
func (ep *endpoint) SetMacAddress(mac net.HardwareAddr) error {
if ep.mac != nil {
return types.ForbiddenErrorf("endpoint interface MAC address present (%s). Cannot be modified with %s.", ep.mac, mac)
}
if mac == nil {
return types.BadRequestErrorf("tried to set nil MAC address to endpoint interface")
}
ep.mac = types.GetMacCopy(mac)
return nil
}
func (ep *endpoint) SetIPAddress(address *net.IPNet) error {
if address.IP == nil {
return types.BadRequestErrorf("tried to set nil IP address to endpoint interface")
}
if address.IP.To4() == nil {
return types.NotImplementedErrorf("do not support ipv6 yet")
}
if ep.addr != nil {
return types.ForbiddenErrorf("endpoint interface IP present (%s). Cannot be modified with %s.", ep.addr, address)
}
ep.addr = types.GetIPNetCopy(address)
return nil
}
func (ep *endpoint) MacAddress() net.HardwareAddr {
return types.GetMacCopy(ep.mac)
}
func (ep *endpoint) Address() *net.IPNet {
return types.GetIPNetCopy(ep.addr)
}
func (ep *endpoint) AddressIPv6() *net.IPNet {
return nil
}
func (ep *endpoint) InterfaceName() driverapi.InterfaceNameInfo {
return ep
}
func (ep *endpoint) SetNames(srcName, dstPrefix string) error {
ep.name = srcName
return nil
}
func (ep *endpoint) SetGateway(net.IP) error {
return nil
}
func (ep *endpoint) SetGatewayIPv6(net.IP) error {
return nil
}
func (ep *endpoint) AddStaticRoute(destination *net.IPNet, routeType int,
nextHop net.IP) error {
return nil
}
func (ep *endpoint) AddTableEntry(tableName string, key string, value []byte) error {
return nil
}
func (ep *endpoint) DisableGatewayService() {}
func main() {
if reexec.Init() {
return
}
opt := make(map[string]interface{})
if len(os.Args) > 1 {
opt[netlabel.OverlayBindInterface] = os.Args[1]
}
if len(os.Args) > 2 {
opt[netlabel.OverlayNeighborIP] = os.Args[2]
}
if len(os.Args) > 3 {
opt[netlabel.GlobalKVProvider] = os.Args[3]
}
if len(os.Args) > 4 {
opt[netlabel.GlobalKVProviderURL] = os.Args[4]
}
r := &router{}
if err := overlay.Init(r, opt); err != nil {
fmt.Printf("Failed to initialize overlay driver: %v\n", err)
os.Exit(1)
}
if err := r.d.CreateNetwork("testnetwork",
map[string]interface{}{}, nil, nil, nil); err != nil {
fmt.Printf("Failed to create network in the driver: %v\n", err)
os.Exit(1)
}
ep := &endpoint{}
if err := r.d.CreateEndpoint("testnetwork", "testep",
ep, map[string]interface{}{}); err != nil {
fmt.Printf("Failed to create endpoint in the driver: %v\n", err)
os.Exit(1)
}
if err := r.d.Join("testnetwork", "testep",
"", ep, map[string]interface{}{}); err != nil {
fmt.Printf("Failed to join an endpoint in the driver: %v\n", err)
os.Exit(1)
}
link, err := netlink.LinkByName(ep.name)
if err != nil {
fmt.Printf("Failed to find the container interface with name %s: %v\n",
ep.name, err)
os.Exit(1)
}
ipAddr := &netlink.Addr{IPNet: ep.addr, Label: ""}
if err := netlink.AddrAdd(link, ipAddr); err != nil {
fmt.Printf("Failed to add address to the interface: %v\n", err)
os.Exit(1)
}
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt, os.Kill)
for {
select {
case <-sigCh:
r.d.Leave("testnetwork", "testep")
overlay.Fini(r.d)
os.Exit(0)
}
}
}