| ... | ... |
@@ -968,3 +968,66 @@ func TestRunCidFile(t *testing.T) {
|
| 968 | 968 |
}) |
| 969 | 969 |
|
| 970 | 970 |
} |
| 971 |
+ |
|
| 972 |
+func TestContainerOrphaning(t *testing.T) {
|
|
| 973 |
+ |
|
| 974 |
+ // setup a temporary directory |
|
| 975 |
+ tmpDir, err := ioutil.TempDir("", "project")
|
|
| 976 |
+ if err != nil {
|
|
| 977 |
+ t.Fatal(err) |
|
| 978 |
+ } |
|
| 979 |
+ defer os.RemoveAll(tmpDir) |
|
| 980 |
+ |
|
| 981 |
+ // setup a CLI and server |
|
| 982 |
+ cli := docker.NewDockerCli(nil, os.Stdout, ioutil.Discard, testDaemonProto, testDaemonAddr) |
|
| 983 |
+ defer cleanup(globalEngine, t) |
|
| 984 |
+ srv := mkServerFromEngine(globalEngine, t) |
|
| 985 |
+ |
|
| 986 |
+ // closure to build something |
|
| 987 |
+ buildSomething := func(template string, image string) string {
|
|
| 988 |
+ dockerfile := path.Join(tmpDir, "Dockerfile") |
|
| 989 |
+ replacer := strings.NewReplacer("{IMAGE}", unitTestImageID)
|
|
| 990 |
+ contents := replacer.Replace(template) |
|
| 991 |
+ ioutil.WriteFile(dockerfile, []byte(contents), 0x777) |
|
| 992 |
+ if err := cli.CmdBuild("-t", image, tmpDir); err != nil {
|
|
| 993 |
+ t.Fatal(err) |
|
| 994 |
+ } |
|
| 995 |
+ img, err := srv.ImageInspect(image) |
|
| 996 |
+ if err != nil {
|
|
| 997 |
+ t.Fatal(err) |
|
| 998 |
+ } |
|
| 999 |
+ return img.ID |
|
| 1000 |
+ } |
|
| 1001 |
+ |
|
| 1002 |
+ // build an image |
|
| 1003 |
+ imageName := "orphan-test" |
|
| 1004 |
+ template1 := ` |
|
| 1005 |
+ from {IMAGE}
|
|
| 1006 |
+ cmd ["/bin/echo", "holla"] |
|
| 1007 |
+ ` |
|
| 1008 |
+ img1 := buildSomething(template1, imageName) |
|
| 1009 |
+ |
|
| 1010 |
+ // create a container using the fist image |
|
| 1011 |
+ if err := cli.CmdRun(imageName); err != nil {
|
|
| 1012 |
+ t.Fatal(err) |
|
| 1013 |
+ } |
|
| 1014 |
+ |
|
| 1015 |
+ // build a new image that splits lineage |
|
| 1016 |
+ template2 := ` |
|
| 1017 |
+ from {IMAGE}
|
|
| 1018 |
+ cmd ["/bin/echo", "holla"] |
|
| 1019 |
+ expose 22 |
|
| 1020 |
+ ` |
|
| 1021 |
+ buildSomething(template2, imageName) |
|
| 1022 |
+ |
|
| 1023 |
+ // remove the second image by name |
|
| 1024 |
+ resp, err := srv.ImageDelete(imageName, true) |
|
| 1025 |
+ |
|
| 1026 |
+ // see if we deleted the first image (and orphaned the container) |
|
| 1027 |
+ for _, i := range resp {
|
|
| 1028 |
+ if img1 == i.Deleted {
|
|
| 1029 |
+ t.Fatal("Orphaned image with container")
|
|
| 1030 |
+ } |
|
| 1031 |
+ } |
|
| 1032 |
+ |
|
| 1033 |
+} |