mirror of https://github.com/k3s-io/k3s
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
commit
9292074a6b
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
|
||||
|
|
|
@ -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"`
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
@ -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:`)
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue