... | ... |
@@ -54,7 +54,7 @@ func (srv *Server) Help() string { |
54 | 54 |
{"reset", "Reset changes to a container's filesystem"}, |
55 | 55 |
{"restart", "Restart a running container"}, |
56 | 56 |
{"rm", "Remove a container"}, |
57 |
- {"rmimage", "Remove an image"}, |
|
57 |
+ {"rmi", "Remove an image"}, |
|
58 | 58 |
{"run", "Run a command in a new container"}, |
59 | 59 |
{"start", "Start a stopped container"}, |
60 | 60 |
{"stop", "Stop a running container"}, |
... | ... |
@@ -356,29 +356,27 @@ func (srv *Server) CmdPort(stdin io.ReadCloser, stdout io.Writer, args ...string |
356 | 356 |
} |
357 | 357 |
|
358 | 358 |
// 'docker rmi NAME' removes all images with the name NAME |
359 |
-func (srv *Server) CmdRmi(stdin io.ReadCloser, stdout io.Writer, args ...string) error { |
|
359 |
+func (srv *Server) CmdRmi(stdin io.ReadCloser, stdout io.Writer, args ...string) (err error) { |
|
360 | 360 |
cmd := rcli.Subcmd(stdout, "rmimage", "[OPTIONS] IMAGE", "Remove an image") |
361 | 361 |
fl_all := cmd.Bool("a", false, "Use IMAGE as a path and remove ALL images in this path") |
362 |
- if err := cmd.Parse(args); err != nil { |
|
363 |
- cmd.Usage() |
|
364 |
- return nil |
|
365 |
- } |
|
366 |
- if cmd.NArg() < 1 { |
|
362 |
+ fl_regexp := cmd.Bool("r", false, "Use IMAGE as a regular expression instead of an exact name") |
|
363 |
+ if cmd.Parse(args) != nil || cmd.NArg() < 1 { |
|
367 | 364 |
cmd.Usage() |
368 | 365 |
return nil |
369 | 366 |
} |
370 | 367 |
for _, name := range cmd.Args() { |
371 |
- var err error |
|
372 |
- if *fl_all { |
|
368 |
+ if *fl_regexp { |
|
369 |
+ err = srv.images.RemoveRegexp(name) |
|
370 |
+ } else if *fl_all { |
|
373 | 371 |
err = srv.images.RemoveInPath(name) |
374 | 372 |
} else { |
375 |
- image, err := srv.images.Get(name) |
|
376 |
- if err != nil { |
|
377 |
- return err |
|
378 |
- } else if image == nil { |
|
379 |
- return errors.New("No such image: " + name) |
|
373 |
+ if image, err1 := srv.images.Find(name); err1 != nil { |
|
374 |
+ err = err1 |
|
375 |
+ } else if err1 == nil && image == nil { |
|
376 |
+ err = fmt.Errorf("No such image: %s", name) |
|
377 |
+ } else { |
|
378 |
+ err = srv.images.Remove(image) |
|
380 | 379 |
} |
381 |
- err = srv.images.Remove(image) |
|
382 | 380 |
} |
383 | 381 |
if err != nil { |
384 | 382 |
return err |
... | ... |
@@ -6,6 +6,7 @@ import ( |
6 | 6 |
"io/ioutil" |
7 | 7 |
"os" |
8 | 8 |
"os/exec" |
9 |
+ "os/user" |
|
9 | 10 |
"testing" |
10 | 11 |
) |
11 | 12 |
|
... | ... |
@@ -42,6 +43,12 @@ func init() { |
42 | 42 |
return |
43 | 43 |
} |
44 | 44 |
|
45 |
+ if usr, err := user.Current(); err != nil { |
|
46 |
+ panic(err) |
|
47 |
+ } else if usr.Uid != "0" { |
|
48 |
+ panic("docker tests needs to be run as root") |
|
49 |
+ } |
|
50 |
+ |
|
45 | 51 |
// Create a temp directory |
46 | 52 |
root, err := ioutil.TempDir("", "docker-test") |
47 | 53 |
if err != nil { |
48 | 54 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,223 @@ |
0 |
+package fs |
|
1 |
+ |
|
2 |
+import ( |
|
3 |
+ "fmt" |
|
4 |
+ "github.com/dotcloud/docker/fake" |
|
5 |
+ "testing" |
|
6 |
+) |
|
7 |
+ |
|
8 |
+func countImages(store *Store) int { |
|
9 |
+ paths, err := store.Images() |
|
10 |
+ if err != nil { |
|
11 |
+ panic(err) |
|
12 |
+ } |
|
13 |
+ return len(paths) |
|
14 |
+} |
|
15 |
+ |
|
16 |
+func TestRemoveInPath(t *testing.T) { |
|
17 |
+ store, err := TempStore("test-remove-in-path") |
|
18 |
+ if err != nil { |
|
19 |
+ t.Fatal(err) |
|
20 |
+ } |
|
21 |
+ defer nuke(store) |
|
22 |
+ archive, err := fake.FakeTar() |
|
23 |
+ if err != nil { |
|
24 |
+ t.Fatal(err) |
|
25 |
+ } |
|
26 |
+ if c := countImages(store); c != 0 { |
|
27 |
+ t.Fatalf("Expected 0 images, %d found", c) |
|
28 |
+ } |
|
29 |
+ |
|
30 |
+ // Test 10 create / Delete all |
|
31 |
+ for i := 0; i < 10; i++ { |
|
32 |
+ if _, err := store.Create(archive, nil, "foo", "Testing"); err != nil { |
|
33 |
+ t.Fatal(err) |
|
34 |
+ } |
|
35 |
+ } |
|
36 |
+ if c := countImages(store); c != 10 { |
|
37 |
+ t.Fatalf("Expected 10 images, %d found", c) |
|
38 |
+ } |
|
39 |
+ if err := store.RemoveInPath("foo"); err != nil { |
|
40 |
+ t.Fatal(err) |
|
41 |
+ } |
|
42 |
+ if c := countImages(store); c != 0 { |
|
43 |
+ t.Fatalf("Expected 0 images, %d found", c) |
|
44 |
+ } |
|
45 |
+ |
|
46 |
+ // Test 10 create / Delete 1 |
|
47 |
+ for i := 0; i < 10; i++ { |
|
48 |
+ if _, err := store.Create(archive, nil, fmt.Sprintf("foo-%d", i), "Testing"); err != nil { |
|
49 |
+ t.Fatal(err) |
|
50 |
+ } |
|
51 |
+ } |
|
52 |
+ if c := countImages(store); c != 10 { |
|
53 |
+ t.Fatalf("Expected 10 images, %d found", c) |
|
54 |
+ } |
|
55 |
+ if err := store.RemoveInPath("foo-0"); err != nil { |
|
56 |
+ t.Fatal(err) |
|
57 |
+ } |
|
58 |
+ if c := countImages(store); c != 9 { |
|
59 |
+ t.Fatalf("Expected 9 images, %d found", c) |
|
60 |
+ } |
|
61 |
+ |
|
62 |
+ // Delete failure |
|
63 |
+ if err := store.RemoveInPath("Not_Foo"); err != nil { |
|
64 |
+ t.Fatal(err) |
|
65 |
+ } |
|
66 |
+ if c := countImages(store); c != 9 { |
|
67 |
+ t.Fatalf("Expected 9 images, %d found", c) |
|
68 |
+ } |
|
69 |
+} |
|
70 |
+ |
|
71 |
+func TestRemove(t *testing.T) { |
|
72 |
+ store, err := TempStore("test-remove") |
|
73 |
+ if err != nil { |
|
74 |
+ t.Fatal(err) |
|
75 |
+ } |
|
76 |
+ defer nuke(store) |
|
77 |
+ archive, err := fake.FakeTar() |
|
78 |
+ if err != nil { |
|
79 |
+ t.Fatal(err) |
|
80 |
+ } |
|
81 |
+ if c := countImages(store); c != 0 { |
|
82 |
+ t.Fatalf("Expected 0 images, %d found", c) |
|
83 |
+ } |
|
84 |
+ |
|
85 |
+ // Test 1 create / 1 delete |
|
86 |
+ img, err := store.Create(archive, nil, "foo", "Testing") |
|
87 |
+ if err != nil { |
|
88 |
+ t.Fatal(err) |
|
89 |
+ } |
|
90 |
+ if c := countImages(store); c != 1 { |
|
91 |
+ t.Fatalf("Expected 1 images, %d found", c) |
|
92 |
+ } |
|
93 |
+ if err := store.Remove(img); err != nil { |
|
94 |
+ t.Fatal(err) |
|
95 |
+ } |
|
96 |
+ if c := countImages(store); c != 0 { |
|
97 |
+ t.Fatalf("Expected 0 images, %d found", c) |
|
98 |
+ } |
|
99 |
+ |
|
100 |
+ // Test 2 create (same name) / 1 delete |
|
101 |
+ img1, err := store.Create(archive, nil, "foo", "Testing") |
|
102 |
+ if err != nil { |
|
103 |
+ t.Fatal(err) |
|
104 |
+ } |
|
105 |
+ img2, err := store.Create(archive, nil, "foo", "Testing") |
|
106 |
+ if err != nil { |
|
107 |
+ t.Fatal(err) |
|
108 |
+ } |
|
109 |
+ if c := countImages(store); c != 2 { |
|
110 |
+ t.Fatalf("Expected 2 images, %d found", c) |
|
111 |
+ } |
|
112 |
+ if err := store.Remove(img1); err != nil { |
|
113 |
+ t.Fatal(err) |
|
114 |
+ } |
|
115 |
+ if c := countImages(store); c != 1 { |
|
116 |
+ t.Fatalf("Expected 1 images, %d found", c) |
|
117 |
+ } |
|
118 |
+ |
|
119 |
+ // Test delete wrong name |
|
120 |
+ // Note: If we change orm and Delete of non existing return error, we will need to change this test |
|
121 |
+ if err := store.Remove(&Image{Id: "Not_foo", store: img2.store}); err != nil { |
|
122 |
+ t.Fatal(err) |
|
123 |
+ } |
|
124 |
+ if c := countImages(store); c != 1 { |
|
125 |
+ t.Fatalf("Expected 1 images, %d found", c) |
|
126 |
+ } |
|
127 |
+ |
|
128 |
+ // Test delete last one |
|
129 |
+ if err := store.Remove(img2); err != nil { |
|
130 |
+ t.Fatal(err) |
|
131 |
+ } |
|
132 |
+ if c := countImages(store); c != 0 { |
|
133 |
+ t.Fatalf("Expected 0 images, %d found", c) |
|
134 |
+ } |
|
135 |
+} |
|
136 |
+ |
|
137 |
+func TestRemoveRegexp(t *testing.T) { |
|
138 |
+ store, err := TempStore("test-remove-regexp") |
|
139 |
+ if err != nil { |
|
140 |
+ t.Fatal(err) |
|
141 |
+ } |
|
142 |
+ defer nuke(store) |
|
143 |
+ archive, err := fake.FakeTar() |
|
144 |
+ if err != nil { |
|
145 |
+ t.Fatal(err) |
|
146 |
+ } |
|
147 |
+ if c := countImages(store); c != 0 { |
|
148 |
+ t.Fatalf("Expected 0 images, %d found", c) |
|
149 |
+ } |
|
150 |
+ |
|
151 |
+ // Test 10 create with different names / Delete all good regexp |
|
152 |
+ for i := 0; i < 10; i++ { |
|
153 |
+ if _, err := store.Create(archive, nil, fmt.Sprintf("foo-%d", i), "Testing"); err != nil { |
|
154 |
+ t.Fatal(err) |
|
155 |
+ } |
|
156 |
+ } |
|
157 |
+ if c := countImages(store); c != 10 { |
|
158 |
+ t.Fatalf("Expected 10 images, %d found", c) |
|
159 |
+ } |
|
160 |
+ if err := store.RemoveRegexp("foo"); err != nil { |
|
161 |
+ t.Fatal(err) |
|
162 |
+ } |
|
163 |
+ if c := countImages(store); c != 0 { |
|
164 |
+ t.Fatalf("Expected 0 images, %d found", c) |
|
165 |
+ } |
|
166 |
+ |
|
167 |
+ // Test 10 create with different names / Delete all good regexp globing |
|
168 |
+ for i := 0; i < 10; i++ { |
|
169 |
+ if _, err := store.Create(archive, nil, fmt.Sprintf("foo-%d", i), "Testing"); err != nil { |
|
170 |
+ t.Fatal(err) |
|
171 |
+ } |
|
172 |
+ } |
|
173 |
+ if c := countImages(store); c != 10 { |
|
174 |
+ t.Fatalf("Expected 10 images, %d found", c) |
|
175 |
+ } |
|
176 |
+ if err := store.RemoveRegexp("foo-*"); err != nil { |
|
177 |
+ t.Fatal(err) |
|
178 |
+ } |
|
179 |
+ if c := countImages(store); c != 0 { |
|
180 |
+ t.Fatalf("Expected 0 images, %d found", c) |
|
181 |
+ } |
|
182 |
+ |
|
183 |
+ // Test 10 create with different names / Delete all bad regexp |
|
184 |
+ for i := 0; i < 10; i++ { |
|
185 |
+ if _, err := store.Create(archive, nil, fmt.Sprintf("foo-%d", i), "Testing"); err != nil { |
|
186 |
+ t.Fatal(err) |
|
187 |
+ } |
|
188 |
+ } |
|
189 |
+ if c := countImages(store); c != 10 { |
|
190 |
+ t.Fatalf("Expected 10 images, %d found", c) |
|
191 |
+ } |
|
192 |
+ if err := store.RemoveRegexp("oo-*"); err != nil { |
|
193 |
+ t.Fatal(err) |
|
194 |
+ } |
|
195 |
+ if c := countImages(store); c != 0 { |
|
196 |
+ t.Fatalf("Expected 0 images, %d found", c) |
|
197 |
+ } |
|
198 |
+ |
|
199 |
+ // Test 10 create with different names / Delete none strict regexp |
|
200 |
+ for i := 0; i < 10; i++ { |
|
201 |
+ if _, err := store.Create(archive, nil, fmt.Sprintf("foo-%d", i), "Testing"); err != nil { |
|
202 |
+ t.Fatal(err) |
|
203 |
+ } |
|
204 |
+ } |
|
205 |
+ if c := countImages(store); c != 10 { |
|
206 |
+ t.Fatalf("Expected 10 images, %d found", c) |
|
207 |
+ } |
|
208 |
+ if err := store.RemoveRegexp("^oo-"); err != nil { |
|
209 |
+ t.Fatal(err) |
|
210 |
+ } |
|
211 |
+ if c := countImages(store); c != 10 { |
|
212 |
+ t.Fatalf("Expected 10 images, %d found", c) |
|
213 |
+ } |
|
214 |
+ |
|
215 |
+ // Test delete 2 |
|
216 |
+ if err := store.RemoveRegexp("^foo-[1,2]$"); err != nil { |
|
217 |
+ t.Fatal(err) |
|
218 |
+ } |
|
219 |
+ if c := countImages(store); c != 8 { |
|
220 |
+ t.Fatalf("Expected 8 images, %d found", c) |
|
221 |
+ } |
|
222 |
+} |
... | ... |
@@ -11,6 +11,7 @@ import ( |
11 | 11 |
"os" |
12 | 12 |
"path" |
13 | 13 |
"path/filepath" |
14 |
+ "regexp" |
|
14 | 15 |
"strings" |
15 | 16 |
"syscall" |
16 | 17 |
"time" |
... | ... |
@@ -105,6 +106,27 @@ func (store *Store) RemoveInPath(pth string) error { |
105 | 105 |
return nil |
106 | 106 |
} |
107 | 107 |
|
108 |
+// DeleteMatch deletes all images whose name matches `pattern` |
|
109 |
+func (store *Store) RemoveRegexp(pattern string) error { |
|
110 |
+ // Retrieve all the paths |
|
111 |
+ paths, err := store.Paths() |
|
112 |
+ if err != nil { |
|
113 |
+ return err |
|
114 |
+ } |
|
115 |
+ // Check the pattern on each elements |
|
116 |
+ for _, pth := range paths { |
|
117 |
+ if match, err := regexp.MatchString(pattern, pth); err != nil { |
|
118 |
+ return err |
|
119 |
+ } else if match { |
|
120 |
+ // If there is a match, remove it |
|
121 |
+ if err := store.RemoveInPath(pth); err != nil { |
|
122 |
+ return nil |
|
123 |
+ } |
|
124 |
+ } |
|
125 |
+ } |
|
126 |
+ return nil |
|
127 |
+} |
|
128 |
+ |
|
108 | 129 |
func (store *Store) Remove(img *Image) error { |
109 | 130 |
_, err := store.orm.Delete(img) |
110 | 131 |
return err |
... | ... |
@@ -1,7 +1,6 @@ |
1 | 1 |
package fs |
2 | 2 |
|
3 | 3 |
import ( |
4 |
- "errors" |
|
5 | 4 |
"fmt" |
6 | 5 |
"github.com/dotcloud/docker/fake" |
7 | 6 |
"github.com/dotcloud/docker/future" |
... | ... |
@@ -11,6 +10,8 @@ import ( |
11 | 11 |
"time" |
12 | 12 |
) |
13 | 13 |
|
14 |
+// FIXME: Remove the Fake package |
|
15 |
+ |
|
14 | 16 |
func TestInit(t *testing.T) { |
15 | 17 |
store, err := TempStore("testinit") |
16 | 18 |
if err != nil { |
... | ... |
@@ -26,6 +27,8 @@ func TestInit(t *testing.T) { |
26 | 26 |
} |
27 | 27 |
} |
28 | 28 |
|
29 |
+// FIXME: Do more extensive tests (ex: create multiple, delete, recreate; |
|
30 |
+// create multiple, check the amount of images and paths, etc..) |
|
29 | 31 |
func TestCreate(t *testing.T) { |
30 | 32 |
store, err := TempStore("testcreate") |
31 | 33 |
if err != nil { |
... | ... |
@@ -229,63 +232,6 @@ func TestMountpointDuplicateRoot(t *testing.T) { |
229 | 229 |
} |
230 | 230 |
} |
231 | 231 |
|
232 |
-func TestMount(t *testing.T) { |
|
233 |
- store, err := TempStore("test-mount") |
|
234 |
- if err != nil { |
|
235 |
- t.Fatal(err) |
|
236 |
- } |
|
237 |
- defer nuke(store) |
|
238 |
- archive, err := fake.FakeTar() |
|
239 |
- if err != nil { |
|
240 |
- t.Fatal(err) |
|
241 |
- } |
|
242 |
- image, err := store.Create(archive, nil, "foo", "Testing") |
|
243 |
- if err != nil { |
|
244 |
- t.Fatal(err) |
|
245 |
- } |
|
246 |
- // Create mount targets |
|
247 |
- root, err := ioutil.TempDir("", "docker-fs-test") |
|
248 |
- if err != nil { |
|
249 |
- t.Fatal(err) |
|
250 |
- } |
|
251 |
- rw, err := ioutil.TempDir("", "docker-fs-test") |
|
252 |
- if err != nil { |
|
253 |
- t.Fatal(err) |
|
254 |
- } |
|
255 |
- mountpoint, err := image.Mount(root, rw) |
|
256 |
- if err != nil { |
|
257 |
- t.Fatal(err) |
|
258 |
- } |
|
259 |
- defer mountpoint.Umount() |
|
260 |
- // Mountpoint should be marked as mounted |
|
261 |
- if !mountpoint.Mounted() { |
|
262 |
- t.Fatal("Mountpoint not mounted") |
|
263 |
- } |
|
264 |
- // There should be one mountpoint registered |
|
265 |
- if mps, err := image.Mountpoints(); err != nil { |
|
266 |
- t.Fatal(err) |
|
267 |
- } else if len(mps) != 1 { |
|
268 |
- t.Fatal("Wrong number of mountpoints registered (should be %d, not %d)", 1, len(mps)) |
|
269 |
- } |
|
270 |
- // Unmounting should work |
|
271 |
- if err := mountpoint.Umount(); err != nil { |
|
272 |
- t.Fatal(err) |
|
273 |
- } |
|
274 |
- // De-registering should work |
|
275 |
- if err := mountpoint.Deregister(); err != nil { |
|
276 |
- t.Fatal(err) |
|
277 |
- } |
|
278 |
- if mps, err := image.Mountpoints(); err != nil { |
|
279 |
- t.Fatal(err) |
|
280 |
- } else if len(mps) != 0 { |
|
281 |
- t.Fatal("Wrong number of mountpoints registered (should be %d, not %d)", 0, len(mps)) |
|
282 |
- } |
|
283 |
- // General health check |
|
284 |
- if err := healthCheck(store); err != nil { |
|
285 |
- t.Fatal(err) |
|
286 |
- } |
|
287 |
-} |
|
288 |
- |
|
289 | 232 |
func TempStore(prefix string) (*Store, error) { |
290 | 233 |
dir, err := ioutil.TempDir("", "docker-fs-test-"+prefix) |
291 | 234 |
if err != nil { |
... | ... |
@@ -314,7 +260,7 @@ func healthCheck(store *Store) error { |
314 | 314 |
for _, img := range images { |
315 | 315 |
// Check for duplicate IDs per path |
316 | 316 |
if _, exists := IDs[img.Id]; exists { |
317 |
- return errors.New(fmt.Sprintf("Duplicate ID: %s", img.Id)) |
|
317 |
+ return fmt.Errorf("Duplicate ID: %s", img.Id) |
|
318 | 318 |
} else { |
319 | 319 |
IDs[img.Id] = true |
320 | 320 |
} |
... | ... |
@@ -327,7 +273,7 @@ func healthCheck(store *Store) error { |
327 | 327 |
// Check non-existing parents |
328 | 328 |
for parent := range parents { |
329 | 329 |
if _, exists := parents[parent]; !exists { |
330 |
- return errors.New("Reference to non-registered parent: " + parent) |
|
330 |
+ return fmt.Errorf("Reference to non-registered parent: %s", parent) |
|
331 | 331 |
} |
332 | 332 |
} |
333 | 333 |
return nil |
334 | 334 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,115 @@ |
0 |
+package docker |
|
1 |
+ |
|
2 |
+import ( |
|
3 |
+ "fmt" |
|
4 |
+ "github.com/dotcloud/docker/fake" |
|
5 |
+ "github.com/dotcloud/docker/fs" |
|
6 |
+ "io/ioutil" |
|
7 |
+ "os" |
|
8 |
+ "testing" |
|
9 |
+) |
|
10 |
+ |
|
11 |
+// Look for inconsistencies in a store. |
|
12 |
+func healthCheck(store *fs.Store) error { |
|
13 |
+ parents := make(map[string]bool) |
|
14 |
+ paths, err := store.Paths() |
|
15 |
+ if err != nil { |
|
16 |
+ return err |
|
17 |
+ } |
|
18 |
+ for _, path := range paths { |
|
19 |
+ images, err := store.List(path) |
|
20 |
+ if err != nil { |
|
21 |
+ return err |
|
22 |
+ } |
|
23 |
+ IDs := make(map[string]bool) // All IDs for this path |
|
24 |
+ for _, img := range images { |
|
25 |
+ // Check for duplicate IDs per path |
|
26 |
+ if _, exists := IDs[img.Id]; exists { |
|
27 |
+ return fmt.Errorf("Duplicate ID: %s", img.Id) |
|
28 |
+ } else { |
|
29 |
+ IDs[img.Id] = true |
|
30 |
+ } |
|
31 |
+ // Store parent for 2nd pass |
|
32 |
+ if parent := img.Parent; parent != "" { |
|
33 |
+ parents[parent] = true |
|
34 |
+ } |
|
35 |
+ } |
|
36 |
+ } |
|
37 |
+ // Check non-existing parents |
|
38 |
+ for parent := range parents { |
|
39 |
+ if _, exists := parents[parent]; !exists { |
|
40 |
+ return fmt.Errorf("Reference to non-registered parent: %s", parent) |
|
41 |
+ } |
|
42 |
+ } |
|
43 |
+ return nil |
|
44 |
+} |
|
45 |
+ |
|
46 |
+// Note: This test is in the docker package because he needs to be run as root |
|
47 |
+func TestMount(t *testing.T) { |
|
48 |
+ dir, err := ioutil.TempDir("", "docker-fs-test-mount") |
|
49 |
+ if err != nil { |
|
50 |
+ t.Fatal(err) |
|
51 |
+ } |
|
52 |
+ defer os.RemoveAll(dir) |
|
53 |
+ |
|
54 |
+ store, err := fs.New(dir) |
|
55 |
+ if err != nil { |
|
56 |
+ t.Fatal(err) |
|
57 |
+ } |
|
58 |
+ |
|
59 |
+ archive, err := fake.FakeTar() |
|
60 |
+ if err != nil { |
|
61 |
+ t.Fatal(err) |
|
62 |
+ } |
|
63 |
+ |
|
64 |
+ image, err := store.Create(archive, nil, "foo", "Testing") |
|
65 |
+ if err != nil { |
|
66 |
+ t.Fatal(err) |
|
67 |
+ } |
|
68 |
+ |
|
69 |
+ // Create mount targets |
|
70 |
+ root, err := ioutil.TempDir("", "docker-fs-test") |
|
71 |
+ if err != nil { |
|
72 |
+ t.Fatal(err) |
|
73 |
+ } |
|
74 |
+ defer os.RemoveAll(root) |
|
75 |
+ |
|
76 |
+ rw, err := ioutil.TempDir("", "docker-fs-test") |
|
77 |
+ if err != nil { |
|
78 |
+ t.Fatal(err) |
|
79 |
+ } |
|
80 |
+ defer os.RemoveAll(rw) |
|
81 |
+ |
|
82 |
+ mountpoint, err := image.Mount(root, rw) |
|
83 |
+ if err != nil { |
|
84 |
+ t.Fatal(err) |
|
85 |
+ } |
|
86 |
+ defer mountpoint.Umount() |
|
87 |
+ // Mountpoint should be marked as mounted |
|
88 |
+ if !mountpoint.Mounted() { |
|
89 |
+ t.Fatal("Mountpoint not mounted") |
|
90 |
+ } |
|
91 |
+ // There should be one mountpoint registered |
|
92 |
+ if mps, err := image.Mountpoints(); err != nil { |
|
93 |
+ t.Fatal(err) |
|
94 |
+ } else if len(mps) != 1 { |
|
95 |
+ t.Fatal("Wrong number of mountpoints registered (should be %d, not %d)", 1, len(mps)) |
|
96 |
+ } |
|
97 |
+ // Unmounting should work |
|
98 |
+ if err := mountpoint.Umount(); err != nil { |
|
99 |
+ t.Fatal(err) |
|
100 |
+ } |
|
101 |
+ // De-registering should work |
|
102 |
+ if err := mountpoint.Deregister(); err != nil { |
|
103 |
+ t.Fatal(err) |
|
104 |
+ } |
|
105 |
+ if mps, err := image.Mountpoints(); err != nil { |
|
106 |
+ t.Fatal(err) |
|
107 |
+ } else if len(mps) != 0 { |
|
108 |
+ t.Fatal("Wrong number of mountpoints registered (should be %d, not %d)", 0, len(mps)) |
|
109 |
+ } |
|
110 |
+ // General health check |
|
111 |
+ if err := healthCheck(store); err != nil { |
|
112 |
+ t.Fatal(err) |
|
113 |
+ } |
|
114 |
+} |