Beispiel #1
0
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())
	}
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
0
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
	}
}
Beispiel #5
0
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())
}
Beispiel #6
0
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
}
Beispiel #8
0
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
}
Beispiel #9
0
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
}
Beispiel #10
0
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
}
Beispiel #11
0
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"))
}
Beispiel #12
0
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.")
}
Beispiel #13
0
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
}
Beispiel #14
0
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
}
Beispiel #15
0
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
}
Beispiel #16
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))
	}
}
Beispiel #19
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())
			}
Beispiel #21
0
			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{
Beispiel #22
0
	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() {
Beispiel #23
0
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
Beispiel #26
0
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))
Beispiel #28
0
	"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{})
Beispiel #29
0
				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())