func (p *LinuxContainerPool) Create(spec backend.ContainerSpec) (linux_backend.Container, error) { uid, err := p.uidPool.Acquire() if err != nil { return nil, err } network, err := p.networkPool.Acquire() if err != nil { p.uidPool.Release(uid) return nil, err } id := <-p.containerIDs containerPath := path.Join(p.depotPath, id) cgroupsManager := cgroups_manager.New("/tmp/warden/cgroup", id) bandwidthManager := bandwidth_manager.New(containerPath, id, p.runner) handle := id if spec.Handle != "" { handle = spec.Handle } container := linux_backend.NewLinuxContainer( id, handle, containerPath, spec.GraceTime, linux_backend.NewResources(uid, network, []uint32{}), p.portPool, p.runner, cgroupsManager, p.quotaManager, bandwidthManager, ) create := &exec.Cmd{ Path: path.Join(p.rootPath, "create.sh"), Args: []string{containerPath}, Env: []string{ "id=" + container.ID(), "rootfs_path=" + p.rootFSPath, fmt.Sprintf("user_uid=%d", uid), fmt.Sprintf("network_host_ip=%s", network.HostIP()), fmt.Sprintf("network_container_ip=%s", network.ContainerIP()), "network_netmask=255.255.255.252", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", }, } err = p.runner.Run(create) if err != nil { p.uidPool.Release(uid) p.networkPool.Release(network) return nil, err } err = p.writeBindMounts(containerPath, spec.BindMounts) if err != nil { return nil, err } return container, nil }
func (p *LinuxContainerPool) Restore(snapshot io.Reader) (linux_backend.Container, error) { var containerSnapshot linux_backend.ContainerSnapshot err := json.NewDecoder(snapshot).Decode(&containerSnapshot) if err != nil { return nil, err } id := containerSnapshot.ID log.Println("restoring", id) resources := containerSnapshot.Resources err = p.uidPool.Remove(resources.UID) if err != nil { return nil, err } err = p.networkPool.Remove(resources.Network) if err != nil { p.uidPool.Release(resources.UID) return nil, err } for _, port := range resources.Ports { err = p.portPool.Remove(port) if err != nil { p.uidPool.Release(resources.UID) p.networkPool.Release(resources.Network) for _, port := range resources.Ports { p.portPool.Release(port) } return nil, err } } containerPath := path.Join(p.depotPath, id) cgroupsManager := cgroups_manager.New("/tmp/warden/cgroup", id) bandwidthManager := bandwidth_manager.New(containerPath, id, p.runner) container := linux_backend.NewLinuxContainer( id, containerSnapshot.Handle, containerPath, containerSnapshot.GraceTime, linux_backend.NewResources( resources.UID, resources.Network, resources.Ports, ), p.portPool, p.runner, cgroupsManager, p.quotaManager, bandwidthManager, ) err = container.Restore(containerSnapshot) if err != nil { return nil, err } return container, nil }
. "github.com/onsi/gomega" "github.com/pivotal-cf-experimental/garden/linux_backend/cgroups_manager" ) var _ = Describe("Container cgroups", func() { var cgroupsPath string var cgroupsManager *cgroups_manager.ContainerCgroupsManager BeforeEach(func() { tmpdir, err := ioutil.TempDir(os.TempDir(), "some-cgroups") Expect(err).ToNot(HaveOccurred()) cgroupsPath = tmpdir cgroupsManager = cgroups_manager.New(cgroupsPath, "some-container-id") }) Describe("setting", func() { It("writes the value to the name under the subsytem", func() { containerMemoryCgroupsPath := path.Join(cgroupsPath, "memory", "instance-some-container-id") err := os.MkdirAll(containerMemoryCgroupsPath, 0755) Expect(err).ToNot(HaveOccurred()) err = cgroupsManager.Set("memory", "memory.limit_in_bytes", "42") Expect(err).ToNot(HaveOccurred()) value, err := ioutil.ReadFile(path.Join(containerMemoryCgroupsPath, "memory.limit_in_bytes")) Expect(err).ToNot(HaveOccurred()) Expect(string(value)).To(Equal("42")) })