Skip to content

Commit f6e51e8

Browse files
committed
Reorganize code to allow conditional enablement of runtimes
Change-Id: I76583736d7ad39190a1a2bca820d4e957caadc84
1 parent 4ca6c21 commit f6e51e8

File tree

22 files changed

+474
-191
lines changed

22 files changed

+474
-191
lines changed

cadvisor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ func main() {
150150

151151
collectorHttpClient := createCollectorHttpClient(*collectorCert, *collectorKey)
152152

153-
containerManager, err := manager.New(memoryStorage, sysFs, *maxHousekeepingInterval, *allowDynamicHousekeeping, includedMetrics, &collectorHttpClient, strings.Split(*rawCgroupPrefixWhiteList, ","))
153+
containerManager, err := New(memoryStorage, sysFs, *maxHousekeepingInterval, *allowDynamicHousekeeping, includedMetrics, &collectorHttpClient, strings.Split(*rawCgroupPrefixWhiteList, ","))
154154
if err != nil {
155155
klog.Fatalf("Failed to create a Container Manager: %s", err)
156156
}

cadvisor_helper.go

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// Copyright 2019 Google Inc. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
"context"
19+
"fmt"
20+
"net/http"
21+
"os"
22+
"time"
23+
24+
"github.com/google/cadvisor/accelerators"
25+
"github.com/google/cadvisor/cache/memory"
26+
"github.com/google/cadvisor/container"
27+
_ "github.com/google/cadvisor/container/containerd"
28+
"github.com/google/cadvisor/container/crio"
29+
"github.com/google/cadvisor/container/docker"
30+
_ "github.com/google/cadvisor/container/mesos"
31+
_ "github.com/google/cadvisor/container/raw"
32+
"github.com/google/cadvisor/container/rkt"
33+
_ "github.com/google/cadvisor/container/systemd"
34+
"github.com/google/cadvisor/fs"
35+
info "github.com/google/cadvisor/info/v1"
36+
"github.com/google/cadvisor/machine"
37+
"github.com/google/cadvisor/manager"
38+
"github.com/google/cadvisor/utils/sysfs"
39+
"github.com/google/cadvisor/watcher"
40+
41+
"github.com/opencontainers/runc/libcontainer/cgroups"
42+
"k8s.io/klog"
43+
)
44+
45+
const dockerClientTimeout = 10 * time.Second
46+
47+
// New takes a memory storage and returns a new manager.
48+
func New(memoryCache *memory.InMemoryCache, sysfs sysfs.SysFs, maxHousekeepingInterval time.Duration, allowDynamicHousekeeping bool, includedMetricsSet container.MetricSet, collectorHttpClient *http.Client, rawContainerCgroupPathPrefixWhiteList []string) (manager.Manager, error) {
49+
if memoryCache == nil {
50+
return nil, fmt.Errorf("manager requires memory storage")
51+
}
52+
53+
// Detect the container we are running on.
54+
selfContainer, err := cgroups.GetOwnCgroupPath("cpu")
55+
if err != nil {
56+
return nil, err
57+
}
58+
klog.V(2).Infof("cAdvisor running in container: %q", selfContainer)
59+
60+
var (
61+
dockerStatus info.DockerStatus
62+
rktPath string
63+
)
64+
docker.SetTimeout(dockerClientTimeout)
65+
// Try to connect to docker indefinitely on startup.
66+
dockerStatus = retryDockerStatus()
67+
68+
if tmpRktPath, err := rkt.RktPath(); err != nil {
69+
klog.V(5).Infof("Rkt not connected: %v", err)
70+
} else {
71+
rktPath = tmpRktPath
72+
}
73+
74+
crioClient, err := crio.Client()
75+
if err != nil {
76+
return nil, err
77+
}
78+
crioInfo, err := crioClient.Info()
79+
if err != nil {
80+
klog.V(5).Infof("CRI-O not connected: %v", err)
81+
}
82+
83+
context := fs.Context{
84+
Docker: fs.DockerContext{
85+
Root: docker.RootDir(),
86+
Driver: dockerStatus.Driver,
87+
DriverStatus: dockerStatus.DriverStatus,
88+
},
89+
RktPath: rktPath,
90+
Crio: fs.CrioContext{
91+
Root: crioInfo.StorageRoot,
92+
},
93+
}
94+
fsInfo, err := fs.NewFsInfo(context)
95+
if err != nil {
96+
return nil, err
97+
}
98+
99+
// If cAdvisor was started with host's rootfs mounted, assume that its running
100+
// in its own namespaces.
101+
inHostNamespace := false
102+
if _, err := os.Stat("/rootfs/proc"); os.IsNotExist(err) {
103+
inHostNamespace = true
104+
}
105+
106+
// Register for new subcontainers.
107+
eventsChannel := make(chan watcher.ContainerEvent, 16)
108+
109+
machineInfo, err := machine.Info(sysfs, fsInfo, inHostNamespace)
110+
if err != nil {
111+
return nil, err
112+
}
113+
klog.V(1).Infof("Machine: %+v", *machineInfo)
114+
115+
newManager := manager.New(
116+
memoryCache,
117+
fsInfo,
118+
sysfs,
119+
*machineInfo,
120+
make([]chan error, 0, 2),
121+
selfContainer,
122+
inHostNamespace,
123+
time.Now(),
124+
maxHousekeepingInterval,
125+
allowDynamicHousekeeping,
126+
includedMetricsSet,
127+
[]watcher.ContainerWatcher{},
128+
eventsChannel,
129+
collectorHttpClient,
130+
&accelerators.NvidiaManager{},
131+
rawContainerCgroupPathPrefixWhiteList)
132+
133+
versionInfo, err := newManager.GetVersionInfo()
134+
if err != nil {
135+
return nil, err
136+
}
137+
klog.V(1).Infof("Version: %+v", *versionInfo)
138+
return newManager, nil
139+
}
140+
141+
func retryDockerStatus() info.DockerStatus {
142+
startupTimeout := dockerClientTimeout
143+
maxTimeout := 4 * startupTimeout
144+
for {
145+
ctx, e := context.WithTimeout(context.Background(), startupTimeout)
146+
if e != nil {
147+
klog.V(5).Infof("error during timeout: %v", e)
148+
}
149+
dockerStatus, err := docker.StatusWithContext(ctx)
150+
if err == nil {
151+
return dockerStatus
152+
}
153+
154+
switch err {
155+
case context.DeadlineExceeded:
156+
klog.Warningf("Timeout trying to communicate with docker during initialization, will retry")
157+
default:
158+
klog.V(5).Infof("Docker not connected: %v", err)
159+
return info.DockerStatus{}
160+
}
161+
162+
startupTimeout = 2 * startupTimeout
163+
if startupTimeout > maxTimeout {
164+
startupTimeout = maxTimeout
165+
}
166+
}
167+
}

