Support parallel kill,rm
| ... | ... |
@@ -39,8 +39,11 @@ func NewKillCommand(dockerCli *command.DockerCli) *cobra.Command {
|
| 39 | 39 |
func runKill(dockerCli *command.DockerCli, opts *killOptions) error {
|
| 40 | 40 |
var errs []string |
| 41 | 41 |
ctx := context.Background() |
| 42 |
+ errChan := parallelOperation(ctx, opts.containers, func(ctx context.Context, container string) error {
|
|
| 43 |
+ return dockerCli.Client().ContainerKill(ctx, container, opts.signal) |
|
| 44 |
+ }) |
|
| 42 | 45 |
for _, name := range opts.containers {
|
| 43 |
- if err := dockerCli.Client().ContainerKill(ctx, name, opts.signal); err != nil {
|
|
| 46 |
+ if err := <-errChan; err != nil {
|
|
| 44 | 47 |
errs = append(errs, err.Error()) |
| 45 | 48 |
} else {
|
| 46 | 49 |
fmt.Fprintf(dockerCli.Out(), "%s\n", name) |
| ... | ... |
@@ -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 |
-} |
| ... | ... |
@@ -99,8 +99,8 @@ func getExitCode(dockerCli *command.DockerCli, ctx context.Context, containerID |
| 99 | 99 |
return c.State.Running, c.State.ExitCode, nil |
| 100 | 100 |
} |
| 101 | 101 |
|
| 102 |
-func parallelOperation(ctx context.Context, cids []string, op func(ctx context.Context, id string) error) chan error {
|
|
| 103 |
- if len(cids) == 0 {
|
|
| 102 |
+func parallelOperation(ctx context.Context, containers []string, op func(ctx context.Context, container string) error) chan error {
|
|
| 103 |
+ if len(containers) == 0 {
|
|
| 104 | 104 |
return nil |
| 105 | 105 |
} |
| 106 | 106 |
const defaultParallel int = 50 |
| ... | ... |
@@ -109,18 +109,18 @@ func parallelOperation(ctx context.Context, cids []string, op func(ctx context.C |
| 109 | 109 |
|
| 110 | 110 |
// make sure result is printed in correct order |
| 111 | 111 |
output := map[string]chan error{}
|
| 112 |
- for _, c := range cids {
|
|
| 112 |
+ for _, c := range containers {
|
|
| 113 | 113 |
output[c] = make(chan error, 1) |
| 114 | 114 |
} |
| 115 | 115 |
go func() {
|
| 116 |
- for _, c := range cids {
|
|
| 116 |
+ for _, c := range containers {
|
|
| 117 | 117 |
err := <-output[c] |
| 118 | 118 |
errChan <- err |
| 119 | 119 |
} |
| 120 | 120 |
}() |
| 121 | 121 |
|
| 122 | 122 |
go func() {
|
| 123 |
- for _, c := range cids {
|
|
| 123 |
+ for _, c := range containers {
|
|
| 124 | 124 |
sem <- struct{}{} // Wait for active queue sem to drain.
|
| 125 | 125 |
go func(container string) {
|
| 126 | 126 |
output[container] <- op(ctx, container) |