126 lines
3.3 KiB
Go
126 lines
3.3 KiB
Go
package plugin
|
|
|
|
import (
|
|
"net"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/docker/libnetwork/ipamapi"
|
|
weaveapi "github.com/weaveworks/weave/api"
|
|
"github.com/weaveworks/weave/common"
|
|
"github.com/weaveworks/weave/common/docker"
|
|
weavenet "github.com/weaveworks/weave/net"
|
|
ipamplugin "github.com/weaveworks/weave/plugin/ipam"
|
|
netplugin "github.com/weaveworks/weave/plugin/net"
|
|
"github.com/weaveworks/weave/plugin/skel"
|
|
)
|
|
|
|
const (
|
|
pluginV2Name = "net-plugin"
|
|
defaultNetwork = "weave"
|
|
MulticastOption = netplugin.MulticastOption
|
|
)
|
|
|
|
var Log = common.Log
|
|
|
|
type Config struct {
|
|
Socket string
|
|
MeshSocket string
|
|
Enable bool
|
|
EnableV2 bool
|
|
EnableV2Multicast bool
|
|
DNS bool
|
|
DefaultSubnet string
|
|
ProcPath string // path to reach host /proc filesystem
|
|
}
|
|
|
|
type Plugin struct {
|
|
Config
|
|
}
|
|
|
|
func NewPlugin(config Config) *Plugin {
|
|
if !config.Enable && !config.EnableV2 {
|
|
return nil
|
|
}
|
|
plugin := &Plugin{Config: config}
|
|
return plugin
|
|
}
|
|
|
|
func (plugin *Plugin) Start(weaveAPIAddr string, dockerClient *docker.Client, ready func()) {
|
|
weave := weaveapi.NewClient(weaveAPIAddr, Log)
|
|
|
|
Log.Info("Waiting for Weave API Server...")
|
|
weave.WaitAPIServer(30)
|
|
Log.Info("Finished waiting for Weave API Server")
|
|
|
|
if err := plugin.run(dockerClient, weave, ready); err != nil {
|
|
Log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func (plugin *Plugin) run(dockerClient *docker.Client, weave *weaveapi.Client, ready func()) error {
|
|
endChan := make(chan error, 1)
|
|
|
|
if plugin.Socket != "" {
|
|
globalListener, err := listenAndServe(dockerClient, weave, plugin.Socket, endChan, "global", false, plugin.DNS, plugin.EnableV2, plugin.EnableV2Multicast, plugin.ProcPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer os.Remove(plugin.Socket)
|
|
defer globalListener.Close()
|
|
}
|
|
if plugin.MeshSocket != "" {
|
|
meshListener, err := listenAndServe(dockerClient, weave, plugin.MeshSocket, endChan, "local", true, plugin.DNS, plugin.EnableV2, plugin.EnableV2Multicast, plugin.ProcPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer os.Remove(plugin.MeshSocket)
|
|
defer meshListener.Close()
|
|
if !plugin.EnableV2 {
|
|
Log.Printf("Creating default %q network", defaultNetwork)
|
|
options := map[string]interface{}{MulticastOption: "true"}
|
|
dockerClient.EnsureNetwork(defaultNetwork, pluginNameFromAddress(plugin.MeshSocket), plugin.DefaultSubnet, options)
|
|
}
|
|
}
|
|
ready()
|
|
|
|
return <-endChan
|
|
}
|
|
|
|
func listenAndServe(dockerClient *docker.Client, weave *weaveapi.Client, address string, endChan chan<- error, scope string, withIpam, dns bool, isPluginV2, forceMulticast bool, procPath string) (net.Listener, error) {
|
|
var name string
|
|
if isPluginV2 {
|
|
name = pluginV2Name
|
|
} else {
|
|
name = pluginNameFromAddress(address)
|
|
}
|
|
|
|
d, err := netplugin.New(dockerClient, weave, name, scope, dns, isPluginV2, forceMulticast, procPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var i ipamapi.Ipam
|
|
if withIpam {
|
|
i = ipamplugin.NewIpam(weave)
|
|
}
|
|
|
|
listener, err := weavenet.ListenUnixSocket(address)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
Log.Printf("Listening on %s for %s scope", address, scope)
|
|
|
|
go func() {
|
|
endChan <- skel.Listen(listener, d, i)
|
|
}()
|
|
|
|
return listener, nil
|
|
}
|
|
|
|
// Take a socket address like "/run/docker/plugins/weavemesh.sock" and extract the plugin name "weavemesh"
|
|
func pluginNameFromAddress(address string) string {
|
|
return strings.TrimSuffix(path.Base(address), ".sock")
|
|
}
|