From d2bb3aba7edd17df02450385ae378dc70907c449 Mon Sep 17 00:00:00 2001 From: Zhang Wei Date: Wed, 21 Sep 2016 22:06:43 +0800 Subject: [PATCH 1/2] Support parallel kill Signed-off-by: Zhang Wei --- cli/command/container/kill.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cli/command/container/kill.go b/cli/command/container/kill.go index 8d9af6f7a64f..6da91a40e34d 100644 --- a/cli/command/container/kill.go +++ b/cli/command/container/kill.go @@ -39,8 +39,11 @@ func NewKillCommand(dockerCli *command.DockerCli) *cobra.Command { func runKill(dockerCli *command.DockerCli, opts *killOptions) error { var errs []string ctx := context.Background() + errChan := parallelOperation(ctx, opts.containers, func(ctx context.Context, container string) error { + return dockerCli.Client().ContainerKill(ctx, container, opts.signal) + }) for _, name := range opts.containers { - if err := dockerCli.Client().ContainerKill(ctx, name, opts.signal); err != nil { + if err := <-errChan; err != nil { errs = append(errs, err.Error()) } else { fmt.Fprintf(dockerCli.Out(), "%s\n", name) From 2b773257e0ee45db2c413774a3affae01c7996c1 Mon Sep 17 00:00:00 2001 From: Zhang Wei Date: Wed, 21 Sep 2016 22:35:08 +0800 Subject: [PATCH 2/2] Support parallel rm Signed-off-by: Zhang Wei --- cli/command/container/rm.go | 29 +++++++++++++---------------- cli/command/container/utils.go | 10 +++++----- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/cli/command/container/rm.go b/cli/command/container/rm.go index 622a69b51076..60724f194bfe 100644 --- a/cli/command/container/rm.go +++ b/cli/command/container/rm.go @@ -45,13 +45,22 @@ func runRm(dockerCli *command.DockerCli, opts *rmOptions) error { ctx := context.Background() var errs []string - for _, name := range opts.containers { - if name == "" { + options := types.ContainerRemoveOptions{ + RemoveVolumes: opts.rmVolumes, + RemoveLinks: opts.rmLink, + Force: opts.force, + } + + errChan := parallelOperation(ctx, opts.containers, func(ctx context.Context, container string) error { + if container == "" { return fmt.Errorf("Container name cannot be empty") } - name = strings.Trim(name, "/") + container = strings.Trim(container, "/") + return dockerCli.Client().ContainerRemove(ctx, container, options) + }) - if err := removeContainer(dockerCli, ctx, name, opts.rmVolumes, opts.rmLink, opts.force); err != nil { + for _, name := range opts.containers { + if err := <-errChan; err != nil { errs = append(errs, err.Error()) } else { fmt.Fprintf(dockerCli.Out(), "%s\n", name) @@ -62,15 +71,3 @@ func runRm(dockerCli *command.DockerCli, opts *rmOptions) error { } return nil } - -func removeContainer(dockerCli *command.DockerCli, ctx context.Context, container string, removeVolumes, removeLinks, force bool) error { - options := types.ContainerRemoveOptions{ - RemoveVolumes: removeVolumes, - RemoveLinks: removeLinks, - Force: force, - } - if err := dockerCli.Client().ContainerRemove(ctx, container, options); err != nil { - return err - } - return nil -} diff --git a/cli/command/container/utils.go b/cli/command/container/utils.go index 7e895834f9a9..2e129f03243e 100644 --- a/cli/command/container/utils.go +++ b/cli/command/container/utils.go @@ -91,8 +91,8 @@ func getExitCode(dockerCli *command.DockerCli, ctx context.Context, containerID return c.State.Running, c.State.ExitCode, nil } -func parallelOperation(ctx context.Context, cids []string, op func(ctx context.Context, id string) error) chan error { - if len(cids) == 0 { +func parallelOperation(ctx context.Context, containers []string, op func(ctx context.Context, container string) error) chan error { + if len(containers) == 0 { return nil } const defaultParallel int = 50 @@ -101,18 +101,18 @@ func parallelOperation(ctx context.Context, cids []string, op func(ctx context.C // make sure result is printed in correct order output := map[string]chan error{} - for _, c := range cids { + for _, c := range containers { output[c] = make(chan error, 1) } go func() { - for _, c := range cids { + for _, c := range containers { err := <-output[c] errChan <- err } }() go func() { - for _, c := range cids { + for _, c := range containers { sem <- struct{}{} // Wait for active queue sem to drain. go func(container string) { output[container] <- op(ctx, container)