diff --git a/hack/vendor.sh b/hack/vendor.sh index 9b2eb173bb..4175a6b941 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -65,7 +65,7 @@ mv tmp-digest src/github.com/docker/distribution/digest mkdir -p src/github.com/docker/distribution/registry mv tmp-api src/github.com/docker/distribution/registry/api -clone git github.com/docker/libcontainer 90f8aa670f1f424041059060c7c63fe4dee2e441 +clone git github.com/docker/libcontainer a37b2a4f152e2a1c9de596f54c051cb889de0691 # libcontainer deps (see src/github.com/docker/libcontainer/update-vendor.sh) clone git github.com/coreos/go-systemd v2 clone git github.com/godbus/dbus v2 diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go index fa6478b5f3..99c7845745 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go @@ -262,6 +262,11 @@ func (raw *data) join(subsystem string) (string, error) { } func writeFile(dir, file, data string) error { + // Normally dir should not be empty, one case is that cgroup subsystem + // is not mounted, we will get empty dir, and we want it fail here. + if dir == "" { + return fmt.Errorf("no such directory for %s.", file) + } return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700) } diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/cpu.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/cpu.go index 1fbf7b1540..c9d4ad1a16 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/fs/cpu.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/cpu.go @@ -17,7 +17,7 @@ func (s *CpuGroup) Apply(d *data) error { // We always want to join the cpu group, to allow fair cpu scheduling // on a container basis dir, err := d.join("cpu") - if err != nil { + if err != nil && !cgroups.IsNotFound(err) { return err } diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuset.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuset.go index d8465a666b..6ad42a5838 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuset.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuset.go @@ -16,7 +16,7 @@ type CpusetGroup struct { func (s *CpusetGroup) Apply(d *data) error { dir, err := d.path("cpuset") - if err != nil { + if err != nil && !cgroups.IsNotFound(err) { return err } @@ -48,6 +48,11 @@ func (s *CpusetGroup) GetStats(path string, stats *cgroups.Stats) error { } func (s *CpusetGroup) ApplyDir(dir string, cgroup *configs.Cgroup, pid int) error { + // This might happen if we have no cpuset cgroup mounted. + // Just do nothing and don't fail. + if dir == "" { + return nil + } if err := s.ensureParent(dir); err != nil { return err } diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/devices.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/devices.go index be588d67a1..09ce92ef24 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/fs/devices.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/devices.go @@ -11,6 +11,8 @@ type DevicesGroup struct { func (s *DevicesGroup) Apply(d *data) error { dir, err := d.join("devices") if err != nil { + // We will return error even it's `not found` error, devices + // cgroup is hard requirement for container's security. return err } diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/fs/memory.go b/vendor/src/github.com/docker/libcontainer/cgroups/fs/memory.go index d5dbaf6570..2dcef0f44c 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/fs/memory.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/fs/memory.go @@ -16,8 +16,7 @@ type MemoryGroup struct { func (s *MemoryGroup) Apply(d *data) error { dir, err := d.join("memory") - // only return an error for memory if it was specified - if err != nil && (d.c.Memory != 0 || d.c.MemoryReservation != 0 || d.c.MemorySwap != 0) { + if err != nil && !cgroups.IsNotFound(err) { return err } defer func() { diff --git a/vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go b/vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go index 2ba10cbb34..4fb8d8d5ea 100644 --- a/vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go +++ b/vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go @@ -256,6 +256,11 @@ func (m *Manager) GetPaths() map[string]string { } func writeFile(dir, file, data string) error { + // Normally dir should not be empty, one case is that cgroup subsystem + // is not mounted, we will get empty dir, and we want it fail here. + if dir == "" { + return fmt.Errorf("no such directory for %s.", file) + } return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700) } @@ -276,16 +281,16 @@ func join(c *configs.Cgroup, subsystem string, pid int) (string, error) { func joinCpu(c *configs.Cgroup, pid int) error { path, err := getSubsystemPath(c, "cpu") - if err != nil { + if err != nil && !cgroups.IsNotFound(err) { return err } if c.CpuQuota != 0 { - if err = ioutil.WriteFile(filepath.Join(path, "cpu.cfs_quota_us"), []byte(strconv.FormatInt(c.CpuQuota, 10)), 0700); err != nil { + if err = writeFile(path, "cpu.cfs_quota_us", strconv.FormatInt(c.CpuQuota, 10)); err != nil { return err } } if c.CpuPeriod != 0 { - if err = ioutil.WriteFile(filepath.Join(path, "cpu.cfs_period_us"), []byte(strconv.FormatInt(c.CpuPeriod, 10)), 0700); err != nil { + if err = writeFile(path, "cpu.cfs_period_us", strconv.FormatInt(c.CpuPeriod, 10)); err != nil { return err } } @@ -293,7 +298,7 @@ func joinCpu(c *configs.Cgroup, pid int) error { } func joinFreezer(c *configs.Cgroup, pid int) error { - if _, err := join(c, "freezer", pid); err != nil { + if _, err := join(c, "freezer", pid); err != nil && !cgroups.IsNotFound(err) { return err } @@ -393,6 +398,8 @@ func getUnitName(c *configs.Cgroup) string { // This happens at least for v208 when any sibling unit is started. func joinDevices(c *configs.Cgroup, pid int) error { path, err := join(c, "devices", pid) + // Even if it's `not found` error, we'll return err because devices cgroup + // is hard requirement for container security. if err != nil { return err } @@ -410,11 +417,11 @@ func joinMemory(c *configs.Cgroup, pid int) error { } path, err := getSubsystemPath(c, "memory") - if err != nil { + if err != nil && !cgroups.IsNotFound(err) { return err } - return ioutil.WriteFile(filepath.Join(path, "memory.memsw.limit_in_bytes"), []byte(strconv.FormatInt(memorySwap, 10)), 0700) + return writeFile(path, "memory.memsw.limit_in_bytes", strconv.FormatInt(memorySwap, 10)) } // systemd does not atm set up the cpuset controller, so we must manually @@ -422,7 +429,7 @@ func joinMemory(c *configs.Cgroup, pid int) error { // level must have a full setup as the default for a new directory is "no cpus" func joinCpuset(c *configs.Cgroup, pid int) error { path, err := getSubsystemPath(c, "cpuset") - if err != nil { + if err != nil && !cgroups.IsNotFound(err) { return err } diff --git a/vendor/src/github.com/docker/libcontainer/rootfs_linux.go b/vendor/src/github.com/docker/libcontainer/rootfs_linux.go index 0cd60373c8..4ddfff1fe2 100644 --- a/vendor/src/github.com/docker/libcontainer/rootfs_linux.go +++ b/vendor/src/github.com/docker/libcontainer/rootfs_linux.go @@ -215,7 +215,6 @@ func checkMountDestination(rootfs, dest string) error { } invalidDestinations := []string{ "/proc", - "/sys", } for _, invalid := range invalidDestinations { path, err := filepath.Rel(filepath.Join(rootfs, invalid), dest) diff --git a/vendor/src/github.com/docker/libcontainer/rootfs_linux_test.go b/vendor/src/github.com/docker/libcontainer/rootfs_linux_test.go index 54df065ccc..a3bb07708b 100644 --- a/vendor/src/github.com/docker/libcontainer/rootfs_linux_test.go +++ b/vendor/src/github.com/docker/libcontainer/rootfs_linux_test.go @@ -15,8 +15,8 @@ func TestCheckMountDestOnProc(t *testing.T) { func TestCheckMountDestInSys(t *testing.T) { dest := "/rootfs//sys/fs/cgroup" err := checkMountDestination("/rootfs", dest) - if err == nil { - t.Fatal("destination inside proc should return an error") + if err != nil { + t.Fatal("destination inside /sys should not return an error") } } diff --git a/vendor/src/github.com/docker/libcontainer/update-vendor.sh b/vendor/src/github.com/docker/libcontainer/update-vendor.sh index ab471872b7..6d03d770a3 100755 --- a/vendor/src/github.com/docker/libcontainer/update-vendor.sh +++ b/vendor/src/github.com/docker/libcontainer/update-vendor.sh @@ -44,6 +44,6 @@ clone git github.com/codegangsta/cli 1.1.0 clone git github.com/coreos/go-systemd v2 clone git github.com/godbus/dbus v2 clone git github.com/Sirupsen/logrus v0.7.3 -clone git github.com/syndtr/gocapability 8e4cdcb +clone git github.com/syndtr/gocapability 66ef2aa # intentionally not vendoring Docker itself... that'd be a circle :)