Merge pull request #50629 from sjenning/bump-cadvisor

Automatic merge from submit-queue (batch tested with PRs 50893, 50913, 50963, 50629, 50640)

bump(github.com/google/cadvisor): 27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6

Bump cadvisor dep to include 556c7b125a.

This is required for supporting huge pages for 1.8

https://github.com/kubernetes/community/pull/837
https://github.com/kubernetes/features/issues/275

@dashpole @derekwaynecarr @eparis @jeremyeder
pull/6/head
Kubernetes Submit Queue 2017-08-22 05:31:12 -07:00 committed by GitHub
commit 9292074a6b
20 changed files with 348 additions and 171 deletions

164
Godeps/Godeps.json generated
View File

@ -1336,208 +1336,208 @@
},
{
"ImportPath": "github.com/google/cadvisor/api",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/cache/memory",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/client/v2",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/collector",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/container",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/container/common",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/container/docker",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/container/libcontainer",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/container/raw",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/container/rkt",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/container/systemd",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/devicemapper",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/events",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/fs",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/healthz",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/http",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/http/mux",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/info/v1",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/info/v2",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/machine",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/manager",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/manager/watcher",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/manager/watcher/raw",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/manager/watcher/rkt",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/metrics",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/pages",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/pages/static",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/storage",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/summary",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/utils",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/utils/cloudinfo",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/utils/cpuload",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/utils/cpuload/netlink",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/utils/docker",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/utils/oomparser",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/utils/sysfs",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/utils/sysinfo",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/utils/tail",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/validate",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/version",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/cadvisor/zfs",
"Comment": "v0.26.1",
"Rev": "d19cc94b760cd8f150a0a5d95b404dec39a121a1"
"Comment": "v0.26.0-37-g27e1acb",
"Rev": "27e1acbb4ef0fe1889208b21f8f4a6d0863e02f6"
},
{
"ImportPath": "github.com/google/certificate-transparency/go",

View File

@ -85,7 +85,7 @@ func handleRequest(supportedApiVersions map[string]ApiVersion, m manager.Manager
versions = append(versions, v)
}
sort.Strings(versions)
fmt.Fprintf(w, "Supported API versions: %s", strings.Join(versions, ","))
http.Error(w, fmt.Sprintf("Supported API versions: %s", strings.Join(versions, ",")), http.StatusBadRequest)
return nil
}
@ -109,7 +109,7 @@ func handleRequest(supportedApiVersions map[string]ApiVersion, m manager.Manager
if requestType == "" {
requestTypes := versionHandler.SupportedRequestTypes()
sort.Strings(requestTypes)
fmt.Fprintf(w, "Supported request types: %q", strings.Join(requestTypes, ","))
http.Error(w, fmt.Sprintf("Supported request types: %q", strings.Join(requestTypes, ",")), http.StatusBadRequest)
return nil
}

View File

@ -127,15 +127,13 @@ func GetSpec(cgroupPaths map[string]string, machineInfoFactory info.MachineInfoF
func readString(dirpath string, file string) string {
cgroupFile := path.Join(dirpath, file)
// Ignore non-existent files
if !utils.FileExists(cgroupFile) {
return ""
}
// Read
out, err := ioutil.ReadFile(cgroupFile)
if err != nil {
glog.Errorf("readString: Failed to read %q: %s", cgroupFile, err)
// Ignore non-existent files
if !os.IsNotExist(err) {
glog.Errorf("readString: Failed to read %q: %s", cgroupFile, err)
}
return ""
}
return strings.TrimSpace(string(out))
@ -158,13 +156,12 @@ func readUInt64(dirpath string, file string) uint64 {
// Lists all directories under "path" and outputs the results as children of "parent".
func ListDirectories(dirpath string, parent string, recursive bool, output map[string]struct{}) error {
// Ignore if this hierarchy does not exist.
if !utils.FileExists(dirpath) {
return nil
}
entries, err := ioutil.ReadDir(dirpath)
if err != nil {
// Ignore if this hierarchy does not exist.
if os.IsNotExist(err) {
err = nil
}
return err
}
for _, entry := range entries {

View File

@ -80,7 +80,7 @@ func parseThinLsOutput(output []byte) map[string]uint64 {
deviceID := fields[0]
usage, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
glog.Warning("unexpected error parsing thin_ls output: %v", err)
glog.Warningf("unexpected error parsing thin_ls output: %v", err)
continue
}

View File

@ -79,6 +79,8 @@ type RealFsInfo struct {
// Map from label to block device path.
// Labels are intent-specific tags that are auto-detected.
labels map[string]string
// Map from mountpoint to mount information.
mounts map[string]*mount.Info
// devicemapper client
dmsetup devicemapper.DmsetupClient
}
@ -106,9 +108,14 @@ func NewFsInfo(context Context) (FsInfo, error) {
fsInfo := &RealFsInfo{
partitions: processMounts(mounts, excluded),
labels: make(map[string]string, 0),
mounts: make(map[string]*mount.Info, 0),
dmsetup: devicemapper.NewDmsetupClient(),
}
for _, mount := range mounts {
fsInfo.mounts[mount.Mountpoint] = mount
}
fsInfo.addRktImagesLabel(context, mounts)
// need to call this before the log line below printing out the partitions, as this function may
// add a "partition" for devicemapper to fsInfo.partitions
@ -125,6 +132,7 @@ func processMounts(mounts []*mount.Info, excludedMountpointPrefixes []string) ma
supportedFsType := map[string]bool{
// all ext systems are checked through prefix.
"btrfs": true,
"tmpfs": true,
"xfs": true,
"zfs": true,
}
@ -152,25 +160,12 @@ func processMounts(mounts []*mount.Info, excludedMountpointPrefixes []string) ma
// btrfs fix: following workaround fixes wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo.
// instead of using values from /proc/self/mountinfo we use stat to get Ids from btrfs mount point
if mount.Fstype == "btrfs" && mount.Major == 0 && strings.HasPrefix(mount.Source, "/dev/") {
buf := new(syscall.Stat_t)
err := syscall.Stat(mount.Source, buf)
major, minor, err := getBtrfsMajorMinorIds(mount)
if err != nil {
glog.Warningf("stat failed on %s with error: %s", mount.Source, err)
glog.Warningf("%s", err)
} else {
glog.Infof("btrfs mount %#v", mount)
if buf.Mode&syscall.S_IFMT == syscall.S_IFBLK {
err := syscall.Stat(mount.Mountpoint, buf)
if err != nil {
glog.Warningf("stat failed on %s with error: %s", mount.Mountpoint, err)
} else {
glog.Infof("btrfs dev major:minor %d:%d\n", int(major(buf.Dev)), int(minor(buf.Dev)))
glog.Infof("btrfs rdev major:minor %d:%d\n", int(major(buf.Rdev)), int(minor(buf.Rdev)))
mount.Major = int(major(buf.Dev))
mount.Minor = int(minor(buf.Dev))
}
}
mount.Major = major
mount.Minor = minor
}
}
@ -444,6 +439,7 @@ func (self *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
if err != nil {
return nil, fmt.Errorf("stat failed on %s with error: %s", dir, err)
}
major := major(buf.Dev)
minor := minor(buf.Dev)
for device, partition := range self.partitions {
@ -451,6 +447,16 @@ func (self *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
return &DeviceInfo{device, major, minor}, nil
}
}
mount, found := self.mounts[dir]
if found && mount.Fstype == "btrfs" && mount.Major == 0 && strings.HasPrefix(mount.Source, "/dev/") {
major, minor, err := getBtrfsMajorMinorIds(mount)
if err != nil {
glog.Warningf("%s", err)
} else {
return &DeviceInfo{mount.Source, uint(major), uint(minor)}, nil
}
}
return nil, fmt.Errorf("could not find device with major: %d, minor: %d in cached partitions map", major, minor)
}
@ -644,3 +650,32 @@ func (b *byteCounter) Write(p []byte) (int, error) {
b.bytesWritten += uint64(len(p))
return len(p), nil
}
// Get major and minor Ids for a mount point using btrfs as filesystem.
func getBtrfsMajorMinorIds(mount *mount.Info) (int, int, error) {
// btrfs fix: following workaround fixes wrong btrfs Major and Minor Ids reported in /proc/self/mountinfo.
// instead of using values from /proc/self/mountinfo we use stat to get Ids from btrfs mount point
buf := new(syscall.Stat_t)
err := syscall.Stat(mount.Source, buf)
if err != nil {
err = fmt.Errorf("stat failed on %s with error: %s", mount.Source, err)
return 0, 0, err
}
glog.Infof("btrfs mount %#v", mount)
if buf.Mode&syscall.S_IFMT == syscall.S_IFBLK {
err := syscall.Stat(mount.Mountpoint, buf)
if err != nil {
err = fmt.Errorf("stat failed on %s with error: %s", mount.Mountpoint, err)
return 0, 0, err
}
glog.Infof("btrfs dev major:minor %d:%d\n", int(major(buf.Dev)), int(minor(buf.Dev)))
glog.Infof("btrfs rdev major:minor %d:%d\n", int(major(buf.Rdev)), int(minor(buf.Rdev)))
return int(major(buf.Dev)), int(minor(buf.Dev)), nil
} else {
return 0, 0, fmt.Errorf("%s is not a block device", mount.Source)
}
}

View File

@ -44,7 +44,7 @@ func RegisterHandlers(mux httpmux.Mux, containerManager manager.Manager, httpAut
mux.HandleFunc(validate.ValidatePage, func(w http.ResponseWriter, r *http.Request) {
err := validate.HandleRequest(w, containerManager)
if err != nil {
fmt.Fprintf(w, "%s", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})
@ -104,15 +104,9 @@ func RegisterPrometheusHandler(mux httpmux.Mux, containerManager manager.Manager
}
func staticHandlerNoAuth(w http.ResponseWriter, r *http.Request) {
err := static.HandleRequest(w, r.URL)
if err != nil {
fmt.Fprintf(w, "%s", err)
}
static.HandleRequest(w, r.URL)
}
func staticHandler(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
err := static.HandleRequest(w, r.URL)
if err != nil {
fmt.Fprintf(w, "%s", err)
}
static.HandleRequest(w, r.URL)
}

View File

@ -94,6 +94,14 @@ func (self *Node) AddPerCoreCache(c Cache) {
}
}
type HugePagesInfo struct {
// huge page size (in kB)
PageSize uint64 `json:"page_size"`
// number of huge pages
NumPages uint64 `json:"num_pages"`
}
type DiskInfo struct {
// device name
Name string `json:"name"`
@ -158,6 +166,9 @@ type MachineInfo struct {
// The amount of memory (in bytes) in this machine
MemoryCapacity uint64 `json:"memory_capacity"`
// HugePages on this machine.
HugePages []HugePagesInfo `json:"hugepages"`
// The machine id
MachineID string `json:"machine_id"`

View File

@ -52,6 +52,9 @@ type Attributes struct {
// The system uuid
SystemUUID string `json:"system_uuid"`
// HugePages on this machine.
HugePages []v1.HugePagesInfo `json:"hugepages"`
// Filesystems on this machine.
Filesystems []v1.FsInfo `json:"filesystems"`

View File

@ -17,8 +17,10 @@ package machine
import (
"bytes"
"flag"
"fmt"
"io/ioutil"
"path/filepath"
"strconv"
"strings"
"syscall"
@ -31,6 +33,8 @@ import (
"github.com/golang/glog"
)
const hugepagesDirectory = "/sys/kernel/mm/hugepages/"
var machineIdFilePath = flag.String("machine_id_file", "/etc/machine-id,/var/lib/dbus/machine-id", "Comma-separated list of files to check for machine-id. Use the first one that exists.")
var bootIdFilePath = flag.String("boot_id_file", "/proc/sys/kernel/random/boot_id", "Comma-separated list of files to check for boot-id. Use the first one that exists.")
@ -48,6 +52,45 @@ func getInfoFromFiles(filePaths string) string {
return ""
}
// GetHugePagesInfo returns information about pre-allocated huge pages
func GetHugePagesInfo() ([]info.HugePagesInfo, error) {
var hugePagesInfo []info.HugePagesInfo
files, err := ioutil.ReadDir(hugepagesDirectory)
if err != nil {
// treat as non-fatal since kernels and machine can be
// configured to disable hugepage support
return hugePagesInfo, nil
}
for _, st := range files {
nameArray := strings.Split(st.Name(), "-")
pageSizeArray := strings.Split(nameArray[1], "kB")
pageSize, err := strconv.ParseUint(string(pageSizeArray[0]), 10, 64)
if err != nil {
return hugePagesInfo, err
}
numFile := hugepagesDirectory + st.Name() + "/nr_hugepages"
val, err := ioutil.ReadFile(numFile)
if err != nil {
return hugePagesInfo, err
}
var numPages uint64
// we use sscanf as the file as a new-line that trips up ParseUint
// it returns the number of tokens successfully parsed, so if
// n != 1, it means we were unable to parse a number from the file
n, err := fmt.Sscanf(string(val), "%d", &numPages)
if err != nil || n != 1 {
return hugePagesInfo, fmt.Errorf("could not parse file %v contents %q", numFile, string(val))
}
hugePagesInfo = append(hugePagesInfo, info.HugePagesInfo{
NumPages: numPages,
PageSize: pageSize,
})
}
return hugePagesInfo, nil
}
func Info(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (*info.MachineInfo, error) {
rootFs := "/"
if !inHostNamespace {
@ -65,6 +108,11 @@ func Info(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (*info.Mach
return nil, err
}
hugePagesInfo, err := GetHugePagesInfo()
if err != nil {
return nil, err
}
filesystems, err := fsInfo.GetGlobalFsInfo()
if err != nil {
glog.Errorf("Failed to get global filesystem information: %v", err)
@ -99,6 +147,7 @@ func Info(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (*info.Mach
NumCores: numCores,
CpuFrequency: clockSpeed,
MemoryCapacity: memoryCapacity,
HugePages: hugePagesInfo,
DiskMap: diskMap,
NetworkDevices: netDevices,
Topology: topology,

View File

@ -113,16 +113,18 @@ func (c *containerData) allowErrorLogging() bool {
return false
}
func (c *containerData) GetInfo() (*containerInfo, error) {
func (c *containerData) GetInfo(shouldUpdateSubcontainers bool) (*containerInfo, error) {
// Get spec and subcontainers.
if time.Since(c.lastUpdatedTime) > 5*time.Second {
err := c.updateSpec()
if err != nil {
return nil, err
}
err = c.updateSubcontainers()
if err != nil {
return nil, err
if shouldUpdateSubcontainers {
err = c.updateSubcontainers()
if err != nil {
return nil, err
}
}
c.lastUpdatedTime = time.Now()
}

View File

@ -400,7 +400,7 @@ func (self *manager) GetContainerSpec(containerName string, options v2.RequestOp
var errs partialFailure
specs := make(map[string]v2.ContainerSpec)
for name, cont := range conts {
cinfo, err := cont.GetInfo()
cinfo, err := cont.GetInfo(false)
if err != nil {
errs.append(name, "GetInfo", err)
}
@ -449,7 +449,7 @@ func (self *manager) GetContainerInfoV2(containerName string, options v2.Request
infos := make(map[string]v2.ContainerInfo, len(containers))
for name, container := range containers {
result := v2.ContainerInfo{}
cinfo, err := container.GetInfo()
cinfo, err := container.GetInfo(false)
if err != nil {
errs.append(name, "GetInfo", err)
infos[name] = result
@ -473,7 +473,7 @@ func (self *manager) GetContainerInfoV2(containerName string, options v2.Request
func (self *manager) containerDataToContainerInfo(cont *containerData, query *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
// Get the info from the container.
cinfo, err := cont.GetInfo()
cinfo, err := cont.GetInfo(true)
if err != nil {
return nil, err
}

View File

@ -189,6 +189,13 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Cpu.CFS.ThrottledTime) / float64(time.Second)}}
},
}, {
name: "container_cpu_load_average_10s",
help: "Value of container cpu load average over the last 10 seconds.",
valueType: prometheus.GaugeValue,
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{{value: float64(s.Cpu.LoadAverage)}}
},
}, {
name: "container_memory_cache",
help: "Number of bytes of page cache memory.",
@ -578,6 +585,84 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
}
return values
},
}, {
name: "container_network_tcp_usage_total",
help: "tcp connection usage statistic for container",
valueType: prometheus.GaugeValue,
extraLabels: []string{"tcp_state"},
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{
{
value: float64(s.Network.Tcp.Established),
labels: []string{"established"},
},
{
value: float64(s.Network.Tcp.SynSent),
labels: []string{"synsent"},
},
{
value: float64(s.Network.Tcp.SynRecv),
labels: []string{"synrecv"},
},
{
value: float64(s.Network.Tcp.FinWait1),
labels: []string{"finwait1"},
},
{
value: float64(s.Network.Tcp.FinWait2),
labels: []string{"finwait2"},
},
{
value: float64(s.Network.Tcp.TimeWait),
labels: []string{"timewait"},
},
{
value: float64(s.Network.Tcp.Close),
labels: []string{"close"},
},
{
value: float64(s.Network.Tcp.CloseWait),
labels: []string{"closewait"},
},
{
value: float64(s.Network.Tcp.LastAck),
labels: []string{"lastack"},
},
{
value: float64(s.Network.Tcp.Listen),
labels: []string{"listen"},
},
{
value: float64(s.Network.Tcp.Closing),
labels: []string{"closing"},
},
}
},
}, {
name: "container_network_udp_usage_total",
help: "udp connection usage statistic for container",
valueType: prometheus.GaugeValue,
extraLabels: []string{"udp_state"},
getValues: func(s *info.ContainerStats) metricValues {
return metricValues{
{
value: float64(s.Network.Udp.Listen),
labels: []string{"listen"},
},
{
value: float64(s.Network.Udp.Dropped),
labels: []string{"dropped"},
},
{
value: float64(s.Network.Udp.RxQueued),
labels: []string{"rxqueued"},
},
{
value: float64(s.Network.Udp.TxQueued),
labels: []string{"txqueued"},
},
}
},
}, {
name: "container_tasks_state",
help: "Number of tasks in given state",
@ -610,6 +695,7 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
},
},
}
return c
}

View File

@ -163,7 +163,7 @@ func printUnit(bytes uint64) string {
return ByteSize(bytes).Unit()
}
func serveContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) error {
func serveContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) {
start := time.Now()
// The container name is the path after the handler
@ -175,14 +175,16 @@ func serveContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) e
}
cont, err := m.GetContainerInfo(containerName, &reqParams)
if err != nil {
return fmt.Errorf("failed to get container %q with error: %v", containerName, err)
http.Error(w, fmt.Sprintf("failed to get container %q with error: %v", containerName, err), http.StatusNotFound)
return
}
displayName := getContainerDisplayName(cont.ContainerReference)
// Get the MachineInfo
machineInfo, err := m.GetMachineInfo()
if err != nil {
return err
http.Error(w, fmt.Sprintf("failed to get machine info: %v", err), http.StatusInternalServerError)
return
}
rootDir := getRootDir(containerName)
@ -241,7 +243,6 @@ func serveContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) e
}
glog.V(5).Infof("Request took %s", time.Since(start))
return nil
}
// Build a relative path to the root of the container page.

View File

@ -51,7 +51,7 @@ func toStatusKV(status info.DockerStatus) ([]keyVal, []keyVal) {
}, ds
}
func serveDockerPage(m manager.Manager, w http.ResponseWriter, u *url.URL) error {
func serveDockerPage(m manager.Manager, w http.ResponseWriter, u *url.URL) {
start := time.Now()
// The container name is the path after the handler
@ -66,7 +66,8 @@ func serveDockerPage(m manager.Manager, w http.ResponseWriter, u *url.URL) error
}
conts, err := m.AllDockerContainers(&reqParams)
if err != nil {
return fmt.Errorf("failed to get container %q with error: %v", containerName, err)
http.Error(w, fmt.Sprintf("failed to get container %q with error: %v", containerName, err), http.StatusNotFound)
return
}
subcontainers := make([]link, 0, len(conts))
for _, cont := range conts {
@ -79,14 +80,16 @@ func serveDockerPage(m manager.Manager, w http.ResponseWriter, u *url.URL) error
// Get Docker status
status, err := m.DockerInfo()
if err != nil {
return err
http.Error(w, fmt.Sprintf("failed to get docker info: %v", err), http.StatusInternalServerError)
return
}
dockerStatus, driverStatus := toStatusKV(status)
// Get Docker Images
images, err := m.DockerImages()
if err != nil {
return err
http.Error(w, fmt.Sprintf("failed to get docker images: %v", err), http.StatusInternalServerError)
return
}
dockerContainersText := "Docker Containers"
@ -110,7 +113,8 @@ func serveDockerPage(m manager.Manager, w http.ResponseWriter, u *url.URL) error
}
cont, err := m.DockerContainer(containerName[1:], &reqParams)
if err != nil {
return fmt.Errorf("failed to get container %q with error: %v", containerName, err)
http.Error(w, fmt.Sprintf("failed to get container %q with error: %v", containerName, err), http.StatusNotFound)
return
}
displayName := getContainerDisplayName(cont.ContainerReference)
@ -128,7 +132,8 @@ func serveDockerPage(m manager.Manager, w http.ResponseWriter, u *url.URL) error
// Get the MachineInfo
machineInfo, err := m.GetMachineInfo()
if err != nil {
return err
http.Error(w, fmt.Sprintf("failed to get machine info: %v", err), http.StatusInternalServerError)
return
}
data = &pageData{
DisplayName: displayName,
@ -153,5 +158,5 @@ func serveDockerPage(m manager.Manager, w http.ResponseWriter, u *url.URL) error
}
glog.V(5).Infof("Request took %s", time.Since(start))
return nil
return
}

View File

@ -77,37 +77,25 @@ func init() {
func containerHandlerNoAuth(containerManager manager.Manager) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
err := serveContainersPage(containerManager, w, r.URL)
if err != nil {
fmt.Fprintf(w, "%s", err)
}
serveContainersPage(containerManager, w, r.URL)
}
}
func containerHandler(containerManager manager.Manager) auth.AuthenticatedHandlerFunc {
return func(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
err := serveContainersPage(containerManager, w, r.URL)
if err != nil {
fmt.Fprintf(w, "%s", err)
}
serveContainersPage(containerManager, w, r.URL)
}
}
func dockerHandlerNoAuth(containerManager manager.Manager) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
err := serveDockerPage(containerManager, w, r.URL)
if err != nil {
fmt.Fprintf(w, "%s", err)
}
serveDockerPage(containerManager, w, r.URL)
}
}
func dockerHandler(containerManager manager.Manager) auth.AuthenticatedHandlerFunc {
return func(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
err := serveDockerPage(containerManager, w, r.URL)
if err != nil {
fmt.Fprintf(w, "%s", err)
}
serveDockerPage(containerManager, w, r.URL)
}
}

View File

@ -7,6 +7,7 @@ go_library(
"static.go",
],
visibility = ["//visibility:public"],
deps = ["//vendor/github.com/golang/glog:go_default_library"],
)
filegroup(

File diff suppressed because one or more lines are too long

View File

@ -22,6 +22,8 @@ import (
"net/http"
"net/url"
"path"
"github.com/golang/glog"
)
const StaticResource = "/static/"
@ -47,16 +49,18 @@ var staticFiles = map[string][]byte{
"jquery-1.10.2.min.js": jqueryJs,
}
func HandleRequest(w http.ResponseWriter, u *url.URL) error {
func HandleRequest(w http.ResponseWriter, u *url.URL) {
if len(u.Path) <= len(StaticResource) {
return fmt.Errorf("unknown static resource %q", u.Path)
http.Error(w, fmt.Sprintf("unknown static resource %q", u.Path), http.StatusNotFound)
return
}
// Get the static content if it exists.
resource := u.Path[len(StaticResource):]
content, ok := staticFiles[resource]
if !ok {
return fmt.Errorf("unknown static resource %q", resource)
http.Error(w, fmt.Sprintf("unknown static resource %q", u.Path), http.StatusNotFound)
return
}
// Set Content-Type if we were able to detect it.
@ -65,6 +69,7 @@ func HandleRequest(w http.ResponseWriter, u *url.URL) error {
w.Header().Set("Content-Type", contentType)
}
_, err := w.Write(content)
return err
if _, err := w.Write(content); err != nil {
glog.Errorf("Failed to write response: %v", err)
}
}

File diff suppressed because one or more lines are too long

View File

@ -32,7 +32,7 @@ import (
var (
containerRegexp = regexp.MustCompile(`Task in (.*) killed as a result of limit of (.*)`)
lastLineRegexp = regexp.MustCompile(`(^[A-Z][a-z]{2} .*[0-9]{1,2} [0-9]{1,2}:[0-9]{2}:[0-9]{2}) .* Killed process ([0-9]+) \(([\w]+)\)`)
lastLineRegexp = regexp.MustCompile(`(^[A-Z][a-z]{2} .*[0-9]{1,2} [0-9]{1,2}:[0-9]{2}:[0-9]{2}) .* Killed process ([0-9]+) \((.+)\)`)
firstLineRegexp = regexp.MustCompile(`invoked oom-killer:`)
)