Create server package for containerd daemon
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
c4da4ed393
commit
a6e77432df
@ -15,9 +15,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultRoot = "/var/lib/containerd-test"
|
defaultRoot = "/var/lib/containerd-test"
|
||||||
defaultState = "/run/containerd-test"
|
testImage = "docker.io/library/alpine:latest"
|
||||||
testImage = "docker.io/library/alpine:latest"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -58,25 +57,28 @@ func TestMain(m *testing.M) {
|
|||||||
// setup a new containerd daemon if !testing.Short
|
// setup a new containerd daemon if !testing.Short
|
||||||
cmd = exec.Command("containerd",
|
cmd = exec.Command("containerd",
|
||||||
"--root", defaultRoot,
|
"--root", defaultRoot,
|
||||||
"--state", defaultState,
|
|
||||||
"--address", address,
|
"--address", address,
|
||||||
)
|
)
|
||||||
cmd.Stderr = buf
|
cmd.Stderr = buf
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
fmt.Println(err)
|
cmd.Wait()
|
||||||
|
fmt.Fprintf(os.Stderr, "%s: %s", err, buf.String())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := waitForDaemonStart(ctx, address)
|
client, err := waitForDaemonStart(ctx, address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "immediate fail!", err)
|
cmd.Wait()
|
||||||
|
fmt.Fprintf(os.Stderr, "%s: %s", err, buf.String())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pull a seed image
|
// pull a seed image
|
||||||
if _, err = client.Pull(ctx, testImage, WithPullUnpack); err != nil {
|
if _, err = client.Pull(ctx, testImage, WithPullUnpack); err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
cmd.Process.Signal(syscall.SIGTERM)
|
||||||
|
cmd.Wait()
|
||||||
|
fmt.Fprintf(os.Stderr, "%s: %s", err, buf.String())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,77 +14,9 @@ var configCommand = cli.Command{
|
|||||||
Name: "default",
|
Name: "default",
|
||||||
Usage: "see the output of the default config",
|
Usage: "see the output of the default config",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
_, err := conf.WriteTo(os.Stdout)
|
_, err := defaultConfig().WriteTo(os.Stdout)
|
||||||
return err
|
return err
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadConfig loads the config from the provided path
|
|
||||||
func loadConfig(path string) error {
|
|
||||||
md, err := toml.DecodeFile(path, conf)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
conf.md = md
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// config specifies the containerd configuration file in the TOML format.
|
|
||||||
// It contains fields to configure various subsystems and containerd as a whole.
|
|
||||||
type config struct {
|
|
||||||
// Root is the path to a directory where containerd will store persistent data
|
|
||||||
Root string `toml:"root"`
|
|
||||||
// GRPC configuration settings
|
|
||||||
GRPC grpcConfig `toml:"grpc"`
|
|
||||||
// Debug and profiling settings
|
|
||||||
Debug debug `toml:"debug"`
|
|
||||||
// Metrics and monitoring settings
|
|
||||||
Metrics metricsConfig `toml:"metrics"`
|
|
||||||
// Snapshotter specifies which snapshot driver to use
|
|
||||||
Snapshotter string `toml:"snapshotter"`
|
|
||||||
// Differ specifies which differ to use. Differ is tightly coupled with the snapshotter
|
|
||||||
// so not all combinations may work.
|
|
||||||
Differ string `toml:"differ"`
|
|
||||||
// Plugins provides plugin specific configuration for the initialization of a plugin
|
|
||||||
Plugins map[string]toml.Primitive `toml:"plugins"`
|
|
||||||
// Enable containerd as a subreaper
|
|
||||||
Subreaper bool `toml:"subreaper"`
|
|
||||||
// OOMScore adjust the containerd's oom score
|
|
||||||
OOMScore int `toml:"oom_score"`
|
|
||||||
|
|
||||||
md toml.MetaData
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *config) decodePlugin(name string, v interface{}) error {
|
|
||||||
p, ok := c.Plugins[name]
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return c.md.PrimitiveDecode(p, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *config) WriteTo(w io.Writer) (int64, error) {
|
|
||||||
buf := bytes.NewBuffer(nil)
|
|
||||||
e := toml.NewEncoder(buf)
|
|
||||||
if err := e.Encode(c); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return io.Copy(w, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
type grpcConfig struct {
|
|
||||||
Address string `toml:"address"`
|
|
||||||
Uid int `toml:"uid"`
|
|
||||||
Gid int `toml:"gid"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type debug struct {
|
|
||||||
Address string `toml:"address"`
|
|
||||||
Level string `toml:"level"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type metricsConfig struct {
|
|
||||||
Address string `toml:"address"`
|
|
||||||
}
|
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/containerd/containerd"
|
import (
|
||||||
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/containerd/containerd/server"
|
||||||
|
)
|
||||||
|
|
||||||
func defaultConfig() *config {
|
func defaultConfig() *server.Config {
|
||||||
return &config{
|
return &server.Config{
|
||||||
Root: "/var/lib/containerd",
|
Root: "/var/lib/containerd",
|
||||||
GRPC: grpcConfig{
|
GRPC: server.GRPCConfig{
|
||||||
Address: containerd.DefaultAddress,
|
Address: containerd.DefaultAddress,
|
||||||
},
|
},
|
||||||
Debug: debug{
|
Debug: server.Debug{
|
||||||
Level: "info",
|
Level: "info",
|
||||||
Address: "/run/containerd/debug.sock",
|
Address: "/run/containerd/debug.sock",
|
||||||
},
|
},
|
||||||
|
@ -2,13 +2,15 @@
|
|||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
func defaultConfig() *config {
|
import "github.com/containerd/containerd/server"
|
||||||
return &config{
|
|
||||||
|
func defaultConfig() *server.Config {
|
||||||
|
return &server.Config{
|
||||||
Root: "/var/lib/containerd",
|
Root: "/var/lib/containerd",
|
||||||
GRPC: grpcConfig{
|
GRPC: server.GRPCConfig{
|
||||||
Address: "/run/containerd/containerd.sock",
|
Address: "/run/containerd/containerd.sock",
|
||||||
},
|
},
|
||||||
Debug: debug{
|
Debug: server.Debug{
|
||||||
Level: "info",
|
Level: "info",
|
||||||
Address: "/run/containerd/debug.sock",
|
Address: "/run/containerd/debug.sock",
|
||||||
},
|
},
|
||||||
|
@ -3,15 +3,17 @@ package main
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/server"
|
||||||
)
|
)
|
||||||
|
|
||||||
func defaultConfig() *config {
|
func defaultConfig() *server.Config {
|
||||||
return &config{
|
return &server.Config{
|
||||||
Root: filepath.Join(os.Getenv("programfiles"), "containerd", "root"),
|
Root: filepath.Join(os.Getenv("programfiles"), "containerd", "root"),
|
||||||
GRPC: grpcConfig{
|
GRPC: server.GRPCConfig{
|
||||||
Address: `\\.\pipe\containerd-containerd`,
|
Address: `\\.\pipe\containerd-containerd`,
|
||||||
},
|
},
|
||||||
Debug: debug{
|
Debug: server.Debug{
|
||||||
Level: "info",
|
Level: "info",
|
||||||
Address: `\\.\pipe\containerd-debug`,
|
Address: `\\.\pipe\containerd-debug`,
|
||||||
},
|
},
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "expvar"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net"
|
||||||
_ "net/http/pprof"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -12,27 +11,15 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/boltdb/bolt"
|
"github.com/boltdb/bolt"
|
||||||
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
|
||||||
gocontext "golang.org/x/net/context"
|
gocontext "golang.org/x/net/context"
|
||||||
"google.golang.org/grpc"
|
|
||||||
"google.golang.org/grpc/health/grpc_health_v1"
|
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
containersapi "github.com/containerd/containerd/api/services/containers/v1"
|
|
||||||
contentapi "github.com/containerd/containerd/api/services/content/v1"
|
|
||||||
diffapi "github.com/containerd/containerd/api/services/diff/v1"
|
|
||||||
imagesapi "github.com/containerd/containerd/api/services/images/v1"
|
|
||||||
namespacesapi "github.com/containerd/containerd/api/services/namespaces/v1"
|
|
||||||
snapshotapi "github.com/containerd/containerd/api/services/snapshot/v1"
|
|
||||||
api "github.com/containerd/containerd/api/services/tasks/v1"
|
|
||||||
versionapi "github.com/containerd/containerd/api/services/version/v1"
|
|
||||||
"github.com/containerd/containerd/content"
|
"github.com/containerd/containerd/content"
|
||||||
"github.com/containerd/containerd/events"
|
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
|
"github.com/containerd/containerd/server"
|
||||||
"github.com/containerd/containerd/sys"
|
"github.com/containerd/containerd/sys"
|
||||||
"github.com/containerd/containerd/version"
|
"github.com/containerd/containerd/version"
|
||||||
metrics "github.com/docker/go-metrics"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
@ -47,11 +34,6 @@ const usage = `
|
|||||||
high performance container runtime
|
high performance container runtime
|
||||||
`
|
`
|
||||||
|
|
||||||
var (
|
|
||||||
conf = defaultConfig()
|
|
||||||
global = log.WithModule(gocontext.Background(), "containerd")
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cli.VersionPrinter = func(c *cli.Context) {
|
cli.VersionPrinter = func(c *cli.Context) {
|
||||||
fmt.Println(c.App.Name, version.Package, c.App.Version)
|
fmt.Println(c.App.Name, version.Package, c.App.Version)
|
||||||
@ -73,10 +55,6 @@ func main() {
|
|||||||
Name: "log-level,l",
|
Name: "log-level,l",
|
||||||
Usage: "set the logging level [debug, info, warn, error, fatal, panic]",
|
Usage: "set the logging level [debug, info, warn, error, fatal, panic]",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
|
||||||
Name: "state",
|
|
||||||
Usage: "containerd state directory",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "address,a",
|
Name: "address,a",
|
||||||
Usage: "address for containerd's GRPC server",
|
Usage: "address for containerd's GRPC server",
|
||||||
@ -89,81 +67,66 @@ func main() {
|
|||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
configCommand,
|
configCommand,
|
||||||
}
|
}
|
||||||
app.Before = before
|
|
||||||
app.Action = func(context *cli.Context) error {
|
app.Action = func(context *cli.Context) error {
|
||||||
start := time.Now()
|
var (
|
||||||
|
start = time.Now()
|
||||||
|
signals = make(chan os.Signal, 2048)
|
||||||
|
ctx = log.WithModule(gocontext.Background(), "containerd")
|
||||||
|
config = defaultConfig()
|
||||||
|
)
|
||||||
// start the signal handler as soon as we can to make sure that
|
// start the signal handler as soon as we can to make sure that
|
||||||
// we don't miss any signals during boot
|
// we don't miss any signals during boot
|
||||||
signals := make(chan os.Signal, 2048)
|
|
||||||
signal.Notify(signals, handledSignals...)
|
signal.Notify(signals, handledSignals...)
|
||||||
if err := platformInit(context); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.G(global).Info("starting containerd boot...")
|
|
||||||
|
|
||||||
// load all plugins into containerd
|
if err := server.LoadConfig(context.GlobalString("config"), config); err != nil && !os.IsNotExist(err) {
|
||||||
if err := plugin.Load(filepath.Join(conf.Root, "plugins")); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
registerContentStore()
|
// apply flags to the config
|
||||||
registerMetaDB()
|
if err := applyFlags(context, config); err != nil {
|
||||||
// start debug and metrics APIs
|
return err
|
||||||
if err := serveDebugAPI(); err != nil {
|
}
|
||||||
|
address := config.GRPC.Address
|
||||||
|
if address == "" {
|
||||||
|
return errors.New("grpc address cannot be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := platformInit(ctx, config); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.G(ctx).Info("starting containerd boot...")
|
||||||
|
|
||||||
|
plugins, err := loadPlugins(config)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
server, err := server.New(ctx, config, plugins)
|
||||||
services []plugin.Service
|
if err != nil {
|
||||||
plugins = make(map[plugin.PluginType][]interface{})
|
return err
|
||||||
eventEmitter = events.NewEmitter()
|
}
|
||||||
)
|
if config.Debug.Address != "" {
|
||||||
for _, init := range plugin.Graph() {
|
l, err := sys.GetLocalListener(config.Debug.Address, config.Debug.Uid, config.Debug.Gid)
|
||||||
id := init.URI()
|
|
||||||
if !shouldLoad(init) {
|
|
||||||
log.G(global).WithField("type", init.Type).Infof("skipping plugin %q...", id)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.G(global).WithField("type", init.Type).Infof("loading plugin %q...", id)
|
|
||||||
ic := plugin.NewContext(plugins)
|
|
||||||
ic.Root = filepath.Join(conf.Root, id)
|
|
||||||
|
|
||||||
rCtx := events.WithPoster(global, eventEmitter)
|
|
||||||
ic.Context = log.WithModule(rCtx, id)
|
|
||||||
if init.Config != nil {
|
|
||||||
if err := loadPluginConfig(init.ID, init.Config, ic); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ic.Emitter = eventEmitter
|
|
||||||
|
|
||||||
p, err := init.Init(ic)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
plugins[init.Type] = append(plugins[init.Type], p)
|
serve(log.WithModule(ctx, "debug"), l, server.ServeDebug)
|
||||||
if s, ok := p.(plugin.Service); ok {
|
|
||||||
services = append(services, s)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if config.Metrics.Address != "" {
|
||||||
// start the GRPC api with the execution service registered
|
l, err := net.Listen("tcp", config.Metrics.Address)
|
||||||
server := newGRPCServer()
|
if err != nil {
|
||||||
for _, service := range services {
|
|
||||||
if err := service.Register(server); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
serve(log.WithModule(ctx, "metrics"), l, server.ServeMetrics)
|
||||||
}
|
}
|
||||||
// register metrics last after all other services
|
|
||||||
grpc_prometheus.Register(server)
|
l, err := sys.GetLocalListener(address, config.GRPC.Uid, config.GRPC.Gid)
|
||||||
log.G(global).Info("starting GRPC API server...")
|
if err != nil {
|
||||||
if err := serveGRPC(server); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// start the prometheus metrics API for containerd
|
serve(log.WithModule(ctx, "grpc"), l, server.ServeGRPC)
|
||||||
serveMetricsAPI()
|
|
||||||
|
|
||||||
log.G(global).Infof("containerd successfully booted in %fs", time.Since(start).Seconds())
|
log.G(ctx).Infof("containerd successfully booted in %fs", time.Since(start).Seconds())
|
||||||
return handleSignals(signals, server)
|
return handleSignals(ctx, signals, server)
|
||||||
}
|
}
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(os.Args); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
|
fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
|
||||||
@ -171,14 +134,21 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func before(context *cli.Context) error {
|
func serve(ctx context.Context, l net.Listener, serveFunc func(net.Listener) error) {
|
||||||
err := loadConfig(context.GlobalString("config"))
|
path := l.Addr().String()
|
||||||
if err != nil && !os.IsNotExist(err) {
|
log.G(ctx).WithField("address", path).Info("serving...")
|
||||||
return err
|
go func() {
|
||||||
}
|
defer l.Close()
|
||||||
|
if err := serveFunc(l); err != nil {
|
||||||
|
log.G(ctx).WithError(err).WithField("address", path).Fatal("serve failure")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyFlags(context *cli.Context, config *server.Config) error {
|
||||||
// the order for config vs flag values is that flags will always override
|
// the order for config vs flag values is that flags will always override
|
||||||
// the config values if they are set
|
// the config values if they are set
|
||||||
if err := setLevel(context); err != nil {
|
if err := setLevel(context, config); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, v := range []struct {
|
for _, v := range []struct {
|
||||||
@ -187,11 +157,11 @@ func before(context *cli.Context) error {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "root",
|
name: "root",
|
||||||
d: &conf.Root,
|
d: &config.Root,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "address",
|
name: "address",
|
||||||
d: &conf.GRPC.Address,
|
d: &config.GRPC.Address,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
if s := context.GlobalString(v.name); s != "" {
|
if s := context.GlobalString(v.name); s != "" {
|
||||||
@ -201,10 +171,10 @@ func before(context *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setLevel(context *cli.Context) error {
|
func setLevel(context *cli.Context, config *server.Config) error {
|
||||||
l := context.GlobalString("log-level")
|
l := context.GlobalString("log-level")
|
||||||
if l == "" {
|
if l == "" {
|
||||||
l = conf.Debug.Level
|
l = config.Debug.Level
|
||||||
}
|
}
|
||||||
if l != "" {
|
if l != "" {
|
||||||
lvl, err := logrus.ParseLevel(l)
|
lvl, err := logrus.ParseLevel(l)
|
||||||
@ -216,43 +186,16 @@ func setLevel(context *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func serveMetricsAPI() {
|
func loadPlugins(config *server.Config) ([]*plugin.Registration, error) {
|
||||||
if conf.Metrics.Address != "" {
|
// load all plugins into containerd
|
||||||
log.G(global).WithField("metrics", conf.Metrics.Address).Info("starting metrics API...")
|
if err := plugin.Load(filepath.Join(config.Root, "plugins")); err != nil {
|
||||||
h := newMetricsHandler()
|
return nil, err
|
||||||
go func() {
|
|
||||||
if err := http.ListenAndServe(conf.Metrics.Address, h); err != nil {
|
|
||||||
log.G(global).WithError(err).Fatal("serve metrics API")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
}
|
// load additional plugins that don't automatically register themselves
|
||||||
|
registerContentStore()
|
||||||
func newMetricsHandler() http.Handler {
|
registerMetaDB()
|
||||||
m := http.NewServeMux()
|
// return the ordered graph for plugins
|
||||||
m.Handle("/metrics", metrics.Handler())
|
return plugin.Graph(), nil
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func serveDebugAPI() error {
|
|
||||||
path := conf.Debug.Address
|
|
||||||
if path == "" {
|
|
||||||
return errors.New("debug socket path cannot be empty")
|
|
||||||
}
|
|
||||||
l, err := sys.GetLocalListener(path, conf.GRPC.Uid, conf.GRPC.Gid)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.G(global).WithField("debug", path).Info("starting debug API...")
|
|
||||||
go func() {
|
|
||||||
defer l.Close()
|
|
||||||
// pprof and expvars are imported and automatically register their endpoints
|
|
||||||
// under /debug
|
|
||||||
if err := http.Serve(l, nil); err != nil {
|
|
||||||
log.G(global).WithError(err).Fatal("serve debug API")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerContentStore() {
|
func registerContentStore() {
|
||||||
@ -278,63 +221,6 @@ func registerMetaDB() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGRPCServer() *grpc.Server {
|
|
||||||
s := grpc.NewServer(
|
|
||||||
grpc.UnaryInterceptor(interceptor),
|
|
||||||
grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
|
|
||||||
)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func serveGRPC(server *grpc.Server) error {
|
|
||||||
path := conf.GRPC.Address
|
|
||||||
if path == "" {
|
|
||||||
return errors.New("--socket path cannot be empty")
|
|
||||||
}
|
|
||||||
l, err := sys.GetLocalListener(path, conf.GRPC.Uid, conf.GRPC.Gid)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
defer l.Close()
|
|
||||||
if err := server.Serve(l); err != nil {
|
|
||||||
log.G(global).WithError(err).Fatal("serve GRPC")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func interceptor(ctx gocontext.Context,
|
|
||||||
req interface{},
|
|
||||||
info *grpc.UnaryServerInfo,
|
|
||||||
handler grpc.UnaryHandler,
|
|
||||||
) (interface{}, error) {
|
|
||||||
ctx = log.WithModule(ctx, "containerd")
|
|
||||||
switch info.Server.(type) {
|
|
||||||
case api.TasksServer:
|
|
||||||
ctx = log.WithModule(ctx, "execution")
|
|
||||||
case containersapi.ContainersServer:
|
|
||||||
ctx = log.WithModule(ctx, "containers")
|
|
||||||
case contentapi.ContentServer:
|
|
||||||
ctx = log.WithModule(ctx, "content")
|
|
||||||
case imagesapi.ImagesServer:
|
|
||||||
ctx = log.WithModule(ctx, "images")
|
|
||||||
case grpc_health_v1.HealthServer:
|
|
||||||
// No need to change the context
|
|
||||||
case versionapi.VersionServer:
|
|
||||||
ctx = log.WithModule(ctx, "version")
|
|
||||||
case snapshotapi.SnapshotsServer:
|
|
||||||
ctx = log.WithModule(ctx, "snapshot")
|
|
||||||
case diffapi.DiffServer:
|
|
||||||
ctx = log.WithModule(ctx, "diff")
|
|
||||||
case namespacesapi.NamespacesServer:
|
|
||||||
ctx = log.WithModule(ctx, "namespaces")
|
|
||||||
default:
|
|
||||||
log.G(ctx).Warnf("unknown GRPC server type: %#v\n", info.Server)
|
|
||||||
}
|
|
||||||
return grpc_prometheus.UnaryServerInterceptor(ctx, req, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dumpStacks() {
|
func dumpStacks() {
|
||||||
var (
|
var (
|
||||||
buf []byte
|
buf []byte
|
||||||
@ -349,23 +235,3 @@ func dumpStacks() {
|
|||||||
buf = buf[:stackSize]
|
buf = buf[:stackSize]
|
||||||
logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
|
logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadPluginConfig(name string, c interface{}, ic *plugin.InitContext) error {
|
|
||||||
if err := conf.decodePlugin(name, c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ic.Config = c
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func shouldLoad(r *plugin.Registration) bool {
|
|
||||||
// only load certain plugins based on the config values
|
|
||||||
switch r.Type {
|
|
||||||
case plugin.SnapshotPlugin:
|
|
||||||
return r.URI() == conf.Snapshotter
|
|
||||||
case plugin.DiffPlugin:
|
|
||||||
return r.URI() == conf.Differ
|
|
||||||
default:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/reaper"
|
"github.com/containerd/containerd/reaper"
|
||||||
|
"github.com/containerd/containerd/server"
|
||||||
"github.com/containerd/containerd/sys"
|
"github.com/containerd/containerd/sys"
|
||||||
"github.com/urfave/cli"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultConfigPath = "/etc/containerd/config.toml"
|
const defaultConfigPath = "/etc/containerd/config.toml"
|
||||||
@ -21,29 +21,29 @@ var handledSignals = []os.Signal{
|
|||||||
unix.SIGCHLD,
|
unix.SIGCHLD,
|
||||||
}
|
}
|
||||||
|
|
||||||
func platformInit(context *cli.Context) error {
|
func platformInit(ctx context.Context, config *server.Config) error {
|
||||||
if conf.Subreaper {
|
if config.Subreaper {
|
||||||
log.G(global).Info("setting subreaper...")
|
log.G(ctx).Info("setting subreaper...")
|
||||||
if err := sys.SetSubreaper(1); err != nil {
|
if err := sys.SetSubreaper(1); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if conf.OOMScore != 0 {
|
if config.OOMScore != 0 {
|
||||||
log.G(global).Infof("changing OOM score to %d", conf.OOMScore)
|
log.G(ctx).Infof("changing OOM score to %d", config.OOMScore)
|
||||||
if err := sys.SetOOMScore(os.Getpid(), conf.OOMScore); err != nil {
|
if err := sys.SetOOMScore(os.Getpid(), config.OOMScore); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleSignals(signals chan os.Signal, server *grpc.Server) error {
|
func handleSignals(ctx context.Context, signals chan os.Signal, server *server.Server) error {
|
||||||
for s := range signals {
|
for s := range signals {
|
||||||
log.G(global).WithField("signal", s).Debug("received signal")
|
log.G(ctx).WithField("signal", s).Debug("received signal")
|
||||||
switch s {
|
switch s {
|
||||||
case unix.SIGCHLD:
|
case unix.SIGCHLD:
|
||||||
if err := reaper.Reap(); err != nil {
|
if err := reaper.Reap(); err != nil {
|
||||||
log.G(global).WithError(err).Error("reap containerd processes")
|
log.G(ctx).WithError(err).Error("reap containerd processes")
|
||||||
}
|
}
|
||||||
case unix.SIGUSR1:
|
case unix.SIGUSR1:
|
||||||
dumpStacks()
|
dumpStacks()
|
||||||
|
@ -3,35 +3,36 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/reaper"
|
"github.com/containerd/containerd/reaper"
|
||||||
"github.com/urfave/cli"
|
"github.com/containerd/containerd/server"
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const defaultConfigPath = "/etc/containerd/config.toml"
|
||||||
defaultConfigPath = "/etc/containerd/config.toml"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var handledSignals = []os.Signal{
|
||||||
handledSignals = []os.Signal{unix.SIGTERM, unix.SIGINT, unix.SIGUSR1, unix.SIGCHLD}
|
unix.SIGTERM,
|
||||||
)
|
unix.SIGINT,
|
||||||
|
unix.SIGUSR1,
|
||||||
|
unix.SIGCHLD,
|
||||||
|
}
|
||||||
|
|
||||||
func platformInit(context *cli.Context) error {
|
func platformInit(context context.Context, config *server.Config) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleSignals(signals chan os.Signal, server *grpc.Server) error {
|
func handleSignals(ctx context.Context, signals chan os.Signal, server *server.Server) error {
|
||||||
for s := range signals {
|
for s := range signals {
|
||||||
log.G(global).WithField("signal", s).Debug("received signal")
|
log.G(ctx).WithField("signal", s).Debug("received signal")
|
||||||
switch s {
|
switch s {
|
||||||
case unix.SIGCHLD:
|
case unix.SIGCHLD:
|
||||||
if err := reaper.Reap(); err != nil {
|
if err := reaper.Reap(); err != nil {
|
||||||
log.G(global).WithError(err).Error("reap containerd processes")
|
log.G(ctx).WithError(err).Error("reap containerd processes")
|
||||||
}
|
}
|
||||||
case unix.SIGUSR1:
|
case unix.SIGUSR1:
|
||||||
dumpStacks()
|
dumpStacks()
|
||||||
|
@ -1,27 +1,30 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/urfave/cli"
|
"github.com/containerd/containerd/server"
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
defaultConfigPath = filepath.Join(os.Getenv("programfiles"), "containerd", "config.toml")
|
defaultConfigPath = filepath.Join(os.Getenv("programfiles"), "containerd", "config.toml")
|
||||||
handledSignals = []os.Signal{syscall.SIGTERM, syscall.SIGINT}
|
handledSignals = []os.Signal{
|
||||||
|
syscall.SIGTERM,
|
||||||
|
syscall.SIGINT,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func platformInit(context *cli.Context) error {
|
func platformInit(context context.Context, config *server.Config) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleSignals(signals chan os.Signal, server *grpc.Server) error {
|
func handleSignals(ctx context.Context, signals chan os.Signal, server *server.Server) error {
|
||||||
for s := range signals {
|
for s := range signals {
|
||||||
log.G(global).WithField("signal", s).Debug("received signal")
|
log.G(ctx).WithField("signal", s).Debug("received signal")
|
||||||
server.Stop()
|
server.Stop()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -3,13 +3,17 @@ package plugin
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/containerd/containerd/events"
|
"github.com/containerd/containerd/events"
|
||||||
|
"github.com/containerd/containerd/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewContext(plugins map[PluginType][]interface{}) *InitContext {
|
func NewContext(ctx context.Context, plugins map[PluginType][]interface{}, root, id string) *InitContext {
|
||||||
return &InitContext{
|
return &InitContext{
|
||||||
plugins: plugins,
|
plugins: plugins,
|
||||||
|
Root: filepath.Join(root, id),
|
||||||
|
Context: log.WithModule(ctx, id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
86
server/config.go
Normal file
86
server/config.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config provides containerd configuration data for the server
|
||||||
|
type Config struct {
|
||||||
|
// Root is the path to a directory where containerd will store persistent data
|
||||||
|
Root string `toml:"root"`
|
||||||
|
// GRPC configuration settings
|
||||||
|
GRPC GRPCConfig `toml:"grpc"`
|
||||||
|
// Debug and profiling settings
|
||||||
|
Debug Debug `toml:"debug"`
|
||||||
|
// Metrics and monitoring settings
|
||||||
|
Metrics MetricsConfig `toml:"metrics"`
|
||||||
|
// Snapshotter specifies which snapshot driver to use
|
||||||
|
Snapshotter string `toml:"snapshotter"`
|
||||||
|
// Differ specifies which differ to use. Differ is tightly coupled with the snapshotter
|
||||||
|
// so not all combinations may work.
|
||||||
|
Differ string `toml:"differ"`
|
||||||
|
// Plugins provides plugin specific configuration for the initialization of a plugin
|
||||||
|
Plugins map[string]toml.Primitive `toml:"plugins"`
|
||||||
|
// Enable containerd as a subreaper
|
||||||
|
Subreaper bool `toml:"subreaper"`
|
||||||
|
// OOMScore adjust the containerd's oom score
|
||||||
|
OOMScore int `toml:"oom_score"`
|
||||||
|
|
||||||
|
md toml.MetaData
|
||||||
|
}
|
||||||
|
|
||||||
|
type GRPCConfig struct {
|
||||||
|
Address string `toml:"address"`
|
||||||
|
Uid int `toml:"uid"`
|
||||||
|
Gid int `toml:"gid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Debug struct {
|
||||||
|
Address string `toml:"address"`
|
||||||
|
Uid int `toml:"uid"`
|
||||||
|
Gid int `toml:"gid"`
|
||||||
|
Level string `toml:"level"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MetricsConfig struct {
|
||||||
|
Address string `toml:"address"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode unmarshals a plugin specific configuration by plugin id
|
||||||
|
func (c *Config) Decode(id string, v interface{}) (interface{}, error) {
|
||||||
|
data, ok := c.Plugins[id]
|
||||||
|
if !ok {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
if err := c.md.PrimitiveDecode(data, v); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo marshals the config to the provided writer
|
||||||
|
func (c *Config) WriteTo(w io.Writer) (int64, error) {
|
||||||
|
buf := bytes.NewBuffer(nil)
|
||||||
|
e := toml.NewEncoder(buf)
|
||||||
|
if err := e.Encode(c); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return io.Copy(w, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadConfig loads the containerd server config from the provided path
|
||||||
|
func LoadConfig(path string, v *Config) error {
|
||||||
|
if v == nil {
|
||||||
|
v = &Config{}
|
||||||
|
}
|
||||||
|
md, err := toml.DecodeFile(path, v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.md = md
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
175
server/server.go
Normal file
175
server/server.go
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"expvar"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/http/pprof"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
containers "github.com/containerd/containerd/api/services/containers/v1"
|
||||||
|
content "github.com/containerd/containerd/api/services/content/v1"
|
||||||
|
diff "github.com/containerd/containerd/api/services/diff/v1"
|
||||||
|
images "github.com/containerd/containerd/api/services/images/v1"
|
||||||
|
namespaces "github.com/containerd/containerd/api/services/namespaces/v1"
|
||||||
|
snapshot "github.com/containerd/containerd/api/services/snapshot/v1"
|
||||||
|
tasks "github.com/containerd/containerd/api/services/tasks/v1"
|
||||||
|
version "github.com/containerd/containerd/api/services/version/v1"
|
||||||
|
"github.com/containerd/containerd/events"
|
||||||
|
"github.com/containerd/containerd/log"
|
||||||
|
"github.com/containerd/containerd/plugin"
|
||||||
|
metrics "github.com/docker/go-metrics"
|
||||||
|
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/health/grpc_health_v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New creates and initializes a new containerd server
|
||||||
|
func New(ctx context.Context, config *Config, plugins []*plugin.Registration) (*Server, error) {
|
||||||
|
if config.Root == "" {
|
||||||
|
return nil, errors.New("root must be specified")
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(config.Root, 0700); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rpc := grpc.NewServer(
|
||||||
|
grpc.UnaryInterceptor(interceptor),
|
||||||
|
grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
|
||||||
|
)
|
||||||
|
var (
|
||||||
|
services []plugin.Service
|
||||||
|
s = &Server{
|
||||||
|
rpc: rpc,
|
||||||
|
emitter: events.NewEmitter(),
|
||||||
|
}
|
||||||
|
initialized = make(map[plugin.PluginType][]interface{})
|
||||||
|
)
|
||||||
|
for _, p := range plugins {
|
||||||
|
id := p.URI()
|
||||||
|
if !shouldLoadPlugin(p, config) {
|
||||||
|
log.G(ctx).WithField("type", p.Type).Infof("skip loading plugin %q...", id)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
log.G(ctx).WithField("type", p.Type).Infof("loading plugin %q...", id)
|
||||||
|
|
||||||
|
initContext := plugin.NewContext(
|
||||||
|
events.WithPoster(ctx, s.emitter),
|
||||||
|
initialized,
|
||||||
|
config.Root,
|
||||||
|
id,
|
||||||
|
)
|
||||||
|
initContext.Emitter = s.emitter
|
||||||
|
|
||||||
|
// load the plugin specific configuration if it is provided
|
||||||
|
if p.Config != nil {
|
||||||
|
pluginConfig, err := config.Decode(p.ID, p.Config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
initContext.Config = pluginConfig
|
||||||
|
}
|
||||||
|
instance, err := p.Init(initContext)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
initialized[p.Type] = append(initialized[p.Type], instance)
|
||||||
|
// check for grpc services that should be registered with the server
|
||||||
|
if service, ok := instance.(plugin.Service); ok {
|
||||||
|
services = append(services, service)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// register services after all plugins have been initialized
|
||||||
|
for _, service := range services {
|
||||||
|
if err := service.Register(rpc); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server is the containerd main daemon
|
||||||
|
type Server struct {
|
||||||
|
rpc *grpc.Server
|
||||||
|
emitter *events.Emitter
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeGRPC provides the containerd grpc APIs on the provided listener
|
||||||
|
func (s *Server) ServeGRPC(l net.Listener) error {
|
||||||
|
// before we start serving the grpc API regster the grpc_prometheus metrics
|
||||||
|
// handler. This needs to be the last service registered so that it can collect
|
||||||
|
// metrics for every other service
|
||||||
|
grpc_prometheus.Register(s.rpc)
|
||||||
|
return s.rpc.Serve(l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeMetrics provides a prometheus endpoint for exposing metrics
|
||||||
|
func (s *Server) ServeMetrics(l net.Listener) error {
|
||||||
|
m := http.NewServeMux()
|
||||||
|
m.Handle("/metrics", metrics.Handler())
|
||||||
|
return http.Serve(l, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServeDebug provides a debug endpoint
|
||||||
|
func (s *Server) ServeDebug(l net.Listener) error {
|
||||||
|
// don't use the default http server mux to make sure nothing gets registered
|
||||||
|
// that we don't want to expose via containerd
|
||||||
|
m := http.NewServeMux()
|
||||||
|
m.Handle("/debug/vars", expvar.Handler())
|
||||||
|
m.Handle("/debug/pprof/", http.HandlerFunc(pprof.Index))
|
||||||
|
m.Handle("/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline))
|
||||||
|
m.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile))
|
||||||
|
m.Handle("/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol))
|
||||||
|
m.Handle("/debug/pprof/trace", http.HandlerFunc(pprof.Trace))
|
||||||
|
return http.Serve(l, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop gracefully stops the containerd server
|
||||||
|
func (s *Server) Stop() {
|
||||||
|
s.rpc.GracefulStop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldLoadPlugin(p *plugin.Registration, config *Config) bool {
|
||||||
|
switch p.Type {
|
||||||
|
case plugin.SnapshotPlugin:
|
||||||
|
return p.URI() == config.Snapshotter
|
||||||
|
case plugin.DiffPlugin:
|
||||||
|
return p.URI() == config.Differ
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func interceptor(
|
||||||
|
ctx context.Context,
|
||||||
|
req interface{},
|
||||||
|
info *grpc.UnaryServerInfo,
|
||||||
|
handler grpc.UnaryHandler,
|
||||||
|
) (interface{}, error) {
|
||||||
|
ctx = log.WithModule(ctx, "containerd")
|
||||||
|
switch info.Server.(type) {
|
||||||
|
case tasks.TasksServer:
|
||||||
|
ctx = log.WithModule(ctx, "execution")
|
||||||
|
case containers.ContainersServer:
|
||||||
|
ctx = log.WithModule(ctx, "containers")
|
||||||
|
case content.ContentServer:
|
||||||
|
ctx = log.WithModule(ctx, "content")
|
||||||
|
case images.ImagesServer:
|
||||||
|
ctx = log.WithModule(ctx, "images")
|
||||||
|
case grpc_health_v1.HealthServer:
|
||||||
|
// No need to change the context
|
||||||
|
case version.VersionServer:
|
||||||
|
ctx = log.WithModule(ctx, "version")
|
||||||
|
case snapshot.SnapshotsServer:
|
||||||
|
ctx = log.WithModule(ctx, "snapshot")
|
||||||
|
case diff.DiffServer:
|
||||||
|
ctx = log.WithModule(ctx, "diff")
|
||||||
|
case namespaces.NamespacesServer:
|
||||||
|
ctx = log.WithModule(ctx, "namespaces")
|
||||||
|
default:
|
||||||
|
log.G(ctx).Warnf("unknown GRPC server type: %#v\n", info.Server)
|
||||||
|
}
|
||||||
|
return grpc_prometheus.UnaryServerInterceptor(ctx, req, info, handler)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user