Beispiel #1
0
func (p *provider) ProvideContainer(spec linux_backend.LinuxContainerSpec) linux_backend.Container {
	cgroupReader := &cgroups_manager.LinuxCgroupReader{
		Path: p.sysconfig.CgroupNodeFilePath,
	}

	cgroupsManager := cgroups_manager.New(p.sysconfig.CgroupPath, spec.ID, cgroupReader)

	oomWatcher := linux_container.NewOomNotifier(
		p.runner, spec.ContainerPath, cgroupsManager,
	)

	return linux_container.NewLinuxContainer(
		spec,
		p.portPool,
		p.runner,
		cgroupsManager,
		p.quotaManager,
		bandwidth_manager.New(spec.ContainerPath, spec.ID, p.runner),
		process_tracker.New(spec.ContainerPath, p.runner),
		p.ProvideFilter(spec.ID),
		p.ipTablesMgr,
		devices.Link{Name: p.sysconfig.NetworkInterfacePrefix + spec.ID + "-0"},
		oomWatcher,
		p.log.Session("container", lager.Data{"handle": spec.Handle}),
	)
}
	BeforeEach(func() {
		var err error

		tmpdir, err = ioutil.TempDir("", "process-tracker-tests")
		Expect(err).ToNot(HaveOccurred())

		err = os.MkdirAll(filepath.Join(tmpdir, "bin"), 0755)
		Expect(err).ToNot(HaveOccurred())

		err = copyFile(iodaemonBin, filepath.Join(tmpdir, "bin", "iodaemon"))
		Expect(err).ToNot(HaveOccurred())

		signaller = &process_tracker.LinkSignaller{}

		processTracker = process_tracker.New(tmpdir, linux_command_runner.New())
	})

	AfterEach(func() {
		os.RemoveAll(tmpdir)
	})

	Describe("Running processes", func() {
		It("runs the process and returns its exit code", func() {
			cmd := exec.Command("bash", "-c", "exit 42")

			process, err := processTracker.Run(555, cmd, garden.ProcessIO{}, nil, signaller)
			Expect(err).NotTo(HaveOccurred())

			status, err := process.Wait()
			Expect(err).ToNot(HaveOccurred())
Beispiel #3
0
func (c *RuncContainerCreator) Create(spec garden.ContainerSpec) (*Container, error) {
	dir, err := c.Depot.Create()
	if err != nil {
		return nil, fmt.Errorf("create depot dir: %s", err)
	}

	if len(spec.RootFSPath) == 0 {
		spec.RootFSPath = c.DefaultRootfs
	}

	rootfs, err := url.Parse(spec.RootFSPath)
	if err != nil {
		return nil, fmt.Errorf("create: not a valid rootfs path: %s", err)
	}

	if _, err := exec.Command("cp", "-r", rootfs.Path, path.Join(dir, "rootfs")).CombinedOutput(); err != nil {
		return nil, fmt.Errorf("create: copy rootfs: %s", err)
	}

	runcSpec := runc.PortableSpec{
		Version: "0.1",
		OS:      runtime.GOOS,
		Arch:    runtime.GOARCH,
		Cpus:    1.1,
		Memory:  1024,
		Root: runc.Root{
			Path:     "rootfs",
			Readonly: false,
		},
		Namespaces: []runc.Namespace{
			{
				Type: "process",
			},
			{
				Type: "network",
			},
			{
				Type: "mount",
			},
			{
				Type: "ipc",
			},
			{
				Type: "uts",
			},
		},
		Devices: []string{
			"null",
			"random",
			"full",
			"tty",
			"zero",
			"urandom",
		},
		Mounts: []runc.Mount{
			{
				Type:        "proc",
				Source:      "proc",
				Destination: "/proc",
				Options:     "",
			},
			{
				Type:        "tmpfs",
				Source:      "tmpfs",
				Destination: "/dev",
				Options:     "nosuid,strictatime,mode=755,size=65536k",
			},
			{
				Type:        "devpts",
				Source:      "devpts",
				Destination: "/dev/pts",
				Options:     "nosuid,noexec,newinstance,ptmxmode=0666,mode=0620,gid=5",
			},
			{
				Type:        "tmpfs",
				Source:      "shm",
				Destination: "/dev/shm",
				Options:     "nosuid,noexec,nodev,mode=1777,size=65536k",
			},
			{
				Type:        "mqueue",
				Source:      "mqueue",
				Destination: "/dev/mqueue",
				Options:     "nosuid,noexec,nodev",
			},
			{
				Type:        "sysfs",
				Source:      "sysfs",
				Destination: "/sys",
				Options:     "nosuid,noexec,nodev",
			},
			{
				Type:        "bind",
				Source:      c.InitdPath,
				Destination: "/garden-bin/initd",
				Options:     "bind",
			}, {
				Type:        "bind",
				Source:      path.Join(dir, "run"),
				Destination: "/run/garden",
				Options:     "bind",
			}},
		Processes: []*runc.Process{{
			// User: "******",
			// Args: []string{
			// 	"/bin/ls", "-lR", "/garden-bin",
			// },
			// }},
			User: "******",
			Args: []string{
				"/garden-bin/initd",
				"-socket", "/run/garden/initd.sock",
				"-unmountAfterListening", "/run/garden",
			},
		}},
	}

	data, err := json.MarshalIndent(&runcSpec, "", "\t")
	if err != nil {
		return nil, fmt.Errorf("create: marshal runc spec: %s", err)
	}

	err = ioutil.WriteFile(path.Join(dir, "container.json"), data, 0700)
	if err != nil {
		return nil, fmt.Errorf("create: write runc spec: %s", err)
	}

	os.Setenv("CGO_ENABLED", "1")
	runcBin, err := gexec.Build("github.com/opencontainers/runc")
	if err != nil {
		return nil, fmt.Errorf("create: build runc: %s", err)
	}

	runcCommand := exec.Command(runcBin)
	runcCommand.Dir = dir
	if err := c.CommandRunner.Start(runcCommand); err != nil {
		return nil, fmt.Errorf("create: start runc container: %s", err)
	}

	time.Sleep(2 * time.Second)

	return &Container{
		LimitsHandler: &LimitsHandler{},
		StreamHandler: &StreamHandler{},
		InfoHandler: &InfoHandler{
			Spec:          spec,
			ContainerPath: dir,
			PropsHandler:  &PropsHandler{},
		},
		NetHandler: &NetHandler{
			Chain:    c.Chain,
			PortPool: c.PortPool,
		},
		RunHandler: &RunHandler{
			ProcessTracker: process_tracker.New(dir, c.CommandRunner),
			ContainerCmd: &doshcmd{
				Path:      filepath.Join(dir, "bin", "dosh"),
				InitdSock: filepath.Join(dir, "run", "initd.sock"),
			},
		},
	}, nil
}