github.com/mgoltzsche/ctnr@v0.7.1-alpha/run/librunner/manager.go (about)

     1  package librunner
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	exterrors "github.com/mgoltzsche/ctnr/pkg/errors"
     9  	"github.com/mgoltzsche/ctnr/pkg/log"
    10  	"github.com/mgoltzsche/ctnr/run"
    11  	"github.com/opencontainers/runc/libcontainer"
    12  	"github.com/pkg/errors"
    13  )
    14  
    15  var _ run.ContainerManager = &ContainerManager{}
    16  
    17  type ContainerManager struct {
    18  	factory  libcontainer.Factory
    19  	runners  map[string]run.Container
    20  	rootDir  string
    21  	rootless bool
    22  	loggers  log.Loggers
    23  }
    24  
    25  func NewContainerManager(rootDir string, rootless bool, loggers log.Loggers) (r *ContainerManager, err error) {
    26  	absRoot, err := filepath.Abs(rootDir)
    27  	if err != nil {
    28  		return
    29  	}
    30  	r = &ContainerManager{runners: map[string]run.Container{}, rootDir: absRoot, rootless: rootless, loggers: loggers}
    31  	binary, err := os.Executable()
    32  	if err != nil {
    33  		return nil, errors.Wrapf(err, "new container manager: resolve %q executable", os.Args[0])
    34  	}
    35  	// TODO: also support systemd cgroup usage: libcontainer.SystemdCgroups
    36  	if r.factory, err = libcontainer.New(rootDir, libcontainer.Cgroupfs, libcontainer.InitArgs(binary, "init")); err != nil {
    37  		return nil, errors.Wrap(err, "new container manager")
    38  	}
    39  	return
    40  }
    41  
    42  func (m *ContainerManager) NewContainer(cfg *run.ContainerConfig) (c run.Container, err error) {
    43  	return NewContainer(cfg, m.rootless, m.factory, m.loggers)
    44  }
    45  
    46  func (m *ContainerManager) Get(id string) (run.Container, error) {
    47  	return LoadContainer(id, m.factory, m.loggers)
    48  }
    49  
    50  func (m *ContainerManager) Exist(id string) (e bool, err error) {
    51  	if _, err = os.Stat(filepath.Join(m.rootDir, id, "state.json")); err != nil {
    52  		if os.IsNotExist(err) {
    53  			return false, nil
    54  		}
    55  	}
    56  	return true, err
    57  }
    58  
    59  func (m *ContainerManager) Kill(id string, signal os.Signal, all bool) (err error) {
    60  	c, err := LoadContainer(id, m.factory, m.loggers)
    61  	if err == nil {
    62  		err = c.container.Signal(signal, all)
    63  	}
    64  	return errors.Wrap(err, "kill")
    65  }
    66  
    67  func (m *ContainerManager) List() (r []run.ContainerInfo, err error) {
    68  	r = []run.ContainerInfo{}
    69  	if _, e := os.Stat(m.rootDir); !os.IsNotExist(e) {
    70  		files, e := ioutil.ReadDir(m.rootDir)
    71  		if e == nil {
    72  			for _, f := range files {
    73  				if _, e = os.Stat(filepath.Join(m.rootDir, f.Name(), "state.json")); !os.IsNotExist(e) {
    74  					r = append(r, run.ContainerInfo{f.Name(), "running"})
    75  				}
    76  			}
    77  		} else {
    78  			err = exterrors.Append(err, errors.New(e.Error()))
    79  		}
    80  	}
    81  	return
    82  }