Implement live restore with shim
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
a861ae9d18
commit
3551d4c0b9
4 changed files with 49 additions and 5 deletions
|
@ -15,6 +15,33 @@ import (
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func reloadContainer() error {
|
||||||
|
// create a new runtime runtime that implements the ExecutionDriver interface
|
||||||
|
runtime, err := shim.Load("/run/cshim/test")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dockerContainer := &testConfig{}
|
||||||
|
container, err := containerkit.LoadContainer(dockerContainer, runtime)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// wait for it to exit and get the exit status
|
||||||
|
logrus.Info("wait container")
|
||||||
|
status, err := container.Wait()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete the container after it is done
|
||||||
|
logrus.Info("delete container")
|
||||||
|
if container.Delete(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logrus.Infof("exit status %d", status)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func runContainer() error {
|
func runContainer() error {
|
||||||
// create a new runtime runtime that implements the ExecutionDriver interface
|
// create a new runtime runtime that implements the ExecutionDriver interface
|
||||||
runtime, err := shim.New(shim.Opts{
|
runtime, err := shim.New(shim.Opts{
|
||||||
|
@ -84,9 +111,7 @@ func runContainer() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if load {
|
if load {
|
||||||
if container, err = containerkit.LoadContainer(dockerContainer, runtime); err != nil {
|
return nil
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for it to exit and get the exit status
|
// wait for it to exit and get the exit status
|
||||||
|
@ -108,16 +133,24 @@ func runContainer() error {
|
||||||
var (
|
var (
|
||||||
exec int
|
exec int
|
||||||
load bool
|
load bool
|
||||||
|
reload bool
|
||||||
)
|
)
|
||||||
|
|
||||||
// "Hooks do optional work. Drivers do mandatory work"
|
// "Hooks do optional work. Drivers do mandatory work"
|
||||||
func main() {
|
func main() {
|
||||||
flag.IntVar(&exec, "exec", 0, "run n number of execs")
|
flag.IntVar(&exec, "exec", 0, "run n number of execs")
|
||||||
flag.BoolVar(&load, "load", false, "reload the container")
|
flag.BoolVar(&load, "load", false, "reload the container")
|
||||||
|
flag.BoolVar(&reload, "reload", false, "reload the container live")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
if err := osutils.SetSubreaper(1); err != nil {
|
if err := osutils.SetSubreaper(1); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
if reload {
|
||||||
|
if err := reloadContainer(); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
if err := runContainer(); err != nil {
|
if err := runContainer(); err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,10 @@ func (r *OCIRuntime) Args() []string {
|
||||||
return r.args
|
return r.args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *OCIRuntime) Root() string {
|
||||||
|
return r.root
|
||||||
|
}
|
||||||
|
|
||||||
func (r *OCIRuntime) Create(c *containerkit.Container) (containerkit.ProcessDelegate, error) {
|
func (r *OCIRuntime) Create(c *containerkit.Container) (containerkit.ProcessDelegate, error) {
|
||||||
pidFile := fmt.Sprintf("%s/%s.pid", filepath.Join(r.root, c.ID()), "init")
|
pidFile := fmt.Sprintf("%s/%s.pid", filepath.Join(r.root, c.ID()), "init")
|
||||||
cmd := r.Command("create", "--pid-file", pidFile, "--bundle", c.Path(), c.ID())
|
cmd := r.Command("create", "--pid-file", pidFile, "--bundle", c.Path(), c.ID())
|
||||||
|
|
|
@ -184,6 +184,7 @@ func (p *process) UnmarshalJSON(b []byte) error {
|
||||||
p.stderr = ps.Stderr
|
p.stderr = ps.Stderr
|
||||||
p.root = ps.Root
|
p.root = ps.Root
|
||||||
p.startTime = ps.StartTime
|
p.startTime = ps.StartTime
|
||||||
|
p.done = make(chan struct{})
|
||||||
pid, err := readPid(filepath.Join(p.root, "pid"))
|
pid, err := readPid(filepath.Join(p.root, "pid"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -151,12 +151,14 @@ type Shim struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type state struct {
|
type state struct {
|
||||||
|
Root string `json:"root"`
|
||||||
// Bundle is the path to the container's bundle
|
// Bundle is the path to the container's bundle
|
||||||
Bundle string `json:"bundle"`
|
Bundle string `json:"bundle"`
|
||||||
// OCI runtime binary name
|
// OCI runtime binary name
|
||||||
Runtime string `json:"runtime"`
|
Runtime string `json:"runtime"`
|
||||||
// OCI runtime args
|
// OCI runtime args
|
||||||
RuntimeArgs []string `json:"runtimeArgs"`
|
RuntimeArgs []string `json:"runtimeArgs"`
|
||||||
|
RuntimeRoot string `json:"runtimeRoot"`
|
||||||
// Shim binary name
|
// Shim binary name
|
||||||
Name string `json:"shim"`
|
Name string `json:"shim"`
|
||||||
/// NoPivotRoot option
|
/// NoPivotRoot option
|
||||||
|
@ -171,8 +173,10 @@ func (s *Shim) MarshalJSON() ([]byte, error) {
|
||||||
Bundle: s.bundle,
|
Bundle: s.bundle,
|
||||||
Runtime: s.runtime.Name(),
|
Runtime: s.runtime.Name(),
|
||||||
RuntimeArgs: s.runtime.Args(),
|
RuntimeArgs: s.runtime.Args(),
|
||||||
|
RuntimeRoot: s.runtime.Root(),
|
||||||
NoPivotRoot: s.noPivotRoot,
|
NoPivotRoot: s.noPivotRoot,
|
||||||
Timeout: s.timeout,
|
Timeout: s.timeout,
|
||||||
|
Root: s.root,
|
||||||
}
|
}
|
||||||
return json.Marshal(st)
|
return json.Marshal(st)
|
||||||
}
|
}
|
||||||
|
@ -182,6 +186,7 @@ func (s *Shim) UnmarshalJSON(b []byte) error {
|
||||||
if err := json.Unmarshal(b, &st); err != nil {
|
if err := json.Unmarshal(b, &st); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
s.root = st.Root
|
||||||
s.name = st.Name
|
s.name = st.Name
|
||||||
s.bundle = st.Bundle
|
s.bundle = st.Bundle
|
||||||
s.timeout = st.Timeout
|
s.timeout = st.Timeout
|
||||||
|
@ -189,6 +194,7 @@ func (s *Shim) UnmarshalJSON(b []byte) error {
|
||||||
r, err := oci.New(oci.Opts{
|
r, err := oci.New(oci.Opts{
|
||||||
Name: st.Runtime,
|
Name: st.Runtime,
|
||||||
Args: st.RuntimeArgs,
|
Args: st.RuntimeArgs,
|
||||||
|
Root: st.RuntimeRoot,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in a new issue