github.com/openshift/installer@v1.4.17/cmd/openshift-install/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "flag" 6 "io" 7 "os" 8 "path/filepath" 9 10 "github.com/pkg/errors" 11 "github.com/sirupsen/logrus" 12 "github.com/spf13/cobra" 13 terminal "golang.org/x/term" 14 "k8s.io/klog" 15 klogv2 "k8s.io/klog/v2" 16 ctrl "sigs.k8s.io/controller-runtime" 17 "sigs.k8s.io/controller-runtime/pkg/manager/signals" 18 19 "github.com/openshift/installer/cmd/openshift-install/command" 20 "github.com/openshift/installer/pkg/clusterapi" 21 ) 22 23 func main() { 24 // This attempts to configure klog (used by vendored Kubernetes code) not 25 // to log anything. 26 // Handle k8s.io/klog 27 var fs flag.FlagSet 28 klog.InitFlags(&fs) 29 fs.Set("stderrthreshold", "4") 30 klog.SetOutput(io.Discard) 31 // Handle k8s.io/klog/v2 32 var fsv2 flag.FlagSet 33 klogv2.InitFlags(&fsv2) 34 fsv2.Set("stderrthreshold", "4") 35 klogv2.SetOutput(io.Discard) 36 37 ctrl.SetLogger(klogv2.Background()) 38 39 installerMain() 40 } 41 42 func installerMain() { 43 rootCmd := newRootCmd() 44 45 // Perform a graceful shutdown upon interrupt or at exit. 46 ctx := handleInterrupt(signals.SetupSignalHandler()) 47 logrus.RegisterExitHandler(shutdown) 48 49 for _, subCmd := range []*cobra.Command{ 50 newCreateCmd(ctx), 51 newDestroyCmd(), 52 newWaitForCmd(), 53 newGatherCmd(ctx), 54 newAnalyzeCmd(), 55 newVersionCmd(), 56 newGraphCmd(), 57 newCoreOSCmd(), 58 newCompletionCmd(), 59 newExplainCmd(), 60 newAgentCmd(ctx), 61 newListFeaturesCmd(), 62 newImageBasedCmd(ctx), 63 } { 64 rootCmd.AddCommand(subCmd) 65 } 66 67 if err := rootCmd.Execute(); err != nil { 68 logrus.Fatalf("Error executing openshift-install: %v", err) 69 } 70 } 71 72 func newRootCmd() *cobra.Command { 73 cmd := &cobra.Command{ 74 Use: filepath.Base(os.Args[0]), 75 Short: "Creates OpenShift clusters", 76 Long: "", 77 PersistentPreRun: runRootCmd, 78 SilenceErrors: true, 79 SilenceUsage: true, 80 } 81 cmd.PersistentFlags().StringVar(&command.RootOpts.Dir, "dir", ".", "assets directory") 82 cmd.PersistentFlags().StringVar(&command.RootOpts.LogLevel, "log-level", "info", "log level (e.g. \"debug | info | warn | error\")") 83 return cmd 84 } 85 86 func runRootCmd(cmd *cobra.Command, args []string) { 87 logrus.SetOutput(io.Discard) 88 logrus.SetLevel(logrus.TraceLevel) 89 90 level, err := logrus.ParseLevel(command.RootOpts.LogLevel) 91 if err != nil { 92 level = logrus.InfoLevel 93 } 94 95 logrus.AddHook(command.NewFileHookWithNewlineTruncate(os.Stderr, level, &logrus.TextFormatter{ 96 // Setting ForceColors is necessary because logrus.TextFormatter determines 97 // whether or not to enable colors by looking at the output of the logger. 98 // In this case, the output is io.Discard, which is not a terminal. 99 // Overriding it here allows the same check to be done, but against the 100 // hook's output instead of the logger's output. 101 ForceColors: terminal.IsTerminal(int(os.Stderr.Fd())), 102 DisableTimestamp: true, 103 DisableLevelTruncation: true, 104 DisableQuote: true, 105 })) 106 107 if err != nil { 108 logrus.Fatal(errors.Wrap(err, "invalid log-level")) 109 } 110 } 111 112 // handleInterrupt executes a graceful shutdown then exits in 113 // the case of a user interrupt. It returns a new context that 114 // will be cancelled upon interrupt. 115 func handleInterrupt(signalCtx context.Context) context.Context { 116 ctx, cancel := context.WithCancel(context.Background()) 117 118 // If the context from the signal handler is done, 119 // an interrupt has been received, so shutdown & exit. 120 go func() { 121 <-signalCtx.Done() 122 logrus.Warn("Received interrupt signal") 123 shutdown() 124 cancel() 125 logrus.Exit(exitCodeInterrupt) 126 }() 127 128 return ctx 129 } 130 131 func shutdown() { 132 clusterapi.System().Teardown() 133 }