container/containerd/factory.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
"github.com/google/cadvisor/container/libcontainer"
2929
"github.com/google/cadvisor/fs"
3030
info "github.com/google/cadvisor/info/v1"
31-
"github.com/google/cadvisor/manager/watcher"
31+
"github.com/google/cadvisor/watcher"
3232
)
3333

3434
var ArgContainerdEndpoint = flag.String("containerd", "/run/containerd/containerd.sock", "containerd endpoint")

container/containerd/init.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2019 Google Inc. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package containerd
16+
17+
import (
18+
"github.com/google/cadvisor/container"
19+
"github.com/google/cadvisor/fs"
20+
info "github.com/google/cadvisor/info/v1"
21+
"github.com/google/cadvisor/watcher"
22+
"k8s.io/klog"
23+
)
24+
25+
func init() {
26+
err := container.RegisterPlugin("containerd", func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
27+
err := Register(factory, fsInfo, includedMetrics)
28+
if err != nil {
29+
klog.V(5).Infof("Registration of the containerd container factory failed: %v.", err)
30+
}
31+
return nil, nil
32+
})
33+
if err != nil {
34+
klog.Fatalf("Failed to register containerd plugin: %v", err)
35+
}
36+
}

container/crio/factory.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
"github.com/google/cadvisor/container/libcontainer"
2525
"github.com/google/cadvisor/fs"
2626
info "github.com/google/cadvisor/info/v1"
27-
"github.com/google/cadvisor/manager/watcher"
27+
"github.com/google/cadvisor/watcher"
2828

2929
"k8s.io/klog"
3030
)

