start mulit-containers with `runc start` command

With this patch, `runc start` command can start mulit-containers
at one command this patch also checks the argument of the `start`
command.

root@ubuntu:# runc list
ID          PID         STATUS      BUNDLE         CREATED
a           0           stopped     /mycontainer   2016-09-23T08:56:42.754026567Z
b           62979       created     /mycontainer   2016-09-23T09:01:36.421976458Z
c           62993       running     /mycontainer   2016-09-23T09:01:38.105940389Z
d           63006       created     /mycontainer   2016-09-23T09:01:39.65441942Z
e           63020       created     /mycontainer   2016-09-23T09:01:40.989995515Z
root@ubuntu:# runc start
runc: "start" requires a minimum of 1 argument
root@ubuntu:# runc start a b c d e f
cannot start a container that has run and stopped
cannot start an already running container
container f is not exist
all or part of the containers start failed
root@ubuntu:# runc list
ID          PID         STATUS      BUNDLE         CREATED
a           0           stopped     /mycontainer   2016-09-23T08:56:42.754026567Z
b           62979       running     /mycontainer   2016-09-23T09:01:36.421976458Z
c           62993       running     /mycontainer   2016-09-23T09:01:38.105940389Z
d           63006       running     /mycontainer   2016-09-23T09:01:39.65441942Z
e           63020       running     /mycontainer   2016-09-23T09:01:40.989995515Z

Signed-off-by: Wang Long <long.wanglong@huawei.com>
This commit is contained in:
Wang Long 2016-09-23 17:02:53 +08:00
parent 45c30e75ab
commit 74bfe500e4
3 changed files with 85 additions and 16 deletions

View File

@ -2,7 +2,7 @@
runc start - start signals a created container to execute the user defined process runc start - start signals a created container to execute the user defined process
# SYNOPSIS # SYNOPSIS
runc start <container-id> runc start <container-id> [container-id...]
Where "<container-id>" is your name for the instance of the container that you Where "<container-id>" is your name for the instance of the container that you
are starting. The name you provide for the container instance must be unique on are starting. The name you provide for the container instance must be unique on

View File

@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"os"
"github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -10,30 +11,57 @@ import (
var startCommand = cli.Command{ var startCommand = cli.Command{
Name: "start", Name: "start",
Usage: "executes the user defined process in a created container", Usage: "executes the user defined process in a created container",
ArgsUsage: `<container-id> ArgsUsage: `<container-id> [container-id...]
Where "<container-id>" is your name for the instance of the container that you Where "<container-id>" is your name for the instance of the container that you
are starting. The name you provide for the container instance must be unique on are starting. The name you provide for the container instance must be unique on
your host.`, your host.`,
Description: `The start command executes the user defined process in a created container.`, Description: `The start command executes the user defined process in a created container .`,
Action: func(context *cli.Context) error { Action: func(context *cli.Context) error {
container, err := getContainer(context) hasError := false
if !context.Args().Present() {
return fmt.Errorf("runc: \"start\" requires a minimum of 1 argument")
}
factory, err := loadFactory(context)
if err != nil { if err != nil {
return err return err
} }
status, err := container.Status()
if err != nil { for _, id := range context.Args() {
return err container, err := factory.Load(id)
if err != nil {
fmt.Fprintf(os.Stderr, "container %s is not exist\n", id)
hasError = true
continue
}
status, err := container.Status()
if err != nil {
fmt.Fprintf(os.Stderr, "status for %s: %v\n", id, err)
hasError = true
continue
}
switch status {
case libcontainer.Created:
if err := container.Exec(); err != nil {
fmt.Fprintf(os.Stderr, "start for %s failed: %v\n", id, err)
hasError = true
}
case libcontainer.Stopped:
fmt.Fprintln(os.Stderr, "cannot start a container that has run and stopped")
hasError = true
case libcontainer.Running:
fmt.Fprintln(os.Stderr, "cannot start an already running container")
hasError = true
default:
fmt.Fprintf(os.Stderr, "cannot start a container in the %s state\n", status)
hasError = true
}
} }
switch status {
case libcontainer.Created: if hasError {
return container.Exec() return fmt.Errorf("one or more of container start failed")
case libcontainer.Stopped:
return fmt.Errorf("cannot start a container that has run and stopped")
case libcontainer.Running:
return fmt.Errorf("cannot start an already running container")
default:
return fmt.Errorf("cannot start a container in the %s state", status)
} }
return nil
}, },
} }

View File

@ -0,0 +1,41 @@
#!/usr/bin/env bats
load helpers
function setup() {
teardown_busybox
setup_busybox
}
function teardown() {
teardown_busybox
}
@test "runc start" {
runc create --console /dev/pts/ptmx test_busybox1
[ "$status" -eq 0 ]
testcontainer test_busybox1 created
runc create --console /dev/pts/ptmx test_busybox2
[ "$status" -eq 0 ]
testcontainer test_busybox2 created
# start conatiner test_busybox1 and test_busybox2
runc start test_busybox1 test_busybox2
[ "$status" -eq 0 ]
testcontainer test_busybox1 running
testcontainer test_busybox2 running
# delete test_busybox1 and test_busybox2
runc delete --force test_busybox1 test_busybox2
runc state test_busybox1
[ "$status" -ne 0 ]
runc state test_busybox2
[ "$status" -ne 0 ]
}