For previous versions of Docker, `--rm` was handled client side, as such
there was no support in the daemon for it.
Now it is handled daemon side, but we still need to handle the case of a
newer client talking to an older daemon.
Falls back to client-side removal when the daemon does not support it.
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit f4bb8c51de3a52bdbc3c3e7be426e6bb90feb421)
Signed-off-by: Victor Vieux <victorvieux@gmail.com>
| ... | ... |
@@ -9,6 +9,7 @@ import ( |
| 9 | 9 |
"github.com/docker/docker/api/types" |
| 10 | 10 |
"github.com/docker/docker/api/types/events" |
| 11 | 11 |
"github.com/docker/docker/api/types/filters" |
| 12 |
+ "github.com/docker/docker/api/types/versions" |
|
| 12 | 13 |
"github.com/docker/docker/cli/command" |
| 13 | 14 |
clientapi "github.com/docker/docker/client" |
| 14 | 15 |
) |
| ... | ... |
@@ -19,11 +20,21 @@ func waitExitOrRemoved(dockerCli *command.DockerCli, ctx context.Context, contai |
| 19 | 19 |
panic("Internal Error: waitExitOrRemoved needs a containerID as parameter")
|
| 20 | 20 |
} |
| 21 | 21 |
|
| 22 |
+ var removeErr error |
|
| 22 | 23 |
statusChan := make(chan int) |
| 23 | 24 |
exitCode := 125 |
| 24 | 25 |
|
| 25 |
- eventProcessor := func(e events.Message) bool {
|
|
| 26 |
+ // Get events via Events API |
|
| 27 |
+ f := filters.NewArgs() |
|
| 28 |
+ f.Add("type", "container")
|
|
| 29 |
+ f.Add("container", containerID)
|
|
| 30 |
+ options := types.EventsOptions{
|
|
| 31 |
+ Filters: f, |
|
| 32 |
+ } |
|
| 33 |
+ eventCtx, cancel := context.WithCancel(ctx) |
|
| 34 |
+ eventq, errq := dockerCli.Client().Events(eventCtx, options) |
|
| 26 | 35 |
|
| 36 |
+ eventProcessor := func(e events.Message) bool {
|
|
| 27 | 37 |
stopProcessing := false |
| 28 | 38 |
switch e.Status {
|
| 29 | 39 |
case "die": |
| ... | ... |
@@ -37,6 +48,18 @@ func waitExitOrRemoved(dockerCli *command.DockerCli, ctx context.Context, contai |
| 37 | 37 |
} |
| 38 | 38 |
if !waitRemove {
|
| 39 | 39 |
stopProcessing = true |
| 40 |
+ } else {
|
|
| 41 |
+ // If we are talking to an older daemon, `AutoRemove` is not supported. |
|
| 42 |
+ // We need to fall back to the old behavior, which is client-side removal |
|
| 43 |
+ if versions.LessThan(dockerCli.Client().ClientVersion(), "1.25") {
|
|
| 44 |
+ go func() {
|
|
| 45 |
+ removeErr = dockerCli.Client().ContainerRemove(ctx, containerID, types.ContainerRemoveOptions{RemoveVolumes: true})
|
|
| 46 |
+ if removeErr != nil {
|
|
| 47 |
+ logrus.Errorf("error removing container: %v", removeErr)
|
|
| 48 |
+ cancel() // cancel the event Q |
|
| 49 |
+ } |
|
| 50 |
+ }() |
|
| 51 |
+ } |
|
| 40 | 52 |
} |
| 41 | 53 |
case "detach": |
| 42 | 54 |
exitCode = 0 |
| ... | ... |
@@ -44,39 +67,27 @@ func waitExitOrRemoved(dockerCli *command.DockerCli, ctx context.Context, contai |
| 44 | 44 |
case "destroy": |
| 45 | 45 |
stopProcessing = true |
| 46 | 46 |
} |
| 47 |
- |
|
| 48 |
- if stopProcessing {
|
|
| 49 |
- statusChan <- exitCode |
|
| 50 |
- return true |
|
| 51 |
- } |
|
| 52 |
- |
|
| 53 |
- return false |
|
| 47 |
+ return stopProcessing |
|
| 54 | 48 |
} |
| 55 | 49 |
|
| 56 |
- // Get events via Events API |
|
| 57 |
- f := filters.NewArgs() |
|
| 58 |
- f.Add("type", "container")
|
|
| 59 |
- f.Add("container", containerID)
|
|
| 60 |
- options := types.EventsOptions{
|
|
| 61 |
- Filters: f, |
|
| 62 |
- } |
|
| 63 |
- |
|
| 64 |
- eventCtx, cancel := context.WithCancel(ctx) |
|
| 65 |
- eventq, errq := dockerCli.Client().Events(eventCtx, options) |
|
| 66 |
- |
|
| 67 | 50 |
go func() {
|
| 68 |
- defer cancel() |
|
| 51 |
+ defer func() {
|
|
| 52 |
+ statusChan <- exitCode // must always send an exit code or the caller will block |
|
| 53 |
+ cancel() |
|
| 54 |
+ }() |
|
| 69 | 55 |
|
| 70 | 56 |
for {
|
| 71 | 57 |
select {
|
| 58 |
+ case <-eventCtx.Done(): |
|
| 59 |
+ if removeErr != nil {
|
|
| 60 |
+ return |
|
| 61 |
+ } |
|
| 72 | 62 |
case evt := <-eventq: |
| 73 | 63 |
if eventProcessor(evt) {
|
| 74 | 64 |
return |
| 75 | 65 |
} |
| 76 |
- |
|
| 77 | 66 |
case err := <-errq: |
| 78 | 67 |
logrus.Errorf("error getting events from daemon: %v", err)
|
| 79 |
- statusChan <- exitCode |
|
| 80 | 68 |
return |
| 81 | 69 |
} |
| 82 | 70 |
} |