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 (store *GardenStore) transitionToComplete(logger lager.Logger, gardenContainer garden.Container, result executor.ContainerRunResult) error { resultJson, err := json.Marshal(result) if err != nil { return err } err = gardenContainer.SetProperty(ContainerResultProperty, string(resultJson)) if err != nil { return err } err = gardenContainer.SetProperty(ContainerStateProperty, string(executor.StateCompleted)) if err != nil { return err } executorContainer, err := store.exchanger.Info(logger, gardenContainer) if err != nil { return err } store.eventEmitter.Emit(executor.NewContainerCompleteEvent(executorContainer)) return nil }
func (c *checker) run(logger lager.Logger, container garden.Container) (garden.Process, error) { logger = logger.Session("run", lager.Data{ "processPath": c.healthcheckSpec.Path, "processArgs": c.healthcheckSpec.Args, "processUser": c.healthcheckSpec.User, "processEnv": c.healthcheckSpec.Env, "processDir": c.healthcheckSpec.Dir, }) logger.Debug("starting") defer logger.Debug("finished") var proc garden.Process err := retryOnFail(c.retryInterval, func(attempt uint) (runErr error) { proc, runErr = container.Run(c.healthcheckSpec, garden.ProcessIO{}) if runErr != nil { logger.Error("failed", runErr, lager.Data{"attempt": attempt}) return runErr } logger.Debug("succeeded", lager.Data{"attempt": attempt}) return nil }) return proc, err }
func main() { flag.Parse() gclient := client.New(connection.New("tcp", "localhost:7777")) var container garden.Container containers, err := gclient.Containers(garden.Properties{}) must(err) for _, c := range containers { if c.Handle() == *containerHandle { container = c break } } if container == nil { panic("Container not found!") } process, err := container.Attach(uint32(*processId), garden.ProcessIO{}) must(err) switch *signalType { case "term": fmt.Println("Signalling term") must(process.Signal(garden.SignalTerminate)) break case "kill": fmt.Println("Signalling kill") must(process.Signal(garden.SignalKill)) break } }
func (s *GardenServer) reapContainer(container garden.Container) { s.logger.Info("reaping", lager.Data{ "handle": container.Handle(), "grace-time": s.backend.GraceTime(container).String(), }) s.backend.Destroy(container.Handle()) }
func runCommand(container garden.Container, path string, args []string) { proc, err := container.Run( garden.ProcessSpec{ Path: path, Args: args, }, ginkgoIO) Expect(err).NotTo(HaveOccurred()) exitCode, err := proc.Wait() Expect(err).NotTo(HaveOccurred()) Expect(exitCode).To(Equal(0)) }
func (b *LinuxBackend) ApplyLimits(container garden.Container, limits garden.Limits) error { if limits.CPU != (garden.CPULimits{}) { if err := container.LimitCPU(limits.CPU); err != nil { return err } } if limits.Disk != (garden.DiskLimits{}) { if err := container.LimitDisk(limits.Disk); err != nil { return err } } if limits.Bandwidth != (garden.BandwidthLimits{}) { if err := container.LimitBandwidth(limits.Bandwidth); err != nil { return err } } if limits.Memory != (garden.MemoryLimits{}) { if err := container.LimitMemory(limits.Memory); err != nil { return err } } return nil }
func runInContainer(container garden.Container, script string) (garden.Process, *gbytes.Buffer) { out := gbytes.NewBuffer() process, err := container.Run(garden.ProcessSpec{ User: "******", Path: "sh", Args: []string{"-c", script}, }, garden.ProcessIO{ Stdout: io.MultiWriter(out, GinkgoWriter), Stderr: GinkgoWriter, }) Expect(err).ToNot(HaveOccurred()) return process, out }
func listenInContainer(container garden.Container, containerPort uint32) error { _, err := container.Run(garden.ProcessSpec{ User: "******", Path: "sh", Args: []string{"-c", fmt.Sprintf("echo %d | nc -l -p %d", containerPort, containerPort)}, }, garden.ProcessIO{ Stdout: GinkgoWriter, Stderr: GinkgoWriter, }) Expect(err).ToNot(HaveOccurred()) time.Sleep(2 * time.Second) return err }
func (store *GardenStore) transitionToRunning(logger lager.Logger, gardenContainer garden.Container) error { err := gardenContainer.SetProperty(ContainerStateProperty, string(executor.StateRunning)) if err != nil { return err } executorContainer, err := store.exchanger.Info(logger, gardenContainer) if err != nil { return err } store.eventEmitter.Emit(executor.NewContainerRunningEvent(executorContainer)) return nil }
func AssertMemoryLimits(container garden.Container) { buf := make([]byte, 0, 1024*1024) stdout := bytes.NewBuffer(buf) process, err := container.Run(garden.ProcessSpec{ Path: "bin/consume.exe", Args: []string{"memory", "128"}, }, garden.ProcessIO{Stdout: stdout}) Expect(err).ShouldNot(HaveOccurred()) exitCode, err := process.Wait() Expect(err).ShouldNot(HaveOccurred()) // consume script will exit 42 if it is not killed Expect(exitCode).ToNot(Equal(42), "process did not get OOM killed") Expect(stdout.String()).To(ContainSubstring("Consumed: 3 mb")) }
func canCreateAndUseFuseFileSystem(container garden.Container, user string) { mountpoint := "/tmp/fuse-test" process, err := container.Run(garden.ProcessSpec{ User: user, Path: "mkdir", Args: []string{"-p", mountpoint}, }, garden.ProcessIO{Stdout: GinkgoWriter, Stderr: GinkgoWriter}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0), "Could not make temporary directory!") process, err = container.Run(garden.ProcessSpec{ User: user, Path: "/usr/bin/hellofs", Args: []string{mountpoint}, }, garden.ProcessIO{Stdout: GinkgoWriter, Stderr: GinkgoWriter}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0), "Failed to mount hello filesystem.") stdout := gbytes.NewBuffer() process, err = container.Run(garden.ProcessSpec{ User: user, Path: "cat", Args: []string{filepath.Join(mountpoint, "hello")}, }, garden.ProcessIO{Stdout: stdout, Stderr: GinkgoWriter}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0), "Failed to find hello file.") Expect(stdout).To(gbytes.Say("Hello World!")) process, err = container.Run(garden.ProcessSpec{ User: user, Path: "fusermount", Args: []string{"-u", mountpoint}, }, garden.ProcessIO{Stdout: GinkgoWriter, Stderr: GinkgoWriter}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0), "Failed to unmount user filesystem.") stdout2 := gbytes.NewBuffer() process, err = container.Run(garden.ProcessSpec{ User: user, Path: "ls", Args: []string{mountpoint}, }, garden.ProcessIO{Stdout: stdout2, Stderr: GinkgoWriter}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0)) Expect(stdout2).ToNot(gbytes.Say("hello"), "Fuse filesystem appears still to be visible after being unmounted.") }
func (step *taskStep) ensureBuildDirExists(container garden.Container) error { emptyTar := new(bytes.Buffer) err := tar.NewWriter(emptyTar).Close() if err != nil { return err } err = container.StreamIn(garden.StreamInSpec{ Path: step.artifactsRoot, TarStream: emptyTar, }) if err != nil { return err } return nil }
func createContainerDir(container garden.Container, dir string) error { emptyTar := new(bytes.Buffer) err := tar.NewWriter(emptyTar).Close() if err != nil { return err } err = container.StreamIn(garden.StreamInSpec{ Path: dir, TarStream: emptyTar, }) if err != nil { return err } return nil }
func ethInterfaceName(container garden.Container) string { buffer := gbytes.NewBuffer() proc, err := container.Run( garden.ProcessSpec{ Path: "sh", Args: []string{"-c", "ifconfig | grep 'Ethernet' | cut -f 1 -d ' '"}, User: "******", }, garden.ProcessIO{ Stdout: buffer, Stderr: GinkgoWriter, }, ) Expect(err).NotTo(HaveOccurred()) Expect(proc.Wait()).To(Equal(0)) contIfaceName := string(buffer.Contents()) // w3-abc-1 return contIfaceName[:len(contIfaceName)-2] + "0" // w3-abc-0 }
func checkConnection(container garden.Container, ip string, port int) error { process, err := container.Run(garden.ProcessSpec{ User: "******", Path: "sh", Args: []string{"-c", fmt.Sprintf("echo hello | nc -w1 %s %d", ip, port)}, }, garden.ProcessIO{Stdout: GinkgoWriter, Stderr: GinkgoWriter}) if err != nil { return err } exitCode, err := process.Wait() if err != nil { return err } if exitCode == 0 { return nil } else { return fmt.Errorf("Request failed. Process exited with code %d", exitCode) } }
func createContainerTestFileIn(container garden.Container, dir string) string { fileName := "bind-mount-test-file" filePath := filepath.Join(dir, fileName) process, err := container.Run(garden.ProcessSpec{ Path: "touch", Args: []string{filePath}, User: "******", }, garden.ProcessIO{nil, os.Stdout, os.Stderr}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0)) process, err = container.Run(garden.ProcessSpec{ Path: "chmod", Args: []string{"0777", filePath}, User: "******", }, garden.ProcessIO{nil, os.Stdout, os.Stderr}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0)) return fileName }
func checkFileAccess(container garden.Container, bindMountMode garden.BindMountMode, bindMountOrigin garden.BindMountOrigin, dstPath string, fileName string, privCtr, privReq bool) { readOnly := (garden.BindMountModeRO == bindMountMode) ctrOrigin := (garden.BindMountOriginContainer == bindMountOrigin) realRoot := (privReq && privCtr) // can we read a file? filePath := filepath.Join(dstPath, fileName) var user string if privReq { user = "******" } else { user = "******" } process, err := container.Run(garden.ProcessSpec{ Path: "cat", Args: []string{filePath}, User: user, }, garden.ProcessIO{}) Expect(err).ToNot(HaveOccurred()) Expect(process.Wait()).To(Equal(0)) // try to write a new file filePath = filepath.Join(dstPath, "checkFileAccess-file") process, err = container.Run(garden.ProcessSpec{ Path: "touch", Args: []string{filePath}, User: user, }, garden.ProcessIO{ Stderr: GinkgoWriter, Stdout: GinkgoWriter, }) Expect(err).ToNot(HaveOccurred()) if readOnly || (!realRoot && !ctrOrigin) { Expect(process.Wait()).ToNot(Equal(0)) } else { Expect(process.Wait()).To(Equal(0)) } // try to delete an existing file filePath = filepath.Join(dstPath, fileName) process, err = container.Run(garden.ProcessSpec{ Path: "rm", Args: []string{filePath}, User: user, }, garden.ProcessIO{}) Expect(err).ToNot(HaveOccurred()) if readOnly || (!realRoot && !ctrOrigin) { Expect(process.Wait()).ToNot(Equal(0)) } else { Expect(process.Wait()).To(Equal(0)) } }
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) }
Expect(err).ToNot(HaveOccurred()) Expect(exitStatus).To(Equal(0)) Expect(stdout).To(gbytes.Say(`lo:0`)) cat := exec.Command("ifconfig") catSession, err := gexec.Start(cat, GinkgoWriter, GinkgoWriter) Expect(err).ToNot(HaveOccurred()) Eventually(catSession).Should(gexec.Exit(0)) Expect(catSession).ToNot(gbytes.Say("lo:0")) }) }) Describe("IPC namespace", func() { var sharedDir string var container garden.Container BeforeEach(func() { var err error sharedDir, err = ioutil.TempDir("", "shared-mount") Expect(err).ToNot(HaveOccurred()) Expect(os.MkdirAll(sharedDir, 0755)).To(Succeed()) }) AfterEach(func() { if container != nil { Expect(client.Destroy(container.Handle())).To(Succeed()) } if sharedDir != "" { Expect(os.RemoveAll(sharedDir)).To(Succeed()) }
Expect(err).ToNot(HaveOccurred()) _, err = http.Get(fmt.Sprintf("http://%s/log-level -X PUT -d info", debugAddr)) Expect(err).ToNot(HaveOccurred()) _, err = http.Get(fmt.Sprintf("http://%s/log-level -X PUT -d error", debugAddr)) Expect(err).ToNot(HaveOccurred()) _, err = http.Get(fmt.Sprintf("http://%s/log-level -X PUT -d fatal", debugAddr)) Expect(err).ToNot(HaveOccurred()) }) Describe("vars", func() { var ( diskLimits garden.DiskLimits container garden.Container vars map[string]interface{} ) BeforeEach(func() { diskLimits = garden.DiskLimits{ ByteHard: 10 * 1024 * 1024, Scope: garden.DiskLimitScopeExclusive, } }) JustBeforeEach(func() { var err error container, err = client.Create(garden.ContainerSpec{ Limits: garden.Limits{
Expect(err).ShouldNot(HaveOccurred()) return c } func StreamIn(c garden.Container) error { tarFile, err := os.Open("../../greenhouse-security-fixtures/output/SecurityFixtures.tgz") Expect(err).ShouldNot(HaveOccurred()) defer tarFile.Close() return c.StreamIn(garden.StreamInSpec{Path: "bin", TarStream: tarFile}) } var _ = XDescribe("Breakout", func() { Describe("a started process", func() { Describe("breaking out", func() { var ( container garden.Container pingProcess ps.Process ) BeforeEach(func() { container = createContainer() }) AfterEach(func() { if pingProcess == nil { return } process, err := os.FindProcess(pingProcess.Pid()) if err == nil { process.Kill() } }) It("is not allowed", func() {
func StreamIn(c garden.Container) error { tarFile, err := os.Open("../../greenhouse-security-fixtures/output/SecurityFixtures.tgz") Expect(err).ShouldNot(HaveOccurred()) defer tarFile.Close() return c.StreamIn(garden.StreamInSpec{Path: "bin", TarStream: tarFile}) }
package lifecycle import ( "bytes" "os" "time" "github.com/cloudfoundry-incubator/garden" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Lifecycle", func() { var c garden.Container var err error JustBeforeEach(func() { client = startGarden() c, err = client.Create(garden.ContainerSpec{}) Expect(err).ToNot(HaveOccurred()) }) AfterEach(func() { err := client.Destroy(c.Handle()) Expect(err).ShouldNot(HaveOccurred()) }) Describe("process", func() { It("pid is returned", func() { tarFile, err := os.Open("../bin/consume.tar") Expect(err).ShouldNot(HaveOccurred())
"github.com/gorilla/websocket" "github.com/onsi/gomega/gbytes" "github.com/onsi/gomega/ghttp" "github.com/pivotal-golang/lager/lagertest" "net/http" "net/url" ) func uint64ptr(n uint64) *uint64 { return &n } var _ = Describe("container", func() { var server *ghttp.Server var container garden.Container var logger *lagertest.TestLogger var client *dotnet.Client var externalIP string BeforeEach(func() { server = ghttp.NewServer() externalIP = "10.11.12.13" logger = lagertest.NewTestLogger("container") serverUri, _ := url.Parse(server.URL()) client = dotnet.NewClient(logger, serverUri) container = netContainer.NewContainer(client, "containerhandle", logger) }) AfterEach(func() { //shut down the server between tests
package gardener_test import ( "github.com/cloudfoundry-incubator/garden" "github.com/cloudfoundry-incubator/guardian/gardener" "github.com/cloudfoundry-incubator/guardian/gardener/fakes" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Container", func() { var ( container garden.Container propertyManager *fakes.FakePropertyManager ) Describe("Properties", func() { BeforeEach(func() { propertyManager = new(fakes.FakePropertyManager) container = gardener.NewContainer(nil, "some-handle", nil, nil, propertyManager) }) It("delegates to the property manager for Properties", func() { container.Properties() Expect(propertyManager.AllCallCount()).To(Equal(1)) handle := propertyManager.AllArgsForCall(0) Expect(handle).To(Equal("some-handle")) }) It("delegates to the property manager for SetProperty", func() { container.SetProperty("name", "value")
num *uint64 } func (w *byteCounterWriter) Write(d []byte) (int, error) { atomic.AddUint64(w.num, uint64(len(d))) return len(d), nil } func (w *byteCounterWriter) Close() error { return nil } var _ = Describe("The Garden server", func() { runtime.GOMAXPROCS(runtime.NumCPU()) var container garden.Container var firstGoroutineCount uint64 var debugAddr string BeforeEach(func() { firstGoroutineCount = 0 debugAddr = fmt.Sprintf("0.0.0.0:%d", 15000+GinkgoParallelNode()) client = startGarden("--debugAddr", debugAddr) var err error container, err = client.Create(garden.ContainerSpec{}) Expect(err).ToNot(HaveOccurred()) }) getGoroutineCount := func(printIt ...bool) uint64 { resp, err := http.Get(fmt.Sprintf("http://%s/debug/pprof/goroutine?debug=1", debugAddr))
"io/ioutil" "net" "strings" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/gbytes" "github.com/cloudfoundry-incubator/garden" . "github.com/cloudfoundry-incubator/garden/client" "github.com/cloudfoundry-incubator/garden/client/connection/fakes" wfakes "github.com/cloudfoundry-incubator/garden/fakes" ) var _ = Describe("Container", func() { var container garden.Container var fakeConnection *fakes.FakeConnection BeforeEach(func() { fakeConnection = new(fakes.FakeConnection) }) JustBeforeEach(func() { var err error client := New(fakeConnection) fakeConnection.CreateReturns("some-handle", nil) container, err = client.Create(garden.ContainerSpec{})
for i := 0; i < 2; i++ { handle, name, value := propertyManager.SetArgsForCall(i) Expect(handle).To(Equal("something")) allProps[name] = value } Expect(allProps).To(Equal(map[string]string{ "blingy": "bling", "thingy": "thing", })) }) }) }) Context("when having a container", func() { var container garden.Container BeforeEach(func() { var err error container, err = gdnr.Lookup("banana") Expect(err).NotTo(HaveOccurred()) }) Describe("running a process in a container", func() { It("asks the containerizer to run the process", func() { origSpec := garden.ProcessSpec{Path: "ripe"} origIO := garden.ProcessIO{ Stdout: gbytes.NewBuffer(), } _, err := container.Run(origSpec, origIO) Expect(err).ToNot(HaveOccurred())
containers, err := client.Containers(nil) Expect(err).ToNot(HaveOccurred()) Expect(containers).To(HaveLen(2)) bulkInfo, err := client.BulkInfo(handles) Expect(err).ToNot(HaveOccurred()) Expect(bulkInfo).To(HaveLen(2)) for _, containerInfoEntry := range bulkInfo { Expect(containerInfoEntry.Err).ToNot(HaveOccurred()) } }) }) }) Describe("for a single container", func() { var container garden.Container BeforeEach(func() { var err error container, err = client.Create(garden.ContainerSpec{ Properties: garden.Properties{ "foo": "bar", "a": "b", }, }) Expect(err).ToNot(HaveOccurred()) }) AfterEach(func() { client.Destroy(container.Handle())