Improve error handling in runc

The error handling on the runc cli is currenly pretty messy because
messages to the user are split between regular stderr format and logrus
message format.  This changes all the error reporting to the cli to only
output on stderr and exit(1) for consumers of the api.

By default logrus logs to /dev/null so that it is not seen by the user.
If the user wants extra and/or structured loggging/errors from runc they
can use the `--log` flag to provide a path to the file where they want
this information.  This allows a consistent behavior on the cli but
extra power and information when debugging with logs.

This also includes a change to enable the same logging information
inside the container's init by adding an init cli command that can share
the existing flags for all other runc commands.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby
2016-03-08 18:05:50 -08:00
parent 4155b68a24
commit 044e298507
8 changed files with 47 additions and 30 deletions

View File

@@ -152,15 +152,31 @@ func containerPreload(context *cli.Context) error {
// loadFactory returns the configured factory instance for execing containers.
func loadFactory(context *cli.Context) (libcontainer.Factory, error) {
root := context.GlobalString("root")
var (
debug = "false"
root = context.GlobalString("root")
)
if context.GlobalBool("debug") {
debug = "true"
}
abs, err := filepath.Abs(root)
if err != nil {
return nil, err
}
logAbs, err := filepath.Abs(context.GlobalString("log"))
if err != nil {
return nil, err
}
return libcontainer.New(abs, libcontainer.Cgroupfs, func(l *libcontainer.LinuxFactory) error {
l.CriuPath = context.GlobalString("criu")
return nil
})
},
libcontainer.InitArgs(os.Args[0],
"--log", logAbs,
"--log-format", context.GlobalString("log-format"),
fmt.Sprintf("--debug=%s", debug),
"init"),
)
}
// getContainer returns the specified container instance by loading it from state
@@ -180,6 +196,8 @@ func getContainer(context *cli.Context) (libcontainer.Container, error) {
// 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)
// return proper unix error codes
if exerr, ok := err.(*exec.Error); ok {
switch exerr.Err {
@@ -196,14 +214,14 @@ func fatal(err error) {
}
}
}
if lerr, ok := err.(libcontainer.Error); ok {
lerr.Detail(os.Stderr)
os.Exit(1)
}
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
func fatalf(t string, v ...interface{}) {
fatal(fmt.Errorf(t, v...))
}
func getDefaultImagePath(context *cli.Context) string {
cwd, err := os.Getwd()
if err != nil {