linux: Bubble up runc error message
Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
This commit is contained in:
parent
33598cc5d3
commit
5922cfaba8
@ -86,7 +86,7 @@ func newExecProcess(context context.Context, path string, r *shimapi.ExecRequest
|
|||||||
spec.Terminal = r.Terminal
|
spec.Terminal = r.Terminal
|
||||||
|
|
||||||
if err := parent.runc.Exec(context, parent.id, spec, opts); err != nil {
|
if err := parent.runc.Exec(context, parent.id, spec, opts); err != nil {
|
||||||
return nil, err
|
return nil, parent.runcError(err, "runc exec failed")
|
||||||
}
|
}
|
||||||
if r.Stdin != "" {
|
if r.Stdin != "" {
|
||||||
sc, err := fifo.OpenFifo(context, r.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
|
sc, err := fifo.OpenFifo(context, r.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0)
|
||||||
|
@ -4,6 +4,7 @@ package shim
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@ -109,7 +110,7 @@ func newInitProcess(context context.Context, path, namespace string, r *shimapi.
|
|||||||
NoSubreaper: true,
|
NoSubreaper: true,
|
||||||
}
|
}
|
||||||
if _, err := p.runc.Restore(context, r.ID, r.Bundle, opts); err != nil {
|
if _, err := p.runc.Restore(context, r.ID, r.Bundle, opts); err != nil {
|
||||||
return nil, err
|
return nil, p.runcError(err, "runc restore failed")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
opts := &runc.CreateOpts{
|
opts := &runc.CreateOpts{
|
||||||
@ -121,7 +122,7 @@ func newInitProcess(context context.Context, path, namespace string, r *shimapi.
|
|||||||
opts.ConsoleSocket = socket
|
opts.ConsoleSocket = socket
|
||||||
}
|
}
|
||||||
if err := p.runc.Create(context, r.ID, r.Bundle, opts); err != nil {
|
if err := p.runc.Create(context, r.ID, r.Bundle, opts); err != nil {
|
||||||
return nil, err
|
return nil, p.runcError(err, "runc create failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if r.Stdin != "" {
|
if r.Stdin != "" {
|
||||||
@ -173,7 +174,7 @@ func (p *initProcess) ExitedAt() time.Time {
|
|||||||
func (p *initProcess) ContainerStatus(ctx context.Context) (string, error) {
|
func (p *initProcess) ContainerStatus(ctx context.Context) (string, error) {
|
||||||
c, err := p.runc.State(ctx, p.id)
|
c, err := p.runc.State(ctx, p.id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", p.runcError(err, "runc state failed")
|
||||||
}
|
}
|
||||||
return c.Status, nil
|
return c.Status, nil
|
||||||
}
|
}
|
||||||
@ -181,7 +182,8 @@ func (p *initProcess) ContainerStatus(ctx context.Context) (string, error) {
|
|||||||
func (p *initProcess) Start(context context.Context) error {
|
func (p *initProcess) Start(context context.Context) error {
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
defer p.mu.Unlock()
|
defer p.mu.Unlock()
|
||||||
return p.runc.Start(context, p.id)
|
err := p.runc.Start(context, p.id)
|
||||||
|
return p.runcError(err, "runc start failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *initProcess) Exited(status int) {
|
func (p *initProcess) Exited(status int) {
|
||||||
@ -208,7 +210,7 @@ func (p *initProcess) Delete(context context.Context) error {
|
|||||||
}
|
}
|
||||||
p.io.Close()
|
p.io.Close()
|
||||||
}
|
}
|
||||||
return err
|
return p.runcError(err, "runc delete failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *initProcess) Resize(ws console.WinSize) error {
|
func (p *initProcess) Resize(ws console.WinSize) error {
|
||||||
@ -219,23 +221,27 @@ func (p *initProcess) Resize(ws console.WinSize) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *initProcess) Pause(context context.Context) error {
|
func (p *initProcess) Pause(context context.Context) error {
|
||||||
return p.runc.Pause(context, p.id)
|
err := p.runc.Pause(context, p.id)
|
||||||
|
return p.runcError(err, "runc pause failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *initProcess) Resume(context context.Context) error {
|
func (p *initProcess) Resume(context context.Context) error {
|
||||||
return p.runc.Resume(context, p.id)
|
err := p.runc.Resume(context, p.id)
|
||||||
|
return p.runcError(err, "runc resume failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *initProcess) Kill(context context.Context, signal uint32, all bool) error {
|
func (p *initProcess) Kill(context context.Context, signal uint32, all bool) error {
|
||||||
return p.runc.Kill(context, p.id, int(signal), &runc.KillOpts{
|
err := p.runc.Kill(context, p.id, int(signal), &runc.KillOpts{
|
||||||
All: all,
|
All: all,
|
||||||
})
|
})
|
||||||
|
return p.runcError(err, "runc kill failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *initProcess) killAll(context context.Context) error {
|
func (p *initProcess) killAll(context context.Context) error {
|
||||||
return p.runc.Kill(context, p.id, int(syscall.SIGKILL), &runc.KillOpts{
|
err := p.runc.Kill(context, p.id, int(syscall.SIGKILL), &runc.KillOpts{
|
||||||
All: true,
|
All: true,
|
||||||
})
|
})
|
||||||
|
return p.runcError(err, "runc killall failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *initProcess) Signal(sig int) error {
|
func (p *initProcess) Signal(sig int) error {
|
||||||
@ -271,6 +277,55 @@ func (p *initProcess) Checkpoint(context context.Context, r *shimapi.CheckpointR
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(mlaventure): move to runc package?
|
||||||
|
func getLastRuncError(r *runc.Runc) (string, error) {
|
||||||
|
if r.Log == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.OpenFile(r.Log, os.O_RDONLY, 0400)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
errMsg string
|
||||||
|
log struct {
|
||||||
|
Level string
|
||||||
|
Msg string
|
||||||
|
Time time.Time
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
dec := json.NewDecoder(f)
|
||||||
|
for err = nil; err == nil; {
|
||||||
|
if err = dec.Decode(&log); err != nil && err != io.EOF {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if log.Level == "error" {
|
||||||
|
errMsg = strings.TrimSpace(log.Msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errMsg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *initProcess) runcError(rErr error, msg string) error {
|
||||||
|
if rErr == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rMsg, err := getLastRuncError(p.runc)
|
||||||
|
switch {
|
||||||
|
case err != nil:
|
||||||
|
return errors.Wrapf(err, "%s: %s (%s)", msg, "unable to retrieve runc error", err.Error())
|
||||||
|
case rMsg == "":
|
||||||
|
return errors.Wrap(err, msg)
|
||||||
|
default:
|
||||||
|
return errors.Errorf("%s: %s", msg, rMsg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// criuError returns only the first line of the error message from criu
|
// criuError returns only the first line of the error message from criu
|
||||||
// it tries to add an invalid dump log location when returning the message
|
// it tries to add an invalid dump log location when returning the message
|
||||||
func criuError(err error) string {
|
func criuError(err error) string {
|
||||||
|
Loading…
Reference in New Issue
Block a user