execution: remove statedir type
Signed-off-by: Kenfe-Mickael Laventure <mickael.laventure@gmail.com>
This commit is contained in:
@@ -1,91 +1,179 @@
|
||||
package execution
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
func NewContainer(stateRoot, id, bundle string) (*Container, error) {
|
||||
stateDir, err := NewStateDir(stateRoot, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Container{
|
||||
"github.com/docker/containerd/log"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
InitProcessID = "init"
|
||||
processesDirName = "processes"
|
||||
bundleFileName = "bundle"
|
||||
)
|
||||
|
||||
func LoadContainer(ctx context.Context, stateDir, id string) (c *Container, err error) {
|
||||
c = &Container{
|
||||
id: id,
|
||||
bundle: bundle,
|
||||
stateDir: stateDir,
|
||||
status: Created,
|
||||
processes: make(map[string]Process),
|
||||
}, nil
|
||||
processes: make(map[string]Process, 1),
|
||||
ctx: ctx,
|
||||
status: Unknown,
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(filepath.Join(stateDir, bundleFileName))
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "failed to read bundle path")
|
||||
return
|
||||
}
|
||||
c.bundle = string(data)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func LoadContainer(dir StateDir, id, bundle string, status Status) *Container {
|
||||
return &Container{
|
||||
func NewContainer(ctx context.Context, stateDir, id, bundle string) (c *Container, err error) {
|
||||
c = &Container{
|
||||
id: id,
|
||||
stateDir: dir,
|
||||
stateDir: stateDir,
|
||||
bundle: bundle,
|
||||
status: status,
|
||||
processes: make(map[string]Process),
|
||||
processes: make(map[string]Process, 1),
|
||||
status: Created,
|
||||
ctx: ctx,
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
c.Cleanup()
|
||||
c = nil
|
||||
}
|
||||
}()
|
||||
|
||||
if err = os.Mkdir(stateDir, 0700); err != nil {
|
||||
err = errors.Wrap(err, "failed to create container state dir")
|
||||
return
|
||||
}
|
||||
|
||||
bundleFile := filepath.Join(stateDir, bundleFileName)
|
||||
if err = ioutil.WriteFile(bundleFile, []byte(bundle), 0600); err != nil {
|
||||
err = errors.Wrap(err, "failed to store bundle path")
|
||||
return
|
||||
}
|
||||
|
||||
processesDir := filepath.Join(stateDir, processesDirName)
|
||||
if err = os.Mkdir(processesDir, 0700); err != nil {
|
||||
err = errors.Wrap(err, "failed to create processes statedir")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type Container struct {
|
||||
id string
|
||||
bundle string
|
||||
stateDir StateDir
|
||||
initPid int64
|
||||
status Status
|
||||
|
||||
id string
|
||||
stateDir string
|
||||
bundle string
|
||||
processes map[string]Process
|
||||
status Status
|
||||
|
||||
ctx context.Context
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func (c *Container) ID() string {
|
||||
return c.id
|
||||
}
|
||||
|
||||
func (c *Container) Status() Status {
|
||||
for _, p := range c.processes {
|
||||
if p.Pid() == c.initPid {
|
||||
c.status = p.Status()
|
||||
break
|
||||
}
|
||||
}
|
||||
return c.status
|
||||
}
|
||||
|
||||
func (c *Container) Bundle() string {
|
||||
return c.bundle
|
||||
}
|
||||
|
||||
func (c *Container) StateDir() StateDir {
|
||||
return c.stateDir
|
||||
}
|
||||
|
||||
func (c *Container) Wait() (uint32, error) {
|
||||
for _, p := range c.processes {
|
||||
if p.Pid() == c.initPid {
|
||||
return p.Wait()
|
||||
}
|
||||
}
|
||||
return 0, fmt.Errorf("no init process")
|
||||
initProcess := c.GetProcess(InitProcessID)
|
||||
return initProcess.Wait()
|
||||
}
|
||||
|
||||
func (c *Container) AddProcess(p Process, isInit bool) {
|
||||
if isInit {
|
||||
c.initPid = p.Pid()
|
||||
}
|
||||
func (c *Container) Status() Status {
|
||||
initProcess := c.GetProcess(InitProcessID)
|
||||
return initProcess.Status()
|
||||
}
|
||||
|
||||
func (c *Container) AddProcess(p Process) {
|
||||
c.mu.Lock()
|
||||
c.processes[p.ID()] = p
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
func (c *Container) RemoveProcess(id string) error {
|
||||
if _, ok := c.processes[id]; !ok {
|
||||
return errors.Errorf("no such process %s", id)
|
||||
}
|
||||
|
||||
c.mu.Lock()
|
||||
delete(c.processes, id)
|
||||
c.mu.Unlock()
|
||||
|
||||
processStateDir := filepath.Join(c.stateDir, processesDirName, id)
|
||||
err := os.RemoveAll(processStateDir)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to remove process state dir")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) GetProcess(id string) Process {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.processes[id]
|
||||
}
|
||||
|
||||
func (c *Container) RemoveProcess(id string) {
|
||||
delete(c.processes, id)
|
||||
func (c *Container) Processes() []Process {
|
||||
var procs []Process
|
||||
|
||||
c.mu.Lock()
|
||||
for _, p := range c.processes {
|
||||
procs = append(procs, p)
|
||||
}
|
||||
c.mu.Unlock()
|
||||
|
||||
return procs
|
||||
}
|
||||
|
||||
func (c *Container) Processes() []Process {
|
||||
var out []Process
|
||||
for _, p := range c.processes {
|
||||
out = append(out, p)
|
||||
}
|
||||
return out
|
||||
// ProcessStateDir returns the path of the state dir for a given
|
||||
// process id. The process doesn't have to exist for this to succeed.
|
||||
func (c *Container) ProcessStateDir(id string) string {
|
||||
return filepath.Join(c.stateDir, processesDirName, id)
|
||||
}
|
||||
|
||||
// ProcessesStateDir returns a map matching process ids to their state
|
||||
// directory
|
||||
func (c *Container) ProcessesStateDir() (map[string]string, error) {
|
||||
root := filepath.Join(c.stateDir, processesDirName)
|
||||
dirs, err := ioutil.ReadDir(root)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to list processes state dirs")
|
||||
}
|
||||
|
||||
procs := make(map[string]string, 1)
|
||||
for _, d := range dirs {
|
||||
if d.IsDir() {
|
||||
procs[d.Name()] = filepath.Join(root, d.Name())
|
||||
}
|
||||
}
|
||||
|
||||
return procs, nil
|
||||
}
|
||||
|
||||
func (c *Container) Cleanup() {
|
||||
if err := os.RemoveAll(c.stateDir); err != nil {
|
||||
log.G(c.ctx).Warnf("failed to remove container state dir: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Container) Context() context.Context {
|
||||
return c.ctx
|
||||
}
|
||||
|
Reference in New Issue
Block a user