Add loading of existing container

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2016-09-30 13:51:10 -07:00
parent 06e42ec370
commit 23adfe42f9
4 changed files with 94 additions and 9 deletions

View file

@ -42,6 +42,43 @@ func NewContainer(root, id string, m Mount, s *specs.Spec, driver ExecutionDrive
}, nil
}
func LoadContainer(root, id string, driver ExecutionDriver) (*Container, error) {
path := filepath.Join(root, id)
spec, err := loadSpec(path)
if err != nil {
return nil, err
}
process, err := driver.Load(id)
if err != nil {
return nil, err
}
// TODO: load exec processes
return &Container{
id: id,
path: path,
s: spec,
driver: driver,
init: &Process{
d: process,
driver: driver,
},
}, nil
}
func loadSpec(path string) (*specs.Spec, error) {
f, err := os.Open(filepath.Join(path, "config.json"))
if err != nil {
return nil, err
}
var s specs.Spec
err = json.NewDecoder(f).Decode(&s)
f.Close()
if err != nil {
return nil, err
}
return &s, nil
}
type Container struct {
mu sync.Mutex
id string

View file

@ -29,7 +29,11 @@ func getContainerRootfs() containerkit.Mount {
func runContainer() error {
// create a new runc runtime that implements the ExecutionDriver interface
driver, err := oci.New("/run/runc", "runc", "/tmp/runc")
driver, err := oci.New(oci.Opts{
Root: "/run/runc",
Name: "runc",
LogFile: "/tmp/runc",
})
if err != nil {
return err
}
@ -89,6 +93,15 @@ func runContainer() error {
logrus.Infof("process %d returned with %d", i, procStatus)
}
container, err = containerkit.LoadContainer(
"/var/lib/containerkit", /* container root */
"test", /* container id */
driver, /* the exec driver to use for the container */
)
if err != nil {
return err
}
// wait for it to exit and get the exit status
logrus.Info("wait container")
status, err := container.Wait()
@ -151,7 +164,7 @@ func spec(id string) *specs.Spec {
},
Process: specs.Process{
Env: env,
Args: []string{"sleep", "10"},
Args: []string{"sleep", "30"},
Terminal: false,
Cwd: "/",
NoNewPrivileges: true,

View file

@ -11,4 +11,5 @@ type ExecutionDriver interface {
Start(*Container) error
Delete(*Container) error
Exec(*Container, *Process) (ProcessDelegate, error)
Load(id string) (ProcessDelegate, error)
}

View file

@ -9,18 +9,27 @@ import (
"path/filepath"
"strconv"
"syscall"
"time"
"github.com/docker/containerkit"
)
func New(root, name, log string) (*OCIRuntime, error) {
if err := os.MkdirAll(root, 0711); err != nil {
type Opts struct {
Name string
Root string
Args []string
LogFile string
}
func New(opts Opts) (*OCIRuntime, error) {
if err := os.MkdirAll(opts.Root, 0711); err != nil {
return nil, err
}
return &OCIRuntime{
root: root,
log: log,
name: name,
root: opts.Root,
log: opts.LogFile,
name: opts.Name,
args: opts.Args,
}, nil
}
@ -32,6 +41,8 @@ type OCIRuntime struct {
name string
// log is the path to the log files for the containers
log string
// args specifies additional arguments to the OCI runtime
args []string
}
func (r *OCIRuntime) Create(c *containerkit.Container) (containerkit.ProcessDelegate, error) {
@ -88,11 +99,34 @@ func (r *OCIRuntime) Exec(c *containerkit.Container, p *containerkit.Process) (c
return newProcess(i)
}
type state struct {
ID string `json:"id"`
Pid int `json:"pid"`
Status string `json:"status"`
Bundle string `json:"bundle"`
Rootfs string `json:"rootfs"`
Created time.Time `json:"created"`
Annotations map[string]string `json:"annotations"`
}
func (r *OCIRuntime) Load(id string) (containerkit.ProcessDelegate, error) {
data, err := r.command("state", id).Output()
if err != nil {
return nil, err
}
var s state
if err := json.Unmarshal(data, &s); err != nil {
return nil, err
}
return newProcess(s.Pid)
}
func (r *OCIRuntime) command(args ...string) *exec.Cmd {
return exec.Command(r.name, append([]string{
baseArgs := append([]string{
"--root", r.root,
"--log", r.log,
}, args...)...)
}, r.args...)
return exec.Command(r.name, append(baseArgs, args...)...)
}
func newProcess(pid int) (*process, error) {