github.com/containerd/Containerd@v1.4.13/runtime/v1/linux/process.go (about)

     1  // +build linux
     2  
     3  /*
     4     Copyright The containerd Authors.
     5  
     6     Licensed under the Apache License, Version 2.0 (the "License");
     7     you may not use this file except in compliance with the License.
     8     You may obtain a copy of the License at
     9  
    10         http://www.apache.org/licenses/LICENSE-2.0
    11  
    12     Unless required by applicable law or agreed to in writing, software
    13     distributed under the License is distributed on an "AS IS" BASIS,
    14     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15     See the License for the specific language governing permissions and
    16     limitations under the License.
    17  */
    18  
    19  package linux
    20  
    21  import (
    22  	"context"
    23  
    24  	eventstypes "github.com/containerd/containerd/api/events"
    25  	"github.com/containerd/containerd/api/types/task"
    26  	"github.com/containerd/containerd/errdefs"
    27  	"github.com/containerd/containerd/runtime"
    28  	shim "github.com/containerd/containerd/runtime/v1/shim/v1"
    29  	"github.com/containerd/ttrpc"
    30  	"github.com/pkg/errors"
    31  )
    32  
    33  // Process implements a linux process
    34  type Process struct {
    35  	id string
    36  	t  *Task
    37  }
    38  
    39  // ID of the process
    40  func (p *Process) ID() string {
    41  	return p.id
    42  }
    43  
    44  // Kill sends the provided signal to the underlying process
    45  //
    46  // Unable to kill all processes in the task using this method on a process
    47  func (p *Process) Kill(ctx context.Context, signal uint32, _ bool) error {
    48  	_, err := p.t.shim.Kill(ctx, &shim.KillRequest{
    49  		Signal: signal,
    50  		ID:     p.id,
    51  	})
    52  	if err != nil {
    53  		return errdefs.FromGRPC(err)
    54  	}
    55  	return err
    56  }
    57  
    58  // State of process
    59  func (p *Process) State(ctx context.Context) (runtime.State, error) {
    60  	// use the container status for the status of the process
    61  	response, err := p.t.shim.State(ctx, &shim.StateRequest{
    62  		ID: p.id,
    63  	})
    64  	if err != nil {
    65  		if !errors.Is(err, ttrpc.ErrClosed) {
    66  			return runtime.State{}, errdefs.FromGRPC(err)
    67  		}
    68  
    69  		// We treat ttrpc.ErrClosed as the shim being closed, but really this
    70  		// likely means that the process no longer exists. We'll have to plumb
    71  		// the connection differently if this causes problems.
    72  		return runtime.State{}, errdefs.ErrNotFound
    73  	}
    74  	var status runtime.Status
    75  	switch response.Status {
    76  	case task.StatusCreated:
    77  		status = runtime.CreatedStatus
    78  	case task.StatusRunning:
    79  		status = runtime.RunningStatus
    80  	case task.StatusStopped:
    81  		status = runtime.StoppedStatus
    82  	case task.StatusPaused:
    83  		status = runtime.PausedStatus
    84  	case task.StatusPausing:
    85  		status = runtime.PausingStatus
    86  	}
    87  	return runtime.State{
    88  		Pid:        response.Pid,
    89  		Status:     status,
    90  		Stdin:      response.Stdin,
    91  		Stdout:     response.Stdout,
    92  		Stderr:     response.Stderr,
    93  		Terminal:   response.Terminal,
    94  		ExitStatus: response.ExitStatus,
    95  	}, nil
    96  }
    97  
    98  // ResizePty changes the side of the process's PTY to the provided width and height
    99  func (p *Process) ResizePty(ctx context.Context, size runtime.ConsoleSize) error {
   100  	_, err := p.t.shim.ResizePty(ctx, &shim.ResizePtyRequest{
   101  		ID:     p.id,
   102  		Width:  size.Width,
   103  		Height: size.Height,
   104  	})
   105  	if err != nil {
   106  		err = errdefs.FromGRPC(err)
   107  	}
   108  	return err
   109  }
   110  
   111  // CloseIO closes the provided IO pipe for the process
   112  func (p *Process) CloseIO(ctx context.Context) error {
   113  	_, err := p.t.shim.CloseIO(ctx, &shim.CloseIORequest{
   114  		ID:    p.id,
   115  		Stdin: true,
   116  	})
   117  	if err != nil {
   118  		return errdefs.FromGRPC(err)
   119  	}
   120  	return nil
   121  }
   122  
   123  // Start the process
   124  func (p *Process) Start(ctx context.Context) error {
   125  	r, err := p.t.shim.Start(ctx, &shim.StartRequest{
   126  		ID: p.id,
   127  	})
   128  	if err != nil {
   129  		return errdefs.FromGRPC(err)
   130  	}
   131  	p.t.events.Publish(ctx, runtime.TaskExecStartedEventTopic, &eventstypes.TaskExecStarted{
   132  		ContainerID: p.t.id,
   133  		Pid:         r.Pid,
   134  		ExecID:      p.id,
   135  	})
   136  	return nil
   137  }
   138  
   139  // Wait on the process to exit and return the exit status and timestamp
   140  func (p *Process) Wait(ctx context.Context) (*runtime.Exit, error) {
   141  	r, err := p.t.shim.Wait(ctx, &shim.WaitRequest{
   142  		ID: p.id,
   143  	})
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  	return &runtime.Exit{
   148  		Timestamp: r.ExitedAt,
   149  		Status:    r.ExitStatus,
   150  	}, nil
   151  }
   152  
   153  // Delete the process and return the exit status
   154  func (p *Process) Delete(ctx context.Context) (*runtime.Exit, error) {
   155  	r, err := p.t.shim.DeleteProcess(ctx, &shim.DeleteProcessRequest{
   156  		ID: p.id,
   157  	})
   158  	if err != nil {
   159  		return nil, errdefs.FromGRPC(err)
   160  	}
   161  	return &runtime.Exit{
   162  		Status:    r.ExitStatus,
   163  		Timestamp: r.ExitedAt,
   164  		Pid:       r.Pid,
   165  	}, nil
   166  }