github.com/rumpl/bof@v23.0.0-rc.2+incompatible/daemon/exec/exec.go (about)

     1  package exec // import "github.com/docker/docker/daemon/exec"
     2  
     3  import (
     4  	"context"
     5  	"runtime"
     6  	"sync"
     7  
     8  	"github.com/containerd/containerd/cio"
     9  	"github.com/docker/docker/container/stream"
    10  	"github.com/docker/docker/pkg/stringid"
    11  	"github.com/sirupsen/logrus"
    12  )
    13  
    14  // Config holds the configurations for execs. The Daemon keeps
    15  // track of both running and finished execs so that they can be
    16  // examined both during and after completion.
    17  type Config struct {
    18  	sync.Mutex
    19  	Started      chan struct{}
    20  	StreamConfig *stream.Config
    21  	ID           string
    22  	Running      bool
    23  	ExitCode     *int
    24  	OpenStdin    bool
    25  	OpenStderr   bool
    26  	OpenStdout   bool
    27  	CanRemove    bool
    28  	ContainerID  string
    29  	DetachKeys   []byte
    30  	Entrypoint   string
    31  	Args         []string
    32  	Tty          bool
    33  	Privileged   bool
    34  	User         string
    35  	WorkingDir   string
    36  	Env          []string
    37  	Pid          int
    38  	ConsoleSize  *[2]uint
    39  }
    40  
    41  // NewConfig initializes the a new exec configuration
    42  func NewConfig() *Config {
    43  	return &Config{
    44  		ID:           stringid.GenerateRandomID(),
    45  		StreamConfig: stream.NewConfig(),
    46  		Started:      make(chan struct{}),
    47  	}
    48  }
    49  
    50  type rio struct {
    51  	cio.IO
    52  
    53  	sc *stream.Config
    54  }
    55  
    56  func (i *rio) Close() error {
    57  	i.IO.Close()
    58  
    59  	return i.sc.CloseStreams()
    60  }
    61  
    62  func (i *rio) Wait() {
    63  	i.sc.Wait(context.Background())
    64  
    65  	i.IO.Wait()
    66  }
    67  
    68  // InitializeStdio is called by libcontainerd to connect the stdio.
    69  func (c *Config) InitializeStdio(iop *cio.DirectIO) (cio.IO, error) {
    70  	c.StreamConfig.CopyToPipe(iop)
    71  
    72  	if c.StreamConfig.Stdin() == nil && !c.Tty && runtime.GOOS == "windows" {
    73  		if iop.Stdin != nil {
    74  			if err := iop.Stdin.Close(); err != nil {
    75  				logrus.Errorf("error closing exec stdin: %+v", err)
    76  			}
    77  		}
    78  	}
    79  
    80  	return &rio{IO: iop, sc: c.StreamConfig}, nil
    81  }
    82  
    83  // CloseStreams closes the stdio streams for the exec
    84  func (c *Config) CloseStreams() error {
    85  	return c.StreamConfig.CloseStreams()
    86  }
    87  
    88  // SetExitCode sets the exec config's exit code
    89  func (c *Config) SetExitCode(code int) {
    90  	c.ExitCode = &code
    91  }
    92  
    93  // Store keeps track of the exec configurations.
    94  type Store struct {
    95  	byID map[string]*Config
    96  	sync.RWMutex
    97  }
    98  
    99  // NewStore initializes a new exec store.
   100  func NewStore() *Store {
   101  	return &Store{
   102  		byID: make(map[string]*Config),
   103  	}
   104  }
   105  
   106  // Commands returns the exec configurations in the store.
   107  func (e *Store) Commands() map[string]*Config {
   108  	e.RLock()
   109  	byID := make(map[string]*Config, len(e.byID))
   110  	for id, config := range e.byID {
   111  		byID[id] = config
   112  	}
   113  	e.RUnlock()
   114  	return byID
   115  }
   116  
   117  // Add adds a new exec configuration to the store.
   118  func (e *Store) Add(id string, Config *Config) {
   119  	e.Lock()
   120  	e.byID[id] = Config
   121  	e.Unlock()
   122  }
   123  
   124  // Get returns an exec configuration by its id.
   125  func (e *Store) Get(id string) *Config {
   126  	e.RLock()
   127  	res := e.byID[id]
   128  	e.RUnlock()
   129  	return res
   130  }
   131  
   132  // Delete removes an exec configuration from the store.
   133  func (e *Store) Delete(id string, pid int) {
   134  	e.Lock()
   135  	delete(e.byID, id)
   136  	e.Unlock()
   137  }
   138  
   139  // List returns the list of exec ids in the store.
   140  func (e *Store) List() []string {
   141  	var IDs []string
   142  	e.RLock()
   143  	for id := range e.byID {
   144  		IDs = append(IDs, id)
   145  	}
   146  	e.RUnlock()
   147  	return IDs
   148  }