From 74bfe500e406fa8cc605e18d1fa770852c4403f5 Mon Sep 17 00:00:00 2001 From: Wang Long Date: Fri, 23 Sep 2016 17:02:53 +0800 Subject: [PATCH] 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 --- man/runc-start.8.md | 2 +- start.go | 58 ++++++++++++++++++++++++++---------- tests/integration/start.bats | 41 +++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 16 deletions(-) create mode 100644 tests/integration/start.bats diff --git a/man/runc-start.8.md b/man/runc-start.8.md index 2791a0452..667212082 100644 --- a/man/runc-start.8.md +++ b/man/runc-start.8.md @@ -2,7 +2,7 @@ runc start - start signals a created container to execute the user defined process # SYNOPSIS - runc start + runc start [container-id...] Where "" 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 diff --git a/start.go b/start.go index 4645dc2b7..30d7d8fd1 100644 --- a/start.go +++ b/start.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "os" "github.com/opencontainers/runc/libcontainer" "github.com/urfave/cli" @@ -10,30 +11,57 @@ import ( var startCommand = cli.Command{ Name: "start", Usage: "executes the user defined process in a created container", - ArgsUsage: ` + ArgsUsage: ` [container-id...] Where "" 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 { - 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 { return err } - status, err := container.Status() - if err != nil { - return err + + for _, id := range context.Args() { + 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: - return container.Exec() - 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) + + if hasError { + return fmt.Errorf("one or more of container start failed") } + return nil }, } diff --git a/tests/integration/start.bats b/tests/integration/start.bats new file mode 100644 index 000000000..fb21e7f35 --- /dev/null +++ b/tests/integration/start.bats @@ -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 ] +}