mirror of
https://github.com/opencontainers/runc.git
synced 2025-04-18 19:44:09 +03:00
Function fatal() and method (*FatalWriter).Write log the error to the logger when prints it to stderr just be be sure. Since by default the logger is configured to write to os.Stderr, we get something like this as a result: > # ./runc checkpoint xx5 > ERRO[0000] Container cannot be checkpointed in stopped state > Container cannot be checkpointed in stopped state or > # ./runc sdf > ERRO[0000] No help topic for 'sdf' > No help topic for 'sdf' This is very annoying. To fix, check if logrus is logging into stderr, and if it is, skip the second write. After this commit: > # ./runc sdf > ERRO[0000] No help topic for 'sdf' > [root@kir-rhat runc]# ./runc --log=out sdf > No help topic for 'sdf' Note that now the logrus prefix might be in or out, depending on whether logrus is logging to stderr or not. This is not perfect, but better than the old behavior. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
103 lines
2.2 KiB
Go
103 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/opencontainers/runtime-spec/specs-go"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/urfave/cli"
|
|
)
|
|
|
|
const (
|
|
exactArgs = iota
|
|
minArgs
|
|
maxArgs
|
|
)
|
|
|
|
func checkArgs(context *cli.Context, expected, checkType int) error {
|
|
var err error
|
|
cmdName := context.Command.Name
|
|
switch checkType {
|
|
case exactArgs:
|
|
if context.NArg() != expected {
|
|
err = fmt.Errorf("%s: %q requires exactly %d argument(s)", os.Args[0], cmdName, expected)
|
|
}
|
|
case minArgs:
|
|
if context.NArg() < expected {
|
|
err = fmt.Errorf("%s: %q requires a minimum of %d argument(s)", os.Args[0], cmdName, expected)
|
|
}
|
|
case maxArgs:
|
|
if context.NArg() > expected {
|
|
err = fmt.Errorf("%s: %q requires a maximum of %d argument(s)", os.Args[0], cmdName, expected)
|
|
}
|
|
}
|
|
|
|
if err != nil {
|
|
fmt.Printf("Incorrect Usage.\n\n")
|
|
cli.ShowCommandHelp(context, cmdName)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func logrusToStderr() bool {
|
|
l, ok := logrus.StandardLogger().Out.(*os.File)
|
|
return ok && l.Fd() == os.Stderr.Fd()
|
|
}
|
|
|
|
// fatal prints the error's details if it is a libcontainer specific error type
|
|
// then exits the program with an exit status of 1.
|
|
func fatal(err error) {
|
|
// make sure the error is written to the logger
|
|
logrus.Error(err)
|
|
if !logrusToStderr() {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
}
|
|
|
|
os.Exit(1)
|
|
}
|
|
|
|
// setupSpec performs initial setup based on the cli.Context for the container
|
|
func setupSpec(context *cli.Context) (*specs.Spec, error) {
|
|
bundle := context.String("bundle")
|
|
if bundle != "" {
|
|
if err := os.Chdir(bundle); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
spec, err := loadSpec(specConfig)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return spec, nil
|
|
}
|
|
|
|
func revisePidFile(context *cli.Context) error {
|
|
pidFile := context.String("pid-file")
|
|
if pidFile == "" {
|
|
return nil
|
|
}
|
|
|
|
// convert pid-file to an absolute path so we can write to the right
|
|
// file after chdir to bundle
|
|
pidFile, err := filepath.Abs(pidFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return context.Set("pid-file", pidFile)
|
|
}
|
|
|
|
// parseBoolOrAuto returns (nil, nil) if s is empty or "auto"
|
|
func parseBoolOrAuto(s string) (*bool, error) {
|
|
if s == "" || strings.ToLower(s) == "auto" {
|
|
return nil, nil
|
|
}
|
|
b, err := strconv.ParseBool(s)
|
|
return &b, err
|
|
}
|