Browse code

container: Fix Delete on nonexistent container

Delete needs to release names related to a container even if that
container isn't present in the db. However, slightly overzealous error
checking causes the transaction to get rolled back. Ignore the error
from Delete on the container itself, since it may not be present.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>

Aaron Lehmann authored on 2017/07/27 08:43:10
Showing 2 changed files
... ...
@@ -168,9 +168,9 @@ func (db *memDB) Delete(c *Container) error {
168 168
 			txn.Delete(memdbNamesTable, nameAssociation{name: name})
169 169
 		}
170 170
 
171
-		if err := txn.Delete(memdbContainersTable, NewBaseContainer(c.ID, c.Root)); err != nil {
172
-			return err
173
-		}
171
+		// Ignore error - the container may not actually exist in the
172
+		// db, but we still need to clean up associated names.
173
+		txn.Delete(memdbContainersTable, NewBaseContainer(c.ID, c.Root))
174 174
 		return nil
175 175
 	})
176 176
 }
... ...
@@ -150,4 +150,12 @@ func TestNames(t *testing.T) {
150 150
 
151 151
 	view = db.Snapshot()
152 152
 	assert.Equal(t, map[string][]string{"containerid1": {"name1", "name3", "name4"}, "containerid4": {"name2"}}, view.GetAllNames())
153
+
154
+	// Release containerid1's names with Delete even though no container exists
155
+	assert.NoError(t, db.Delete(&Container{ID: "containerid1"}))
156
+
157
+	// Reusing one of those names should work
158
+	assert.NoError(t, db.ReserveName("name1", "containerid4"))
159
+	view = db.Snapshot()
160
+	assert.Equal(t, map[string][]string{"containerid4": {"name1", "name2"}}, view.GetAllNames())
153 161
 }