func checkHostAccess(container garden.Container, permitted bool) { info1, ierr := container.Info() Expect(ierr).ToNot(HaveOccurred()) listener, err := net.Listen("tcp", fmt.Sprintf("%s:0", info1.HostIP)) Expect(err).ToNot(HaveOccurred()) defer listener.Close() mux := http.NewServeMux() mux.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello") }) go (&http.Server{Handler: mux}).Serve(listener) port, err := strconv.Atoi(strings.Split(listener.Addr().String(), ":")[1]) Expect(err).ToNot(HaveOccurred()) err = checkConnection(container, info1.HostIP, port) if permitted { Expect(err).ToNot(HaveOccurred()) } else { Expect(err).To(HaveOccurred()) } }
func (exchanger exchanger) Info(logger lager.Logger, gardenContainer garden.Container) (executor.Container, error) { logger = logger.Session("info", lager.Data{"handle": gardenContainer.Handle()}) logger.Debug("getting-info") info, err := gardenContainer.Info() if err != nil { logger.Error("failed-getting-info", err) return executor.Container{}, err } logger.Debug("succeeded-getting-info") return garden2executor(gardenContainer.Handle(), info) }
Describe("Info", func() { Describe("for a valid handle", func() { BeforeEach(func() { server.AppendHandlers( ghttp.CombineHandlers( ghttp.VerifyRequest("GET", "/api/containers/containerhandle/info"), ghttp.RespondWith(200, `{"Properties":{"Keymaster": "Gatekeeper"},"MappedPorts":[{"ContainerPort":8080,"HostPort":6543}], "ExternalIP":"`+externalIP+`"}`), func(w http.ResponseWriter, req *http.Request) { req.Body.Close() }, ), ) }) It("returns info about the container", func() { info, err := container.Info() Expect(err).NotTo(HaveOccurred()) Expect(info.Properties).Should(Equal(garden.Properties{"Keymaster": "Gatekeeper"})) Expect(info.ExternalIP).Should(Equal(externalIP)) Expect(len(info.MappedPorts)).Should(Equal(1)) Expect(info.MappedPorts[0].ContainerPort).Should(Equal(uint32(8080))) Expect(info.MappedPorts[0].HostPort).Should(Equal(uint32(6543))) }) }) Describe("for an invalid handle", func() { BeforeEach(func() { server.AppendHandlers( ghttp.CombineHandlers(
Expect(err).ToNot(HaveOccurred()) }) Measure("it should not adversely affect the rest of the API", func(b Benchmarker) { var newContainer garden.Container b.Time("creating another container", func() { var err error newContainer, err = client.Create(garden.ContainerSpec{}) Expect(err).ToNot(HaveOccurred()) }) for i := 0; i < repeats; i++ { b.Time("getting container info ("+strconv.Itoa(repeats)+"x)", func() { _, err := newContainer.Info() Expect(err).ToNot(HaveOccurred()) }) } for i := 0; i < repeats; i++ { b.Time("running a job ("+strconv.Itoa(repeats)+"x)", func() { process, err := newContainer.Run(garden.ProcessSpec{ User: "******", Path: "ls", }, garden.ProcessIO{}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0)) }) }
// TODO: Make user an explicit argument, always func runInContainer(container garden.Container, cmd string) (string, string, error) { info, err := container.Info() Ω(err).ShouldNot(HaveOccurred()) return runCommand(fmt.Sprintf("cd %v && sudo ./bin/wsh %v", info.ContainerPath, cmd)) }
}, garden.ProcessIO{ Stdout: stdout, Stderr: stderr, }) Expect(err).ToNot(HaveOccurred()) rc, err := process.Wait() Expect(err).ToNot(HaveOccurred()) Expect(rc).To(Equal(0)) Expect(stdout.Contents()).To(ContainSubstring(fmt.Sprintf(" inet addr:10.%d.0.2 ", GinkgoParallelNode()))) }) }) Describe("container's info", func() { It("has the correct host IP address", func() { info, err := container1.Info() Expect(err).ToNot(HaveOccurred()) Expect(info.HostIP).To(Equal(fmt.Sprintf("10.%d.0.1", GinkgoParallelNode()))) }) }) }) Context("when the Network parameter is not a subnet address", func() { BeforeEach(func() { containerNetwork1 = fmt.Sprintf("10.%d.0.2/24", GinkgoParallelNode()) }) Describe("container's network interface", func() { It("has the specified IP address", func() { stdout := gbytes.NewBuffer()
container, err = client.Create(garden.ContainerSpec{}) Expect(err).ToNot(HaveOccurred()) }) Context("when a request takes longer than the grace time", func() { It("is not destroyed after the request is over", func() { process, err := container.Run(garden.ProcessSpec{ User: "******", Path: "sleep", Args: []string{"5"}, }, garden.ProcessIO{}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0)) _, err = container.Info() Expect(err).ToNot(HaveOccurred()) }) }) Context("when no requests are made for longer than the grace time", func() { It("is destroyed", func() { Eventually(func() error { _, err := client.Lookup(container.Handle()) return err }, 10, 1).Should(HaveOccurred()) }) }) })
}) Context("when garden is shut down and restarted", func() { BeforeEach(func() { stopGarden() client = startGarden() Expect(client.Ping()).ToNot(HaveOccurred()) }) It("the subnet's bridge still exists", func() { cmd := exec.Command("ip", "a") Expect(cmd.CombinedOutput()).To(ContainSubstring(bridgeEvidence)) }) It("containers are still pingable", func() { info1, ierr := ctr1.Info() Expect(ierr).ToNot(HaveOccurred()) out, err := exec.Command("/bin/ping", "-c 2", info1.ContainerIP).Output() Expect(out).To(ContainSubstring(" 0% packet loss")) Expect(err).ToNot(HaveOccurred()) }) It("a container can still reach external networks", func() { Expect(checkInternet(ctr1)).To(Succeed()) }) }) }) })
defer tarFile.Close() err = c.StreamIn(garden.StreamInSpec{Path: "bin", TarStream: tarFile}) Expect(err).ShouldNot(HaveOccurred()) }) AfterEach(func() { err := client.Destroy(c.Handle()) Expect(err).ShouldNot(HaveOccurred()) }) It("Sets MappedPorts correctly in container's info", func() { httpPort, _, err := c.NetIn(0, 8080) Expect(err).To(BeNil()) sshPort, _, err := c.NetIn(0, 2222) Expect(err).To(BeNil()) info, err := c.Info() Expect(err).To(BeNil()) mapping := map[uint32]uint32{ 8080: httpPort, 2222: sshPort, } Expect(info.MappedPorts).To(HaveLen(2)) Expect(info.MappedPorts[0]).ToNot(Equal(info.MappedPorts[1])) for _, mp := range info.MappedPorts { Expect(mp.HostPort).To(Equal(mapping[mp.ContainerPort])) } }) It("overrides the container's internal port with it's external port", func() { By("Creating two NetIn mappings") const externalPort1, internalPort1 uint32 = 1000, 1001
func containerIP(ctr garden.Container) string { info, err := ctr.Info() Expect(err).ToNot(HaveOccurred()) return info.ContainerIP }
err := container.SetProperty("foo", "bar") Ω(err).ShouldNot(HaveOccurred()) value, err := container.Property("foo") Ω(err).ShouldNot(HaveOccurred()) Ω(value).Should(Equal("bar")) }) }) Context("that's unprivileged", func() { BeforeEach(func() { container = createContainer(gardenClient, garden.ContainerSpec{Privileged: false}) }) PIt("allows containers to be destroyed when wshd isn't running", func() { info, _ := container.Info() pidFile, err := os.Open(filepath.Join(info.ContainerPath, "run", "wshd.pid")) Ω(err).ShouldNot(HaveOccurred()) var pid int _, err = fmt.Fscanf(pidFile, "%d", &pid) Ω(err).ShouldNot(HaveOccurred()) _, _, err = runCommand("sudo kill -9 " + strconv.Itoa(pid)) Ω(err).ShouldNot(HaveOccurred()) err = gardenClient.Destroy(container.Handle()) Ω(err).ShouldNot(HaveOccurred()) }) It("can send TERM and KILL signals to processes (#83231270)", func() {
Expect(process.Wait()).ToNot(Equal(42), "process did not get OOM killed") }) }) Describe("a container's active job", func() { It("is still tracked", func() { process, err := container.Run(garden.ProcessSpec{ User: "******", Path: "sh", Args: []string{"-c", "while true; do echo hi; sleep 0.5; done"}, }, garden.ProcessIO{}) Expect(err).ToNot(HaveOccurred()) restartGarden(gardenArgs...) info, err := container.Info() Expect(err).ToNot(HaveOccurred()) Expect(info.ProcessIDs).To(ContainElement(process.ID())) }) }) Describe("a container's list of events", func() { It("is still reported", func() { err := container.LimitMemory(garden.MemoryLimits{4 * 1024 * 1024}) Expect(err).ToNot(HaveOccurred()) // trigger 'out of memory' event process, err := container.Run(garden.ProcessSpec{ User: "******", Path: "sh",
eventSource.Close() }) Context("when the container can be created", func() { var gardenContainer garden.Container JustBeforeEach(func() { gardenContainer = findGardenContainer(guid) }) It("returns no error", func() { Expect(runErr).NotTo(HaveOccurred()) }) It("creates it with the configured owner", func() { info, err := gardenContainer.Info() Expect(err).NotTo(HaveOccurred()) Expect(info.Properties["executor:owner"]).To(Equal(ownerName)) }) It("sets global environment variables on the container", func() { output := gbytes.NewBuffer() process, err := gardenContainer.Run(garden.ProcessSpec{ Path: "env", User: "******", }, garden.ProcessIO{ Stdout: output, }) Expect(err).NotTo(HaveOccurred())