freeze before exit when _MINIO_DEBUG_NO_EXIT is defined (#15709)

this is to ensure keep k8s pods running, when they reach a "crashloop" stage
This commit is contained in:
Anis Elleuch 2022-09-22 19:57:27 +01:00 committed by GitHub
parent 6f56ba80b3
commit 20c89ebbb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 3 deletions

View File

@ -23,11 +23,13 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"runtime/debug"
"sort" "sort"
"strings" "strings"
"github.com/minio/cli" "github.com/minio/cli"
"github.com/minio/minio/internal/color" "github.com/minio/minio/internal/color"
"github.com/minio/minio/internal/logger"
"github.com/minio/pkg/console" "github.com/minio/pkg/console"
"github.com/minio/pkg/trie" "github.com/minio/pkg/trie"
"github.com/minio/pkg/words" "github.com/minio/pkg/words"
@ -189,8 +191,27 @@ func Main(args []string) {
// Set the minio app name. // Set the minio app name.
appName := filepath.Base(args[0]) appName := filepath.Base(args[0])
if os.Getenv("_MINIO_DEBUG_NO_EXIT") != "" {
freeze := func(_ int) {
// Infinite blocking op
<-make(chan struct{})
}
// Override the logger os.Exit()
logger.ExitFunc = freeze
defer func() {
if err := recover(); err != nil {
fmt.Println("panic:", err)
fmt.Println("")
fmt.Println(string(debug.Stack()))
}
freeze(-1)
}()
}
// Run the app - exit on error. // Run the app - exit on error.
if err := newApp(appName).Run(args); err != nil { if err := newApp(appName).Run(args); err != nil {
os.Exit(1) os.Exit(1) //nolint:gocritic
} }
} }

View File

@ -32,6 +32,9 @@ import (
// ConsoleLoggerTgt is a stringified value to represent console logging // ConsoleLoggerTgt is a stringified value to represent console logging
const ConsoleLoggerTgt = "console+http" const ConsoleLoggerTgt = "console+http"
// ExitFunc is called by Fatal() class functions, by default it calls os.Exit()
var ExitFunc = os.Exit
// Logger interface describes the methods that need to be implemented to satisfy the interface requirements. // Logger interface describes the methods that need to be implemented to satisfy the interface requirements.
type Logger interface { type Logger interface {
json(msg string, args ...interface{}) json(msg string, args ...interface{})
@ -90,7 +93,7 @@ func (f fatalMsg) json(msg string, args ...interface{}) {
} }
fmt.Println(string(logJSON)) fmt.Println(string(logJSON))
os.Exit(1) ExitFunc(1)
} }
func (f fatalMsg) quiet(msg string, args ...interface{}) { func (f fatalMsg) quiet(msg string, args ...interface{}) {
@ -143,7 +146,7 @@ func (f fatalMsg) pretty(msg string, args ...interface{}) {
} }
// Exit because this is a fatal error message // Exit because this is a fatal error message
os.Exit(1) ExitFunc(1)
} }
type infoMsg struct{} type infoMsg struct{}