| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
"os" |
| 7 | 7 |
"path" |
| 8 | 8 |
"path/filepath" |
| 9 |
+ "strings" |
|
| 9 | 10 |
"time" |
| 10 | 11 |
) |
| 11 | 12 |
|
| ... | ... |
@@ -103,12 +104,44 @@ func (graph *Graph) Garbage() (*Graph, error) {
|
| 103 | 103 |
return NewGraph(path.Join(graph.Root, ":garbage:")) |
| 104 | 104 |
} |
| 105 | 105 |
|
| 106 |
+// Check if given error is "not empty" |
|
| 107 |
+// Note: this is the way golang do it internally with os.IsNotExists |
|
| 108 |
+func isNotEmpty(err error) bool {
|
|
| 109 |
+ switch pe := err.(type) {
|
|
| 110 |
+ case nil: |
|
| 111 |
+ return false |
|
| 112 |
+ case *os.PathError: |
|
| 113 |
+ err = pe.Err |
|
| 114 |
+ case *os.LinkError: |
|
| 115 |
+ err = pe.Err |
|
| 116 |
+ } |
|
| 117 |
+ return strings.Contains(err.Error(), " not empty") |
|
| 118 |
+} |
|
| 119 |
+ |
|
| 106 | 120 |
func (graph *Graph) Delete(id string) error {
|
| 107 | 121 |
garbage, err := graph.Garbage() |
| 108 | 122 |
if err != nil {
|
| 109 | 123 |
return err |
| 110 | 124 |
} |
| 111 |
- return os.Rename(graph.imageRoot(id), garbage.imageRoot(id)) |
|
| 125 |
+ err = os.Rename(graph.imageRoot(id), garbage.imageRoot(id)) |
|
| 126 |
+ if err != nil {
|
|
| 127 |
+ if isNotEmpty(err) {
|
|
| 128 |
+ Debugf("The image %s is already present in garbage. Removing it.", id)
|
|
| 129 |
+ if err = os.RemoveAll(garbage.imageRoot(id)); err != nil {
|
|
| 130 |
+ Debugf("Error while removing the image %s from garbage: %s\n", id, err)
|
|
| 131 |
+ return err |
|
| 132 |
+ } |
|
| 133 |
+ Debugf("Image %s removed from garbage", id)
|
|
| 134 |
+ if err = os.Rename(graph.imageRoot(id), garbage.imageRoot(id)); err != nil {
|
|
| 135 |
+ return err |
|
| 136 |
+ } |
|
| 137 |
+ Debugf("Image %s put in the garbage", id)
|
|
| 138 |
+ } else {
|
|
| 139 |
+ Debugf("Error putting the image %s to garbage: %s\n", id, err)
|
|
| 140 |
+ } |
|
| 141 |
+ return err |
|
| 142 |
+ } |
|
| 143 |
+ return nil |
|
| 112 | 144 |
} |
| 113 | 145 |
|
| 114 | 146 |
func (graph *Graph) Undelete(id string) error {
|