mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-04 07:49:35 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			209 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			209 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2016 Google Inc. All Rights Reserved.
 | 
						|
//
 | 
						|
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
// you may not use this file except in compliance with the License.
 | 
						|
// You may obtain a copy of the License at
 | 
						|
//
 | 
						|
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
//
 | 
						|
// Unless required by applicable law or agreed to in writing, software
 | 
						|
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
// See the License for the specific language governing permissions and
 | 
						|
// limitations under the License.
 | 
						|
 | 
						|
// Provides global docker information.
 | 
						|
package docker
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"regexp"
 | 
						|
	"strconv"
 | 
						|
 | 
						|
	dockertypes "github.com/docker/docker/api/types"
 | 
						|
	"golang.org/x/net/context"
 | 
						|
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/google/cadvisor/info/v1"
 | 
						|
	"github.com/google/cadvisor/machine"
 | 
						|
)
 | 
						|
 | 
						|
var dockerTimeout = 10 * time.Second
 | 
						|
 | 
						|
func defaultContext() context.Context {
 | 
						|
	ctx, _ := context.WithTimeout(context.Background(), dockerTimeout)
 | 
						|
	return ctx
 | 
						|
}
 | 
						|
 | 
						|
func SetTimeout(timeout time.Duration) {
 | 
						|
	dockerTimeout = timeout
 | 
						|
}
 | 
						|
 | 
						|
func Status() (v1.DockerStatus, error) {
 | 
						|
	return StatusWithContext(defaultContext())
 | 
						|
}
 | 
						|
 | 
						|
func StatusWithContext(ctx context.Context) (v1.DockerStatus, error) {
 | 
						|
	client, err := Client()
 | 
						|
	if err != nil {
 | 
						|
		return v1.DockerStatus{}, fmt.Errorf("unable to communicate with docker daemon: %v", err)
 | 
						|
	}
 | 
						|
	dockerInfo, err := client.Info(ctx)
 | 
						|
	if err != nil {
 | 
						|
		return v1.DockerStatus{}, err
 | 
						|
	}
 | 
						|
	return StatusFromDockerInfo(dockerInfo)
 | 
						|
}
 | 
						|
 | 
						|
