diff --git a/cmd/oci-lifecycle-demo/main.go b/cmd/oci-lifecycle-demo/main.go new file mode 100644 index 000000000..646f18e1c --- /dev/null +++ b/cmd/oci-lifecycle-demo/main.go @@ -0,0 +1,85 @@ +package main + +import ( + "fmt" + + l "github.com/opencontainers/runtime-tools/lifecycle" +) + +func TestDemo() { + runtime := "runc" + + type ActionCase struct { + action l.LifecycleAction + args []string + expected bool + } + cases := []struct { + bundle string + id string + actions []ActionCase + }{ + {"noexist_bundle", "1", []ActionCase{ + {action: l.LifecycleCreate, expected: false}}, + }, + {"exist_bundle", "1", []ActionCase{ + {action: l.LifecycleCreate, expected: true}}, + }, + {"exist_bundle", "1", []ActionCase{ + {action: l.LifecycleCreate, expected: true}, + {action: l.LifecycleCreate, expected: false}}, + }, + {"exist_bundle_run_err", "1", []ActionCase{ + {action: l.LifecycleCreate, expected: true}, + {action: l.LifecycleStart, expected: false}}, + }, + } + for _, c := range cases { + //TODO: Prepare c.bundle + lc, _ := l.NewLifecycle(runtime, c.bundle, c.id) + for _, a := range c.actions { + _, err := lc.Operate(a.action) + if err != nil && a.expected == true { + fmt.Printf("Failed in test") + break + } else if err == nil && a.expected == false { + fmt.Printf("Failed in test") + break + } + } + + //TODO: Remove it anyway + lc.Operate(l.LifecycleDelete) + } +} + +func main() { + runtime := "runc" + bundle := "bundle" + id := "25" + lc, _ := l.NewLifecycle(runtime, bundle, id) + + fmt.Println("create") + out, err := lc.Operate(l.LifecycleCreate) + fmt.Println(string(out), err) + + fmt.Println("state") + out, err = lc.Operate(l.LifecycleState) + fmt.Println(string(out), err) + + fmt.Println("start") + out, err = lc.Operate(l.LifecycleStart) + fmt.Println(string(out), err) + + fmt.Println("state") + out, _ = lc.Operate(l.LifecycleState) + fmt.Println(string(out)) + + fmt.Println("delete") + out, _ = lc.Operate(l.LifecycleDelete) + fmt.Println(string(out)) + + fmt.Println("state") + out, _ = lc.Operate(l.LifecycleState) + fmt.Println(string(out)) +} diff --git a/lifecycle/lifecycle.go b/lifecycle/lifecycle.go new file mode 100644 index 000000000..72f4958c6 --- /dev/null +++ b/lifecycle/lifecycle.go @@ -0,0 +1,63 @@ +package lifecycle + +import ( + "errors" + "fmt" + "os/exec" +) + +// LifecycleAction defines lifecycle action according to oci spec +type LifecycleAction string + +// Define actions for Lifecycle +const ( + LifecycleState LifecycleAction = "state" + LifecycleCreate LifecycleAction = "create" + LifecycleStart LifecycleAction = "start" + LifecycleKill LifecycleAction = "kill" + LifecycleDelete LifecycleAction = "delete" +) + +// Lifecycle storages the runtime location, bundle path and the container id +type Lifecycle struct { + ID string + Runtime string + BundlePath string +} + +// NewLifecycle creates a lifecycle with a runtime, bundle path and the container id +// no need to check the validate of bundlepath or id +func NewLifecycle(runtime, bundlePath, id string) (Lifecycle, error) { + var lc Lifecycle + lc.Runtime = runtime + lc.BundlePath = bundlePath + lc.ID = id + return lc, nil +} + +// Operate provides lifecycle operations +func (lc *Lifecycle) Operate(action LifecycleAction, arg ...string) ([]byte, error) { + var cmd *exec.Cmd + + switch action { + case LifecycleState: + cmd = exec.Command(lc.Runtime, string(action), lc.ID) + case LifecycleCreate: + // FIXME: '-b' is used in 'runc' + cmd = exec.Command(lc.Runtime, string(action), "-b", lc.BundlePath, lc.ID) + case LifecycleStart: + cmd = exec.Command(lc.Runtime, string(action), lc.ID) + case LifecycleKill: + if len(arg) != 1 { + return nil, errors.New("Should choose a 'signal' to kill a container") + } + cmd = exec.Command(lc.Runtime, string(action), lc.ID, arg[0]) + case LifecycleDelete: + cmd = exec.Command(lc.Runtime, string(action), lc.ID) + default: + return nil, fmt.Errorf("'%s' is not supported", string(action)) + + } + + return cmd.CombinedOutput() +}