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)
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.
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 π
This is great. Happy to see all those
os.Exit()
calls removed.There is at least one more thing that calls
os.Exit()
- https://github.com/kubernetes/kubernetes/blob/dac94e1c9ee31034d174815e287ba39fa67b2b72/staging/src/k8s.io/kubectl/pkg/cmd/util/helpers.go#L114-L116. Itβs used in a lot of places, such as https://github.com/kubernetes/kubernetes/blob/dac94e1c9ee31034d174815e287ba39fa67b2b72/staging/src/k8s.io/kubectl/pkg/cmd/logs/logs.go#L157-L159.