in traffic_ops/traffic_ops_golang/traffic_ops_golang.go [62:262]
func main() {
showVersion := flag.Bool("version", false, "Show version and exit")
showPlugins := flag.Bool("plugins", false, "Show the list of plugins and exit")
showRoutes := flag.Bool("api-routes", false, "Show the list of API routes and exit")
configFileName := flag.String("cfg", "", "The config file path")
dbConfigFileName := flag.String("dbcfg", "", "The db config file path")
riakConfigFileName := flag.String("riakcfg", "", "The riak config file path (DEPRECATED: use traffic_vault_backend = riak and traffic_vault_config in cdn.conf instead)")
backendConfigFileName := flag.String("backendcfg", "", "The backend config file path")
flag.Parse()
if *showVersion {
fmt.Println(about.About.RPMVersion)
os.Exit(0)
}
if *showPlugins {
fmt.Println(strings.Join(plugin.List(), "\n"))
os.Exit(0)
}
if *showRoutes {
fake := routing.ServerData{Config: config.NewFakeConfig()}
routes, _, _ := routing.Routes(fake)
if len(*configFileName) != 0 {
cfg, err := config.LoadCdnConfig(*configFileName)
if err != nil {
fmt.Printf("Loading cdn config from '%s': %v", *configFileName, err)
os.Exit(1)
}
disabledRoutes := routing.GetRouteIDMap(cfg.DisabledRoutes)
for _, r := range routes {
_, isDisabled := disabledRoutes[r.ID]
fmt.Printf("%s\tis_disabled=%t\n", r, isDisabled)
}
} else {
for _, r := range routes {
fmt.Printf("%s\n", r)
}
}
os.Exit(0)
}
if len(os.Args) < 2 {
flag.Usage()
os.Exit(1)
}
cfg, errsToLog, blockStart := config.LoadConfig(*configFileName, *dbConfigFileName, version)
for _, err := range errsToLog {
fmt.Fprintf(os.Stderr, "Loading Config: %v\n", err)
}
if blockStart {
os.Exit(1)
}
if err := log.InitCfg(cfg); err != nil {
fmt.Printf("Error initializing loggers: %v\n", err)
for _, err := range errsToLog {
fmt.Println(err)
}
os.Exit(1)
}
for _, err := range errsToLog {
log.Warnln(err)
}
logConfig(cfg)
err := auth.LoadPasswordBlacklist("app/conf/invalid_passwords.txt")
if err != nil {
log.Errorf("loading password blacklist: %v\n", err)
os.Exit(1)
}
sslStr := "require"
if !cfg.DB.SSL {
sslStr = "disable"
}
db, err := sqlx.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=%s&fallback_application_name=trafficops", cfg.DB.User, cfg.DB.Password, cfg.DB.Hostname, cfg.DB.Port, cfg.DB.DBName, sslStr))
if err != nil {
log.Errorf("opening database: %v\n", err)
os.Exit(1)
}
defer db.Close()
db.SetMaxOpenConns(cfg.MaxDBConnections)
db.SetMaxIdleConns(cfg.DBMaxIdleConnections)
db.SetConnMaxLifetime(time.Duration(cfg.DBConnMaxLifetimeSeconds) * time.Second)
auth.InitUsersCache(time.Duration(cfg.UserCacheRefreshIntervalSec)*time.Second, db.DB, time.Duration(cfg.DBQueryTimeoutSeconds)*time.Second)
server.InitServerUpdateStatusCache(time.Duration(cfg.ServerUpdateStatusCacheRefreshIntervalSec)*time.Second, db.DB, time.Duration(cfg.DBQueryTimeoutSeconds)*time.Second)
trafficVault := setupTrafficVault(*riakConfigFileName, &cfg)
// TODO combine
plugins := plugin.Get(cfg)
profiling := cfg.ProfilingEnabled
pprofMux := http.DefaultServeMux
http.DefaultServeMux = http.NewServeMux() // this is so we don't serve pprof over 443.
pprofMux.Handle("/db-stats", routing.DBStatsHandler(db))
pprofMux.Handle("/memory-stats", routing.MemoryStatsHandler())
go func() {
debugServer := http.Server{
Addr: "localhost:6060",
Handler: pprofMux,
}
log.Errorln(debugServer.ListenAndServe())
}()
var backendConfig config.BackendConfig
if *backendConfigFileName != "" {
backendConfig, err = config.LoadBackendConfig(*backendConfigFileName)
routing.SetBackendConfig(backendConfig)
if err != nil {
log.Errorf("error loading backend config: %v", err)
}
}
mux := http.NewServeMux()
d := routing.ServerData{DB: db, Config: cfg, Profiling: &profiling, Plugins: plugins, TrafficVault: trafficVault, Mux: mux}
if err := routing.RegisterRoutes(d); err != nil {
log.Errorf("registering routes: %v\n", err)
os.Exit(1)
}
plugins.OnStartup(plugin.StartupData{Data: plugin.Data{SharedCfg: cfg.PluginSharedConfig, AppCfg: cfg}})
log.Infof("Listening on " + cfg.Port)
httpServer := &http.Server{
Addr: ":" + cfg.Port,
TLSConfig: cfg.TLSConfig,
ReadTimeout: time.Duration(cfg.ReadTimeout) * time.Second,
ReadHeaderTimeout: time.Duration(cfg.ReadHeaderTimeout) * time.Second,
WriteTimeout: time.Duration(cfg.WriteTimeout) * time.Second,
IdleTimeout: time.Duration(cfg.IdleTimeout) * time.Second,
ErrorLog: log.Error,
}
if httpServer.TLSConfig == nil {
httpServer.TLSConfig = &tls.Config{
ClientAuth: tls.RequestClientCert,
}
}
// Deprecated in 5.0
httpServer.TLSConfig.InsecureSkipVerify = cfg.Insecure
// end deprecated block
go func() {
if cfg.KeyPath == "" {
log.Errorf("key cannot be blank in %s", cfg.KeyPath)
os.Exit(1)
}
if cfg.CertPath == "" {
log.Errorf("cert cannot be blank in %s", cfg.CertPath)
os.Exit(1)
}
if file, err := os.Open(cfg.CertPath); err != nil {
log.Errorf("cannot open %s for read: %s", cfg.CertPath, err.Error())
os.Exit(1)
} else {
file.Close()
}
if file, err := os.Open(cfg.KeyPath); err != nil {
log.Errorf("cannot open %s for read: %s", cfg.KeyPath, err.Error())
os.Exit(1)
} else {
file.Close()
}
httpServer.Handler = mux
if err := httpServer.ListenAndServeTLS(cfg.CertPath, cfg.KeyPath); err != nil {
log.Errorf("stopping server: %v\n", err)
os.Exit(1)
}
}()
profilingLocation, err := getProcessedProfilingLocation(cfg.ProfilingLocation, cfg.LogLocationError)
if err != nil {
log.Errorln("unable to determine profiling location: " + err.Error())
}
log.Infof("profiling location: %s\n", profilingLocation)
log.Infof("profiling enabled set to %t\n", profiling)
if profiling {
continuousProfile(&profiling, &profilingLocation, cfg.Version)
}
reloadProfilingAndBackendConfig := func() {
setNewProfilingInfo(*configFileName, &profiling, &profilingLocation, cfg.Version)
backendConfig, err = getNewBackendConfig(backendConfigFileName)
if err != nil {
log.Errorf("could not reload backend config: %v", err)
} else {
routing.SetBackendConfig(backendConfig)
}
}
signalReloader(unix.SIGHUP, reloadProfilingAndBackendConfig)
}