github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/service/api_main/apiserver.go (about) 1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "net" 7 "net/http" 8 "os" 9 "time" 10 11 "github.com/evergreen-ci/evergreen" 12 "github.com/evergreen-ci/evergreen/db" 13 "github.com/evergreen-ci/evergreen/plugin" 14 _ "github.com/evergreen-ci/evergreen/plugin/config" 15 "github.com/evergreen-ci/evergreen/service" 16 "github.com/evergreen-ci/evergreen/util" 17 "github.com/mongodb/grip" 18 "github.com/mongodb/grip/level" 19 "github.com/mongodb/grip/message" 20 "github.com/mongodb/grip/send" 21 "gopkg.in/tylerb/graceful.v1" 22 ) 23 24 var ( 25 // requestTimeout is the duration to wait until killing 26 // active requests and stopping the server. 27 requestTimeout = 10 * time.Second 28 ) 29 30 func init() { 31 flag.Usage = func() { 32 fmt.Fprintf(os.Stderr, "%s handles communication with running tasks and command line tools.\n\n", os.Args[0]) 33 fmt.Fprintf(os.Stderr, "Usage:\n %s [flags]\n\n", os.Args[0]) 34 fmt.Fprintf(os.Stderr, "Supported flags are:\n") 35 flag.PrintDefaults() 36 } 37 } 38 39 func main() { 40 settings := evergreen.GetSettingsOrExit() 41 42 // setup the logging 43 if settings.Api.LogFile != "" { 44 sender, err := send.MakeFileLogger(settings.Api.LogFile) 45 grip.CatchEmergencyFatal(err) 46 defer sender.Close() 47 grip.CatchEmergencyFatal(grip.SetSender(sender)) 48 } else { 49 sender := send.MakeNative() 50 defer sender.Close() 51 grip.CatchEmergencyFatal(grip.SetSender(sender)) 52 } 53 evergreen.SetLegacyLogger() 54 grip.SetName("evg-api-server") 55 grip.SetDefaultLevel(level.Info) 56 grip.SetThreshold(level.Debug) 57 grip.Notice(message.Fields{"build": evergreen.BuildRevision, "process": grip.Name()}) 58 59 defer util.RecoverAndLogStackTrace() 60 61 db.SetGlobalSessionProvider(db.SessionFactoryFromConfig(settings)) 62 63 tlsConfig, err := util.MakeTlsConfig(settings.Api.HttpsCert, settings.Api.HttpsKey) 64 if err != nil { 65 grip.EmergencyFatalf("Failed to make TLS config: %+v", err) 66 } 67 68 nonSSL, err := service.GetListener(settings.Api.HttpListenAddr) 69 if err != nil { 70 grip.EmergencyFatalf("Failed to get HTTP listener: %+v", err) 71 } 72 73 ssl, err := service.GetTLSListener(settings.Api.HttpsListenAddr, tlsConfig) 74 if err != nil { 75 grip.EmergencyFatalf("Failed to get HTTPS listener: %+v", err) 76 } 77 78 // Start SSL and non-SSL servers in independent goroutines, but exit 79 // the process if either one fails 80 as, err := service.NewAPIServer(settings, plugin.APIPlugins) 81 if err != nil { 82 grip.EmergencyFatalf("Failed to create API server: %+v", err) 83 } 84 85 handler, err := as.Handler() 86 if err != nil { 87 grip.EmergencyFatalf("Failed to get API route handlers: %+v", err) 88 } 89 90 server := &http.Server{Handler: handler} 91 92 errChan := make(chan error, 2) 93 94 go func() { 95 grip.Info("Starting non-SSL API server") 96 err := graceful.Serve(server, nonSSL, requestTimeout) 97 if err != nil { 98 if opErr, ok := err.(*net.OpError); !ok || (ok && opErr.Op != "accept") { 99 grip.Warningf("non-SSL API server error: %+v", err) 100 } else { 101 err = nil 102 } 103 } 104 grip.Info("non-SSL API server cleanly terminated") 105 errChan <- err 106 }() 107 108 go func() { 109 grip.Info("Starting SSL API server") 110 err := graceful.Serve(server, ssl, requestTimeout) 111 if err != nil { 112 if opErr, ok := err.(*net.OpError); !ok || (ok && opErr.Op != "accept") { 113 grip.Warningf("SSL API server error: %+v", err) 114 } else { 115 err = nil 116 } 117 } 118 grip.Info("SSL API server cleanly terminated") 119 errChan <- err 120 }() 121 122 exitCode := 0 123 124 for i := 0; i < 2; i++ { 125 if err := <-errChan; err != nil { 126 grip.Errorf("Error returned from API server: %+v", err) 127 exitCode = 1 128 } 129 } 130 131 os.Exit(exitCode) 132 }