kubernetes: replace klog.Fatal and os.Exit for defer funcs

Hello, team πŸ‘‹

What happened:

The defer function will not be called if os.Exit(1). https://play.golang.org/p/f7IjXeb62dd

deferred functions are not run. https://golang.org/pkg/os/#Exit

Now, the entry points of some Kubernetes components use defer functions to flush logs.

For example, kube-scheduler https://github.com/kubernetes/kubernetes/blob/master/cmd/kube-scheduler/scheduler.go#L41

func main() {
	rand.Seed(time.Now().UnixNano())

	pflag.CommandLine.SetNormalizeFunc(cliflag.WordSepNormalizeFunc)

	command := app.NewSchedulerCommand()

	logs.InitLogs()
	defer logs.FlushLogs()

	if err := command.Execute(); err != nil {
		os.Exit(1)
	}
}

When command.Execute() returns an error, logs are not flushed. Is this an expected behavior?

How to fix

We can ensure that defer is executed by separating the functions as follows.

func main() {
  if err := realmain(); err != nil {
    os.Exit(1)
  }
}

func realmain() error {
	rand.Seed(time.Now().UnixNano())

	pflag.CommandLine.SetNormalizeFunc(cliflag.WordSepNormalizeFunc)

	command := app.NewSchedulerCommand()

	logs.InitLogs()
	defer logs.FlushLogs()

	if err := command.Execute(); err != nil {
		return err
	}
       return nil
}

can I pick this issue? /assign

Edit (October 23)

For entry points, https://github.com/kubernetes/kubernetes/pull/105076 resolves the issue. But it is better to delete all klog.Fatal and os.Exit as much as possible. They can be replaced by returning error/nil. And in some case, we may be able to use panic() (defer funcs are executed when panic ref)

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 3
  • Comments: 36 (31 by maintainers)

Most upvoted comments

I have checked #104774, #104775, #104776 already, the only left one #104773 I’ll working on it this week. @sanposhiho

hi @sanposhiho , I can provide some help if you needs. 🧐

/remove-kind bug /kind cleanup

Changed the issue title to easily understand the current purpose of this issue - delete all klog.Fatal and os.Exit for defer funcs.

So, now, we only have to delete os.Exit on cobra commands for this issue

In the past I’ve said this, but I think we need to eliminate replace all os.Exit and klog.Fatal(it call os.Exit internally) πŸ˜“ , not just the ones on cobra commands. We have to investigate all the places using them.

@kerthcet

By #105076, we don’t have to create another func for entry points. So, now, we only have to delete os.Exit on cobra commands for this issue πŸ˜ƒ