Add loading of existing container
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
06e42ec370
commit
23adfe42f9
4 changed files with 94 additions and 9 deletions
37
container.go
37
container.go
|
@ -42,6 +42,43 @@ func NewContainer(root, id string, m Mount, s *specs.Spec, driver ExecutionDrive
|
||||||
}, nil
|
}, 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 {
|
type Container struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
id string
|
id string
|
||||||
|
|
|
@ -29,7 +29,11 @@ func getContainerRootfs() containerkit.Mount {
|
||||||
|
|
||||||
func runContainer() error {
|
func runContainer() error {
|
||||||
// create a new runc runtime that implements the ExecutionDriver interface
|
// 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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -89,6 +93,15 @@ func runContainer() error {
|
||||||
logrus.Infof("process %d returned with %d", i, procStatus)
|
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
|
// wait for it to exit and get the exit status
|
||||||
logrus.Info("wait container")
|
logrus.Info("wait container")
|
||||||
status, err := container.Wait()
|
status, err := container.Wait()
|
||||||
|
@ -151,7 +164,7 @@ func spec(id string) *specs.Spec {
|
||||||
},
|
},
|
||||||
Process: specs.Process{
|
Process: specs.Process{
|
||||||
Env: env,
|
Env: env,
|
||||||
Args: []string{"sleep", "10"},
|
Args: []string{"sleep", "30"},
|
||||||
Terminal: false,
|
Terminal: false,
|
||||||
Cwd: "/",
|
Cwd: "/",
|
||||||
NoNewPrivileges: true,
|
NoNewPrivileges: true,
|
||||||
|
|
|
@ -11,4 +11,5 @@ type ExecutionDriver interface {
|
||||||
Start(*Container) error
|
Start(*Container) error
|
||||||
Delete(*Container) error
|
Delete(*Container) error
|
||||||
Exec(*Container, *Process) (ProcessDelegate, error)
|
Exec(*Container, *Process) (ProcessDelegate, error)
|
||||||
|
Load(id string) (ProcessDelegate, error)
|
||||||
}
|
}
|
||||||
|
|
48
oci/oci.go
48
oci/oci.go
|
@ -9,18 +9,27 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/docker/containerkit"
|
"github.com/docker/containerkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(root, name, log string) (*OCIRuntime, error) {
|
type Opts struct {
|
||||||
if err := os.MkdirAll(root, 0711); err != nil {
|
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 nil, err
|
||||||
}
|
}
|
||||||
return &OCIRuntime{
|
return &OCIRuntime{
|
||||||
root: root,
|
root: opts.Root,
|
||||||
log: log,
|
log: opts.LogFile,
|
||||||
name: name,
|
name: opts.Name,
|
||||||
|
args: opts.Args,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +41,8 @@ type OCIRuntime struct {
|
||||||
name string
|
name string
|
||||||
// log is the path to the log files for the containers
|
// log is the path to the log files for the containers
|
||||||
log string
|
log string
|
||||||
|
// args specifies additional arguments to the OCI runtime
|
||||||
|
args []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *OCIRuntime) Create(c *containerkit.Container) (containerkit.ProcessDelegate, error) {
|
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)
|
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 {
|
func (r *OCIRuntime) command(args ...string) *exec.Cmd {
|
||||||
return exec.Command(r.name, append([]string{
|
baseArgs := append([]string{
|
||||||
"--root", r.root,
|
"--root", r.root,
|
||||||
"--log", r.log,
|
"--log", r.log,
|
||||||
}, args...)...)
|
}, r.args...)
|
||||||
|
return exec.Command(r.name, append(baseArgs, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newProcess(pid int) (*process, error) {
|
func newProcess(pid int) (*process, error) {
|
||||||
|
|
Loading…
Reference in a new issue