Example #1
0
func TestNewContainerHandler_SecondMatches(t *testing.T) {
	container.ClearContainerHandlerFactories()

	// Register one allways no and one always yes factory.
	allwaysNo := &mockContainerHandlerFactory{
		Name:           "no",
		CanHandleValue: false,
		CanAcceptValue: true,
	}
	container.RegisterContainerHandlerFactory(allwaysNo, []watcher.ContainerWatchSource{watcher.Raw})
	allwaysYes := &mockContainerHandlerFactory{
		Name:           "yes",
		CanHandleValue: true,
		CanAcceptValue: true,
	}
	container.RegisterContainerHandlerFactory(allwaysYes, []watcher.ContainerWatchSource{watcher.Raw})

	// The yes factory should be asked to create the ContainerHandler.
	mockContainer, err := mockFactory.NewContainerHandler(testContainerName, true)
	if err != nil {
		t.Error(err)
	}
	allwaysYes.On("NewContainerHandler", testContainerName).Return(mockContainer, nil)

	cont, _, err := container.NewContainerHandler(testContainerName, watcher.Raw, true)
	if err != nil {
		t.Error(err)
	}
	if cont == nil {
		t.Error("Expected container to not be nil")
	}
}
Example #2
0
func TestNewContainerHandler_Accept(t *testing.T) {
	container.ClearContainerHandlerFactories()

	// Register handler that can handle the container, but can't accept it.
	cannotHandle := &mockContainerHandlerFactory{
		Name:           "no",
		CanHandleValue: false,
		CanAcceptValue: true,
	}
	container.RegisterContainerHandlerFactory(cannotHandle, []watcher.ContainerWatchSource{watcher.Raw})
	cannotAccept := &mockContainerHandlerFactory{
		Name:           "no",
		CanHandleValue: true,
		CanAcceptValue: false,
	}
	container.RegisterContainerHandlerFactory(cannotAccept, []watcher.ContainerWatchSource{watcher.Raw})

	_, accept, err := container.NewContainerHandler(testContainerName, watcher.Raw, true)
	if err != nil {
		t.Error("Expected NewContainerHandler to succeed")
	}
	if accept == true {
		t.Error("Expected NewContainerHandler to ignore the container.")
	}
}
func createContainerDataAndSetHandler(
	driver storage.StorageDriver,
	f func(*container.MockContainerHandler),
	t *testing.T,
) *containerData {
	factory := &container.FactoryForMockContainerHandler{
		Name: "factoryForMockContainer",
		PrepareContainerHandlerFunc: func(name string, handler *container.MockContainerHandler) {
			handler.Name = name
			f(handler)
		},
	}
	container.ClearContainerHandlerFactories()
	container.RegisterContainerHandlerFactory(factory)

	if driver == nil {
		driver = &stest.MockStorageDriver{}
	}

	ret, err := NewContainerData("/container", driver)
	if err != nil {
		t.Fatal(err)
	}
	return ret
}
Example #4
0
func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics map[container.MetricKind]struct{}) error {
	cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
	if err != nil {
		return fmt.Errorf("failed to get cgroup subsystems: %v", err)
	}
	if len(cgroupSubsystems.Mounts) == 0 {
		return fmt.Errorf("failed to find supported cgroup mounts for the raw factory")
	}

	watcher, err := NewInotifyWatcher()
	if err != nil {
		return err
	}

	glog.Infof("Registering Raw factory")
	factory := &rawFactory{
		machineInfoFactory: machineInfoFactory,
		fsInfo:             fsInfo,
		cgroupSubsystems:   &cgroupSubsystems,
		watcher:            watcher,
		ignoreMetrics:      ignoreMetrics,
	}
	container.RegisterContainerHandlerFactory(factory)
	return nil
}
Example #5
0
// 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(),
		client:             client,
	}
	if f.useSystemd {
		log.Printf("System is using systemd")
	}
	log.Printf("Registering Docker factory")
	container.RegisterContainerHandlerFactory(f)
	return nil
}
Example #6
0
// Register root container before running this function!
func Register(factory info.MachineInfoFactory, paths ...string) 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,
	}
	for _, p := range paths {
		if p != "/" && p != "/docker" {
			return fmt.Errorf("%v cannot be managed by docker", p)
		}
		container.RegisterContainerHandlerFactory(p, f)
	}
	return nil
}
Example #7
0
func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics container.MetricSet) error {
	_, err := Client()
	if err != nil {
		return fmt.Errorf("unable to communicate with Rkt api service: %v", err)
	}

	rktPath, err := RktPath()
	if err != nil {
		return fmt.Errorf("unable to get the RktPath variable %v", err)
	}

	cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
	if err != nil {
		return fmt.Errorf("failed to get cgroup subsystems: %v", err)
	}
	if len(cgroupSubsystems.Mounts) == 0 {
		return fmt.Errorf("failed to find supported cgroup mounts for the raw factory")
	}

	glog.Infof("Registering Rkt factory")
	factory := &rktFactory{
		machineInfoFactory: machineInfoFactory,
		fsInfo:             fsInfo,
		cgroupSubsystems:   &cgroupSubsystems,
		ignoreMetrics:      ignoreMetrics,
		rktPath:            rktPath,
	}
	container.RegisterContainerHandlerFactory(factory, []watcher.ContainerWatchSource{watcher.Rkt})
	return nil
}
Example #8
0
// Register root container before running this function!
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics container.MetricSet) error {
	client, err := Client()
	if err != nil {
		return fmt.Errorf("unable to communicate with docker daemon: %v", err)
	}

	dockerInfo, err := ValidateInfo()
	if err != nil {
		return fmt.Errorf("failed to validate Docker info: %v", err)
	}

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

	cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
	if err != nil {
		return fmt.Errorf("failed to get cgroup subsystems: %v", err)
	}

	var (
		dockerStorageDriver                               = storageDriver(dockerInfo.Driver)
		thinPoolWatcher     *devicemapper.ThinPoolWatcher = nil
	)

	if dockerStorageDriver == devicemapperStorageDriver {
		// If the storage drive is devicemapper, create and start a
		// ThinPoolWatcher to monitor the size of container CoW layers with
		// thin_ls.
		dockerThinPoolName, err := dockerutil.DockerThinPoolName(*dockerInfo)
		if err != nil {
			return fmt.Errorf("couldn't find device mapper thin pool name: %v", err)
		}

		dockerMetadataDevice, err := dockerutil.DockerMetadataDevice(*dockerInfo)
		if err != nil {
			return fmt.Errorf("couldn't determine devicemapper metadata device")
		}

		thinPoolWatcher = devicemapper.NewThinPoolWatcher(dockerThinPoolName, dockerMetadataDevice)
		go thinPoolWatcher.Start()
	}

	glog.Infof("registering Docker factory")
	f := &dockerFactory{
		cgroupSubsystems:   cgroupSubsystems,
		client:             client,
		dockerVersion:      dockerVersion,
		fsInfo:             fsInfo,
		machineInfoFactory: factory,
		storageDriver:      storageDriver(dockerInfo.Driver),
		storageDir:         RootDir(),
		ignoreMetrics:      ignoreMetrics,
		thinPoolWatcher:    thinPoolWatcher,
	}

	container.RegisterContainerHandlerFactory(f, []watcher.ContainerWatchSource{watcher.Raw})
	return nil
}
Example #9
0
// Register root container before running this function!
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo) error {
	glog.Infof("Registering Hyper factory")
	f := &hyperFactory{
		client:             NewHyperClient(),
		machineInfoFactory: factory,
		fsInfo:             fsInfo,
	}
	container.RegisterContainerHandlerFactory(f)
	return nil
}
Example #10
0
// 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)
			}
		}
	}

	// Check that the libcontainer execdriver is used.
	information, err := client.Info()
	if err != nil {
		return fmt.Errorf("failed to detect Docker info: %v", err)
	}
	usesNativeDriver := false
	for _, val := range *information {
		if strings.Contains(val, "ExecutionDriver=") && strings.Contains(val, "native") {
			usesNativeDriver = true
			break
		}
	}
	if !usesNativeDriver {
		return fmt.Errorf("Docker found, but not using native exec driver")
	}

	usesAufsDriver := false
	for _, val := range *information {
		if strings.Contains(val, "Driver=") && strings.Contains(val, "aufs") {
			usesAufsDriver = true
			break
		}
	}

	f := &dockerFactory{
		machineInfoFactory: factory,
		client:             client,
		usesAufsDriver:     usesAufsDriver,
	}
	container.RegisterContainerHandlerFactory(f)
	return nil
}
Example #11
0
// Register root container before running this function!
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo) error {
	if UseSystemd() {
		glog.Infof("System is using systemd")
	}

	client, err := Client()
	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{1, 0, 0}
		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 %v or above but we have found version %v reported as \"%v\"", expected_version, version, version_string)
			}
		}
	}

	// Check that the libcontainer execdriver is used.
	information, err := DockerInfo()
	if err != nil {
		return fmt.Errorf("failed to detect Docker info: %v", err)
	}
	execDriver, ok := information["ExecutionDriver"]
	if !ok || !strings.HasPrefix(execDriver, "native") {
		return fmt.Errorf("docker found, but not using native exec driver")
	}

	sd, _ := information["Driver"]

	cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
	if err != nil {
		return fmt.Errorf("failed to get cgroup subsystems: %v", err)
	}

	glog.Infof("Registering Docker factory")
	f := &dockerFactory{
		machineInfoFactory: factory,
		client:             client,
		storageDriver:      storageDriver(sd),
		cgroupSubsystems:   cgroupSubsystems,
		fsInfo:             fsInfo,
	}
	container.RegisterContainerHandlerFactory(f)
	return nil
}
Example #12
0
// Register root container before running this function!
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics container.MetricSet) error {
	glog.Infof("Registering Hyper factory")
	f := &hyperFactory{
		client:             NewHyperClient(),
		machineInfoFactory: factory,
		fsInfo:             fsInfo,
		ignoreMetrics:      ignoreMetrics,
	}
	container.RegisterContainerHandlerFactory(f, []watcher.ContainerWatchSource{watcher.Hyper})
	return nil
}
Example #13
0
func Register(paths ...string) error {
	if _, err := exec.LookPath("lmctfy"); err != nil {
		return errors.New("cannot find lmctfy")
	}
	f := container.AddStatsSummaryToFactory(&lmctfyFactory{})
	for _, path := range paths {
		log.Printf("register lmctfy under %v", path)
		container.RegisterContainerHandlerFactory(path, f)
	}
	return nil
}
Example #14
0
func TestNewContainerHandler_NoneMatch(t *testing.T) {
	container.ClearContainerHandlerFactories()

	// Register two allways no factories.
	allwaysNo1 := &mockContainerHandlerFactory{
		Name:           "no",
		CanHandleValue: false,
		CanAcceptValue: true,
	}
	container.RegisterContainerHandlerFactory(allwaysNo1, []watcher.ContainerWatchSource{watcher.Raw})
	allwaysNo2 := &mockContainerHandlerFactory{
		Name:           "no",
		CanHandleValue: false,
		CanAcceptValue: true,
	}
	container.RegisterContainerHandlerFactory(allwaysNo2, []watcher.ContainerWatchSource{watcher.Raw})

	_, _, err := container.NewContainerHandler(testContainerName, watcher.Raw, true)
	if err == nil {
		t.Error("Expected NewContainerHandler to fail")
	}
}
Example #15
0
func Register(machineInfoFactory info.MachineInfoFactory) error {
	cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
	if err != nil {
		return fmt.Errorf("failed to get cgroup subsystems: %v", err)
	}
	if len(cgroupSubsystems.Mounts) == 0 {
		return fmt.Errorf("failed to find supported cgroup mounts for the raw factory")
	}

	glog.Infof("Registering Raw factory")
	factory := &rawFactory{
		machineInfoFactory: machineInfoFactory,
		cgroupSubsystems:   &cgroupSubsystems,
	}
	container.RegisterContainerHandlerFactory(factory)
	return nil
}
Example #16
0
// Register root container before running this function!
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics container.MetricSet) error {
	client, err := Client()
	if err != nil {
		return fmt.Errorf("unable to communicate with docker daemon: %v", err)
	}

	dockerInfo, err := ValidateInfo()
	if err != nil {
		return fmt.Errorf("failed to validate Docker info: %v", err)
	}

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

	cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
	if err != nil {
		return fmt.Errorf("failed to get cgroup subsystems: %v", err)
	}

	var thinPoolWatcher *devicemapper.ThinPoolWatcher
	if storageDriver(dockerInfo.Driver) == devicemapperStorageDriver {
		thinPoolWatcher, err = startThinPoolWatcher(dockerInfo)
		if err != nil {
			glog.Errorf("devicemapper filesystem stats will not be reported: %v", err)
		}
	}

	glog.Infof("Registering Docker factory")
	f := &dockerFactory{
		cgroupSubsystems:   cgroupSubsystems,
		client:             client,
		dockerVersion:      dockerVersion,
		fsInfo:             fsInfo,
		machineInfoFactory: factory,
		storageDriver:      storageDriver(dockerInfo.Driver),
		storageDir:         RootDir(),
		ignoreMetrics:      ignoreMetrics,
		thinPoolWatcher:    thinPoolWatcher,
	}

	container.RegisterContainerHandlerFactory(f, []watcher.ContainerWatchSource{watcher.Raw})
	return nil
}
Example #17
0
func createManagerAndAddContainers(
	driver *stest.MockStorageDriver,
	containers []string,
	f func(*container.MockContainerHandler),
	t *testing.T,
) *manager {
	if driver == nil {
		driver = &stest.MockStorageDriver{}
	}
	factory := &container.FactoryForMockContainerHandler{
		Name: "factoryForManager",
		PrepareContainerHandlerFunc: func(name string, handler *container.MockContainerHandler) {
			handler.Name = name
			found := false
			for _, c := range containers {
				if c == name {
					found = true
				}
			}
			if !found {
				t.Errorf("Asked to create a container with name %v, which is unknown.", name)
			}
			f(handler)
		},
	}
	container.ClearContainerHandlerFactories()
	container.RegisterContainerHandlerFactory(factory)
	mif, err := New(driver)
	if err != nil {
		t.Fatal(err)
	}
	if ret, ok := mif.(*manager); ok {
		for _, container := range containers {
			ret.containers[container], err = NewContainerData(container, driver)
			if err != nil {
				t.Fatal(err)
			}
		}
		return ret
	}
	t.Fatal("Wrong type")
	return nil
}
Example #18
0
// Register root container before running this function!
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics container.MetricSet) error {
	client, err := Client()
	if err != nil {
		return fmt.Errorf("unable to communicate with docker daemon: %v", err)
	}

	dockerInfo, err := ValidateInfo()
	if err != nil {
		return fmt.Errorf("failed to validate Docker info: %v", err)
	}

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

	storageDir := dockerInfo.DockerRootDir
	if storageDir == "" {
		storageDir = *dockerRootDir
	}
	cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
	if err != nil {
		return fmt.Errorf("failed to get cgroup subsystems: %v", err)
	}

	glog.Infof("Registering Docker factory")
	f := &dockerFactory{
		cgroupSubsystems:   cgroupSubsystems,
		client:             client,
		dockerVersion:      dockerVersion,
		fsInfo:             fsInfo,
		machineInfoFactory: factory,
		storageDriver:      storageDriver(dockerInfo.Driver),
		storageDir:         storageDir,
		ignoreMetrics:      ignoreMetrics,
	}

	container.RegisterContainerHandlerFactory(f)
	return nil
}
Example #19
0
func Register(machineInfoFactory info.MachineInfoFactory) error {
	// Get all cgroup mounts.
	allCgroups, err := cgroups.GetCgroupMounts()
	if err != nil {
		return err
	}
	if len(allCgroups) == 0 {
		return fmt.Errorf("failed to find cgroup mounts for the raw factory")
	}

	// Trim the mounts to only the subsystems we care about.
	supportedCgroups := make([]cgroups.Mount, 0, len(allCgroups))
	mountPoints := make(map[string]string, len(allCgroups))
	for _, mount := range allCgroups {
		for _, subsystem := range mount.Subsystems {
			if _, ok := supportedSubsystems[subsystem]; ok {
				supportedCgroups = append(supportedCgroups, mount)
				mountPoints[subsystem] = mount.Mountpoint
			}
		}
	}
	if len(supportedCgroups) == 0 {
		return fmt.Errorf("failed to find supported cgroup mounts for the raw factory")
	}

	glog.Infof("Registering Raw factory")
	factory := &rawFactory{
		machineInfoFactory: machineInfoFactory,
		cgroupSubsystems: &cgroupSubsystems{
			mounts:      supportedCgroups,
			mountPoints: mountPoints,
		},
	}
	container.RegisterContainerHandlerFactory(factory)
	return nil
}
Example #20
0
// Register registers the systemd container factory.
func Register(machineInfoFactory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics container.MetricSet) error {
	glog.Infof("Registering systemd factory")
	factory := &systemdFactory{}
	container.RegisterContainerHandlerFactory(factory, []watcher.ContainerWatchSource{watcher.Raw})
	return nil
}
Example #21
0
// Register root container before running this function!
func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo) error {
	client, err := Client()
	if err != nil {
		return fmt.Errorf("unable to communicate with docker daemon: %v", err)
	}
	var dockerVersion []int
	if version, err := client.Version(); err != nil {
		return fmt.Errorf("unable to communicate with docker daemon: %v", err)
	} else {
		expected_version := []int{1, 0, 0}
		version_string := version.Get("Version")
		dockerVersion, err = parseDockerVersion(version_string)
		if err != nil {
			return fmt.Errorf("couldn't parse docker version: %v", err)
		}
		for index, number := range dockerVersion {
			if number > expected_version[index] {
				break
			} else if number < expected_version[index] {
				return fmt.Errorf("cAdvisor requires docker version %v or above but we have found version %v reported as \"%v\"", expected_version, dockerVersion, version_string)
			}
		}
	}

	information, err := client.Info()
	if err != nil {
		return fmt.Errorf("failed to detect Docker info: %v", err)
	}

	// Check that the libcontainer execdriver is used.
	execDriver := information.Get("ExecutionDriver")
	if !strings.HasPrefix(execDriver, "native") {
		return fmt.Errorf("docker found, but not using native exec driver")
	}

	sd := information.Get("Driver")
	if sd == "" {
		return fmt.Errorf("failed to find docker storage driver")
	}

	storageDir := information.Get("DockerRootDir")
	if storageDir == "" {
		storageDir = *dockerRootDir
	}
	cgroupSubsystems, err := libcontainer.GetCgroupSubsystems()
	if err != nil {
		return fmt.Errorf("failed to get cgroup subsystems: %v", err)
	}

	glog.Infof("Registering Docker factory")
	f := &dockerFactory{
		cgroupSubsystems:   cgroupSubsystems,
		client:             client,
		dockerVersion:      dockerVersion,
		fsInfo:             fsInfo,
		machineInfoFactory: factory,
		storageDriver:      storageDriver(sd),
		storageDir:         storageDir,
	}

	container.RegisterContainerHandlerFactory(f)
	return nil
}