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 ( config weave.Config justVersion bool protocolMinVersion int ifaceName string routerName string nickName string password string wait int pktdebug bool logLevel string prof string bufSzMB int noDiscovery bool httpAddr string iprangeCIDR string ipsubnetCIDR string peerCount int apiPath string peers []string noDNS bool dnsDomain string dnsPort int dnsTTL int dnsClientTimeout time.Duration ) mflag.BoolVar(&justVersion, []string{"#version", "-version"}, false, "print version and exit") mflag.IntVar(&config.Port, []string{"#port", "-port"}, weave.Port, "router port") mflag.IntVar(&protocolMinVersion, []string{"-min-protocol-version"}, weave.ProtocolMinVersion, "minimum weave protocol version") 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.IntVar(&wait, []string{"#wait", "-wait"}, -1, "number of seconds to wait for interface to come up (0=don't wait, -1=wait forever)") 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"}, fmt.Sprintf(":%d", weave.HTTPPort), "address to bind HTTP interface to (disabled if blank, absolute path indicates unix domain socket)") mflag.StringVar(&iprangeCIDR, []string{"#iprange", "#-iprange", "-ipalloc-range"}, "", "IP address range reserved for automatic allocation, in CIDR notation") mflag.StringVar(&ipsubnetCIDR, []string{"#ipsubnet", "#-ipsubnet", "-ipalloc-default-subnet"}, "", "subnet to allocate within by default, in CIDR notation") mflag.IntVar(&peerCount, []string{"#initpeercount", "#-initpeercount", "-init-peer-count"}, 0, "number of peers in network (for IP address allocation)") mflag.StringVar(&apiPath, []string{"#api", "-api"}, "unix:///var/run/docker.sock", "Path to Docker API socket") mflag.BoolVar(&noDNS, []string{"-no-dns"}, false, "disable DNS server") mflag.StringVar(&dnsDomain, []string{"-dns-domain"}, nameserver.DefaultDomain, "local domain to server requests for") mflag.IntVar(&dnsPort, []string{"-dns-port"}, nameserver.DefaultPort, "port to listen on for DNS requests") mflag.IntVar(&dnsTTL, []string{"-dns-ttl"}, nameserver.DefaultTTL, "TTL for DNS request from our domain") mflag.DurationVar(&dnsClientTimeout, []string{"-dns-fallback-timeout"}, nameserver.DefaultClientTimeout, "timeout for fallback DNS requests") mflag.Parse() peers = mflag.Args() SetLogLevel(logLevel) if justVersion { fmt.Printf("weave router %s\n", version) os.Exit(0) } Log.Println("Command line options:", options()) Log.Println("Command line peers:", peers) if protocolMinVersion < weave.ProtocolMinVersion || protocolMinVersion > weave.ProtocolMaxVersion { Log.Fatalf("--min-protocol-version must be in range [%d,%d]", weave.ProtocolMinVersion, weave.ProtocolMaxVersion) } config.ProtocolMinVersion = byte(protocolMinVersion) var err error if ifaceName != "" { config.Iface, err = weavenet.EnsureInterface(ifaceName, wait) if err != nil { Log.Fatal(err) } } if routerName == "" { if config.Iface == nil { Log.Fatal("Either an interface must be specified with --iface or a name with -name") } routerName = config.Iface.HardwareAddr.String() } name, err := weave.PeerNameFromUserInput(routerName) if err != nil { Log.Fatal(err) } if nickName == "" { nickName, err = os.Hostname() if err != nil { Log.Fatal(err) } } if password == "" { password = os.Getenv("WEAVE_PASSWORD") } if password == "" { Log.Println("Communication between peers is unencrypted.") } else { config.Password = []byte(password) Log.Println("Communication between peers is encrypted.") } if prof != "" { p := *profile.CPUProfile p.ProfilePath = prof p.NoShutdownHook = true defer profile.Start(&p).Stop() } config.BufSz = bufSzMB * 1024 * 1024 config.LogFrame = logFrameFunc(pktdebug) config.PeerDiscovery = !noDiscovery router := weave.NewRouter(config, name, nickName) Log.Println("Our name is", router.Ourself) dockerCli, err := docker.NewClient(apiPath) if err != nil { Log.Fatal("Unable to start docker client: ", err) } var allocator *ipam.Allocator var defaultSubnet address.CIDR if iprangeCIDR != "" { allocator, defaultSubnet = createAllocator(router, iprangeCIDR, ipsubnetCIDR, determineQuorum(peerCount, peers)) if err = dockerCli.AddObserver(allocator); err != nil { Log.Fatal("Unable to start watcher", err) } } else if peerCount > 0 { Log.Fatal("--init-peer-count flag specified without --ipalloc-range") } var ( ns *nameserver.Nameserver dnsserver *nameserver.DNSServer ) if !noDNS { ns = nameserver.New(router.Ourself.Peer.Name, router.Peers, dockerCli, dnsDomain) ns.SetGossip(router.NewGossip("nameserver", ns)) if err = dockerCli.AddObserver(ns); err != nil { Log.Fatal("Unable to start watcher", err) } ns.Start() defer ns.Stop() dnsserver, err = nameserver.NewDNSServer(ns, dnsDomain, dnsPort, uint32(dnsTTL), dnsClientTimeout) if err != nil { Log.Fatal("Unable to start dns server: ", err) } dnsserver.ActivateAndServe() defer dnsserver.Stop() } router.Start() if errors := router.ConnectionMaker.InitiateConnections(peers, false); len(errors) > 0 { Log.Fatal(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 != "" { go handleHTTP(router, httpAddr, allocator, defaultSubnet, dockerCli, ns, dnsserver) } SignalHandlerLoop(router) }
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 ( config weave.Config justVersion bool ifaceName string routerName string nickName string password string wait int pktdebug bool logLevel string prof string bufSzMB int noDiscovery bool httpAddr string iprangeCIDR string ipsubnetCIDR string peerCount int apiPath string peers []string ) flag.BoolVar(&justVersion, "version", false, "print version and exit") flag.IntVar(&config.Port, "port", weave.Port, "router port") flag.StringVar(&ifaceName, "iface", "", "name of interface to capture/inject from (disabled if blank)") flag.StringVar(&routerName, "name", "", "name of router (defaults to MAC of interface)") flag.StringVar(&nickName, "nickname", "", "nickname of peer (defaults to hostname)") flag.StringVar(&password, "password", "", "network password") flag.IntVar(&wait, "wait", -1, "number of seconds to wait for interface to come up (0=don't wait, -1=wait forever)") flag.StringVar(&logLevel, "log-level", "info", "logging level (debug, info, warning, error)") flag.BoolVar(&pktdebug, "pktdebug", false, "enable per-packet debug logging") flag.StringVar(&prof, "profile", "", "enable profiling and write profiles to given path") flag.IntVar(&config.ConnLimit, "connlimit", 30, "connection limit (0 for unlimited)") flag.BoolVar(&noDiscovery, "nodiscovery", false, "disable peer discovery") flag.IntVar(&bufSzMB, "bufsz", 8, "capture buffer size in MB") flag.StringVar(&httpAddr, "httpaddr", fmt.Sprintf(":%d", weave.HTTPPort), "address to bind HTTP interface to (disabled if blank, absolute path indicates unix domain socket)") flag.StringVar(&iprangeCIDR, "iprange", "", "IP address range reserved for automatic allocation, in CIDR notation") flag.StringVar(&ipsubnetCIDR, "ipsubnet", "", "subnet to allocate within by default, in CIDR notation") flag.IntVar(&peerCount, "initpeercount", 0, "number of peers in network (for IP address allocation)") flag.StringVar(&apiPath, "api", "unix:///var/run/docker.sock", "Path to Docker API socket") flag.Parse() peers = flag.Args() SetLogLevel(logLevel) if justVersion { fmt.Printf("weave router %s\n", version) os.Exit(0) } Log.Println("Command line options:", options()) Log.Println("Command line peers:", peers) var err error if ifaceName != "" { config.Iface, err = weavenet.EnsureInterface(ifaceName, wait) if err != nil { Log.Fatal(err) } } if routerName == "" { if config.Iface == nil { Log.Fatal("Either an interface must be specified with -iface or a name with -name") } routerName = config.Iface.HardwareAddr.String() } name, err := weave.PeerNameFromUserInput(routerName) if err != nil { Log.Fatal(err) } if nickName == "" { nickName, err = os.Hostname() if err != nil { Log.Fatal(err) } } if password == "" { password = os.Getenv("WEAVE_PASSWORD") } if password == "" { Log.Println("Communication between peers is unencrypted.") } else { config.Password = []byte(password) Log.Println("Communication between peers is encrypted.") } if prof != "" { p := *profile.CPUProfile p.ProfilePath = prof p.NoShutdownHook = true defer profile.Start(&p).Stop() } config.BufSz = bufSzMB * 1024 * 1024 config.LogFrame = logFrameFunc(pktdebug) config.PeerDiscovery = !noDiscovery router := weave.NewRouter(config, name, nickName) Log.Println("Our name is", router.Ourself) var allocator *ipam.Allocator var defaultSubnet address.CIDR var dockerCli *docker.Client if iprangeCIDR != "" { allocator, defaultSubnet = createAllocator(router, iprangeCIDR, ipsubnetCIDR, determineQuorum(peerCount, peers)) dockerCli, err = docker.NewClient(apiPath) if err != nil { Log.Fatal("Unable to start docker client: ", err) } if err = dockerCli.AddObserver(allocator); err != nil { Log.Fatal("Unable to start watcher", err) } } else if peerCount > 0 { Log.Fatal("-initpeercount flag specified without -iprange") } router.Start() if errors := router.ConnectionMaker.InitiateConnections(peers, false); len(errors) > 0 { Log.Fatal(errorMessages(errors)) } // The weave script always waits for a status call to succeed, // so there is no point in doing "weave launch -httpaddr ''". // This is here to support stand-alone use of weaver. if httpAddr != "" { go handleHTTP(router, httpAddr, allocator, defaultSubnet, dockerCli) } SignalHandlerLoop(router) }