func main() { // Called first to interrupt bootstrap and display usage if the user passed -h. flag.Parse() if *debug { log.SetLevel(log.DebugLevel) } log.Info("starting GORB Daemon v0.2") if os.Geteuid() != 0 { log.Fatalf("this program has to be run with root priveleges to access IPVS") } hostIPs, err := util.InterfaceIPs(*device) if err != nil { log.Fatalf("error while obtaining interface addresses: %s", err) } listenAddr, err := net.ResolveTCPAddr("tcp", *listen) listenPort := uint16(0) if err != nil { log.Fatalf("error while obtaining listening port from '%s': %s", *listen, err) } else { listenPort = uint16(listenAddr.Port) } ctx, err := core.NewContext(core.ContextOptions{ Disco: *consul, Endpoints: hostIPs, Flush: *flush, ListenPort: listenPort, VipInterface: *vipInterface}) if err != nil { log.Fatalf("error while initializing server context: %s", err) } // While it's not strictly required, close IPVS socket explicitly. defer ctx.Close() r := mux.NewRouter() r.Handle("/service/{vsID}", serviceCreateHandler{ctx}).Methods("PUT") r.Handle("/service/{vsID}/{rsID}", backendCreateHandler{ctx}).Methods("PUT") r.Handle("/service/{vsID}/{rsID}", backendUpdateHandler{ctx}).Methods("PATCH") r.Handle("/service/{vsID}", serviceRemoveHandler{ctx}).Methods("DELETE") r.Handle("/service/{vsID}/{rsID}", backendRemoveHandler{ctx}).Methods("DELETE") r.Handle("/service", serviceListHandler{ctx}).Methods("GET") r.Handle("/service/{vsID}", serviceStatusHandler{ctx}).Methods("GET") r.Handle("/service/{vsID}/{rsID}", backendStatusHandler{ctx}).Methods("GET") log.Infof("setting up HTTP server on %s", *listen) log.Fatal(http.ListenAndServe(*listen, r)) }
func main() { // Called first to interrupt bootstrap and display usage if the user passed -h. flag.Parse() if *debug { log.SetLevel(log.DebugLevel) } log.Infof("starting GORB Docker Link Daemon v0.1") if ips, err := util.InterfaceIPs(*device); err != nil { log.Fatalf("error while obtaining interface addresses: %s", err) } else { // F**k Go scoping rules, yay! hostIPs = ips } actions := map[string]portAction{ "start": createBackend, "kill": removeBackend, } c, err := gdc.NewClientFromEnv() if err != nil { log.Fatalf("error while instantiating Docker client: %s", err) } log.Infof("listening on event feed at %s", c.Endpoint()) r, err := c.ListContainers(gdc.ListContainersOptions{}) if err != nil { log.Fatalf("error while listing containers: %s", err) } if len(r) != 0 { log.Infof("bootstrapping with existing containers") e := []error{} for _, o := range r { e = append(e, invokeFunc(o.Image, o.Names[0], o.Ports, createBackend)...) } if len(e) != 0 { log.Warnf("errors while exposing existing containers: %s", e) } } l := make(chan *gdc.APIEvents) defer close(l) // Client has built-in retries and reconnect support, so nothing else we can do. c.AddEventListener(l) for event := range l { log.Debugf("received event [%s] for container %s", event.Status, event.ID) fn, known := actions[event.Status] if !known { continue } i, err := c.InspectContainer(event.ID) if err != nil { log.Errorf("error while inspecting container %s: %s", event.ID, err) continue } b := i.NetworkSettings.PortMappingAPI() if len(b) == 0 { log.Infof("container %s has no exported ports", event.ID) continue } if e := invokeFunc(i.Config.Image, i.Name, b, fn); len(e) != 0 { log.Errorf("error(s) while processing container %s: %s", event.ID, e) } } log.Infof("event feed has been closed, terminating the Daemon") }