mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00

Currently the metrics plugin uses a really hackish host mount with propagated mounts to get the metrics socket into a plugin after the plugin is alreay running. This approach ends up leaking mounts which requires setting the plugin manager root to private, which causes some other issues. With this change, plugin subsystems can register a set of modifiers to apply to the plugin's runtime spec before the plugin is ever started. This will help to generalize some of the customization work that needs to happen for various plugin subsystems (and future ones). Specifically it lets the metrics plugin subsystem append a mount to the runtime spec to mount the metrics socket in the plugin's mount namespace rather than the host's and prevetns any leaking due to this mount. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
56 lines
1.6 KiB
Go
56 lines
1.6 KiB
Go
// +build !windows
|
|
|
|
package daemon
|
|
|
|
import (
|
|
"net"
|
|
"net/http"
|
|
"path/filepath"
|
|
|
|
"github.com/docker/docker/pkg/plugingetter"
|
|
"github.com/docker/docker/pkg/plugins"
|
|
"github.com/docker/docker/plugin"
|
|
metrics "github.com/docker/go-metrics"
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
"github.com/pkg/errors"
|
|
"github.com/sirupsen/logrus"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
func (daemon *Daemon) listenMetricsSock() (string, error) {
|
|
path := filepath.Join(daemon.configStore.ExecRoot, "metrics.sock")
|
|
unix.Unlink(path)
|
|
l, err := net.Listen("unix", path)
|
|
if err != nil {
|
|
return "", errors.Wrap(err, "error setting up metrics plugin listener")
|
|
}
|
|
|
|
mux := http.NewServeMux()
|
|
mux.Handle("/metrics", metrics.Handler())
|
|
go func() {
|
|
http.Serve(l, mux)
|
|
}()
|
|
daemon.metricsPluginListener = l
|
|
return path, nil
|
|
}
|
|
|
|
func registerMetricsPluginCallback(store *plugin.Store, sockPath string) {
|
|
store.RegisterRuntimeOpt(metricsPluginType, func(s *specs.Spec) {
|
|
f := plugin.WithSpecMounts([]specs.Mount{
|
|
{Type: "bind", Source: sockPath, Destination: "/run/docker/metrics.sock", Options: []string{"bind", "ro"}},
|
|
})
|
|
f(s)
|
|
})
|
|
store.Handle(metricsPluginType, func(name string, client *plugins.Client) {
|
|
// Use lookup since nothing in the system can really reference it, no need
|
|
// to protect against removal
|
|
p, err := store.Get(name, metricsPluginType, plugingetter.Lookup)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if err := pluginStartMetricsCollection(p); err != nil {
|
|
logrus.WithError(err).WithField("name", name).Error("error while initializing metrics plugin")
|
|
}
|
|
})
|
|
}
|