cadvisor/container/docker/factory.go
Victor Marmol a187d74e5b Enable the simple raw driver.
It doesn't yet get the spec, but it is functional enough to use.
This removed the registration of lmctfy, the code will be removed in a
future PR once raw GetSpec() is complete.
2014-07-21 19:02:07 -07:00

117 lines
3.6 KiB
Go

// Copyright 2014 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 (
"flag"
"fmt"
"log"
"regexp"
"strconv"
"strings"
"github.com/docker/libcontainer/cgroups/systemd"
"github.com/fsouza/go-dockerclient"
"github.com/google/cadvisor/container"
"github.com/google/cadvisor/info"
)
var ArgDockerEndpoint = flag.String("docker", "unix:///var/run/docker.sock", "docker endpoint")
type dockerFactory struct {
machineInfoFactory info.MachineInfoFactory
// Whether this system is using systemd.
useSystemd bool
}
func (self *dockerFactory) String() string {
return "docker"
}
func (self *dockerFactory) NewContainerHandler(name string) (handler container.ContainerHandler, err error) {
client, err := docker.NewClient(*ArgDockerEndpoint)
if err != nil {
return
}
handler, err = newDockerContainerHandler(
client,
name,
self.machineInfoFactory,
self.useSystemd,
)
return
}
// Docker handles all containers under /docker
func (self *dockerFactory) CanHandle(name string) bool {
// In systemd systems the containers are: /docker-{ID}
if self.useSystemd {
return strings.HasPrefix(name, "/docker-")
}
return strings.HasPrefix(name, "/docker/")
}
func parseDockerVersion(full_version_string string) ([]int, error) {
version_regexp_string := "(\\d+)\\.(\\d+)\\.(\\d+)"
version_re := regexp.MustCompile(version_regexp_string)
matches := version_re.FindAllStringSubmatch(full_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)
}
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)
if err != nil {
return nil, fmt.Errorf("Error while parsing \"%v\" in \"%v\"", version_string, full_version_string)
}
version_array[index] = version
}
return version_array, nil
}
// Register root container before running this function!
func Register(factory info.MachineInfoFactory) error {
client, err := docker.NewClient(*ArgDockerEndpoint)
if err != nil {
return fmt.Errorf("unable to communicate with docker daemon: %v", err)
}
if version, err := client.Version(); err != nil {
return fmt.Errorf("unable to communicate with docker daemon: %v", err)
} else {
expected_version := []int{0, 11, 1}
version_string := version.Get("Version")
version, err := parseDockerVersion(version_string)
if err != nil {
return fmt.Errorf("Couldn't parse docker version: %v", err)
}
for index, number := range version {
if number > expected_version[index] {
break
} else if number < expected_version[index] {
return fmt.Errorf("cAdvisor requires docker version above %v but we have found version %v reported as \"%v\"", expected_version, version, version_string)
}
}
}
f := &dockerFactory{
machineInfoFactory: factory,
useSystemd: systemd.UseSystemd(),
}
log.Printf("Registering Docker factory")
container.RegisterContainerHandlerFactory(f)
return nil
}