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 }