Merge pull request #2217 from liggitt/plugin-init-hooks
move plugin-specific init code into plugin hooks
This commit is contained in:
commit
9db8c7dee2
@ -34,6 +34,9 @@ import (
|
||||
"github.com/google/cadvisor/utils/sysfs"
|
||||
"github.com/google/cadvisor/version"
|
||||
|
||||
// Register container providers
|
||||
_ "github.com/google/cadvisor/container/install"
|
||||
|
||||
// Register CloudProviders
|
||||
_ "github.com/google/cadvisor/utils/cloudinfo/aws"
|
||||
_ "github.com/google/cadvisor/utils/cloudinfo/azure"
|
||||
@ -150,7 +153,7 @@ func main() {
|
||||
|
||||
collectorHttpClient := createCollectorHttpClient(*collectorCert, *collectorKey)
|
||||
|
||||
containerManager, err := New(memoryStorage, sysFs, *maxHousekeepingInterval, *allowDynamicHousekeeping, includedMetrics, &collectorHttpClient, strings.Split(*rawCgroupPrefixWhiteList, ","))
|
||||
containerManager, err := manager.New(memoryStorage, sysFs, *maxHousekeepingInterval, *allowDynamicHousekeeping, includedMetrics, &collectorHttpClient, strings.Split(*rawCgroupPrefixWhiteList, ","))
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to create a Container Manager: %s", err)
|
||||
}
|
||||
|
@ -1,167 +0,0 @@
|
||||
// Copyright 2019 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 main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/accelerators"
|
||||
"github.com/google/cadvisor/cache/memory"
|
||||
"github.com/google/cadvisor/container"
|
||||
_ "github.com/google/cadvisor/container/containerd"
|
||||
"github.com/google/cadvisor/container/crio"
|
||||
"github.com/google/cadvisor/container/docker"
|
||||
_ "github.com/google/cadvisor/container/mesos"
|
||||
_ "github.com/google/cadvisor/container/raw"
|
||||
"github.com/google/cadvisor/container/rkt"
|
||||
_ "github.com/google/cadvisor/container/systemd"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/machine"
|
||||
"github.com/google/cadvisor/manager"
|
||||
"github.com/google/cadvisor/utils/sysfs"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
const dockerClientTimeout = 10 * time.Second
|
||||
|
||||
// New takes a memory storage and returns a new manager.
|
||||
func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingInterval time.Duration, allowDynamicHousekeeping bool, includedMetricsSet container.MetricSet, collectorHttpClient *http.Client, rawContainerCgroupPathPrefixWhiteList []string) (manager.Manager, error) {
|
||||
if memoryCache == nil {
|
||||
return nil, fmt.Errorf("manager requires memory storage")
|
||||
}
|
||||
|
||||
// Detect the container we are running on.
|
||||
selfContainer, err := cgroups.GetOwnCgroupPath("cpu")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
klog.V(2).Infof("cAdvisor running in container: %q", selfContainer)
|
||||
|
||||
var (
|
||||
dockerStatus info.DockerStatus
|
||||
rktPath string
|
||||
)
|
||||
docker.SetTimeout(dockerClientTimeout)
|
||||
// Try to connect to docker indefinitely on startup.
|
||||
dockerStatus = retryDockerStatus()
|
||||
|
||||
if tmpRktPath, err := rkt.RktPath(); err != nil {
|
||||
klog.V(5).Infof("Rkt not connected: %v", err)
|
||||
} else {
|
||||
rktPath = tmpRktPath
|
||||
}
|
||||
|
||||
crioClient, err := crio.Client()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
crioInfo, err := crioClient.Info()
|
||||
if err != nil {
|
||||
klog.V(5).Infof("CRI-O not connected: %v", err)
|
||||
}
|
||||
|
||||
context := fs.Context{
|
||||
Docker: fs.DockerContext{
|
||||
Root: docker.RootDir(),
|
||||
Driver: dockerStatus.Driver,
|
||||
DriverStatus: dockerStatus.DriverStatus,
|
||||
},
|
||||
RktPath: rktPath,
|
||||
Crio: fs.CrioContext{
|
||||
Root: crioInfo.StorageRoot,
|
||||
},
|
||||
}
|
||||
fsInfo, err := fs.NewFsInfo(context)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If cAdvisor was started with host's rootfs mounted, assume that its running
|
||||
// in its own namespaces.
|
||||
inHostNamespace := false
|
||||
if _, err := os.Stat("/rootfs/proc"); os.IsNotExist(err) {
|
||||
inHostNamespace = true
|
||||
}
|
||||
|
||||
// Register for new subcontainers.
|
||||
eventsChannel := make(chan watcher.ContainerEvent, 16)
|
||||
|
||||
machineInfo, err := machine.Info(sysfs, fsInfo, inHostNamespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
klog.V(1).Infof("Machine: %+v", *machineInfo)
|
||||
|
||||
newManager := manager.New(
|
||||
memoryCache,
|
||||
fsInfo,
|
||||
sysfs,
|
||||
*machineInfo,
|
||||
make([]chan error, 0, 2),
|
||||
selfContainer,
|
||||
inHostNamespace,
|
||||
time.Now(),
|
||||
maxHousekeepingInterval,
|
||||
allowDynamicHousekeeping,
|
||||
includedMetricsSet,
|
||||
[]watcher.ContainerWatcher{},
|
||||
eventsChannel,
|
||||
collectorHttpClient,
|
||||
&accelerators.NvidiaManager{},
|
||||
rawContainerCgroupPathPrefixWhiteList)
|
||||
|
||||
versionInfo, err := newManager.GetVersionInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
klog.V(1).Infof("Version: %+v", *versionInfo)
|
||||
return newManager, nil
|
||||
}
|
||||
|
||||
func retryDockerStatus() info.DockerStatus {
|
||||
startupTimeout := dockerClientTimeout
|
||||
maxTimeout := 4 * startupTimeout
|
||||
for {
|
||||
ctx, e := context.WithTimeout(context.Background(), startupTimeout)
|
||||
if e != nil {
|
||||
klog.V(5).Infof("error during timeout: %v", e)
|
||||
}
|
||||
dockerStatus, err := docker.StatusWithContext(ctx)
|
||||
if err == nil {
|
||||
return dockerStatus
|
||||
}
|
||||
|
||||
switch err {
|
||||
case context.DeadlineExceeded:
|
||||
klog.Warningf("Timeout trying to communicate with docker during initialization, will retry")
|
||||
default:
|
||||
klog.V(5).Infof("Docker not connected: %v", err)
|
||||
return info.DockerStatus{}
|
||||
}
|
||||
|
||||
startupTimeout = 2 * startupTimeout
|
||||
if startupTimeout > maxTimeout {
|
||||
startupTimeout = maxTimeout
|
||||
}
|
||||
}
|
||||
}
|
@ -12,21 +12,17 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package containerd
|
||||
// The install package registers containerd.NewPlugin() as the "containerd" container provider when imported
|
||||
package install
|
||||
|
||||
import (
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
"github.com/google/cadvisor/container/containerd"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
err := container.RegisterPlugin("containerd", func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
err := Register(factory, fsInfo, includedMetrics)
|
||||
return nil, err
|
||||
})
|
||||
err := container.RegisterPlugin("containerd", containerd.NewPlugin())
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to register containerd plugin: %v", err)
|
||||
}
|
38
container/containerd/plugin.go
Normal file
38
container/containerd/plugin.go
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2019 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 containerd
|
||||
|
||||
import (
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
)
|
||||
|
||||
// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()
|
||||
func NewPlugin() container.Plugin {
|
||||
return &plugin{}
|
||||
}
|
||||
|
||||
type plugin struct{}
|
||||
|
||||
func (p *plugin) InitializeFSContext(context *fs.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
err := Register(factory, fsInfo, includedMetrics)
|
||||
return nil, err
|
||||
}
|
@ -12,21 +12,17 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package crio
|
||||
// The install package registers crio.NewPlugin() as the "crio" container provider when imported
|
||||
package install
|
||||
|
||||
import (
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
"github.com/google/cadvisor/container/crio"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
err := container.RegisterPlugin("crio", func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
err := Register(factory, fsInfo, includedMetrics)
|
||||
return nil, err
|
||||
})
|
||||
err := container.RegisterPlugin("crio", crio.NewPlugin())
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to register crio plugin: %v", err)
|
||||
}
|
50
container/crio/plugin.go
Normal file
50
container/crio/plugin.go
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2019 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 crio
|
||||
|
||||
import (
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()
|
||||
func NewPlugin() container.Plugin {
|
||||
return &plugin{}
|
||||
}
|
||||
|
||||
type plugin struct{}
|
||||
|
||||
func (p *plugin) InitializeFSContext(context *fs.Context) error {
|
||||
crioClient, err := Client()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
crioInfo, err := crioClient.Info()
|
||||
if err != nil {
|
||||
klog.V(5).Infof("CRI-O not connected: %v", err)
|
||||
} else {
|
||||
context.Crio = fs.CrioContext{Root: crioInfo.StorageRoot}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
err := Register(factory, fsInfo, includedMetrics)
|
||||
return nil, err
|
||||
}
|
@ -12,21 +12,17 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package docker
|
||||
// The install package registers docker.NewPlugin() as the "docker" container provider when imported
|
||||
package install
|
||||
|
||||
import (
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
"github.com/google/cadvisor/container/docker"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
err := container.RegisterPlugin("docker", func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
err := Register(factory, fsInfo, includedMetrics)
|
||||
return nil, err
|
||||
})
|
||||
err := container.RegisterPlugin("docker", docker.NewPlugin())
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to register docker plugin: %v", err)
|
||||
}
|
77
container/docker/plugin.go
Normal file
77
container/docker/plugin.go
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright 2019 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 (
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
"golang.org/x/net/context"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
const dockerClientTimeout = 10 * time.Second
|
||||
|
||||
// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()
|
||||
func NewPlugin() container.Plugin {
|
||||
return &plugin{}
|
||||
}
|
||||
|
||||
type plugin struct{}
|
||||
|
||||
func (p *plugin) InitializeFSContext(context *fs.Context) error {
|
||||
SetTimeout(dockerClientTimeout)
|
||||
// Try to connect to docker indefinitely on startup.
|
||||
dockerStatus := retryDockerStatus()
|
||||
context.Docker = fs.DockerContext{
|
||||
Root: RootDir(),
|
||||
Driver: dockerStatus.Driver,
|
||||
DriverStatus: dockerStatus.DriverStatus,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
err := Register(factory, fsInfo, includedMetrics)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func retryDockerStatus() info.DockerStatus {
|
||||
startupTimeout := dockerClientTimeout
|
||||
maxTimeout := 4 * startupTimeout
|
||||
for {
|
||||
ctx, _ := context.WithTimeout(context.Background(), startupTimeout)
|
||||
dockerStatus, err := StatusWithContext(ctx)
|
||||
if err == nil {
|
||||
return dockerStatus
|
||||
}
|
||||
|
||||
switch err {
|
||||
case context.DeadlineExceeded:
|
||||
klog.Warningf("Timeout trying to communicate with docker during initialization, will retry")
|
||||
default:
|
||||
klog.V(5).Infof("Docker not connected: %v", err)
|
||||
return info.DockerStatus{}
|
||||
}
|
||||
|
||||
startupTimeout = 2 * startupTimeout
|
||||
if startupTimeout > maxTimeout {
|
||||
startupTimeout = maxTimeout
|
||||
}
|
||||
}
|
||||
}
|
@ -73,13 +73,21 @@ func (ms MetricSet) Add(mk MetricKind) {
|
||||
ms[mk] = struct{}{}
|
||||
}
|
||||
|
||||
type Register func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics MetricSet) (watcher.ContainerWatcher, error)
|
||||
|
||||
// All registered auth provider plugins.
|
||||
var pluginsLock sync.Mutex
|
||||
var plugins = make(map[string]Register)
|
||||
var plugins = make(map[string]Plugin)
|
||||
|
||||
func RegisterPlugin(name string, plugin Register) error {
|
||||
type Plugin interface {
|
||||
// InitializeFSContext is invoked when populating an fs.Context object for a new manager.
|
||||
// A returned error here is fatal.
|
||||
InitializeFSContext(context *fs.Context) error
|
||||
|
||||
// Register is invoked when starting a manager. It can optionally return a container watcher.
|
||||
// A returned error is logged, but is not fatal.
|
||||
Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics MetricSet) (watcher.ContainerWatcher, error)
|
||||
}
|
||||
|
||||
func RegisterPlugin(name string, plugin Plugin) error {
|
||||
pluginsLock.Lock()
|
||||
defer pluginsLock.Unlock()
|
||||
if _, found := plugins[name]; found {
|
||||
@ -90,13 +98,26 @@ func RegisterPlugin(name string, plugin Register) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func InitializeFSContext(context *fs.Context) error {
|
||||
pluginsLock.Lock()
|
||||
defer pluginsLock.Unlock()
|
||||
for name, plugin := range plugins {
|
||||
err := plugin.InitializeFSContext(context)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Initialization of the %s context failed: %v", name, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func InitializePlugins(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics MetricSet) []watcher.ContainerWatcher {
|
||||
pluginsLock.Lock()
|
||||
defer pluginsLock.Unlock()
|
||||
|
||||
containerWatchers := []watcher.ContainerWatcher{}
|
||||
for name, register := range plugins {
|
||||
watcher, err := register(factory, fsInfo, includedMetrics)
|
||||
for name, plugin := range plugins {
|
||||
watcher, err := plugin.Register(factory, fsInfo, includedMetrics)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Registration of the %s container factory failed: %v", name, err)
|
||||
}
|
||||
|
25
container/install/install.go
Normal file
25
container/install/install.go
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
// The install package registers all included container providers when imported
|
||||
package install
|
||||
|
||||
import (
|
||||
_ "github.com/google/cadvisor/container/containerd/install"
|
||||
_ "github.com/google/cadvisor/container/crio/install"
|
||||
_ "github.com/google/cadvisor/container/docker/install"
|
||||
_ "github.com/google/cadvisor/container/mesos/install"
|
||||
_ "github.com/google/cadvisor/container/rkt/install"
|
||||
_ "github.com/google/cadvisor/container/systemd/install"
|
||||
)
|
@ -12,21 +12,17 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package mesos
|
||||
// The install package registers mesos.NewPlugin() as the "mesos" container provider when imported
|
||||
package install
|
||||
|
||||
import (
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
"github.com/google/cadvisor/container/mesos"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
err := container.RegisterPlugin("mesos", func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
err := Register(factory, fsInfo, includedMetrics)
|
||||
return nil, err
|
||||
})
|
||||
err := container.RegisterPlugin("mesos", mesos.NewPlugin())
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to register mesos plugin: %v", err)
|
||||
}
|
38
container/mesos/plugin.go
Normal file
38
container/mesos/plugin.go
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2019 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 mesos
|
||||
|
||||
import (
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
)
|
||||
|
||||
// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()
|
||||
func NewPlugin() container.Plugin {
|
||||
return &plugin{}
|
||||
}
|
||||
|
||||
type plugin struct{}
|
||||
|
||||
func (p *plugin) InitializeFSContext(context *fs.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
err := Register(factory, fsInfo, includedMetrics)
|
||||
return nil, err
|
||||
}
|
@ -12,24 +12,17 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package rkt
|
||||
// The install package registers rkt.NewPlugin() as the "rkt" container provider when imported
|
||||
package install
|
||||
|
||||
import (
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
"github.com/google/cadvisor/container/rkt"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
err := container.RegisterPlugin("rkt", func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
err := Register(factory, fsInfo, includedMetrics)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewRktContainerWatcher()
|
||||
})
|
||||
err := container.RegisterPlugin("rkt", rkt.NewPlugin())
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to register rkt plugin: %v", err)
|
||||
}
|
47
container/rkt/plugin.go
Normal file
47
container/rkt/plugin.go
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2019 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 rkt
|
||||
|
||||
import (
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()
|
||||
func NewPlugin() container.Plugin {
|
||||
return &plugin{}
|
||||
}
|
||||
|
||||
type plugin struct{}
|
||||
|
||||
func (p *plugin) InitializeFSContext(context *fs.Context) error {
|
||||
if tmpRktPath, err := RktPath(); err != nil {
|
||||
klog.V(5).Infof("Rkt not connected: %v", err)
|
||||
} else {
|
||||
context.RktPath = tmpRktPath
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
err := Register(factory, fsInfo, includedMetrics)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewRktContainerWatcher()
|
||||
}
|
@ -12,21 +12,17 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package systemd
|
||||
// The install package registers systemd.NewPlugin() as the "systemd" container provider when imported
|
||||
package install
|
||||
|
||||
import (
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
"github.com/google/cadvisor/container/systemd"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
err := container.RegisterPlugin("systemd", func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
err := Register(factory, fsInfo, includedMetrics)
|
||||
return nil, err
|
||||
})
|
||||
err := container.RegisterPlugin("systemd", systemd.NewPlugin())
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to register systemd plugin: %v", err)
|
||||
}
|
38
container/systemd/plugin.go
Normal file
38
container/systemd/plugin.go
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2019 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 systemd
|
||||
|
||||
import (
|
||||
"github.com/google/cadvisor/container"
|
||||
"github.com/google/cadvisor/fs"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
)
|
||||
|
||||
// NewPlugin returns an implementation of container.Plugin suitable for passing to container.RegisterPlugin()
|
||||
func NewPlugin() container.Plugin {
|
||||
return &plugin{}
|
||||
}
|
||||
|
||||
type plugin struct{}
|
||||
|
||||
func (p *plugin) InitializeFSContext(context *fs.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *plugin) Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
|
||||
err := Register(factory, fsInfo, includedMetrics)
|
||||
return nil, err
|
||||
}
|
17
fs/fs.go
17
fs/fs.go
@ -91,23 +91,6 @@ type RealFsInfo struct {
|
||||
fsUUIDToDeviceName map[string]string
|
||||
}
|
||||
|
||||
type Context struct {
|
||||
// docker root directory.
|
||||
Docker DockerContext
|
||||
RktPath string
|
||||
Crio CrioContext
|
||||
}
|
||||
|
||||
type DockerContext struct {
|
||||
Root string
|
||||
Driver string
|
||||
DriverStatus map[string]string
|
||||
}
|
||||
|
||||
type CrioContext struct {
|
||||
Root string
|
||||
}
|
||||
|
||||
func NewFsInfo(context Context) (FsInfo, error) {
|
||||
mounts, err := mount.GetMounts(nil)
|
||||
if err != nil {
|
||||
|
17
fs/types.go
17
fs/types.go
@ -18,6 +18,23 @@ import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
// docker root directory.
|
||||
Docker DockerContext
|
||||
RktPath string
|
||||
Crio CrioContext
|
||||
}
|
||||
|
||||
type DockerContext struct {
|
||||
Root string
|
||||
Driver string
|
||||
DriverStatus map[string]string
|
||||
}
|
||||
|
||||
type CrioContext struct {
|
||||
Root string
|
||||
}
|
||||
|
||||
type DeviceInfo struct {
|
||||
Device string
|
||||
Major uint
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -41,6 +42,7 @@ import (
|
||||
"github.com/google/cadvisor/version"
|
||||
"github.com/google/cadvisor/watcher"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/utils/clock"
|
||||
)
|
||||
@ -130,6 +132,76 @@ type Manager interface {
|
||||
DebugInfo() map[string][]string
|
||||
}
|
||||
|
||||
// New takes a memory storage and returns a new manager.
|
||||
func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingInterval time.Duration, allowDynamicHousekeeping bool, includedMetricsSet container.MetricSet, collectorHttpClient *http.Client, rawContainerCgroupPathPrefixWhiteList []string) (Manager, error) {
|
||||
if memoryCache == nil {
|
||||
return nil, fmt.Errorf("manager requires memory storage")
|
||||
}
|
||||
|
||||
// Detect the container we are running on.
|
||||
selfContainer, err := cgroups.GetOwnCgroupPath("cpu")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
klog.V(2).Infof("cAdvisor running in container: %q", selfContainer)
|
||||
|
||||
context := fs.Context{}
|
||||
|
||||
if err := container.InitializeFSContext(&context); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fsInfo, err := fs.NewFsInfo(context)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If cAdvisor was started with host's rootfs mounted, assume that its running
|
||||
// in its own namespaces.
|
||||
inHostNamespace := false
|
||||
if _, err := os.Stat("/rootfs/proc"); os.IsNotExist(err) {
|
||||
inHostNamespace = true
|
||||
}
|
||||
|
||||
// Register for new subcontainers.
|
||||
eventsChannel := make(chan watcher.ContainerEvent, 16)
|
||||
|
||||
newManager := &manager{
|
||||
containers: make(map[namespacedContainerName]*containerData),
|
||||
quitChannels: make([]chan error, 0, 2),
|
||||
memoryCache: memoryCache,
|
||||
fsInfo: fsInfo,
|
||||
sysFs: sysfs,
|
||||
cadvisorContainer: selfContainer,
|
||||
inHostNamespace: inHostNamespace,
|
||||
startupTime: time.Now(),
|
||||
maxHousekeepingInterval: maxHousekeepingInterval,
|
||||
allowDynamicHousekeeping: allowDynamicHousekeeping,
|
||||
includedMetrics: includedMetricsSet,
|
||||
containerWatchers: []watcher.ContainerWatcher{},
|
||||
eventsChannel: eventsChannel,
|
||||
collectorHttpClient: collectorHttpClient,
|
||||
nvidiaManager: &accelerators.NvidiaManager{},
|
||||
rawContainerCgroupPathPrefixWhiteList: rawContainerCgroupPathPrefixWhiteList,
|
||||
}
|
||||
|
||||
machineInfo, err := machine.Info(sysfs, fsInfo, inHostNamespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newManager.machineInfo = *machineInfo
|
||||
klog.V(1).Infof("Machine: %+v", newManager.machineInfo)
|
||||
|
||||
versionInfo, err := getVersionInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
klog.V(1).Infof("Version: %+v", *versionInfo)
|
||||
|
||||
newManager.eventHandler = events.NewEventManager(parseEventsStoragePolicy())
|
||||
return newManager, nil
|
||||
}
|
||||
|
||||
// A namespaced container name.
|
||||
type namespacedContainerName struct {
|
||||
// The namespace of the container. Can be empty for the root namespace.
|
||||
@ -139,47 +211,6 @@ type namespacedContainerName struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func New(
|
||||
memoryCache *memory.InMemoryCache,
|
||||
fsInfo fs.FsInfo,
|
||||
sysFs sysfs.SysFs,
|
||||
machineInfo info.MachineInfo,
|
||||
quitChannels []chan error,
|
||||
cadvisorContainer string,
|
||||
inHostNamespace bool,
|
||||
startupTime time.Time,
|
||||
maxHousekeepingInterval time.Duration,
|
||||
allowDynamicHousekeeping bool,
|
||||
includedMetrics container.MetricSet,
|
||||
containerWatchers []watcher.ContainerWatcher,
|
||||
eventsChannel chan watcher.ContainerEvent,
|
||||
collectorHttpClient *http.Client,
|
||||
nvidiaManager accelerators.AcceleratorManager,
|
||||
rawContainerCgroupPathPrefixWhiteList []string,
|
||||
) Manager {
|
||||
impl := &manager{
|
||||
containers: make(map[namespacedContainerName]*containerData),
|
||||
memoryCache: memoryCache,
|
||||
fsInfo: fsInfo,
|
||||
sysFs: sysFs,
|
||||
machineInfo: machineInfo,
|
||||
quitChannels: quitChannels,
|
||||
cadvisorContainer: cadvisorContainer,
|
||||
inHostNamespace: inHostNamespace,
|
||||
startupTime: startupTime,
|
||||
maxHousekeepingInterval: maxHousekeepingInterval,
|
||||
allowDynamicHousekeeping: allowDynamicHousekeeping,
|
||||
includedMetrics: includedMetrics,
|
||||
containerWatchers: containerWatchers,
|
||||
eventsChannel: eventsChannel,
|
||||
collectorHttpClient: collectorHttpClient,
|
||||
nvidiaManager: nvidiaManager,
|
||||
rawContainerCgroupPathPrefixWhiteList: rawContainerCgroupPathPrefixWhiteList,
|
||||
}
|
||||
impl.eventHandler = events.NewEventManager(parseEventsStoragePolicy())
|
||||
return impl
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
containers map[namespacedContainerName]*containerData
|
||||
containersLock sync.RWMutex
|
||||
|
@ -35,6 +35,8 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
clock "k8s.io/utils/clock/testing"
|
||||
|
||||
_ "github.com/google/cadvisor/container/install"
|
||||
)
|
||||
|
||||
// TODO(vmarmol): Refactor these tests.
|
||||
|
Loading…
Reference in New Issue
Block a user