func main() { var config Config config.Backend.Type = "vxlan" if backend := os.Getenv("BACKEND"); backend != "" { config.Backend.Type = backend } config.Network = os.Getenv("NETWORK") if config.Network == "" { config.Network = "100.100.0.0/16" } flag.StringVar(&config.SubnetMin, "subnet-min", "", "container network min subnet") flag.StringVar(&config.SubnetMax, "subnet-max", "", "container network max subnet") flag.UintVar(&config.SubnetLen, "subnet-len", 0, "container network subnet length") flag.UintVar(&config.Backend.VNI, "vni", 0, "vxlan network identifier") flag.UintVar(&config.Backend.Port, "port", 0, "vxlan communication port (UDP)") flag.Parse() // wait for discoverd to come up status, err := cluster.WaitForHostStatus(os.Getenv("EXTERNAL_IP"), func(status *host.HostStatus) bool { return status.Discoverd != nil && status.Discoverd.URL != "" }) if err != nil { log.Fatal(err) } // create service and config if not present client := discoverd.NewClientWithURL(status.Discoverd.URL) if err := client.AddService(serviceName, nil); err != nil && !hh.IsObjectExistsError(err) { log.Fatalf("error creating discoverd service: %s", err) } data, err := json.Marshal(map[string]Config{"config": config}) if err != nil { log.Fatal(err) } err = client.Service(serviceName).SetMeta(&discoverd.ServiceMeta{Data: data}) if err != nil && !hh.IsObjectExistsError(err) { log.Fatalf("error creating discoverd service metadata: %s", err) } flanneld, err := exec.LookPath("flanneld") if err != nil { log.Fatal(err) } if err := syscall.Exec( flanneld, []string{ flanneld, "-discoverd-url=" + status.Discoverd.URL, "-iface=" + os.Getenv("EXTERNAL_IP"), "-http-port=" + os.Getenv("PORT"), fmt.Sprintf("-notify-url=http://%s:1113/host/network", os.Getenv("EXTERNAL_IP")), }, os.Environ(), ); err != nil { log.Fatal(err) } }
func waitHostDNSConfig() (addr string, resolvers []string) { // Wait for the host network. status, err := cluster.WaitForHostStatus(os.Getenv("EXTERNAL_IP"), func(status *host.HostStatus) bool { return status.Network != nil && status.Network.Subnet != "" }) if err != nil { log.Fatal(err) } // Parse network subnet to determine bind address. ip, _, err := net.ParseCIDR(status.Network.Subnet) if err != nil { log.Fatal(err) } addr = net.JoinHostPort(ip.String(), "53") return addr, status.Network.Resolvers }
// Run executes the program. func (m *Main) Run(args ...string) error { // Create logger. m.logger = log.New(m.Stdout, "", log.LstdFlags) // Parse command line flags. opt, err := m.ParseFlags(args...) if err != nil { return err } // Open listener. ln, err := net.Listen("tcp4", opt.Addr) if err != nil { return err } m.ln = ln // Multiplex listener to store and http api. storeLn, httpLn := server.Mux(ln) // Set up advertised address and default peer set. advertiseAddr := MergeHostPort(opt.Host, opt.Addr) if len(opt.Peers) == 0 { opt.Peers = []string{advertiseAddr} } // Open store if we are not proxying. if err := m.openStore(opt.DataDir, storeLn, advertiseAddr, opt.Peers); err != nil { return fmt.Errorf("Failed to open store: %s", err) } // Notify user that we're proxying if the store wasn't initialized. if m.store == nil { fmt.Fprintln(m.Stderr, "advertised address not in peer set, joining as proxy") } // Create a slice of peers with their HTTP address set instead. httpPeers, err := SetPortSlice(opt.Peers, opt.Addr) if err != nil { return fmt.Errorf("set port slice: %s", err) } // If we have a DNS address, start a DNS server right away, otherwise // wait for the host network to come up and then start a DNS server. if opt.DNSAddr != "" { if err := m.openDNSServer(opt.DNSAddr, opt.Recursors, httpPeers); err != nil { return fmt.Errorf("Failed to start DNS server: %s", err) } m.logger.Printf("discoverd listening for DNS on %s", opt.DNSAddr) } else if opt.WaitNetDNS { go func() { // Wait for the host network. status, err := cluster.WaitForHostStatus(os.Getenv("EXTERNAL_IP"), func(status *host.HostStatus) bool { return status.Network != nil && status.Network.Subnet != "" }) if err != nil { log.Fatal(err) } // Parse network subnet to determine bind address. ip, _, err := net.ParseCIDR(status.Network.Subnet) if err != nil { log.Fatal(err) } addr := net.JoinHostPort(ip.String(), "53") if err := m.openDNSServer(addr, status.Network.Resolvers, httpPeers); err != nil { log.Fatalf("Failed to start DNS server: %s", err) } m.logger.Printf("discoverd listening for DNS on %s", addr) // Notify webhook. if opt.Notify != "" { m.Notify(opt.Notify, "", addr) } }() } if err := m.openHTTPServer(httpLn, opt.Peers); err != nil { return fmt.Errorf("Failed to start HTTP server: %s", err) } // Notify user that the servers are listening. m.logger.Printf("discoverd listening for HTTP on %s", opt.Addr) // FIXME(benbjohnson): Join to cluster. // Wait for leadership. if err := m.waitForLeader(LeaderTimeout); err != nil { return err } // Notify URL that discoverd is running. httpAddr := ln.Addr().String() host, port, _ := net.SplitHostPort(httpAddr) if host == "0.0.0.0" { httpAddr = net.JoinHostPort(os.Getenv("EXTERNAL_IP"), port) } m.Notify(opt.Notify, "http://"+httpAddr, opt.DNSAddr) go discoverd.NewClientWithURL("http://"+httpAddr).AddServiceAndRegister("discoverd", httpAddr) return nil }
func waitForHostNetwork() (*host.HostStatus, error) { return cluster.WaitForHostStatus(func(status *host.HostStatus) bool { return status.Network != nil && status.Network.Subnet != "" }) }