github.com/schwarzm/garden-linux@v0.0.0-20150507151835-33bca2147c47/integration/lifecycle/nesting_test.go (about) 1 package lifecycle_test 2 3 import ( 4 "fmt" 5 "io" 6 "log" 7 "os" 8 "path/filepath" 9 10 . "github.com/onsi/ginkgo" 11 . "github.com/onsi/gomega" 12 "github.com/onsi/gomega/gbytes" 13 "github.com/onsi/gomega/gexec" 14 15 "github.com/cloudfoundry-incubator/garden" 16 gclient "github.com/cloudfoundry-incubator/garden/client" 17 gconn "github.com/cloudfoundry-incubator/garden/client/connection" 18 ) 19 20 var _ = Describe("When nested", func() { 21 nestedRootfsPath := os.Getenv("GARDEN_NESTABLE_TEST_ROOTFS") 22 if nestedRootfsPath == "" { 23 log.Println("GARDEN_NESTABLE_TEST_ROOTFS undefined; skipping nesting test") 24 return 25 } 26 27 BeforeEach(func() { 28 client = startGarden() 29 }) 30 31 startNestedGarden := func(mountOverlayOnTmpfs bool) (garden.Container, string) { 32 absoluteBinPath, err := filepath.Abs(binPath) 33 Expect(err).ToNot(HaveOccurred()) 34 35 container, err := client.Create(garden.ContainerSpec{ 36 RootFSPath: nestedRootfsPath, 37 // only privileged containers support nesting 38 Privileged: true, 39 BindMounts: []garden.BindMount{ 40 { 41 SrcPath: filepath.Dir(gardenBin), 42 DstPath: "/home/vcap/bin/", 43 Mode: garden.BindMountModeRO, 44 }, 45 { 46 SrcPath: absoluteBinPath, 47 DstPath: "/home/vcap/binpath/bin", 48 Mode: garden.BindMountModeRO, 49 }, 50 { 51 SrcPath: filepath.Join(absoluteBinPath, "..", "skeleton"), 52 DstPath: "/home/vcap/binpath/skeleton", 53 Mode: garden.BindMountModeRO, 54 }, 55 { 56 SrcPath: rootFSPath, 57 DstPath: "/home/vcap/rootfs", 58 Mode: garden.BindMountModeRO, 59 }, 60 }, 61 }) 62 Expect(err).ToNot(HaveOccurred()) 63 64 nestedServerOutput := gbytes.NewBuffer() 65 66 extraMounts := "" 67 if mountOverlayOnTmpfs { 68 extraMounts = "mount -t tmpfs tmpfs /tmp/overlays" 69 } 70 71 // start nested garden, again need to be root 72 _, err = container.Run(garden.ProcessSpec{ 73 Path: "sh", 74 User: "root", 75 Dir: "/home/vcap", 76 Args: []string{ 77 "-c", 78 fmt.Sprintf(` 79 mkdir /tmp/overlays /tmp/containers /tmp/snapshots /tmp/graph; 80 %s 81 mount -t tmpfs tmpfs /tmp/containers 82 83 ./bin/garden-linux \ 84 -bin /home/vcap/binpath/bin \ 85 -rootfs /home/vcap/rootfs \ 86 -depot /tmp/containers \ 87 -overlays /tmp/overlays \ 88 -snapshots /tmp/snapshots \ 89 -graph /tmp/graph \ 90 -disableQuotas \ 91 -listenNetwork tcp \ 92 -listenAddr 0.0.0.0:7778; 93 `, extraMounts), 94 }, 95 }, garden.ProcessIO{ 96 Stdout: io.MultiWriter(nestedServerOutput, gexec.NewPrefixedWriter("\x1b[32m[o]\x1b[34m[nested-garden-linux]\x1b[0m ", GinkgoWriter)), 97 Stderr: gexec.NewPrefixedWriter("\x1b[91m[e]\x1b[34m[nested-garden-linux]\x1b[0m ", GinkgoWriter), 98 }) 99 100 info, err := container.Info() 101 Expect(err).ToNot(HaveOccurred()) 102 103 nestedGardenAddress := fmt.Sprintf("%s:7778", info.ContainerIP) 104 Eventually(nestedServerOutput, "30s").Should(gbytes.Say("garden-linux.started")) 105 106 return container, nestedGardenAddress 107 } 108 109 It("can start a nested garden-linux and run a container inside it", func() { 110 container, nestedGardenAddress := startNestedGarden(true) 111 defer client.Destroy(container.Handle()) 112 113 nestedClient := gclient.New(gconn.New("tcp", nestedGardenAddress)) 114 nestedContainer, err := nestedClient.Create(garden.ContainerSpec{}) 115 Expect(err).ToNot(HaveOccurred()) 116 117 nestedOutput := gbytes.NewBuffer() 118 _, err = nestedContainer.Run(garden.ProcessSpec{ 119 Path: "/bin/echo", 120 Args: []string{ 121 "I am nested!", 122 }, 123 }, garden.ProcessIO{Stdout: nestedOutput, Stderr: nestedOutput}) 124 Expect(err).ToNot(HaveOccurred()) 125 126 Eventually(nestedOutput, "30s").Should(gbytes.Say("I am nested!")) 127 }) 128 129 It("returns helpful error message when depot directory fstype cannot be nested", func() { 130 container, nestedGardenAddress := startNestedGarden(false) 131 defer client.Destroy(container.Handle()) 132 133 nestedClient := gclient.New(gconn.New("tcp", nestedGardenAddress)) 134 _, err := nestedClient.Create(garden.ContainerSpec{}) 135 Expect(err).To(MatchError("overlay.sh: exit status 222, the directories that contain the depot and rootfs must be mounted on a filesystem type that supports aufs or overlayfs")) 136 }) 137 })