func main()

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)
}