Merge pull request #270 from ashahab-altiscale/raw-network-handler
Raw cgroup handler network support using external hints file
This commit is contained in:
commit
08d0aa41d6
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
|||||||
cadvisor
|
cadvisor
|
||||||
*.swp
|
*.swp
|
||||||
|
*.idea
|
||||||
|
*.iml
|
||||||
|
55
container/raw/container_hints.go
Normal file
55
container/raw/container_hints.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// Unmarshal's a Containers description json file. The json file contains
|
||||||
|
// an array of ContainerHint structs, each with a container's id and networkInterface
|
||||||
|
// This allows collecting stats about network interfaces configured outside docker
|
||||||
|
// and lxc
|
||||||
|
package raw
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var argContainerHints = flag.String("container_hints", "/etc/cadvisor/container_hints.json", "container hints file")
|
||||||
|
|
||||||
|
type containerHints struct {
|
||||||
|
AllHosts []containerHint `json:"all_hosts,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type containerHint struct {
|
||||||
|
FullName string `json:"full_path,omitempty"`
|
||||||
|
NetworkInterface *networkInterface `json:"network_interface,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type networkInterface struct {
|
||||||
|
VethHost string `json:"veth_host,omitempty"`
|
||||||
|
VethChild string `json:"veth_child,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func getContainerHintsFromFile(containerHintsFile string) (containerHints, error) {
|
||||||
|
dat, err := ioutil.ReadFile(containerHintsFile)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return containerHints{}, nil
|
||||||
|
}
|
||||||
|
var cHints containerHints
|
||||||
|
if err == nil {
|
||||||
|
err = json.Unmarshal(dat, &cHints)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cHints, err
|
||||||
|
}
|
28
container/raw/container_hints_test.go
Normal file
28
container/raw/container_hints_test.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package raw
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGetContainerHintsFromFile(t *testing.T) {
|
||||||
|
cHints, err := getContainerHintsFromFile("test_resources/container_hints.json")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error in unmarshalling: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cHints.AllHosts[0].NetworkInterface.VethHost != "veth24031eth1" &&
|
||||||
|
cHints.AllHosts[0].NetworkInterface.VethChild != "eth1" {
|
||||||
|
t.Errorf("Cannot find network interface in %s", cHints)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFileNotExist(t *testing.T) {
|
||||||
|
cHints, err := getContainerHintsFromFile("/file_does_not_exist.json")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("getContainerHintsFromFile must not error for blank file: %s", err)
|
||||||
|
}
|
||||||
|
for _, container := range cHints.AllHosts {
|
||||||
|
t.Logf("Container: %s", container)
|
||||||
|
}
|
||||||
|
}
|
@ -23,8 +23,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.google.com/p/go.exp/inotify"
|
"code.google.com/p/go.exp/inotify"
|
||||||
|
dockerlibcontainer "github.com/docker/libcontainer"
|
||||||
"github.com/docker/libcontainer/cgroups"
|
"github.com/docker/libcontainer/cgroups"
|
||||||
cgroup_fs "github.com/docker/libcontainer/cgroups/fs"
|
cgroup_fs "github.com/docker/libcontainer/cgroups/fs"
|
||||||
|
"github.com/docker/libcontainer/network"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/google/cadvisor/container"
|
"github.com/google/cadvisor/container"
|
||||||
"github.com/google/cadvisor/container/libcontainer"
|
"github.com/google/cadvisor/container/libcontainer"
|
||||||
@ -42,6 +44,7 @@ type rawContainerHandler struct {
|
|||||||
stopWatcher chan error
|
stopWatcher chan error
|
||||||
watches map[string]struct{}
|
watches map[string]struct{}
|
||||||
fsInfo fs.FsInfo
|
fsInfo fs.FsInfo
|
||||||
|
networkInterface *networkInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, machineInfoFactory info.MachineInfoFactory) (container.ContainerHandler, error) {
|
func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, machineInfoFactory info.MachineInfoFactory) (container.ContainerHandler, error) {
|
||||||
@ -49,6 +52,17 @@ func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, mac
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
cHints, err := getContainerHintsFromFile(*argContainerHints)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var networkInterface *networkInterface
|
||||||
|
for _, container := range cHints.AllHosts {
|
||||||
|
if name == container.FullName {
|
||||||
|
networkInterface = container.NetworkInterface
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
return &rawContainerHandler{
|
return &rawContainerHandler{
|
||||||
name: name,
|
name: name,
|
||||||
cgroup: &cgroups.Cgroup{
|
cgroup: &cgroups.Cgroup{
|
||||||
@ -60,6 +74,7 @@ func newRawContainerHandler(name string, cgroupSubsystems *cgroupSubsystems, mac
|
|||||||
stopWatcher: make(chan error),
|
stopWatcher: make(chan error),
|
||||||
watches: make(map[string]struct{}),
|
watches: make(map[string]struct{}),
|
||||||
fsInfo: fsInfo,
|
fsInfo: fsInfo,
|
||||||
|
networkInterface: networkInterface,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,11 +167,27 @@ func (self *rawContainerHandler) GetSpec() (info.ContainerSpec, error) {
|
|||||||
if self.name == "/" {
|
if self.name == "/" {
|
||||||
spec.HasFilesystem = true
|
spec.HasFilesystem = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Network
|
||||||
|
if self.networkInterface != nil {
|
||||||
|
spec.HasNetwork = true
|
||||||
|
}
|
||||||
return spec, nil
|
return spec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *rawContainerHandler) GetStats() (*info.ContainerStats, error) {
|
func (self *rawContainerHandler) GetStats() (*info.ContainerStats, error) {
|
||||||
stats, err := libcontainer.GetStatsCgroupOnly(self.cgroup)
|
state := dockerlibcontainer.State{}
|
||||||
|
if self.networkInterface != nil {
|
||||||
|
state = dockerlibcontainer.State{
|
||||||
|
NetworkState: network.NetworkState{
|
||||||
|
VethHost: self.networkInterface.VethHost,
|
||||||
|
VethChild: self.networkInterface.VethChild,
|
||||||
|
NsPath: "unknown",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stats, err := libcontainer.GetStats(self.cgroup, &state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
40
container/raw/test_resources/container_hints.json
Normal file
40
container/raw/test_resources/container_hints.json
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "Container Hints",
|
||||||
|
"description": "Container hints file",
|
||||||
|
"all_hosts": [
|
||||||
|
{
|
||||||
|
"network_interface": {
|
||||||
|
"veth_child": "eth1",
|
||||||
|
"veth_host": "veth24031eth1"
|
||||||
|
},
|
||||||
|
"mounts": [
|
||||||
|
{
|
||||||
|
"host-dir": "/var/run/nm-sdc1",
|
||||||
|
"container-dir": "/var/run/nm-sdc1",
|
||||||
|
"permission": "rw"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"host-dir": "/var/run/nm-sdb3",
|
||||||
|
"container-dir": "/var/run/nm-sdb3",
|
||||||
|
"permission": "rw"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"host-dir": "/var/run/nm-sda3",
|
||||||
|
"container-dir": "/var/run/nm-sda3",
|
||||||
|
"permission": "rw"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"host-dir": "/var/run/netns/root",
|
||||||
|
"container-dir": "/var/run/netns/root",
|
||||||
|
"permission": "ro"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"host-dir": "/var/run/openvswitch/db.sock",
|
||||||
|
"container-dir": "/var/run/openvswitch/db.sock",
|
||||||
|
"permission": "rw"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"full_path": "18a4585950db428e4d5a65c216a5d708d241254709626f4cb300ee963fb4b144"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user