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())
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 }