Abort the process and return a success response, letting the original
request finish its job.
Signed-off-by: David Calavera <david.calavera@gmail.com>
| ... | ... |
@@ -76,22 +76,20 @@ func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) {
|
| 76 | 76 |
} |
| 77 | 77 |
} |
| 78 | 78 |
|
| 79 |
- // stop collection of stats for the container regardless |
|
| 80 |
- // if stats are currently getting collected. |
|
| 81 |
- daemon.statsCollector.stopCollection(container) |
|
| 82 |
- |
|
| 83 |
- element := daemon.containers.Get(container.ID) |
|
| 84 |
- if element == nil {
|
|
| 85 |
- return derr.ErrorCodeRmNotFound.WithArgs(container.ID) |
|
| 86 |
- } |
|
| 87 |
- |
|
| 88 | 79 |
// Container state RemovalInProgress should be used to avoid races. |
| 89 | 80 |
if err = container.setRemovalInProgress(); err != nil {
|
| 81 |
+ if err == derr.ErrorCodeAlreadyRemoving {
|
|
| 82 |
+ // do not fail when the removal is in progress started by other request. |
|
| 83 |
+ return nil |
|
| 84 |
+ } |
|
| 90 | 85 |
return derr.ErrorCodeRmState.WithArgs(err) |
| 91 | 86 |
} |
| 92 |
- |
|
| 93 | 87 |
defer container.resetRemovalInProgress() |
| 94 | 88 |
|
| 89 |
+ // stop collection of stats for the container regardless |
|
| 90 |
+ // if stats are currently getting collected. |
|
| 91 |
+ daemon.statsCollector.stopCollection(container) |
|
| 92 |
+ |
|
| 95 | 93 |
if err = container.Stop(3); err != nil {
|
| 96 | 94 |
return err |
| 97 | 95 |
} |
| 98 | 96 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,39 @@ |
| 0 |
+package daemon |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "io/ioutil" |
|
| 4 |
+ "os" |
|
| 5 |
+ "testing" |
|
| 6 |
+ |
|
| 7 |
+ "github.com/docker/docker/runconfig" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+func TestContainerDoubleDelete(t *testing.T) {
|
|
| 11 |
+ tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-")
|
|
| 12 |
+ if err != nil {
|
|
| 13 |
+ t.Fatal(err) |
|
| 14 |
+ } |
|
| 15 |
+ defer os.RemoveAll(tmp) |
|
| 16 |
+ daemon := &Daemon{
|
|
| 17 |
+ repository: tmp, |
|
| 18 |
+ root: tmp, |
|
| 19 |
+ } |
|
| 20 |
+ |
|
| 21 |
+ container := &Container{
|
|
| 22 |
+ CommonContainer: CommonContainer{
|
|
| 23 |
+ State: NewState(), |
|
| 24 |
+ Config: &runconfig.Config{},
|
|
| 25 |
+ }, |
|
| 26 |
+ } |
|
| 27 |
+ |
|
| 28 |
+ // Mark the container as having a delete in progress |
|
| 29 |
+ if err := container.setRemovalInProgress(); err != nil {
|
|
| 30 |
+ t.Fatal(err) |
|
| 31 |
+ } |
|
| 32 |
+ |
|
| 33 |
+ // Try to remove the container when it's start is removalInProgress. |
|
| 34 |
+ // It should ignore the container and not return an error. |
|
| 35 |
+ if err := daemon.rm(container, true); err != nil {
|
|
| 36 |
+ t.Fatal(err) |
|
| 37 |
+ } |
|
| 38 |
+} |