Browse code

Merge remote-tracking branch 'origin/174-remove_image_twice-fix'

Solomon Hykes authored on 2013/03/29 03:48:41
Showing 2 changed files
... ...
@@ -110,12 +110,44 @@ func (graph *Graph) Garbage() (*Graph, error) {
110 110
 	return NewGraph(path.Join(graph.Root, ":garbage:"))
111 111
 }
112 112
 
113
+// Check if given error is "not empty"
114
+// Note: this is the way golang do it internally with os.IsNotExists
115
+func isNotEmpty(err error) bool {
116
+	switch pe := err.(type) {
117
+	case nil:
118
+		return false
119
+	case *os.PathError:
120
+		err = pe.Err
121
+	case *os.LinkError:
122
+		err = pe.Err
123
+	}
124
+	return strings.Contains(err.Error(), " not empty")
125
+}
126
+
113 127
 func (graph *Graph) Delete(id string) error {
114 128
 	garbage, err := graph.Garbage()
115 129
 	if err != nil {
116 130
 		return err
117 131
 	}
118
-	return os.Rename(graph.imageRoot(id), garbage.imageRoot(id))
132
+	err = os.Rename(graph.imageRoot(id), garbage.imageRoot(id))
133
+	if err != nil {
134
+		if isNotEmpty(err) {
135
+			Debugf("The image %s is already present in garbage. Removing it.", id)
136
+			if err = os.RemoveAll(garbage.imageRoot(id)); err != nil {
137
+				Debugf("Error while removing the image %s from garbage: %s\n", id, err)
138
+				return err
139
+			}
140
+			Debugf("Image %s removed from garbage", id)
141
+			if err = os.Rename(graph.imageRoot(id), garbage.imageRoot(id)); err != nil {
142
+				return err
143
+			}
144
+			Debugf("Image %s put in the garbage", id)
145
+		} else {
146
+			Debugf("Error putting the image %s to garbage: %s\n", id, err)
147
+		}
148
+		return err
149
+	}
150
+	return nil
119 151
 }
120 152
 
121 153
 func (graph *Graph) Undelete(id string) error {
... ...
@@ -158,6 +158,14 @@ func TestDelete(t *testing.T) {
158 158
 	}
159 159
 	assertNImages(graph, t, 1)
160 160
 
161
+	// Test delete twice (pull -> rm -> pull -> rm)
162
+	if err := graph.Register(archive, img1); err != nil {
163
+		t.Fatal(err)
164
+	}
165
+	if err := graph.Delete(img1.Id); err != nil {
166
+		t.Fatal(err)
167
+	}
168
+	assertNImages(graph, t, 1)
161 169
 }
162 170
 
163 171
 func assertNImages(graph *Graph, t *testing.T, n int) {