Skip to content

Commit

Permalink
Merge pull request google#1623 from mkumatag/docker_api_version
Browse files Browse the repository at this point in the history
Add Docker API version
  • Loading branch information
dashpole authored Apr 4, 2017
2 parents bd72ac3 + 8fb1158 commit 2ddeb5f
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 13 deletions.
37 changes: 27 additions & 10 deletions container/docker/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package docker

import (
"fmt"
"regexp"
"strconv"
"strings"

Expand All @@ -39,6 +40,7 @@ func Status() (v1.DockerStatus, error) {

out := v1.DockerStatus{}
out.Version = VersionString()
out.APIVersion = APIVersionString()
out.KernelVersion = machine.KernelVersion()
out.OS = dockerInfo.OperatingSystem
out.Hostname = dockerInfo.Name
Expand Down Expand Up @@ -105,7 +107,7 @@ func ValidateInfo() (*dockertypes.Info, error) {
}
dockerInfo.ServerVersion = version.Version
}
version, err := parseDockerVersion(dockerInfo.ServerVersion)
version, err := parseVersion(dockerInfo.ServerVersion, version_re, 3)
if err != nil {
return nil, err
}
Expand All @@ -129,7 +131,11 @@ func ValidateInfo() (*dockertypes.Info, error) {
}

func Version() ([]int, error) {
return parseDockerVersion(VersionString())
return parseVersion(VersionString(), version_re, 3)
}

func APIVersion() ([]int, error) {
return parseVersion(APIVersionString(), apiversion_re, 2)
}

func VersionString() string {
Expand All @@ -144,18 +150,29 @@ func VersionString() string {
return docker_version
}

// TODO: switch to a semantic versioning library.
func parseDockerVersion(full_version_string string) ([]int, error) {
matches := version_re.FindAllStringSubmatch(full_version_string, -1)
func APIVersionString() string {
docker_api_version := "Unknown"
client, err := Client()
if err == nil {
version, err := client.ServerVersion(context.Background())
if err == nil {
docker_api_version = version.APIVersion
}
}
return docker_api_version
}

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\"", full_version_string, version_regexp_string)
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, 3)
for index, version_string := range version_string_array {
version, err := strconv.Atoi(version_string)
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_string, full_version_string)
return nil, fmt.Errorf("error while parsing \"%v\" in \"%v\"", version_str, version_string)
}
version_array[index] = version
}
Expand Down
51 changes: 51 additions & 0 deletions container/docker/docker_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2017 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.

package docker

import (
"reflect"
"regexp"
"testing"
)