container/crio/init.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2019 Google Inc. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package crio
16+
17+
import (
18+
"github.com/google/cadvisor/container"
19+
"github.com/google/cadvisor/fs"
20+
info "github.com/google/cadvisor/info/v1"
21+
"github.com/google/cadvisor/watcher"
22+
"k8s.io/klog"
23+
)
24+
25+
func init() {
26+
err := container.RegisterPlugin("crio", func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
27+
err := Register(factory, fsInfo, includedMetrics)
28+
if err != nil {
29+
klog.V(5).Infof("Registration of the crio container factory failed: %v.", err)
30+
}
31+
return nil, nil
32+
})
33+
if err != nil {
34+
klog.Fatalf("Failed to register crio plugin: %v", err)
35+
}
36+
}

container/docker/factory.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ import (
3131
"github.com/google/cadvisor/fs"
3232
info "github.com/google/cadvisor/info/v1"
3333
"github.com/google/cadvisor/machine"
34-
"github.com/google/cadvisor/manager/watcher"
3534
dockerutil "github.com/google/cadvisor/utils/docker"
35+
"github.com/google/cadvisor/watcher"
3636
"github.com/google/cadvisor/zfs"
3737

3838
docker "github.com/docker/docker/client"

container/docker/init.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2019 Google Inc. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package docker
16+
17+
import (
18+
"github.com/google/cadvisor/container"
19+
"github.com/google/cadvisor/fs"
20+
info "github.com/google/cadvisor/info/v1"
21+
"github.com/google/cadvisor/watcher"
22+
"k8s.io/klog"
23+
)
24+
25+
func init() {
26+
err := container.RegisterPlugin("docker", func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics container.MetricSet) (watcher.ContainerWatcher, error) {
27+
err := Register(factory, fsInfo, includedMetrics)
28+
if err != nil {
29+
klog.V(5).Infof("Registration of the Docker container factory failed: %v.", err)
30+
}
31+
return nil, nil
32+
})
33+
if err != nil {
34+
klog.Fatalf("Failed to register docker plugin: %v", err)
35+
}
36+
}

container/factory.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ import (
1818
"fmt"
1919
"sync"
2020

21-
"github.com/google/cadvisor/manager/watcher"
21+
"github.com/google/cadvisor/fs"
22+
info "github.com/google/cadvisor/info/v1"
23+
"github.com/google/cadvisor/watcher"
2224

2325
"k8s.io/klog"
2426
)
@@ -71,6 +73,40 @@ func (ms MetricSet) Add(mk MetricKind) {
7173
ms[mk] = struct{}{}
7274
}
7375

76+
type Register func(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics MetricSet) (watcher.ContainerWatcher, error)
77+
78+
// All registered auth provider plugins.
79+
var pluginsLock sync.Mutex
80+
var plugins = make(map[string]Register)
81+
82+
func RegisterPlugin(name string, plugin Register) error {
83+
pluginsLock.Lock()
84+
defer pluginsLock.Unlock()
85+
if _, found := plugins[name]; found {
86+
return fmt.Errorf("Plugin %q was registered twice", name)
87+
}
88+
klog.V(4).Infof("Registered Plugin %q", name)
89+
plugins[name] = plugin
90+
return nil
91+
}
92+
93+
func InitializePlugins(factory info.MachineInfoFactory, fsInfo fs.FsInfo, includedMetrics MetricSet) []watcher.ContainerWatcher {
94+
pluginsLock.Lock()
95+
defer pluginsLock.Unlock()
96+
97+
containerWatchers := []watcher.ContainerWatcher{}
98+
for name, register := range plugins {
99+
watcher, err := register(factory, fsInfo, includedMetrics)
100+
if err != nil {
101+
klog.V(5).Infof("Registration of the %s container factory failed: %v", name, err)
102+
}
103+
if watcher != nil {
104+
containerWatchers = append(containerWatchers, watcher)
105+
}
106+
}
107+
return containerWatchers
108+
}
109+
74110
// TODO(vmarmol): Consider not making this global.
75111
// Global list of factories.
76112
var (

container/factory_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919

2020
"github.com/google/cadvisor/container"
2121
containertest "github.com/google/cadvisor/container/testing"
22-
"github.com/google/cadvisor/manager/watcher"
22+
"github.com/google/cadvisor/watcher"
2323

2424
"github.com/stretchr/testify/mock"
2525
)

0 commit comments

Comments
 (0)