// Boot starts Clair. By exporting this function, anyone can import their own // custom fetchers/updaters into their own package and then call clair.Boot. func Boot(config *config.Config) { rand.Seed(time.Now().UnixNano()) st := utils.NewStopper() // Open database db, err := pgsql.Open(config.Database) if err != nil { log.Fatal(err) } defer db.Close() // Start notifier st.Begin() go notifier.Run(config.Notifier, db, st) // Start API st.Begin() go api.Run(config.API, &context.RouteContext{db, config.API}, st) st.Begin() go api.RunHealth(config.API, &context.RouteContext{db, config.API}, st) // Start updater st.Begin() go updater.Run(config.Updater, db, st) // Wait for interruption and shutdown gracefully. waitForSignals(os.Interrupt) log.Info("Received interruption, gracefully stopping ...") st.Stop() }
func ClairServiceInit() error { // Load database setting if setting.ClairDBPath != "" { clairConf.DBPath = setting.ClairDBPath } else { clairConf.DBPath = DefaultClairDBPath } clairConf.KeepDB = setting.ClairKeepDB clairConf.LogLevel = setting.ClairLogLevel clairConf.Duration = setting.ClairUpdateDuration clairConf.VulnPriority = setting.ClairVulnPriority // Set database if err := database.Open("bolt", clairConf.DBPath); err != nil { logrus.Debug(err) return err } // Set logLevel of clair lib logLevel, err := capnslog.ParseLevel(strings.ToUpper(clairConf.LogLevel)) if err != nil { logLevel, _ = capnslog.ParseLevel(strings.ToUpper(DefaultClairLogLevel)) } capnslog.SetGlobalLogLevel(logLevel) capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stdout, false)) // Set minumum priority parameter. if types.Priority(clairConf.VulnPriority).IsValid() { logrus.Debugf("Vuln priority is invalid :%v.", clairConf.VulnPriority) clairConf.VulnPriority = DefaultClairVulnPriority } // Set 'duration' and Update the CVE database if clairConf.Duration == "" { logrus.Debugf("No duration set, so only update at the beginning.") go updater.Update() clairStopper = nil } else { st := utils.NewStopper() st.Begin() d, err := time.ParseDuration(clairConf.Duration) if err != nil { logrus.Warnf("Wrong duration format, use the default duration: %v.", DefaultClairUpdateDuration) clairConf.Duration = DefaultClairUpdateDuration d, err = time.ParseDuration(clairConf.Duration) if err != nil { logrus.Debugf("Cannot pare du %v", err) } } go updater.Run(d, st) clairStopper = st st.Begin() } return nil }
func main() { rand.Seed(time.Now().UTC().UnixNano()) var err error st := utils.NewStopper() // Parse command-line arguments kingpin.Parse() if *cfgDbType != "memstore" && *cfgDbPath == "" { kingpin.Errorf("required flag --db-path not provided, try --help") os.Exit(1) } if *cfgNotifierType == "http" && *cfgNotifierHTTPURL == "" { kingpin.Errorf("required flag --notifier-http-url not provided, try --help") os.Exit(1) } // Initialize error/logging system logLevel, err := capnslog.ParseLevel(strings.ToUpper(*cfgLogLevel)) capnslog.SetGlobalLogLevel(logLevel) capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stdout, false)) // Enable CPU Profiling if specified if *cfgCPUProfilePath != "" { f, err := os.Create(*cfgCPUProfilePath) if err != nil { log.Fatalf("failed to create profile file: %s", err) } defer f.Close() pprof.StartCPUProfile(f) log.Info("started profiling") defer func() { pprof.StopCPUProfile() log.Info("stopped profiling") }() } // Open database err = database.Open(*cfgDbType, *cfgDbPath) if err != nil { log.Fatal(err) } defer database.Close() // Start notifier var notifierService notifier.Notifier switch *cfgNotifierType { case "http": notifierService, err = notifier.NewHTTPNotifier(*cfgNotifierHTTPURL) if err != nil { log.Fatalf("could not initialize HTTP notifier: %s", err) } } if notifierService != nil { st.Begin() go notifierService.Run(st) } // Start Main API and Health API st.Begin() go api.RunMain(&api.Config{ Port: *cfgAPIPort, TimeOut: *cfgAPITimeout, CertFile: *cfgAPICertFile, KeyFile: *cfgAPIKeyFile, CAFile: *cfgAPICAFile, }, st) st.Begin() go api.RunHealth(*cfgAPIPort+1, st) // Start updater st.Begin() go updater.Run(*cfgUpdateInterval, st) // This blocks the main goroutine which is required to keep all the other goroutines running interrupts := make(chan os.Signal, 1) signal.Notify(interrupts, os.Interrupt) <-interrupts log.Info("Received interruption, gracefully stopping ...") st.Stop() }