vendor files

This commit is contained in:
Serguei Bezverkhi
2018-01-09 13:57:14 -05:00
parent 558bc6c02a
commit 7b24313bd6
16547 changed files with 4527373 additions and 0 deletions

57
vendor/k8s.io/kubernetes/pkg/kubelet/winstats/BUILD generated vendored Normal file
View File

@ -0,0 +1,57 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"winstats.go",
] + select({
"@io_bazel_rules_go//go/platform:windows_amd64": [
"perfcounter_nodestats.go",
"perfcounters.go",
"version.go",
],
"//conditions:default": [],
}),
importpath = "k8s.io/kubernetes/pkg/kubelet/winstats",
deps = [
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/github.com/google/cadvisor/info/v2:go_default_library",
] + select({
"@io_bazel_rules_go//go/platform:windows_amd64": [
"//vendor/github.com/JeffAshton/win_pdh:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/golang.org/x/sys/windows:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
],
"//conditions:default": [],
}),
)
go_test(
name = "go_default_test",
srcs = ["winstats_test.go"],
importpath = "k8s.io/kubernetes/pkg/kubelet/winstats",
library = ":go_default_library",
deps = [
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
"//vendor/github.com/google/cadvisor/info/v2:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",
],
)

View File

@ -0,0 +1,182 @@
// +build windows
/*
Copyright 2017 The Kubernetes Authors.
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 winstats
import (
"errors"
"os"
"runtime"
"sync"
"syscall"
"time"
"unsafe"
"github.com/golang/glog"
cadvisorapi "github.com/google/cadvisor/info/v1"
"k8s.io/apimachinery/pkg/util/wait"
)
var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetPhysicallyInstalledSystemMemory = modkernel32.NewProc("GetPhysicallyInstalledSystemMemory")
)
// NewPerfCounterClient creates a client using perf counters
func NewPerfCounterClient() (Client, error) {
return newClient(&perfCounterNodeStatsClient{})
}
// perfCounterNodeStatsClient is a client that provides Windows Stats via PerfCounters
type perfCounterNodeStatsClient struct {
nodeMetrics
mu sync.RWMutex // mu protects nodeMetrics
nodeInfo
}
func (p *perfCounterNodeStatsClient) startMonitoring() error {
memory, err := getPhysicallyInstalledSystemMemoryBytes()
if err != nil {
return err
}
kernelVersion, err := getKernelVersion()
if err != nil {
return err
}
osImageVersion, err := getOSImageVersion()
if err != nil {
return err
}
p.nodeInfo = nodeInfo{
kernelVersion: kernelVersion,
osImageVersion: osImageVersion,
memoryPhysicalCapacityBytes: memory,
startTime: time.Now(),
}
cpuCounter, err := newPerfCounter(cpuQuery)
if err != nil {
return err
}
memWorkingSetCounter, err := newPerfCounter(memoryPrivWorkingSetQuery)
if err != nil {
return err
}
memCommittedBytesCounter, err := newPerfCounter(memoryCommittedBytesQuery)
if err != nil {
return err
}
go wait.Forever(func() {
p.collectMetricsData(cpuCounter, memWorkingSetCounter, memCommittedBytesCounter)
}, perfCounterUpdatePeriod)
return nil
}
func (p *perfCounterNodeStatsClient) getMachineInfo() (*cadvisorapi.MachineInfo, error) {
hostname, err := os.Hostname()
if err != nil {
return nil, err
}
return &cadvisorapi.MachineInfo{
NumCores: runtime.NumCPU(),
MemoryCapacity: p.nodeInfo.memoryPhysicalCapacityBytes,
MachineID: hostname,
}, nil
}
func (p *perfCounterNodeStatsClient) getVersionInfo() (*cadvisorapi.VersionInfo, error) {
return &cadvisorapi.VersionInfo{
KernelVersion: p.nodeInfo.kernelVersion,
ContainerOsVersion: p.nodeInfo.osImageVersion,
}, nil
}
func (p *perfCounterNodeStatsClient) getNodeMetrics() (nodeMetrics, error) {
p.mu.RLock()
defer p.mu.RUnlock()
return p.nodeMetrics, nil
}
func (p *perfCounterNodeStatsClient) getNodeInfo() nodeInfo {
return p.nodeInfo
}
func (p *perfCounterNodeStatsClient) collectMetricsData(cpuCounter, memWorkingSetCounter, memCommittedBytesCounter *perfCounter) {
cpuValue, err := cpuCounter.getData()
if err != nil {
glog.Errorf("Unable to get cpu perf counter data; err: %v", err)
return
}
memWorkingSetValue, err := memWorkingSetCounter.getData()
if err != nil {
glog.Errorf("Unable to get memWorkingSet perf counter data; err: %v", err)
return
}
memCommittedBytesValue, err := memCommittedBytesCounter.getData()
if err != nil {
glog.Errorf("Unable to get memCommittedBytes perf counter data; err: %v", err)
return
}
p.mu.Lock()
defer p.mu.Unlock()
p.nodeMetrics = nodeMetrics{
cpuUsageCoreNanoSeconds: p.convertCPUValue(cpuValue),
memoryPrivWorkingSetBytes: memWorkingSetValue,
memoryCommittedBytes: memCommittedBytesValue,
timeStamp: time.Now(),
}
}
func (p *perfCounterNodeStatsClient) convertCPUValue(cpuValue uint64) uint64 {
cpuCores := runtime.NumCPU()
// This converts perf counter data which is cpu percentage for all cores into nanoseconds.
// The formula is (cpuPercentage / 100.0) * #cores * 1e+9 (nano seconds). More info here:
// https://github.com/kubernetes/heapster/issues/650
newValue := p.nodeMetrics.cpuUsageCoreNanoSeconds + uint64((float64(cpuValue)/100.0)*float64(cpuCores)*1e9)
return newValue
}
func getPhysicallyInstalledSystemMemoryBytes() (uint64, error) {
var physicalMemoryKiloBytes uint64
if ok := getPhysicallyInstalledSystemMemory(&physicalMemoryKiloBytes); !ok {
return 0, errors.New("unable to read physical memory")
}
return physicalMemoryKiloBytes * 1024, nil // convert kilobytes to bytes
}
func getPhysicallyInstalledSystemMemory(totalMemoryInKilobytes *uint64) bool {
ret, _, _ := syscall.Syscall(procGetPhysicallyInstalledSystemMemory.Addr(), 1,
uintptr(unsafe.Pointer(totalMemoryInKilobytes)),
0,
0)
return ret != 0
}

View File

@ -0,0 +1,102 @@
// +build windows
/*
Copyright 2017 The Kubernetes Authors.
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 winstats
import (
"errors"
"fmt"
"time"
"unsafe"
"github.com/JeffAshton/win_pdh"
)
const (
cpuQuery = "\\Processor(_Total)\\% Processor Time"
memoryPrivWorkingSetQuery = "\\Process(_Total)\\Working Set - Private"
memoryCommittedBytesQuery = "\\Memory\\Committed Bytes"
// Perf counters are updated every second. This is the same as the default cadvisor collection period
// see https://github.com/google/cadvisor/blob/master/docs/runtime_options.md#housekeeping
perfCounterUpdatePeriod = 1 * time.Second
)
type perfCounter struct {
queryHandle win_pdh.PDH_HQUERY
counterHandle win_pdh.PDH_HCOUNTER
}
func newPerfCounter(counter string) (*perfCounter, error) {
var queryHandle win_pdh.PDH_HQUERY
var counterHandle win_pdh.PDH_HCOUNTER
ret := win_pdh.PdhOpenQuery(0, 0, &queryHandle)
if ret != win_pdh.ERROR_SUCCESS {
return nil, errors.New("unable to open query through DLL call")
}
ret = win_pdh.PdhValidatePath(counter)
if ret != win_pdh.ERROR_SUCCESS {
return nil, fmt.Errorf("unable to valid path to counter. Error code is %x", ret)
}
ret = win_pdh.PdhAddEnglishCounter(queryHandle, counter, 0, &counterHandle)
if ret != win_pdh.ERROR_SUCCESS {
return nil, fmt.Errorf("unable to add process counter. Error code is %x", ret)
}
ret = win_pdh.PdhCollectQueryData(queryHandle)
if ret != win_pdh.ERROR_SUCCESS {
return nil, fmt.Errorf("unable to collect data from counter. Error code is %x", ret)
}
return &perfCounter{
queryHandle: queryHandle,
counterHandle: counterHandle,
}, nil
}
func (p *perfCounter) getData() (uint64, error) {
ret := win_pdh.PdhCollectQueryData(p.queryHandle)
if ret != win_pdh.ERROR_SUCCESS {
return 0, fmt.Errorf("unable to collect data from counter. Error code is %x", ret)
}
var bufSize, bufCount uint32
var size = uint32(unsafe.Sizeof(win_pdh.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE{}))
var emptyBuf [1]win_pdh.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE // need at least 1 addressable null ptr.
var data uint64
ret = win_pdh.PdhGetFormattedCounterArrayDouble(p.counterHandle, &bufSize, &bufCount, &emptyBuf[0])
if ret != win_pdh.PDH_MORE_DATA {
return 0, fmt.Errorf("unable to collect data from counter. Error code is %x", ret)
}
filledBuf := make([]win_pdh.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE, bufCount*size)
ret = win_pdh.PdhGetFormattedCounterArrayDouble(p.counterHandle, &bufSize, &bufCount, &filledBuf[0])
if ret != win_pdh.ERROR_SUCCESS {
return 0, fmt.Errorf("unable to collect data from counter. Error code is %x", ret)
}
for i := 0; i < int(bufCount); i++ {
c := filledBuf[i]
data = uint64(c.FmtValue.DoubleValue)
}
return data, nil
}

View File

@ -0,0 +1,96 @@
// +build windows
/*
Copyright 2017 The Kubernetes Authors.
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 winstats
import (
"fmt"
"unsafe"
"golang.org/x/sys/windows"
)
// getCurrentVersionVal gets value of speficied key from registry.
func getCurrentVersionVal(key string) (string, error) {
var h windows.Handle
if err := windows.RegOpenKeyEx(windows.HKEY_LOCAL_MACHINE,
windows.StringToUTF16Ptr(`SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\`),
0,
windows.KEY_READ,
&h); err != nil {
return "", err
}
defer windows.RegCloseKey(h)
var buf [128]uint16
var typ uint32
n := uint32(len(buf) * int(unsafe.Sizeof(buf[0]))) // api expects array of bytes, not uint16
if err := windows.RegQueryValueEx(h,
windows.StringToUTF16Ptr(key),
nil,
&typ,
(*byte)(unsafe.Pointer(&buf[0])),
&n); err != nil {
return "", err
}
return windows.UTF16ToString(buf[:]), nil
}
// getVersionRevision gets revision from UBR registry.
func getVersionRevision() (uint16, error) {
revisionString, err := getCurrentVersionVal("UBR")
if err != nil {
return 0, err
}
revision, err := windows.UTF16FromString(revisionString)
if err != nil {
return 0, err
}
return revision[0], nil
}
// getKernelVersion gets the version of windows kernel.
func getKernelVersion() (string, error) {
ver, err := windows.GetVersion()
if err != nil {
return "", err
}
revision, err := getVersionRevision()
if err != nil {
return "", err
}
major := ver & 0xFF
minor := (ver >> 8) & 0xFF
build := (ver >> 16) & 0xFFFF
return fmt.Sprintf("%d.%d.%05d.%d\n", major, minor, build, revision), nil
}
// getOSImageVersion gets the osImage name and version.
func getOSImageVersion() (string, error) {
productName, err := getCurrentVersionVal("ProductName")
if err != nil {
return "", nil
}
return productName, nil
}

View File

@ -0,0 +1,136 @@
/*
Copyright 2017 The Kubernetes Authors.
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 winstats provides a client to get node and pod level stats on windows
package winstats
import (
"time"
cadvisorapi "github.com/google/cadvisor/info/v1"
cadvisorapiv2 "github.com/google/cadvisor/info/v2"
)
// Client is an interface that is used to get stats information.
type Client interface {
WinContainerInfos() (map[string]cadvisorapiv2.ContainerInfo, error)
WinMachineInfo() (*cadvisorapi.MachineInfo, error)
WinVersionInfo() (*cadvisorapi.VersionInfo, error)
}
// StatsClient is a client that implements the Client interface
type statsClient struct {
client winNodeStatsClient
}
type winNodeStatsClient interface {
startMonitoring() error
getNodeMetrics() (nodeMetrics, error)
getNodeInfo() nodeInfo
getMachineInfo() (*cadvisorapi.MachineInfo, error)
getVersionInfo() (*cadvisorapi.VersionInfo, error)
}
type nodeMetrics struct {
cpuUsageCoreNanoSeconds uint64
memoryPrivWorkingSetBytes uint64
memoryCommittedBytes uint64
timeStamp time.Time
}
type nodeInfo struct {
memoryPhysicalCapacityBytes uint64
kernelVersion string
osImageVersion string
// startTime is the time when the node was started
startTime time.Time
}
// newClient constructs a Client.
func newClient(statsNodeClient winNodeStatsClient) (Client, error) {
statsClient := new(statsClient)
statsClient.client = statsNodeClient
err := statsClient.client.startMonitoring()
if err != nil {
return nil, err
}
return statsClient, nil
}
// WinContainerInfos returns a map of container infos. The map contains node and
// pod level stats. Analogous to cadvisor GetContainerInfoV2 method.
func (c *statsClient) WinContainerInfos() (map[string]cadvisorapiv2.ContainerInfo, error) {
infos := make(map[string]cadvisorapiv2.ContainerInfo)
rootContainerInfo, err := c.createRootContainerInfo()
if err != nil {
return nil, err
}
infos["/"] = *rootContainerInfo
return infos, nil
}
// WinMachineInfo returns a cadvisorapi.MachineInfo with details about the
// node machine. Analogous to cadvisor MachineInfo method.
func (c *statsClient) WinMachineInfo() (*cadvisorapi.MachineInfo, error) {
return c.client.getMachineInfo()
}
// WinVersionInfo returns a cadvisorapi.VersionInfo with version info of
// the kernel and docker runtime. Analogous to cadvisor VersionInfo method.
func (c *statsClient) WinVersionInfo() (*cadvisorapi.VersionInfo, error) {
return c.client.getVersionInfo()
}
func (c *statsClient) createRootContainerInfo() (*cadvisorapiv2.ContainerInfo, error) {
nodeMetrics, err := c.client.getNodeMetrics()
if err != nil {
return nil, err
}
var stats []*cadvisorapiv2.ContainerStats
stats = append(stats, &cadvisorapiv2.ContainerStats{
Timestamp: nodeMetrics.timeStamp,
Cpu: &cadvisorapi.CpuStats{
Usage: cadvisorapi.CpuUsage{
Total: nodeMetrics.cpuUsageCoreNanoSeconds,
},
},
Memory: &cadvisorapi.MemoryStats{
WorkingSet: nodeMetrics.memoryPrivWorkingSetBytes,
Usage: nodeMetrics.memoryCommittedBytes,
},
})
nodeInfo := c.client.getNodeInfo()
rootInfo := cadvisorapiv2.ContainerInfo{
Spec: cadvisorapiv2.ContainerSpec{
CreationTime: nodeInfo.startTime,
HasCpu: true,
HasMemory: true,
Memory: cadvisorapiv2.MemorySpec{
Limit: nodeInfo.memoryPhysicalCapacityBytes,
},
},
Stats: stats,
}
return &rootInfo, nil
}

View File

@ -0,0 +1,125 @@
/*
Copyright 2017 The Kubernetes Authors.
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 winstats
import (
"testing"
"time"
cadvisorapi "github.com/google/cadvisor/info/v1"
cadvisorapiv2 "github.com/google/cadvisor/info/v2"
"github.com/stretchr/testify/assert"
)
var timeStamp = time.Now()
type fakeWinNodeStatsClient struct{}
func (f fakeWinNodeStatsClient) startMonitoring() error {
return nil
}
func (f fakeWinNodeStatsClient) getNodeMetrics() (nodeMetrics, error) {
return nodeMetrics{
cpuUsageCoreNanoSeconds: 123,
memoryPrivWorkingSetBytes: 1234,
memoryCommittedBytes: 12345,
timeStamp: timeStamp,
}, nil
}
func (f fakeWinNodeStatsClient) getNodeInfo() nodeInfo {
return nodeInfo{
kernelVersion: "v42",
memoryPhysicalCapacityBytes: 1.6e+10,
}
}
func (f fakeWinNodeStatsClient) getMachineInfo() (*cadvisorapi.MachineInfo, error) {
return &cadvisorapi.MachineInfo{
NumCores: 4,
MemoryCapacity: 1.6e+10,
MachineID: "somehostname",
}, nil
}
func (f fakeWinNodeStatsClient) getVersionInfo() (*cadvisorapi.VersionInfo, error) {
return &cadvisorapi.VersionInfo{
KernelVersion: "v42",
}, nil
}
func TestWinContainerInfos(t *testing.T) {
c := getClient(t)
actualRootInfos, err := c.WinContainerInfos()
assert.NoError(t, err)
var stats []*cadvisorapiv2.ContainerStats
stats = append(stats, &cadvisorapiv2.ContainerStats{
Timestamp: timeStamp,
Cpu: &cadvisorapi.CpuStats{
Usage: cadvisorapi.CpuUsage{
Total: 123,
},
},
Memory: &cadvisorapi.MemoryStats{
WorkingSet: 1234,
Usage: 12345,
},
})
infos := make(map[string]cadvisorapiv2.ContainerInfo)
infos["/"] = cadvisorapiv2.ContainerInfo{
Spec: cadvisorapiv2.ContainerSpec{
HasCpu: true,
HasMemory: true,
Memory: cadvisorapiv2.MemorySpec{
Limit: 1.6e+10,
},
},
Stats: stats,
}
assert.Equal(t, actualRootInfos, infos)
}
func TestWinMachineInfo(t *testing.T) {
c := getClient(t)
machineInfo, err := c.WinMachineInfo()
assert.NoError(t, err)
assert.Equal(t, machineInfo, &cadvisorapi.MachineInfo{
NumCores: 4,
MemoryCapacity: 1.6e+10,
MachineID: "somehostname"})
}
func TestWinVersionInfo(t *testing.T) {
c := getClient(t)
versionInfo, err := c.WinVersionInfo()
assert.NoError(t, err)
assert.Equal(t, versionInfo, &cadvisorapi.VersionInfo{
KernelVersion: "v42"})
}
func getClient(t *testing.T) Client {
f := fakeWinNodeStatsClient{}
c, err := newClient(f)
assert.NoError(t, err)
assert.NotNil(t, c)
return c
}