func StatusFromDockerInfo(dockerInfo dockertypes.Info) (v1.DockerStatus, error) {
 | 
						|
	out := v1.DockerStatus{}
 | 
						|
	out.KernelVersion = machine.KernelVersion()
 | 
						|
	out.OS = dockerInfo.OperatingSystem
 | 
						|
	out.Hostname = dockerInfo.Name
 | 
						|
	out.RootDir = dockerInfo.DockerRootDir
 | 
						|
	out.Driver = dockerInfo.Driver
 | 
						|
	out.NumImages = dockerInfo.Images
 | 
						|
	out.NumContainers = dockerInfo.Containers
 | 
						|
	out.DriverStatus = make(map[string]string, len(dockerInfo.DriverStatus))
 | 
						|
	for _, v := range dockerInfo.DriverStatus {
 | 
						|
		out.DriverStatus[v[0]] = v[1]
 | 
						|
	}
 | 
						|
	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) {
 | 
						|
	client, err := Client()
 | 
						|
	if err != nil {
 | 
						|
		return nil, fmt.Errorf("unable to communicate with docker daemon: %v", err)
 | 
						|
	}
 | 
						|
	images, err := client.ImageList(defaultContext(), dockertypes.ImageListOptions{All: false})
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	out := []v1.DockerImage{}
 | 
						|
	const unknownTag = "<none>:<none>"
 | 
						|
	for _, image := range images {
 | 
						|
		if len(image.RepoTags) == 1 && image.RepoTags[0] == unknownTag {
 | 
						|
			// images with repo or tags are uninteresting.
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		di := v1.DockerImage{
 | 
						|
			ID:          image.ID,
 | 
						|
			RepoTags:    image.RepoTags,
 | 
						|
			Created:     image.Created,
 | 
						|
			VirtualSize: image.VirtualSize,
 | 
						|
			Size:        image.Size,
 | 
						|
		}
 | 
						|
		out = append(out, di)
 | 
						|
	}
 | 
						|
	return out, nil
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
// Checks whether the dockerInfo reflects a valid docker setup, and returns it if it does, or an
 | 
						|
// error otherwise.
 | 
						|
func ValidateInfo() (*dockertypes.Info, error) {
 | 
						|
	client, err := Client()
 | 
						|
	if err != nil {
 | 
						|
		return nil, fmt.Errorf("unable to communicate with docker daemon: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	dockerInfo, err := client.Info(defaultContext())
 | 
						|
	if err != nil {
 | 
						|
		return nil, fmt.Errorf("failed to detect Docker info: %v", err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Fall back to version API if ServerVersion is not set in info.
 | 
						|
	if dockerInfo.ServerVersion == "" {
 | 
						|
		version, err := client.ServerVersion(defaultContext())
 | 
						|
		if err != nil {
 | 
						|
			return nil, fmt.Errorf("unable to get docker version: %v", err)
 | 
						|
		}
 | 
						|
		dockerInfo.ServerVersion = version.Version
 | 
						|
	}
 | 
						|
	version, err := parseVersion(dockerInfo.ServerVersion, version_re, 3)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	if version[0] < 1 {
 | 
						|
		return nil, fmt.Errorf("cAdvisor requires docker version %v or above but we have found version %v reported as %q", []int{1, 0, 0}, version, dockerInfo.ServerVersion)
 | 
						|
	}
 | 
						|
 | 
						|
	if dockerInfo.Driver == "" {
 | 
						|
		return nil, fmt.Errorf("failed to find docker storage driver")
 | 
						|
	}
 | 
						|
 | 
						|
	return &dockerInfo, nil
 | 
						|
}
 | 
						|
 | 
						|
func Version() ([]int, error) {
 | 
						|
	ver, err := VersionString()
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	return parseVersion(ver, version_re, 3)
 | 
						|
}
 | 
						|
 | 
						|
func APIVersion() ([]int, error) {
 | 
						|
	ver, err := APIVersionString()
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	return parseVersion(ver, apiversion_re, 2)
 | 
						|
}
 | 
						|
 | 
						|
func VersionString() (string, error) {
 | 
						|
	docker_version := "Unknown"
 | 
						|
	client, err := Client()
 | 
						|
	if err == nil {
 | 
						|
		version, err := client.ServerVersion(defaultContext())
 | 
						|
		if err == nil {
 | 
						|
			docker_version = version.Version
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return docker_version, err
 | 
						|
}
 | 
						|
 | 
						|
func APIVersionString() (string, error) {
 | 
						|
	docker_api_version := "Unknown"
 | 
						|
	client, err := Client()
 | 
						|
	if err == nil {
 | 
						|
		version, err := client.ServerVersion(defaultContext())
 | 
						|
		if err == nil {
 | 
						|
			docker_api_version = version.APIVersion
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return docker_api_version, err
 | 
						|
}
 | 
						|
 | 
						|
func parseVersion(version_string string, regex *regexp.Regexp, length int) ([]int, error) {
 | 
						|
	matches := regex.FindAllStringSubmatch(version_string, -1)
 | 
						|
	if len(matches) != 1 {
 | 
						|
		return nil, fmt.Errorf("version string \"%v\" doesn't match expected regular expression: \"%v\"", version_string, regex.String())
 | 
						|
	}
 | 
						|
	version_string_array := matches[0][1:]
 | 
						|
	version_array := make([]int, length)
 | 
						|
	for index, version_str := range version_string_array {
 | 
						|
		version, err := strconv.Atoi(version_str)
 | 
						|
		if err != nil {
 | 
						|
			return nil, fmt.Errorf("error while parsing \"%v\" in \"%v\"", version_str, version_string)
 | 
						|
		}
 | 
						|
		version_array[index] = version
 | 
						|
	}
 | 
						|
	return version_array, nil
 | 
						|
}
 |