in cmd/kubernetes-history-inspector/main.go [108:279]
func run() int {
defer errorreport.CheckAndReportPanic()
logger.InitGlobalKHILogger()
err := parameters.Parse()
if err != nil {
slog.Error(err.Error())
return 1
}
if *parameters.Debug.Verbose {
flag.DumpAll(context.Background())
}
if *parameters.Debug.Profiler {
cfg := profiler.Config{
Service: *parameters.Debug.ProfilerService,
ProjectID: *parameters.Debug.ProfilerProject,
MutexProfiling: true,
}
if err := profiler.Start(cfg); err != nil {
slog.Error(fmt.Sprintf("Failed to start profiler\n%s", err.Error()))
}
slog.Info("Cloud Profiler is enabled")
}
lifecycle.Default.NotifyInit()
slog.Info("Initializing Kubernetes History Inspector...")
k8s.GenerateDefaultMergeConfig()
if *parameters.Auth.QuotaProjectID != "" {
api.DefaultGCPClientFactory.RegisterHeaderProvider(quotaproject.NewHeaderProvider(*parameters.Auth.QuotaProjectID))
}
inspectionServer, err := inspection.NewServer()
if err != nil {
slog.Error(fmt.Sprintf("Failed to construct the inspection server due to unexpected error\n%v", err))
}
if !*parameters.Server.ViewerMode {
for i, taskSetRegistrer := range taskSetRegistrer {
err = taskSetRegistrer(inspectionServer)
if err != nil {
slog.Error(fmt.Sprintf("Failed to call initialize calls for taskSetRegistrer(#%d)\n%v", i, err))
}
}
}
// Channel to receive exit codes from concurrent goroutines
exitCh := make(chan int, 1)
// Start signal handler
go handleTerminateSignal(exitCh)
if !*parameters.Job.JobMode {
slog.Info("Starting Kubernetes History Inspector server...")
uploadFileStoreFolder := "/tmp"
if parameters.Common.UploadFileStoreFolder != nil {
uploadFileStoreFolder = *parameters.Common.UploadFileStoreFolder
}
upload.DefaultUploadFileStore = upload.NewUploadFileStore(upload.NewLocalUploadFileStoreProvider(uploadFileStoreFolder))
config := server.ServerConfig{
ViewerMode: *parameters.Server.ViewerMode,
StaticFolderPath: *parameters.Server.FrontendAssetFolder,
ResourceMonitor: &server.ResourceMonitorImpl{},
ServerBasePath: *parameters.Server.BasePath,
UploadFileStore: upload.DefaultUploadFileStore,
}
engine := server.CreateKHIServer(inspectionServer, &config)
if parameters.Auth.OAuthEnabled() {
err := accesstoken.DefaultOAuthTokenResolver.SetServer(engine)
if err != nil {
slog.Error("failed to register the web server to OAuth Token resolver")
return 1
}
}
go func() {
err = engine.Run(fmt.Sprintf("%s:%d", *parameters.Server.Host, *parameters.Server.Port))
if err != nil {
slog.Error(fmt.Sprintf("Failed to start server\n%s", err.Error()))
exitCh <- 1
} else {
slog.Error("Hitting the unreachable code. Server terminated unexpectedly")
exitCh <- 1
}
}()
displayStartMessage(*parameters.Server.Host, *parameters.Server.Port)
} else {
slog.Info("Starting Kubernetes History Inspector as job mode...")
go func() {
queryParametersInJson := *parameters.Job.InspectionValues
var values map[string]any
err := json.Unmarshal([]byte(queryParametersInJson), &values)
if err != nil {
slog.Error(fmt.Sprintf("Failed to parse an inspection value %s\n%s", queryParametersInJson, err.Error()))
exitCh <- 1
return
}
inspectionID, err := inspectionServer.CreateInspection(*parameters.Job.InspectionType)
if err != nil {
slog.Error(fmt.Sprintf("Failed to create an inspection with type %s\n%s", *parameters.Job.InspectionType, err.Error()))
exitCh <- 1
return
}
features := strings.Split(*parameters.Job.InspectionFeatures, ",")
t := inspectionServer.GetInspection(inspectionID)
// When the features env has `ALL`, it enables every features being available
if len(features) == 1 && strings.ToUpper(features[0]) == "ALL" {
availableFeatures, err := t.FeatureList()
if err != nil {
slog.Error(fmt.Sprintf("Failed to obtain current feature list\n%s", err.Error()))
exitCh <- 1
return
}
allFeatures := []string{}
for _, af := range availableFeatures {
allFeatures = append(allFeatures, af.Id)
}
features = allFeatures
}
err = t.SetFeatureList(features)
if err != nil {
slog.Error(fmt.Sprintf("Failed to set features %v\n%s", features, err.Error()))
exitCh <- 1
return
}
err = t.Run(context.Background(), &inspection_task.InspectionRequest{
Values: values,
})
if err != nil {
slog.Error(fmt.Sprintf("Failed to run inspection task \n%s", err.Error()))
exitCh <- 1
return
}
<-t.Wait()
result, err := t.Result()
if err != nil {
slog.Error(fmt.Sprintf("Failed to get inspection result \n%s", err.Error()))
exitCh <- 1
return
}
reader, err := result.ResultStore.GetReader()
if err != nil {
slog.Error(fmt.Sprintf("Failed to get inspection result reader \n%s", err.Error()))
exitCh <- 1
return
}
defer reader.Close()
file, err := os.OpenFile(*parameters.Job.ExportDestination, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
slog.Error(fmt.Sprintf("Failed to open the destination file \n%s", err.Error()))
exitCh <- 1
return
}
_, err = io.Copy(file, reader)
if err != nil {
slog.Error(fmt.Sprintf("Failed to flush to the destination file \n%s", err.Error()))
exitCh <- 1
return
}
}()
}
// Wait for exit code from any source
code := <-exitCh
return code
}