linux, linux/shim: remove error definitions
Since we now have a common set of error definitions, mapped to existing error codes, we no longer need the specialized error codes used for interaction with linux processes. The main issue was that string matching was being used to map these to useful error codes. With this change, we use errors defined in the `errdefs` package, which map cleanly to GRPC error codes and are recoverable on either side of the request. The main focus of this PR was in removin these from the shim. We may need follow ups to ensure error codes are preserved by the `Tasks` service. Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
@@ -4,12 +4,11 @@ package linux
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/containerd/containerd/api/types/task"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
shim "github.com/containerd/containerd/linux/shim/v1"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type Process struct {
|
||||
@@ -27,7 +26,7 @@ func (p *Process) Kill(ctx context.Context, signal uint32, _ bool) error {
|
||||
ID: p.id,
|
||||
})
|
||||
if err != nil {
|
||||
err = errors.New(grpc.ErrorDesc(err))
|
||||
return errdefs.FromGRPC(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -38,7 +37,7 @@ func (p *Process) State(ctx context.Context) (runtime.State, error) {
|
||||
ID: p.id,
|
||||
})
|
||||
if err != nil {
|
||||
return runtime.State{}, errors.New(grpc.ErrorDesc(err))
|
||||
return runtime.State{}, errdefs.FromGRPC(err)
|
||||
}
|
||||
var status runtime.Status
|
||||
switch response.Status {
|
||||
@@ -69,7 +68,7 @@ func (p *Process) ResizePty(ctx context.Context, size runtime.ConsoleSize) error
|
||||
Height: size.Height,
|
||||
})
|
||||
if err != nil {
|
||||
err = errors.New(grpc.ErrorDesc(err))
|
||||
err = errdefs.FromGRPC(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -80,7 +79,7 @@ func (p *Process) CloseIO(ctx context.Context) error {
|
||||
Stdin: true,
|
||||
})
|
||||
if err != nil {
|
||||
err = errors.New(grpc.ErrorDesc(err))
|
||||
err = errdefs.FromGRPC(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -9,10 +9,9 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
"github.com/containerd/containerd/api/types"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/identifiers"
|
||||
client "github.com/containerd/containerd/linux/shim"
|
||||
shim "github.com/containerd/containerd/linux/shim/v1"
|
||||
@@ -170,7 +169,7 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts
|
||||
})
|
||||
}
|
||||
if _, err = s.Create(ctx, sopts); err != nil {
|
||||
return nil, errors.New(grpc.ErrorDesc(err))
|
||||
return nil, errdefs.FromGRPC(err)
|
||||
}
|
||||
t := newTask(id, namespace, s)
|
||||
if err := r.tasks.Add(ctx, t); err != nil {
|
||||
@@ -197,7 +196,7 @@ func (r *Runtime) Delete(ctx context.Context, c runtime.Task) (*runtime.Exit, er
|
||||
}
|
||||
rsp, err := lc.shim.Delete(ctx, empty)
|
||||
if err != nil {
|
||||
return nil, errors.New(grpc.ErrorDesc(err))
|
||||
return nil, errdefs.FromGRPC(err)
|
||||
}
|
||||
if err := lc.shim.KillShim(ctx); err != nil {
|
||||
log.G(ctx).WithError(err).Error("failed to kill shim")
|
||||
|
||||
@@ -164,7 +164,7 @@ func (e *execProcess) Resize(ws console.WinSize) error {
|
||||
|
||||
func (e *execProcess) Kill(ctx context.Context, sig uint32, _ bool) error {
|
||||
if err := unix.Kill(e.pid, syscall.Signal(sig)); err != nil {
|
||||
return checkKillError(err)
|
||||
return errors.Wrapf(checkKillError(err), "exec kill error")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -17,12 +17,12 @@ import (
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/containerd/console"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/identifiers"
|
||||
"github.com/containerd/containerd/linux/runcopts"
|
||||
shimapi "github.com/containerd/containerd/linux/shim/v1"
|
||||
"github.com/containerd/containerd/log"
|
||||
"github.com/containerd/containerd/mount"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
"github.com/containerd/containerd/typeurl"
|
||||
"github.com/containerd/fifo"
|
||||
runc "github.com/containerd/go-runc"
|
||||
@@ -388,7 +388,7 @@ func checkKillError(err error) error {
|
||||
return nil
|
||||
}
|
||||
if strings.Contains(err.Error(), "os: process already finished") || err == unix.ESRCH {
|
||||
return runtime.ErrProcessExited
|
||||
return errors.Wrapf(errdefs.ErrNotFound, "process already finished")
|
||||
}
|
||||
return err
|
||||
return errors.Wrapf(err, "unknown error after kill")
|
||||
}
|
||||
|
||||
@@ -26,10 +26,6 @@ import (
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
const (
|
||||
ErrContainerNotCreated = "container hasn't been created yet"
|
||||
)
|
||||
|
||||
var empty = &google_protobuf.Empty{}
|
||||
|
||||
const RuncRoot = "/run/containerd/runc"
|
||||
@@ -115,7 +111,7 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (*sh
|
||||
|
||||
func (s *Service) Start(ctx context.Context, r *google_protobuf.Empty) (*google_protobuf.Empty, error) {
|
||||
if s.initProcess == nil {
|
||||
return nil, errors.New(ErrContainerNotCreated)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
||||
}
|
||||
if err := s.initProcess.Start(ctx); err != nil {
|
||||
return nil, err
|
||||
@@ -129,7 +125,7 @@ func (s *Service) Start(ctx context.Context, r *google_protobuf.Empty) (*google_
|
||||
|
||||
func (s *Service) Delete(ctx context.Context, r *google_protobuf.Empty) (*shimapi.DeleteResponse, error) {
|
||||
if s.initProcess == nil {
|
||||
return nil, errors.New(ErrContainerNotCreated)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
||||
}
|
||||
p := s.initProcess
|
||||
// TODO (@crosbymichael): how to handle errors here
|
||||
@@ -152,7 +148,7 @@ func (s *Service) Delete(ctx context.Context, r *google_protobuf.Empty) (*shimap
|
||||
|
||||
func (s *Service) DeleteProcess(ctx context.Context, r *shimapi.DeleteProcessRequest) (*shimapi.DeleteResponse, error) {
|
||||
if s.initProcess == nil {
|
||||
return nil, errors.New(ErrContainerNotCreated)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
||||
}
|
||||
if r.ID == s.initProcess.id {
|
||||
return nil, grpc.Errorf(codes.InvalidArgument, "cannot delete init process with DeleteProcess")
|
||||
@@ -161,7 +157,7 @@ func (s *Service) DeleteProcess(ctx context.Context, r *shimapi.DeleteProcessReq
|
||||
p, ok := s.processes[r.ID]
|
||||
s.mu.Unlock()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("process %s not found", r.ID)
|
||||
return nil, errors.Wrapf(errdefs.ErrNotFound, "process %s not found", r.ID)
|
||||
}
|
||||
// TODO (@crosbymichael): how to handle errors here
|
||||
p.Delete(ctx)
|
||||
@@ -177,14 +173,14 @@ func (s *Service) DeleteProcess(ctx context.Context, r *shimapi.DeleteProcessReq
|
||||
|
||||
func (s *Service) Exec(ctx context.Context, r *shimapi.ExecProcessRequest) (*shimapi.ExecProcessResponse, error) {
|
||||
if s.initProcess == nil {
|
||||
return nil, errors.New(ErrContainerNotCreated)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
||||
}
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
process, err := newExecProcess(ctx, s.path, r, s.initProcess, r.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errdefs.ToGRPC(err)
|
||||
}
|
||||
pid := process.Pid()
|
||||
cmd := &reaper.Cmd{
|
||||
@@ -206,7 +202,7 @@ func (s *Service) Exec(ctx context.Context, r *shimapi.ExecProcessRequest) (*shi
|
||||
|
||||
func (s *Service) ResizePty(ctx context.Context, r *shimapi.ResizePtyRequest) (*google_protobuf.Empty, error) {
|
||||
if r.ID == "" {
|
||||
return nil, grpc.Errorf(codes.InvalidArgument, "id not provided")
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "id not provided")
|
||||
}
|
||||
ws := console.WinSize{
|
||||
Width: uint16(r.Width),
|
||||
@@ -219,18 +215,18 @@ func (s *Service) ResizePty(ctx context.Context, r *shimapi.ResizePtyRequest) (*
|
||||
return nil, errors.Errorf("process does not exist %s", r.ID)
|
||||
}
|
||||
if err := p.Resize(ws); err != nil {
|
||||
return nil, err
|
||||
return nil, errdefs.ToGRPC(err)
|
||||
}
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
func (s *Service) State(ctx context.Context, r *shimapi.StateRequest) (*shimapi.StateResponse, error) {
|
||||
if s.initProcess == nil {
|
||||
return nil, errors.New(ErrContainerNotCreated)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
||||
}
|
||||
p, ok := s.processes[r.ID]
|
||||
if !ok {
|
||||
return nil, grpc.Errorf(codes.NotFound, "process id %s not found", r.ID)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process id %s not found", r.ID)
|
||||
}
|
||||
st, err := s.initProcess.ContainerStatus(ctx)
|
||||
if err != nil {
|
||||
@@ -262,7 +258,7 @@ func (s *Service) State(ctx context.Context, r *shimapi.StateRequest) (*shimapi.
|
||||
|
||||
func (s *Service) Pause(ctx context.Context, r *google_protobuf.Empty) (*google_protobuf.Empty, error) {
|
||||
if s.initProcess == nil {
|
||||
return nil, errors.New(ErrContainerNotCreated)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
||||
}
|
||||
if err := s.initProcess.Pause(ctx); err != nil {
|
||||
return nil, err
|
||||
@@ -275,7 +271,7 @@ func (s *Service) Pause(ctx context.Context, r *google_protobuf.Empty) (*google_
|
||||
|
||||
func (s *Service) Resume(ctx context.Context, r *google_protobuf.Empty) (*google_protobuf.Empty, error) {
|
||||
if s.initProcess == nil {
|
||||
return nil, errors.New(ErrContainerNotCreated)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
||||
}
|
||||
if err := s.initProcess.Resume(ctx); err != nil {
|
||||
return nil, err
|
||||
@@ -288,20 +284,20 @@ func (s *Service) Resume(ctx context.Context, r *google_protobuf.Empty) (*google
|
||||
|
||||
func (s *Service) Kill(ctx context.Context, r *shimapi.KillRequest) (*google_protobuf.Empty, error) {
|
||||
if s.initProcess == nil {
|
||||
return nil, errors.New(ErrContainerNotCreated)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
||||
}
|
||||
if r.ID == "" {
|
||||
if err := s.initProcess.Kill(ctx, r.Signal, r.All); err != nil {
|
||||
return nil, err
|
||||
return nil, errdefs.ToGRPC(err)
|
||||
}
|
||||
return empty, nil
|
||||
}
|
||||
p, ok := s.processes[r.ID]
|
||||
if !ok {
|
||||
return nil, grpc.Errorf(codes.NotFound, "process id %s not found", r.ID)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process id %s not found", r.ID)
|
||||
}
|
||||
if err := p.Kill(ctx, r.Signal, r.All); err != nil {
|
||||
return nil, err
|
||||
return nil, errdefs.ToGRPC(err)
|
||||
}
|
||||
return empty, nil
|
||||
}
|
||||
@@ -309,7 +305,7 @@ func (s *Service) Kill(ctx context.Context, r *shimapi.KillRequest) (*google_pro
|
||||
func (s *Service) ListPids(ctx context.Context, r *shimapi.ListPidsRequest) (*shimapi.ListPidsResponse, error) {
|
||||
pids, err := s.getContainerPids(ctx, r.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errdefs.ToGRPC(err)
|
||||
}
|
||||
return &shimapi.ListPidsResponse{
|
||||
Pids: pids,
|
||||
@@ -319,7 +315,7 @@ func (s *Service) ListPids(ctx context.Context, r *shimapi.ListPidsRequest) (*sh
|
||||
func (s *Service) CloseIO(ctx context.Context, r *shimapi.CloseIORequest) (*google_protobuf.Empty, error) {
|
||||
p, ok := s.processes[r.ID]
|
||||
if !ok {
|
||||
return nil, grpc.Errorf(codes.NotFound, "process does not exist %s", r.ID)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process does not exist %s", r.ID)
|
||||
}
|
||||
if err := p.Stdin().Close(); err != nil {
|
||||
return nil, err
|
||||
@@ -329,10 +325,10 @@ func (s *Service) CloseIO(ctx context.Context, r *shimapi.CloseIORequest) (*goog
|
||||
|
||||
func (s *Service) Checkpoint(ctx context.Context, r *shimapi.CheckpointTaskRequest) (*google_protobuf.Empty, error) {
|
||||
if s.initProcess == nil {
|
||||
return nil, errors.New(ErrContainerNotCreated)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
||||
}
|
||||
if err := s.initProcess.Checkpoint(ctx, r); err != nil {
|
||||
return nil, err
|
||||
return nil, errdefs.ToGRPC(err)
|
||||
}
|
||||
s.events <- &events.TaskCheckpointed{
|
||||
ContainerID: s.id,
|
||||
@@ -348,10 +344,10 @@ func (s *Service) ShimInfo(ctx context.Context, r *google_protobuf.Empty) (*shim
|
||||
|
||||
func (s *Service) Update(ctx context.Context, r *shimapi.UpdateTaskRequest) (*google_protobuf.Empty, error) {
|
||||
if s.initProcess == nil {
|
||||
return nil, errors.New(ErrContainerNotCreated)
|
||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
||||
}
|
||||
if err := s.initProcess.Update(ctx, r); err != nil {
|
||||
return nil, err
|
||||
return nil, errdefs.ToGRPC(err)
|
||||
}
|
||||
return empty, nil
|
||||
}
|
||||
|
||||
@@ -5,14 +5,12 @@ package linux
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/containerd/containerd/api/types/task"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
client "github.com/containerd/containerd/linux/shim"
|
||||
shim "github.com/containerd/containerd/linux/shim/v1"
|
||||
"github.com/containerd/containerd/runtime"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Task struct {
|
||||
@@ -44,7 +42,7 @@ func (t *Task) Info() runtime.TaskInfo {
|
||||
func (t *Task) Start(ctx context.Context) error {
|
||||
_, err := t.shim.Start(ctx, empty)
|
||||
if err != nil {
|
||||
err = errors.New(grpc.ErrorDesc(err))
|
||||
err = errdefs.FromGRPC(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -54,7 +52,7 @@ func (t *Task) State(ctx context.Context) (runtime.State, error) {
|
||||
ID: t.id,
|
||||
})
|
||||
if err != nil {
|
||||
return runtime.State{}, errors.New(grpc.ErrorDesc(err))
|
||||
return runtime.State{}, errdefs.FromGRPC(err)
|
||||
}
|
||||
var status runtime.Status
|
||||
switch response.Status {
|
||||
@@ -81,7 +79,7 @@ func (t *Task) State(ctx context.Context) (runtime.State, error) {
|
||||
func (t *Task) Pause(ctx context.Context) error {
|
||||
_, err := t.shim.Pause(ctx, empty)
|
||||
if err != nil {
|
||||
err = errors.New(grpc.ErrorDesc(err))
|
||||
err = errdefs.FromGRPC(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -89,7 +87,7 @@ func (t *Task) Pause(ctx context.Context) error {
|
||||
func (t *Task) Resume(ctx context.Context) error {
|
||||
_, err := t.shim.Resume(ctx, empty)
|
||||
if err != nil {
|
||||
err = errors.New(grpc.ErrorDesc(err))
|
||||
err = errdefs.FromGRPC(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -101,7 +99,7 @@ func (t *Task) Kill(ctx context.Context, signal uint32, all bool) error {
|
||||
All: all,
|
||||
})
|
||||
if err != nil {
|
||||
err = errors.New(grpc.ErrorDesc(err))
|
||||
return errdefs.FromGRPC(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -116,7 +114,7 @@ func (t *Task) Exec(ctx context.Context, id string, opts runtime.ExecOpts) (runt
|
||||
Spec: opts.Spec,
|
||||
}
|
||||
if _, err := t.shim.Exec(ctx, request); err != nil {
|
||||
return nil, errors.New(grpc.ErrorDesc(err))
|
||||
return nil, errdefs.FromGRPC(err)
|
||||
}
|
||||
return &Process{
|
||||
id: id,
|
||||
@@ -130,7 +128,7 @@ func (t *Task) Pids(ctx context.Context) ([]uint32, error) {
|
||||
ID: t.id,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.New(grpc.ErrorDesc(err))
|
||||
return nil, errdefs.FromGRPC(err)
|
||||
}
|
||||
return resp.Pids, nil
|
||||
}
|
||||
@@ -142,7 +140,7 @@ func (t *Task) ResizePty(ctx context.Context, size runtime.ConsoleSize) error {
|
||||
Height: size.Height,
|
||||
})
|
||||
if err != nil {
|
||||
err = errors.New(grpc.ErrorDesc(err))
|
||||
err = errdefs.FromGRPC(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -153,7 +151,7 @@ func (t *Task) CloseIO(ctx context.Context) error {
|
||||
Stdin: true,
|
||||
})
|
||||
if err != nil {
|
||||
err = errors.New(grpc.ErrorDesc(err))
|
||||
err = errdefs.FromGRPC(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -164,7 +162,7 @@ func (t *Task) Checkpoint(ctx context.Context, path string, options *types.Any)
|
||||
Options: options,
|
||||
}
|
||||
if _, err := t.shim.Checkpoint(ctx, r); err != nil {
|
||||
return errors.New(grpc.ErrorDesc(err))
|
||||
return errdefs.FromGRPC(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -174,7 +172,7 @@ func (t *Task) DeleteProcess(ctx context.Context, id string) (*runtime.Exit, err
|
||||
ID: id,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.New(grpc.ErrorDesc(err))
|
||||
return nil, errdefs.FromGRPC(err)
|
||||
}
|
||||
return &runtime.Exit{
|
||||
Status: r.ExitStatus,
|
||||
|
||||
Reference in New Issue
Block a user