func main() { var ( justVersion bool logLevel = "info" c proxy.Config withDNS bool ) c.Version = version mflag.BoolVar(&justVersion, []string{"#version", "-version"}, false, "print version and exit") mflag.StringVar(&logLevel, []string{"-log-level"}, "info", "logging level (debug, info, warning, error)") mflagext.ListVar(&c.ListenAddrs, []string{"H"}, nil, "addresses on which to listen") mflag.StringVar(&c.HostnameFromLabel, []string{"-hostname-from-label"}, "", "Key of container label from which to obtain the container's hostname") mflag.StringVar(&c.HostnameMatch, []string{"-hostname-match"}, "(.*)", "Regexp pattern to apply on container names (e.g. '^aws-[0-9]+-(.*)$')") mflag.StringVar(&c.HostnameReplacement, []string{"-hostname-replacement"}, "$1", "Expression to generate hostnames based on matches from --hostname-match (e.g. 'my-app-$1')") mflag.BoolVar(&c.RewriteInspect, []string{"-rewrite-inspect"}, false, "Rewrite 'inspect' calls to return the weave network settings (if attached)") mflag.BoolVar(&c.NoDefaultIPAM, []string{"#-no-default-ipam", "-no-default-ipalloc"}, false, "do not automatically allocate addresses for containers without a WEAVE_CIDR") mflag.BoolVar(&c.NoRewriteHosts, []string{"-no-rewrite-hosts"}, false, "do not automatically rewrite /etc/hosts. Use if you need the docker IP to remain in /etc/hosts") mflag.StringVar(&c.TLSConfig.CACert, []string{"#tlscacert", "-tlscacert"}, "", "Trust certs signed only by this CA") mflag.StringVar(&c.TLSConfig.Cert, []string{"#tlscert", "-tlscert"}, "", "Path to TLS certificate file") mflag.BoolVar(&c.TLSConfig.Enabled, []string{"#tls", "-tls"}, false, "Use TLS; implied by --tlsverify") mflag.StringVar(&c.TLSConfig.Key, []string{"#tlskey", "-tlskey"}, "", "Path to TLS key file") mflag.BoolVar(&c.TLSConfig.Verify, []string{"#tlsverify", "-tlsverify"}, false, "Use TLS and verify the remote") mflag.BoolVar(&withDNS, []string{"#-with-dns", "#w"}, false, "option removed") mflag.BoolVar(&c.WithoutDNS, []string{"-without-dns"}, false, "instruct created containers to never use weaveDNS as their nameserver") mflag.BoolVar(&c.NoMulticastRoute, []string{"-no-multicast-route"}, false, "do not add a multicast route via the weave interface when attaching containers") mflag.Parse() if justVersion { fmt.Printf("weave proxy %s\n", version) os.Exit(0) } common.SetLogLevel(logLevel) Log.Infoln("weave proxy", version) Log.Infoln("Command line arguments:", strings.Join(os.Args[1:], " ")) if withDNS { Log.Warning("--with-dns option has been removed; DNS is on by default") } c.Image = getenv("EXEC_IMAGE", "weaveworks/weaveexec") c.DockerBridge = getenv("DOCKER_BRIDGE", "docker0") c.DockerHost = getenv("DOCKER_HOST", "unix:///var/run/docker.sock") p, err := proxy.NewProxy(c) if err != nil { Log.Fatalf("Could not start proxy: %s", err) } defer p.Stop() listeners := p.Listen() p.AttachExistingContainers() go p.Serve(listeners) go p.ListenAndServeStatus("/home/weave/status.sock") common.SignalHandlerLoop() }
func main() { var ( justVersion bool cniNet bool cniIpam bool address string meshAddress string logLevel string noMulticastRoute bool ) flag.BoolVar(&justVersion, "version", false, "print version and exit") flag.BoolVar(&cniNet, "cni-net", false, "act as a CNI network plugin") flag.BoolVar(&cniIpam, "cni-ipam", false, "act as a CNI IPAM plugin") flag.StringVar(&logLevel, "log-level", "info", "logging level (debug, info, warning, error)") flag.StringVar(&address, "socket", "/run/docker/plugins/weave.sock", "socket on which to listen") flag.StringVar(&meshAddress, "meshsocket", "/run/docker/plugins/weavemesh.sock", "socket on which to listen in mesh mode") flag.BoolVar(&noMulticastRoute, "no-multicast-route", false, "deprecated (this is now the default)") flag.Parse() if justVersion { fmt.Printf("weave plugin %s\n", version) os.Exit(0) } common.SetLogLevel(logLevel) weave := weaveapi.NewClient(os.Getenv("WEAVE_HTTP_ADDR"), Log) switch { case cniIpam || strings.HasSuffix(os.Args[0], "weave-ipam"): i := ipamplugin.NewIpam(weave) cni.PluginMain(i.CmdAdd, i.CmdDel) os.Exit(0) case cniNet || strings.HasSuffix(os.Args[0], "weave-net"): n := netplugin.NewCNIPlugin(weave) cni.PluginMain(n.CmdAdd, n.CmdDel) os.Exit(0) } // API 1.21 is the first version that supports docker network commands dockerClient, err := docker.NewVersionedClientFromEnv("1.21") if err != nil { Log.Fatalf("unable to connect to docker: %s", err) } Log.Println("Weave plugin", version, "Command line options:", os.Args[1:]) if noMulticastRoute { Log.Warning("--no-multicast-route option has been removed; multicast is off by default") } Log.Info(dockerClient.Info()) err = run(dockerClient, weave, address, meshAddress) if err != nil { Log.Fatal(err) } }
func main() { procs := runtime.NumCPU() // packet sniffing can block an OS thread, so we need one thread // for that plus at least one more. if procs < 2 { procs = 2 } runtime.GOMAXPROCS(procs) var ( justVersion bool config mesh.Config networkConfig weave.NetworkConfig protocolMinVersion int resume bool ifaceName string routerName string nickName string password string pktdebug bool logLevel string prof string bufSzMB int noDiscovery bool httpAddr string ipamConfig ipamConfig dockerAPI string peers []string noDNS bool dnsConfig dnsConfig datapathName string trustedSubnetStr string dbPrefix string isAWSVPC bool defaultDockerHost = "unix:///var/run/docker.sock" ) if val := os.Getenv("DOCKER_HOST"); val != "" { defaultDockerHost = val } mflag.BoolVar(&justVersion, []string{"#version", "-version"}, false, "print version and exit") mflag.StringVar(&config.Host, []string{"-host"}, "", "router host") mflag.IntVar(&config.Port, []string{"#port", "-port"}, mesh.Port, "router port") mflag.IntVar(&protocolMinVersion, []string{"-min-protocol-version"}, mesh.ProtocolMinVersion, "minimum weave protocol version") mflag.BoolVar(&resume, []string{"-resume"}, false, "resume connections to previous peers") mflag.StringVar(&ifaceName, []string{"#iface", "-iface"}, "", "name of interface to capture/inject from (disabled if blank)") mflag.StringVar(&routerName, []string{"#name", "-name"}, "", "name of router (defaults to MAC of interface)") mflag.StringVar(&nickName, []string{"#nickname", "-nickname"}, "", "nickname of peer (defaults to hostname)") mflag.StringVar(&password, []string{"#password", "-password"}, "", "network password") mflag.StringVar(&logLevel, []string{"-log-level"}, "info", "logging level (debug, info, warning, error)") mflag.BoolVar(&pktdebug, []string{"#pktdebug", "#-pktdebug", "-pkt-debug"}, false, "enable per-packet debug logging") mflag.StringVar(&prof, []string{"#profile", "-profile"}, "", "enable profiling and write profiles to given path") mflag.IntVar(&config.ConnLimit, []string{"#connlimit", "#-connlimit", "-conn-limit"}, 30, "connection limit (0 for unlimited)") mflag.BoolVar(&noDiscovery, []string{"#nodiscovery", "#-nodiscovery", "-no-discovery"}, false, "disable peer discovery") mflag.IntVar(&bufSzMB, []string{"#bufsz", "-bufsz"}, 8, "capture buffer size in MB") mflag.StringVar(&httpAddr, []string{"#httpaddr", "#-httpaddr", "-http-addr"}, "", "address to bind HTTP interface to (disabled if blank, absolute path indicates unix domain socket)") mflag.StringVar(&ipamConfig.Mode, []string{"-ipalloc-init"}, "", "allocator initialisation strategy (consensus, seed or observer)") mflag.StringVar(&ipamConfig.IPRangeCIDR, []string{"#iprange", "#-iprange", "-ipalloc-range"}, "", "IP address range reserved for automatic allocation, in CIDR notation") mflag.StringVar(&ipamConfig.IPSubnetCIDR, []string{"#ipsubnet", "#-ipsubnet", "-ipalloc-default-subnet"}, "", "subnet to allocate within by default, in CIDR notation") mflag.IntVar(&ipamConfig.PeerCount, []string{"#initpeercount", "#-initpeercount", "-init-peer-count"}, 0, "number of peers in network (for IP address allocation)") mflag.StringVar(&dockerAPI, []string{"#api", "#-api", "-docker-api"}, defaultDockerHost, "Docker API endpoint") mflag.BoolVar(&noDNS, []string{"-no-dns"}, false, "disable DNS server") mflag.StringVar(&dnsConfig.Domain, []string{"-dns-domain"}, nameserver.DefaultDomain, "local domain to server requests for") mflag.StringVar(&dnsConfig.ListenAddress, []string{"-dns-listen-address"}, nameserver.DefaultListenAddress, "address to listen on for DNS requests") mflag.IntVar(&dnsConfig.TTL, []string{"-dns-ttl"}, nameserver.DefaultTTL, "TTL for DNS request from our domain") mflag.DurationVar(&dnsConfig.ClientTimeout, []string{"-dns-fallback-timeout"}, nameserver.DefaultClientTimeout, "timeout for fallback DNS requests") mflag.StringVar(&dnsConfig.EffectiveListenAddress, []string{"-dns-effective-listen-address"}, "", "address DNS will actually be listening, after Docker port mapping") mflag.StringVar(&dnsConfig.ResolvConf, []string{"-resolv-conf"}, "", "path to resolver configuration for fallback DNS lookups") mflag.StringVar(&datapathName, []string{"-datapath"}, "", "ODP datapath name") mflag.StringVar(&trustedSubnetStr, []string{"-trusted-subnets"}, "", "comma-separated list of trusted subnets in CIDR notation") mflag.StringVar(&dbPrefix, []string{"-db-prefix"}, "/weavedb/weave", "pathname/prefix of filename to store data") mflag.BoolVar(&isAWSVPC, []string{"-awsvpc"}, false, "use AWS VPC for routing") // crude way of detecting that we probably have been started in a // container, with `weave launch` --> suppress misleading paths in // mflags error messages. if os.Args[0] == "/home/weave/weaver" { // matches the Dockerfile ENTRYPOINT os.Args[0] = "weave" mflag.CommandLine.Init("weave", mflag.ExitOnError) } mflag.Parse() peers = mflag.Args() if resume && len(peers) > 0 { Log.Fatalf("You must not specify an initial peer list in conjunction with --resume") } common.SetLogLevel(logLevel) if justVersion { fmt.Printf("weave router %s\n", version) os.Exit(0) } Log.Println("Command line options:", options()) if prof != "" { defer profile.Start(profile.CPUProfile, profile.ProfilePath(prof), profile.NoShutdownHook).Stop() } if protocolMinVersion < mesh.ProtocolMinVersion || protocolMinVersion > mesh.ProtocolMaxVersion { Log.Fatalf("--min-protocol-version must be in range [%d,%d]", mesh.ProtocolMinVersion, mesh.ProtocolMaxVersion) } config.ProtocolMinVersion = byte(protocolMinVersion) if pktdebug { networkConfig.PacketLogging = packetLogging{} } else { networkConfig.PacketLogging = nopPacketLogging{} } overlay, bridge := createOverlay(datapathName, ifaceName, isAWSVPC, config.Host, config.Port, bufSzMB) networkConfig.Bridge = bridge name := peerName(routerName, bridge.Interface()) if nickName == "" { var err error nickName, err = os.Hostname() checkFatal(err) } config.Password = determinePassword(password) config.TrustedSubnets = parseTrustedSubnets(trustedSubnetStr) config.PeerDiscovery = !noDiscovery if isAWSVPC && len(config.Password) > 0 { Log.Fatalf("--awsvpc mode is not compatible with the --password option") } db, err := db.NewBoltDB(dbPrefix + "data.db") checkFatal(err) defer db.Close() router := weave.NewNetworkRouter(config, networkConfig, name, nickName, overlay, db) Log.Println("Our name is", router.Ourself) if peers, err = router.InitialPeers(resume, peers); err != nil { Log.Fatal("Unable to get initial peer set: ", err) } var dockerCli *docker.Client dockerVersion := "none" if dockerAPI != "" { dc, err := docker.NewClient(dockerAPI) if err != nil { Log.Fatal("Unable to start docker client: ", err) } else { Log.Info(dc.Info()) } dockerCli = dc dockerVersion = dockerCli.DockerVersion() } network := "" if isAWSVPC { network = "awsvpc" } checkForUpdates(dockerVersion, network) observeContainers := func(o docker.ContainerObserver) { if dockerCli != nil { if err := dockerCli.AddObserver(o); err != nil { Log.Fatal("Unable to start watcher", err) } } } isKnownPeer := func(name mesh.PeerName) bool { return router.Peers.Fetch(name) != nil } var ( allocator *ipam.Allocator defaultSubnet address.CIDR trackerName string ) if ipamConfig.Enabled() { var t tracker.LocalRangeTracker if isAWSVPC { Log.Infoln("Creating AWSVPC LocalRangeTracker") t, err = tracker.NewAWSVPCTracker() if err != nil { Log.Fatalf("Cannot create AWSVPC LocalRangeTracker: %s", err) } trackerName = "awsvpc" } allocator, defaultSubnet = createAllocator(router, ipamConfig, db, t, isKnownPeer) observeContainers(allocator) if dockerCli != nil { ids, err := dockerCli.AllContainerIDs() checkFatal(err) allocator.PruneOwned(ids) } } var ( ns *nameserver.Nameserver dnsserver *nameserver.DNSServer ) if !noDNS { ns, dnsserver = createDNSServer(dnsConfig, router.Router, isKnownPeer) observeContainers(ns) ns.Start() defer ns.Stop() dnsserver.ActivateAndServe() defer dnsserver.Stop() } router.Start() if errors := router.InitiateConnections(peers, false); len(errors) > 0 { Log.Fatal(common.ErrorMessages(errors)) } // The weave script always waits for a status call to succeed, // so there is no point in doing "weave launch --http-addr ''". // This is here to support stand-alone use of weaver. if httpAddr != "" { muxRouter := mux.NewRouter() if allocator != nil { allocator.HandleHTTP(muxRouter, defaultSubnet, trackerName, dockerCli) } if ns != nil { ns.HandleHTTP(muxRouter, dockerCli) } router.HandleHTTP(muxRouter) HandleHTTP(muxRouter, version, router, allocator, defaultSubnet, ns, dnsserver) http.Handle("/", common.LoggingHTTPHandler(muxRouter)) Log.Println("Listening for HTTP control messages on", httpAddr) go listenAndServeHTTP(httpAddr) } common.SignalHandlerLoop(router) }