Merge pull request #1830 from jsravn/add-docker-timeouts

Add timeouts for docker queries
This commit is contained in:
David Ashpole 2017-12-07 09:37:53 -08:00 committed by GitHub
commit fc6d4b920c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 20 deletions

View File

@ -23,26 +23,33 @@ import (
dockertypes "github.com/docker/docker/api/types" dockertypes "github.com/docker/docker/api/types"
"golang.org/x/net/context" "golang.org/x/net/context"
"time"
"github.com/google/cadvisor/info/v1" "github.com/google/cadvisor/info/v1"
"github.com/google/cadvisor/machine" "github.com/google/cadvisor/machine"
) )
const defaultTimeout = time.Second * 5
func defaultContext() context.Context {
ctx, _ := context.WithTimeout(context.Background(), defaultTimeout)
return ctx
}
func Status() (v1.DockerStatus, error) { func Status() (v1.DockerStatus, error) {
client, err := Client() client, err := Client()
if err != nil { if err != nil {
return v1.DockerStatus{}, fmt.Errorf("unable to communicate with docker daemon: %v", err) return v1.DockerStatus{}, fmt.Errorf("unable to communicate with docker daemon: %v", err)
} }
dockerInfo, err := client.Info(context.Background()) dockerInfo, err := client.Info(defaultContext())
if err != nil { if err != nil {
return v1.DockerStatus{}, err return v1.DockerStatus{}, err
} }
return StatusFromDockerInfo(dockerInfo), nil return StatusFromDockerInfo(dockerInfo)
} }
func StatusFromDockerInfo(dockerInfo dockertypes.Info) v1.DockerStatus { func StatusFromDockerInfo(dockerInfo dockertypes.Info) (v1.DockerStatus, error) {
out := v1.DockerStatus{} out := v1.DockerStatus{}
out.Version = VersionString()
out.APIVersion = APIVersionString()
out.KernelVersion = machine.KernelVersion() out.KernelVersion = machine.KernelVersion()
out.OS = dockerInfo.OperatingSystem out.OS = dockerInfo.OperatingSystem
out.Hostname = dockerInfo.Name out.Hostname = dockerInfo.Name
@ -54,7 +61,18 @@ func StatusFromDockerInfo(dockerInfo dockertypes.Info) v1.DockerStatus {
for _, v := range dockerInfo.DriverStatus { for _, v := range dockerInfo.DriverStatus {
out.DriverStatus[v[0]] = v[1] out.DriverStatus[v[0]] = v[1]
} }
return out var err error
ver, err := VersionString()
if err != nil {
return out, err
}
out.Version = ver
ver, err = APIVersionString()
if err != nil {
return out, err
}
out.APIVersion = ver
return out, nil
} }
func Images() ([]v1.DockerImage, error) { func Images() ([]v1.DockerImage, error) {
@ -62,7 +80,7 @@ func Images() ([]v1.DockerImage, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to communicate with docker daemon: %v", err) return nil, fmt.Errorf("unable to communicate with docker daemon: %v", err)
} }
images, err := client.ImageList(context.Background(), dockertypes.ImageListOptions{All: false}) images, err := client.ImageList(defaultContext(), dockertypes.ImageListOptions{All: false})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -95,14 +113,14 @@ func ValidateInfo() (*dockertypes.Info, error) {
return nil, fmt.Errorf("unable to communicate with docker daemon: %v", err) return nil, fmt.Errorf("unable to communicate with docker daemon: %v", err)
} }
dockerInfo, err := client.Info(context.Background()) dockerInfo, err := client.Info(defaultContext())
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to detect Docker info: %v", err) return nil, fmt.Errorf("failed to detect Docker info: %v", err)
} }
// Fall back to version API if ServerVersion is not set in info. // Fall back to version API if ServerVersion is not set in info.
if dockerInfo.ServerVersion == "" { if dockerInfo.ServerVersion == "" {
version, err := client.ServerVersion(context.Background()) version, err := client.ServerVersion(defaultContext())
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to get docker version: %v", err) return nil, fmt.Errorf("unable to get docker version: %v", err)
} }
@ -125,35 +143,43 @@ func ValidateInfo() (*dockertypes.Info, error) {
} }
func Version() ([]int, error) { func Version() ([]int, error) {
return parseVersion(VersionString(), version_re, 3) ver, err := VersionString()
if err != nil {
return nil, err
}
return parseVersion(ver, version_re, 3)
} }
func APIVersion() ([]int, error) { func APIVersion() ([]int, error) {
return parseVersion(APIVersionString(), apiversion_re, 2) ver, err := APIVersionString()
if err != nil {
return nil, err
}
return parseVersion(ver, apiversion_re, 2)
} }
func VersionString() string { func VersionString() (string, error) {
docker_version := "Unknown" docker_version := "Unknown"
client, err := Client() client, err := Client()
if err == nil { if err == nil {
version, err := client.ServerVersion(context.Background()) version, err := client.ServerVersion(defaultContext())
if err == nil { if err == nil {
docker_version = version.Version docker_version = version.Version
} }
} }
return docker_version return docker_version, err
} }
func APIVersionString() string { func APIVersionString() (string, error) {
docker_api_version := "Unknown" docker_api_version := "Unknown"
client, err := Client() client, err := Client()
if err == nil { if err == nil {
version, err := client.ServerVersion(context.Background()) version, err := client.ServerVersion(defaultContext())
if err == nil { if err == nil {
docker_api_version = version.APIVersion docker_api_version = version.APIVersion
} }
} }
return docker_api_version return docker_api_version, err
} }
func parseVersion(version_string string, regex *regexp.Regexp, length int) ([]int, error) { func parseVersion(version_string string, regex *regexp.Regexp, length int) ([]int, error) {

View File

@ -340,7 +340,8 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics c
glog.Errorf("devicemapper filesystem stats will not be reported: %v", err) glog.Errorf("devicemapper filesystem stats will not be reported: %v", err)
} }
status := StatusFromDockerInfo(*dockerInfo) // Safe to ignore error - driver status should always be populated.
status, _ := StatusFromDockerInfo(*dockerInfo)
thinPoolName = status.DriverStatus[dockerutil.DriverStatusPoolName] thinPoolName = status.DriverStatus[dockerutil.DriverStatusPoolName]
} }

View File

@ -1343,8 +1343,14 @@ func getVersionInfo() (*info.VersionInfo, error) {
kernel_version := machine.KernelVersion() kernel_version := machine.KernelVersion()
container_os := machine.ContainerOsVersion() container_os := machine.ContainerOsVersion()
docker_version := docker.VersionString() docker_version, err := docker.VersionString()
docker_api_version := docker.APIVersionString() if err != nil {
return nil, err
}
docker_api_version, err := docker.APIVersionString()
if err != nil {
return nil, err
}
return &info.VersionInfo{ return &info.VersionInfo{
KernelVersion: kernel_version, KernelVersion: kernel_version,