Signed-off-by: Zhang Wei <zhangwei555@huawei.com>
| ... | ... |
@@ -45,13 +45,22 @@ func runRm(dockerCli *command.DockerCli, opts *rmOptions) error {
|
| 45 | 45 |
ctx := context.Background() |
| 46 | 46 |
|
| 47 | 47 |
var errs []string |
| 48 |
- for _, name := range opts.containers {
|
|
| 49 |
- if name == "" {
|
|
| 48 |
+ options := types.ContainerRemoveOptions{
|
|
| 49 |
+ RemoveVolumes: opts.rmVolumes, |
|
| 50 |
+ RemoveLinks: opts.rmLink, |
|
| 51 |
+ Force: opts.force, |
|
| 52 |
+ } |
|
| 53 |
+ |
|
| 54 |
+ errChan := parallelOperation(ctx, opts.containers, func(ctx context.Context, container string) error {
|
|
| 55 |
+ if container == "" {
|
|
| 50 | 56 |
return fmt.Errorf("Container name cannot be empty")
|
| 51 | 57 |
} |
| 52 |
- name = strings.Trim(name, "/") |
|
| 58 |
+ container = strings.Trim(container, "/") |
|
| 59 |
+ return dockerCli.Client().ContainerRemove(ctx, container, options) |
|
| 60 |
+ }) |
|
| 53 | 61 |
|
| 54 |
- if err := removeContainer(dockerCli, ctx, name, opts.rmVolumes, opts.rmLink, opts.force); err != nil {
|
|
| 62 |
+ for _, name := range opts.containers {
|
|
| 63 |
+ if err := <-errChan; err != nil {
|
|
| 55 | 64 |
errs = append(errs, err.Error()) |
| 56 | 65 |
} else {
|
| 57 | 66 |
fmt.Fprintf(dockerCli.Out(), "%s\n", name) |
| ... | ... |
@@ -62,15 +71,3 @@ func runRm(dockerCli *command.DockerCli, opts *rmOptions) error {
|
| 62 | 62 |
} |
| 63 | 63 |
return nil |
| 64 | 64 |
} |
| 65 |
- |
|
| 66 |
-func removeContainer(dockerCli *command.DockerCli, ctx context.Context, container string, removeVolumes, removeLinks, force bool) error {
|
|
| 67 |
- options := types.ContainerRemoveOptions{
|
|
| 68 |
- RemoveVolumes: removeVolumes, |
|
| 69 |
- RemoveLinks: removeLinks, |
|
| 70 |
- Force: force, |
|
| 71 |
- } |
|
| 72 |
- if err := dockerCli.Client().ContainerRemove(ctx, container, options); err != nil {
|
|
| 73 |
- return err |
|
| 74 |
- } |
|
| 75 |
- return nil |
|
| 76 |
-} |
| ... | ... |
@@ -91,8 +91,8 @@ func getExitCode(dockerCli *command.DockerCli, ctx context.Context, containerID |
| 91 | 91 |
return c.State.Running, c.State.ExitCode, nil |
| 92 | 92 |
} |
| 93 | 93 |
|
| 94 |
-func parallelOperation(ctx context.Context, cids []string, op func(ctx context.Context, id string) error) chan error {
|
|
| 95 |
- if len(cids) == 0 {
|
|
| 94 |
+func parallelOperation(ctx context.Context, containers []string, op func(ctx context.Context, container string) error) chan error {
|
|
| 95 |
+ if len(containers) == 0 {
|
|
| 96 | 96 |
return nil |
| 97 | 97 |
} |
| 98 | 98 |
const defaultParallel int = 50 |
| ... | ... |
@@ -101,18 +101,18 @@ func parallelOperation(ctx context.Context, cids []string, op func(ctx context.C |
| 101 | 101 |
|
| 102 | 102 |
// make sure result is printed in correct order |
| 103 | 103 |
output := map[string]chan error{}
|
| 104 |
- for _, c := range cids {
|
|
| 104 |
+ for _, c := range containers {
|
|
| 105 | 105 |
output[c] = make(chan error, 1) |
| 106 | 106 |
} |
| 107 | 107 |
go func() {
|
| 108 |
- for _, c := range cids {
|
|
| 108 |
+ for _, c := range containers {
|
|
| 109 | 109 |
err := <-output[c] |
| 110 | 110 |
errChan <- err |
| 111 | 111 |
} |
| 112 | 112 |
}() |
| 113 | 113 |
|
| 114 | 114 |
go func() {
|
| 115 |
- for _, c := range cids {
|
|
| 115 |
+ for _, c := range containers {
|
|
| 116 | 116 |
sem <- struct{}{} // Wait for active queue sem to drain.
|
| 117 | 117 |
go func(container string) {
|
| 118 | 118 |
output[container] <- op(ctx, container) |