func TestParseDockerAPIVersion(t *testing.T) {
tests := []struct {
version string
regex *regexp.Regexp
length int
expected []int
expectedError string
}{
{"17.03.0", version_re, 3, []int{17, 03, 0}, ""},
{"17.a3.0", version_re, 3, []int{}, `version string "17.a3.0" doesn't match expected regular expression: "(\d+)\.(\d+)\.(\d+)"`},
{"1.20", apiversion_re, 2, []int{1, 20}, ""},
{"1.a", apiversion_re, 2, []int{}, `version string "1.a" doesn't match expected regular expression: "(\d+)\.(\d+)"`},
}

for _, test := range tests {
actual, err := parseVersion(test.version, test.regex, test.length)
if err != nil {
if len(test.expectedError) == 0 {
t.Errorf("%s: expected no error, got %v", test.version, err)
} else if err.Error() != test.expectedError {
t.Errorf("%s: expected error %v, got %v", test.version, test.expectedError, err)
}
} else {
if !reflect.DeepEqual(actual, test.expected) {
t.Errorf("%s: expected array %v, got %v", test.version, test.expected, actual)
}
}
}
}
13 changes: 10 additions & 3 deletions container/docker/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ type dockerFactory struct {

dockerVersion []int

dockerAPIVersion []int

ignoreMetrics container.MetricSet

thinPoolWatcher *devicemapper.ThinPoolWatcher
Expand Down Expand Up @@ -185,8 +187,10 @@ func (self *dockerFactory) DebugInfo() map[string][]string {
}

var (
version_regexp_string = `(\d+)\.(\d+)\.(\d+)`
version_re = regexp.MustCompile(version_regexp_string)
version_regexp_string = `(\d+)\.(\d+)\.(\d+)`
version_re = regexp.MustCompile(version_regexp_string)
apiversion_regexp_string = `(\d+)\.(\d+)`
apiversion_re = regexp.MustCompile(apiversion_regexp_string)
)

func startThinPoolWatcher(dockerInfo *dockertypes.Info) (*devicemapper.ThinPoolWatcher, error) {
Expand Down Expand Up @@ -310,7 +314,9 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics c
}

// Version already validated above, assume no error here.
dockerVersion, _ := parseDockerVersion(dockerInfo.ServerVersion)
dockerVersion, _ := parseVersion(dockerInfo.ServerVersion, version_re, 3)

dockerAPIVersion, _ := APIVersion()

cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
if err != nil {
Expand Down Expand Up @@ -338,6 +344,7 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics c
cgroupSubsystems: cgroupSubsystems,
client: client,
dockerVersion: dockerVersion,
dockerAPIVersion: dockerAPIVersion,
fsInfo: fsInfo,
machineInfoFactory: factory,
storageDriver: storageDriver(dockerInfo.Driver),
Expand Down
1 change: 1 addition & 0 deletions info/v1/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package v1

type DockerStatus struct {
Version string `json:"version"`
APIVersion string `json:"api_version"`
KernelVersion string `json:"kernel_version"`
OS string `json:"os"`
Hostname string `json:"hostname"`
Expand Down
3 changes: 3 additions & 0 deletions info/v1/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ type VersionInfo struct {
// Docker version.
DockerVersion string `json:"docker_version"`

// Docker API Version
DockerAPIVersion string `json:"docker_api_version"`

// cAdvisor version.
CadvisorVersion string `json:"cadvisor_version"`
// cAdvisor git revision.
Expand Down
4 changes: 4 additions & 0 deletions info/v2/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ type Attributes struct {
// Docker version.
DockerVersion string `json:"docker_version"`

// Docker API version.
DockerAPIVersion string `json:"docker_api_version"`

// cAdvisor version.
CadvisorVersion string `json:"cadvisor_version"`

Expand Down Expand Up @@ -74,6 +77,7 @@ func GetAttributes(mi *v1.MachineInfo, vi *v1.VersionInfo) Attributes {
KernelVersion: vi.KernelVersion,
ContainerOsVersion: vi.ContainerOsVersion,
DockerVersion: vi.DockerVersion,
DockerAPIVersion: vi.DockerAPIVersion,
CadvisorVersion: vi.CadvisorVersion,
NumCores: mi.NumCores,
CpuFrequency: mi.CpuFrequency,
Expand Down
2 changes: 2 additions & 0 deletions manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -1255,11 +1255,13 @@ func getVersionInfo() (*info.VersionInfo, error) {
kernel_version := machine.KernelVersion()
container_os := machine.ContainerOsVersion()
docker_version := docker.VersionString()
docker_api_version := docker.APIVersionString()

return &info.VersionInfo{
KernelVersion: kernel_version,
ContainerOsVersion: container_os,
DockerVersion: docker_version,
DockerAPIVersion: docker_api_version,
CadvisorVersion: version.Info["version"],
CadvisorRevision: version.Info["revision"],
}, nil
Expand Down
1 change: 1 addition & 0 deletions pages/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func toStatusKV(status info.DockerStatus) ([]keyVal, []keyVal) {
}
return []keyVal{
{Key: "Docker Version", Value: status.Version},
{Key: "Docker API Version", Value: status.APIVersion},
{Key: "Kernel Version", Value: status.KernelVersion},
{Key: "OS Version", Value: status.OS},
{Key: "Host Name", Value: status.Hostname},
Expand Down

0 comments on commit 2ddeb5f

Please sign in to comment.