Remove SplitName().
This is possible thanks to the new libcontainer interface that allows the use of absolute paths.
This commit is contained in:
parent
f2c6beca30
commit
56054e3e31
@ -18,6 +18,7 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -25,7 +26,6 @@ import (
|
|||||||
"github.com/docker/libcontainer/cgroups/systemd"
|
"github.com/docker/libcontainer/cgroups/systemd"
|
||||||
"github.com/fsouza/go-dockerclient"
|
"github.com/fsouza/go-dockerclient"
|
||||||
"github.com/google/cadvisor/container"
|
"github.com/google/cadvisor/container"
|
||||||
"github.com/google/cadvisor/container/libcontainer"
|
|
||||||
"github.com/google/cadvisor/info"
|
"github.com/google/cadvisor/info"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -75,10 +75,7 @@ func (self *dockerFactory) CanHandle(name string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Check if the container is known to docker and it is active.
|
// Check if the container is known to docker and it is active.
|
||||||
_, id, err := libcontainer.SplitName(name)
|
id := path.Base(name)
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
ctnr, err := self.client.InspectContainer(id)
|
ctnr, err := self.client.InspectContainer(id)
|
||||||
// We assume that if Inspect fails then the container is not known to docker.
|
// We assume that if Inspect fails then the container is not known to docker.
|
||||||
// TODO(vishh): Detect lxc containers and avoid handling them.
|
// TODO(vishh): Detect lxc containers and avoid handling them.
|
||||||
|
@ -65,11 +65,8 @@ func newDockerContainerHandler(
|
|||||||
if handler.isDockerRoot() {
|
if handler.isDockerRoot() {
|
||||||
return handler, nil
|
return handler, nil
|
||||||
}
|
}
|
||||||
parent, id, err := containerLibcontainer.SplitName(name)
|
id := path.Base(name)
|
||||||
if err != nil {
|
handler.parent = path.Dir(name)
|
||||||
return nil, fmt.Errorf("invalid docker container %v: %v", name, err)
|
|
||||||
}
|
|
||||||
handler.parent = parent
|
|
||||||
handler.id = id
|
handler.id = id
|
||||||
ctnr, err := client.InspectContainer(id)
|
ctnr, err := client.InspectContainer(id)
|
||||||
// We assume that if Inspect fails then the container is not known to docker.
|
// We assume that if Inspect fails then the container is not known to docker.
|
||||||
|
@ -15,17 +15,12 @@
|
|||||||
package libcontainer
|
package libcontainer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/libcontainer"
|
"github.com/docker/libcontainer"
|
||||||
"github.com/docker/libcontainer/cgroups"
|
"github.com/docker/libcontainer/cgroups"
|
||||||
cgroupfs "github.com/docker/libcontainer/cgroups/fs"
|
cgroupfs "github.com/docker/libcontainer/cgroups/fs"
|
||||||
"github.com/google/cadvisor/info"
|
"github.com/google/cadvisor/info"
|
||||||
"github.com/google/cadvisor/utils/fs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Get stats of the specified container
|
// Get stats of the specified container
|
||||||
@ -88,48 +83,3 @@ func toContainerStats(libcontainerStats *libcontainer.ContainerStats) *info.Cont
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a container name, returns the parent and name of the container to be fed to libcontainer.
|
|
||||||
func SplitName(containerName string) (string, string, error) {
|
|
||||||
parent, id := path.Split(containerName)
|
|
||||||
cgroupSelf, err := fs.Open("/proc/1/cgroup")
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
scanner := bufio.NewScanner(cgroupSelf)
|
|
||||||
|
|
||||||
// Find how nested we are. Libcontainer takes container names relative to the current process.
|
|
||||||
subsys := []string{"memory", "cpu"}
|
|
||||||
nestedLevels := 0
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := scanner.Text()
|
|
||||||
elems := strings.Split(line, ":")
|
|
||||||
if len(elems) < 3 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, s := range subsys {
|
|
||||||
if elems[1] == s {
|
|
||||||
if elems[2] == "/" {
|
|
||||||
// We're running at root, no nesting.
|
|
||||||
nestedLevels = 0
|
|
||||||
} else {
|
|
||||||
// Count how deeply nested we are.
|
|
||||||
nestedLevels = strings.Count(elems[2], "/")
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if nestedLevels > 0 {
|
|
||||||
// we are running inside a docker container
|
|
||||||
upperLevel := strings.Repeat("../", nestedLevels)
|
|
||||||
parent = filepath.Join(upperLevel, parent)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strip the last "/"
|
|
||||||
if parent[len(parent)-1] == '/' {
|
|
||||||
parent = parent[:len(parent)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent, id, nil
|
|
||||||
}
|
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package libcontainer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"code.google.com/p/gomock/gomock"
|
|
||||||
|
|
||||||
"github.com/google/cadvisor/utils/fs"
|
|
||||||
"github.com/google/cadvisor/utils/fs/mockfs"
|
|
||||||
)
|
|
||||||
|
|
||||||
var initCgroupsToParentAndID = []struct {
|
|
||||||
InitCgroupFileContent string
|
|
||||||
ContainerPath string
|
|
||||||
Parent string
|
|
||||||
Id string
|
|
||||||
Error error
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
`
|
|
||||||
11:name=systemd:/
|
|
||||||
10:hugetlb:/
|
|
||||||
9:perf_event:/
|
|
||||||
8:blkio:/
|
|
||||||
7:freezer:/
|
|
||||||
6:devices:/
|
|
||||||
5:memory:/
|
|
||||||
4:cpuacct:/
|
|
||||||
3:cpu:/
|
|
||||||
2:cpuset:/
|
|
||||||
`,
|
|
||||||
"/",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
`
|
|
||||||
11:name=systemd:/
|
|
||||||
10:hugetlb:/
|
|
||||||
9:perf_event:/
|
|
||||||
8:blkio:/
|
|
||||||
7:freezer:/
|
|
||||||
6:devices:/
|
|
||||||
5:memory:/docker/hash
|
|
||||||
4:cpuacct:/
|
|
||||||
3:cpu:/docker/hash
|
|
||||||
2:cpuset:/
|
|
||||||
`,
|
|
||||||
"/parent/id",
|
|
||||||
"../../parent",
|
|
||||||
"id",
|
|
||||||
nil,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSplitName(t *testing.T) {
|
|
||||||
mockCtrl := gomock.NewController(t)
|
|
||||||
defer mockCtrl.Finish()
|
|
||||||
|
|
||||||
for _, testCase := range initCgroupsToParentAndID {
|
|
||||||
mfs := mockfs.NewMockFileSystem(mockCtrl)
|
|
||||||
mockfs.AddTextFile(mfs, "/proc/1/cgroup", testCase.InitCgroupFileContent)
|
|
||||||
fs.ChangeFileSystem(mfs)
|
|
||||||
parent, id, err := SplitName(testCase.ContainerPath)
|
|
||||||
if testCase.Error != nil {
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("did not receive expected error.\ncontent:%v\n, path:%v\n, expected error:%v\n", testCase.InitCgroupFileContent, testCase.ContainerPath, testCase.Error)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if testCase.Parent != parent || testCase.Id != id {
|
|
||||||
t.Errorf("unexpected parent or id:\ncontent:%v\npath:%v\nexpected parent: %v; recevied parent: %v;\nexpected id: %v; received id: %v", testCase.InitCgroupFileContent, testCase.ContainerPath, testCase.Parent, parent, testCase.Id, id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -38,15 +38,11 @@ type rawContainerHandler struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, machineInfoFactory info.MachineInfoFactory) (container.ContainerHandler, error) {
|
func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, machineInfoFactory info.MachineInfoFactory) (container.ContainerHandler, error) {
|
||||||
parent, id, err := libcontainer.SplitName(name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &rawContainerHandler{
|
return &rawContainerHandler{
|
||||||
name: name,
|
name: name,
|
||||||
cgroup: &cgroups.Cgroup{
|
cgroup: &cgroups.Cgroup{
|
||||||
Parent: parent,
|
Parent: "/",
|
||||||
Name: id,
|
Name: name,
|
||||||
},
|
},
|
||||||
cgroupSubsystems: cgroupSubsystems,
|
cgroupSubsystems: cgroupSubsystems,
|
||||||
machineInfoFactory: machineInfoFactory,
|
machineInfoFactory: machineInfoFactory,
|
||||||
|
Loading…
Reference in New Issue
Block a user