Merge pull request #1363 from hqhq/allow_single_cont_oper

Only allow single container operation
This commit is contained in:
Michael Crosby 2017-03-08 10:43:14 -08:00 committed by GitHub
commit 4815f67a5f
10 changed files with 87 additions and 280 deletions

View File

@ -27,8 +27,8 @@ func killContainer(container libcontainer.Container) error {
var deleteCommand = cli.Command{
Name: "delete",
Usage: "delete any resources held by one or more containers often used with detached containers",
ArgsUsage: `<container-id> [container-id...]
Usage: "delete any resources held by the container often used with detached container",
ArgsUsage: `<container-id>
Where "<container-id>" is the name for the instance of the container.
@ -45,62 +45,40 @@ status of "ubuntu01" as "stopped" the following will delete resources held for
},
},
Action: func(context *cli.Context) error {
if err := checkArgs(context, 1, minArgs); err != nil {
if err := checkArgs(context, 1, exactArgs); err != nil {
return err
}
hasError := false
factory, err := loadFactory(context)
id := context.Args().First()
container, err := getContainer(context)
if err != nil {
if lerr, ok := err.(libcontainer.Error); ok && lerr.Code() == libcontainer.ContainerNotExists {
// if there was an aborted start or something of the sort then the container's directory could exist but
// libcontainer does not see it because the state.json file inside that directory was never created.
path := filepath.Join(context.GlobalString("root"), id)
if e := os.RemoveAll(path); e != nil {
fmt.Fprintf(os.Stderr, "remove %s: %v\n", path, e)
}
}
return err
}
s, err := container.Status()
if err != nil {
return err
}
for _, id := range context.Args() {
container, err := factory.Load(id)
if err != nil {
if lerr, ok := err.(libcontainer.Error); ok && lerr.Code() == libcontainer.ContainerNotExists {
// if there was an aborted start or something of the sort then the container's directory could exist but
// libcontainer does not see it because the state.json file inside that directory was never created.
path := filepath.Join(context.GlobalString("root"), id)
if err = os.RemoveAll(path); err != nil {
fmt.Fprintf(os.Stderr, "remove %s: %v\n", path, err)
}
fmt.Fprintf(os.Stderr, "container %s does not exist\n", id)
}
hasError = true
continue
}
s, err := container.Status()
if err != nil {
fmt.Fprintf(os.Stderr, "status for %s: %v\n", id, err)
hasError = true
continue
}
switch s {
case libcontainer.Stopped:
destroy(container)
case libcontainer.Created:
err := killContainer(container)
if err != nil {
fmt.Fprintf(os.Stderr, "kill container %s: %v\n", id, err)
hasError = true
}
default:
if context.Bool("force") {
err := killContainer(container)
if err != nil {
fmt.Fprintf(os.Stderr, "kill container %s: %v\n", id, err)
hasError = true
}
} else {
fmt.Fprintf(os.Stderr, "cannot delete container %s that is not stopped: %s\n", id, s)
hasError = true
}
switch s {
case libcontainer.Stopped:
destroy(container)
case libcontainer.Created:
return killContainer(container)
default:
if context.Bool("force") {
return killContainer(container)
} else {
return fmt.Errorf("cannot delete container %s that is not stopped: %s\n", id, s)
}
}
if hasError {
return fmt.Errorf("one or more of the container deletions failed")
}
return nil
},
}

View File

@ -1,8 +1,8 @@
# NAME
runc delete - delete any resources held by one or more containers often used with detached containers
runc delete - delete any resources held by the container often used with detached container
# SYNOPSIS
runc delete [command options] <container-id> [container-id...]
runc delete [command options] <container-id>
Where "<container-id>" is the name for the instance of the container.

View File

@ -2,7 +2,7 @@
runc pause - pause suspends all processes inside the container
# SYNOPSIS
runc pause <container-id> [container-id...]
runc pause <container-id>
Where "<container-id>" is the name for the instance of the container to be
paused.

View File

@ -2,7 +2,7 @@
runc resume - resumes all processes that have been previously paused
# SYNOPSIS
runc resume <container-id> [container-id...]
runc resume <container-id>
Where "<container-id>" is the name for the instance of the container to be
resumed.

View File

@ -1,12 +1,12 @@
# NAME
runc start - start signals a created container to execute the user defined process
runc start - start executes the user defined process in a created container
# SYNOPSIS
runc start <container-id> [container-id...]
runc start <container-id>
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
your host.
# DESCRIPTION
The start command signals the container to start the user's defined process.
The start command executes the user defined process in a created container.

View File

@ -2,17 +2,12 @@
package main
import (
"fmt"
"os"
"github.com/urfave/cli"
)
import "github.com/urfave/cli"
var pauseCommand = cli.Command{
Name: "pause",
Usage: "pause suspends all processes inside the container",
ArgsUsage: `<container-id> [container-id...]
ArgsUsage: `<container-id>
Where "<container-id>" is the name for the instance of the container to be
paused. `,
@ -20,31 +15,17 @@ paused. `,
Use runc list to identiy instances of containers and their current status.`,
Action: func(context *cli.Context) error {
if err := checkArgs(context, 1, minArgs); err != nil {
if err := checkArgs(context, 1, exactArgs); err != nil {
return err
}
hasError := false
factory, err := loadFactory(context)
container, err := getContainer(context)
if err != nil {
return err
}
for _, id := range context.Args() {
container, err := factory.Load(id)
if err != nil {
fmt.Fprintf(os.Stderr, "container %s does not exist\n", id)
hasError = true
continue
}
if err := container.Pause(); err != nil {
fmt.Fprintf(os.Stderr, "pause container %s : %s\n", id, err)
hasError = true
}
if err := container.Pause(); err != nil {
return err
}
if hasError {
return fmt.Errorf("one or more of container pause failed")
}
return nil
},
}
@ -52,7 +33,7 @@ Use runc list to identiy instances of containers and their current status.`,
var resumeCommand = cli.Command{
Name: "resume",
Usage: "resumes all processes that have been previously paused",
ArgsUsage: `<container-id> [container-id...]
ArgsUsage: `<container-id>
Where "<container-id>" is the name for the instance of the container to be
resumed.`,
@ -60,31 +41,17 @@ resumed.`,
Use runc list to identiy instances of containers and their current status.`,
Action: func(context *cli.Context) error {
if err := checkArgs(context, 1, minArgs); err != nil {
if err := checkArgs(context, 1, exactArgs); err != nil {
return err
}
hasError := false
factory, err := loadFactory(context)
container, err := getContainer(context)
if err != nil {
return err
}
for _, id := range context.Args() {
container, err := factory.Load(id)
if err != nil {
fmt.Fprintf(os.Stderr, "container %s does not exist\n", id)
hasError = true
continue
}
if err := container.Resume(); err != nil {
fmt.Fprintf(os.Stderr, "resume container %s : %s\n", id, err)
hasError = true
}
if err := container.Resume(); err != nil {
return err
}
if hasError {
return fmt.Errorf("one or more of container resume failed")
}
return nil
},
}

View File

@ -1,8 +1,8 @@
package main
import (
"errors"
"fmt"
"os"
"github.com/opencontainers/runc/libcontainer"
"github.com/urfave/cli"
@ -11,56 +11,33 @@ import (
var startCommand = cli.Command{
Name: "start",
Usage: "executes the user defined process in a created container",
ArgsUsage: `<container-id> [container-id...]
ArgsUsage: `<container-id>
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
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 {
if err := checkArgs(context, 1, minArgs); err != nil {
if err := checkArgs(context, 1, exactArgs); err != nil {
return err
}
hasError := false
factory, err := loadFactory(context)
container, err := getContainer(context)
if err != nil {
return err
}
for _, id := range context.Args() {
container, err := factory.Load(id)
if err != nil {
fmt.Fprintf(os.Stderr, "container %s does 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 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
}
status, err := container.Status()
if err != nil {
return err
}
if hasError {
return fmt.Errorf("one or more of container start failed")
switch status {
case libcontainer.Created:
return container.Exec()
case libcontainer.Stopped:
return errors.New("cannot start a container that has stopped")
case libcontainer.Running:
return errors.New("cannot start an already running container")
default:
return fmt.Errorf("cannot start a container in the %s state\n", status)
}
return nil
},
}

View File

@ -48,62 +48,3 @@ function teardown() {
runc state test_busybox
[ "$status" -ne 0 ]
}
@test "run delete with multi-containers" {
# create busybox1 detached
runc create --console-socket $CONSOLE_SOCKET test_busybox1
[ "$status" -eq 0 ]
testcontainer test_busybox1 created
# run busybox2 detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox2
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox2
testcontainer test_busybox2 running
# delete both test_busybox1 and test_busybox2 container
runc delete test_busybox1 test_busybox2
runc state test_busybox1
[ "$status" -ne 0 ]
runc state test_busybox2
[ "$status" -eq 0 ]
runc kill test_busybox2 KILL
# wait for busybox2 to be in the destroyed state
retry 10 1 eval "__runc state test_busybox2 | grep -q 'stopped'"
# delete test_busybox2
runc delete test_busybox2
runc state test_busybox2
[ "$status" -ne 0 ]
}
@test "run delete --force with multi-containers" {
# create busybox1 detached
runc create --console-socket $CONSOLE_SOCKET test_busybox1
[ "$status" -eq 0 ]
testcontainer test_busybox1 created
# run busybox2 detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox2
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox2
testcontainer test_busybox2 running
# delete both test_busybox1 and test_busybox2 container
runc delete --force test_busybox1 test_busybox2
runc state test_busybox1
[ "$status" -ne 0 ]
runc state test_busybox2
[ "$status" -ne 0 ]
}

View File

@ -33,80 +33,34 @@ function teardown() {
testcontainer test_busybox running
}
@test "runc pause and resume with multi-container" {
# run test_busybox1 detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox1
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox1
# run test_busybox2 detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox2
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox2
# pause test_busybox1 and test_busybox2
runc pause test_busybox1 test_busybox2
[ "$status" -eq 0 ]
# test state of test_busybox1 and test_busybox2 is paused
testcontainer test_busybox1 paused
testcontainer test_busybox2 paused
# resume test_busybox1 and test_busybox2
runc resume test_busybox1 test_busybox2
[ "$status" -eq 0 ]
# test state of two containers is back to running
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 ]
}
@test "runc pause and resume with nonexist container" {
# run test_busybox1 detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox1
# run test_busybox detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox1
wait_for_container 15 1 test_busybox
# run test_busybox2 detached
runc run -d --console-socket $CONSOLE_SOCKET test_busybox2
# pause test_busybox and nonexistent container
runc pause test_busybox
[ "$status" -eq 0 ]
wait_for_container 15 1 test_busybox2
# pause test_busybox1, test_busybox2 and nonexistent container
runc pause test_busybox1 test_busybox2 nonexistent
runc pause nonexistent
[ "$status" -ne 0 ]
# test state of test_busybox1 and test_busybox2 is paused
testcontainer test_busybox1 paused
testcontainer test_busybox2 paused
# test state of test_busybox is paused
testcontainer test_busybox paused
# resume test_busybox1, test_busybox2 and nonexistent container
runc resume test_busybox1 test_busybox2 nonexistent
# resume test_busybox and nonexistent container
runc resume test_busybox
[ "$status" -eq 0 ]
runc resume nonexistent
[ "$status" -ne 0 ]
# test state of two containers is back to running
testcontainer test_busybox1 running
testcontainer test_busybox2 running
# test state of test_busybox is back to running
testcontainer test_busybox running
# delete test_busybox1 and test_busybox2
runc delete --force test_busybox1 test_busybox2
# delete test_busybox
runc delete --force test_busybox
runc state test_busybox1
[ "$status" -ne 0 ]
runc state test_busybox2
runc state test_busybox
[ "$status" -ne 0 ]
}

View File

@ -12,30 +12,20 @@ function teardown() {
}
@test "runc start" {
runc create --console-socket $CONSOLE_SOCKET test_busybox1
runc create --console-socket $CONSOLE_SOCKET test_busybox
[ "$status" -eq 0 ]
testcontainer test_busybox1 created
testcontainer test_busybox created
runc create --console-socket $CONSOLE_SOCKET test_busybox2
# start container test_busybox
runc start test_busybox
[ "$status" -eq 0 ]
testcontainer test_busybox2 created
testcontainer test_busybox running
# delete test_busybox
runc delete --force test_busybox
# start container 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
runc state test_busybox
[ "$status" -ne 0 ]
}