github.com/lalkh/containerd@v1.4.3/pkg/process/exec_state.go (about)

     1  // +build !windows
     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 process
    20  
    21  import (
    22  	"context"
    23  
    24  	"github.com/containerd/console"
    25  	"github.com/pkg/errors"
    26  )
    27  
    28  type execState interface {
    29  	Resize(console.WinSize) error
    30  	Start(context.Context) error
    31  	Delete(context.Context) error
    32  	Kill(context.Context, uint32, bool) error
    33  	SetExited(int)
    34  	Status(context.Context) (string, error)
    35  }
    36  
    37  type execCreatedState struct {
    38  	p *execProcess
    39  }
    40  
    41  func (s *execCreatedState) transition(name string) error {
    42  	switch name {
    43  	case "running":
    44  		s.p.execState = &execRunningState{p: s.p}
    45  	case "stopped":
    46  		s.p.execState = &execStoppedState{p: s.p}
    47  	case "deleted":
    48  		s.p.execState = &deletedState{}
    49  	default:
    50  		return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
    51  	}
    52  	return nil
    53  }
    54  
    55  func (s *execCreatedState) Resize(ws console.WinSize) error {
    56  	return s.p.resize(ws)
    57  }
    58  
    59  func (s *execCreatedState) Start(ctx context.Context) error {
    60  	if err := s.p.start(ctx); err != nil {
    61  		return err
    62  	}
    63  	return s.transition("running")
    64  }
    65  
    66  func (s *execCreatedState) Delete(ctx context.Context) error {
    67  	if err := s.p.delete(ctx); err != nil {
    68  		return err
    69  	}
    70  
    71  	return s.transition("deleted")
    72  }
    73  
    74  func (s *execCreatedState) Kill(ctx context.Context, sig uint32, all bool) error {
    75  	return s.p.kill(ctx, sig, all)
    76  }
    77  
    78  func (s *execCreatedState) SetExited(status int) {
    79  	s.p.setExited(status)
    80  
    81  	if err := s.transition("stopped"); err != nil {
    82  		panic(err)
    83  	}
    84  }
    85  
    86  func (s *execCreatedState) Status(ctx context.Context) (string, error) {
    87  	return "created", nil
    88  }
    89  
    90  type execRunningState struct {
    91  	p *execProcess
    92  }
    93  
    94  func (s *execRunningState) transition(name string) error {
    95  	switch name {
    96  	case "stopped":
    97  		s.p.execState = &execStoppedState{p: s.p}
    98  	default:
    99  		return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
   100  	}
   101  	return nil
   102  }
   103  
   104  func (s *execRunningState) Resize(ws console.WinSize) error {
   105  	return s.p.resize(ws)
   106  }
   107  
   108  func (s *execRunningState) Start(ctx context.Context) error {
   109  	return errors.Errorf("cannot start a running process")
   110  }
   111  
   112  func (s *execRunningState) Delete(ctx context.Context) error {
   113  	return errors.Errorf("cannot delete a running process")
   114  }
   115  
   116  func (s *execRunningState) Kill(ctx context.Context, sig uint32, all bool) error {
   117  	return s.p.kill(ctx, sig, all)
   118  }
   119  
   120  func (s *execRunningState) SetExited(status int) {
   121  	s.p.setExited(status)
   122  
   123  	if err := s.transition("stopped"); err != nil {
   124  		panic(err)
   125  	}
   126  }
   127  
   128  func (s *execRunningState) Status(ctx context.Context) (string, error) {
   129  	return "running", nil
   130  }
   131  
   132  type execStoppedState struct {
   133  	p *execProcess
   134  }
   135  
   136  func (s *execStoppedState) transition(name string) error {
   137  	switch name {
   138  	case "deleted":
   139  		s.p.execState = &deletedState{}
   140  	default:
   141  		return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
   142  	}
   143  	return nil
   144  }
   145  
   146  func (s *execStoppedState) Resize(ws console.WinSize) error {
   147  	return errors.Errorf("cannot resize a stopped container")
   148  }
   149  
   150  func (s *execStoppedState) Start(ctx context.Context) error {
   151  	return errors.Errorf("cannot start a stopped process")
   152  }
   153  
   154  func (s *execStoppedState) Delete(ctx context.Context) error {
   155  	if err := s.p.delete(ctx); err != nil {
   156  		return err
   157  	}
   158  
   159  	return s.transition("deleted")
   160  }
   161  
   162  func (s *execStoppedState) Kill(ctx context.Context, sig uint32, all bool) error {
   163  	return s.p.kill(ctx, sig, all)
   164  }
   165  
   166  func (s *execStoppedState) SetExited(status int) {
   167  	// no op
   168  }
   169  
   170  func (s *execStoppedState) Status(ctx context.Context) (string, error) {
   171  	return "stopped", nil
   172  }