mirror of
https://github.com/moby/moby.git
synced 2026-01-11 02:31:44 +00:00
NRI: instantiate and start/stop NRI adaptation
Signed-off-by: Rob Murray <rob.murray@docker.com>
This commit is contained in:
@@ -37,6 +37,7 @@ import (
|
||||
networktypes "github.com/moby/moby/api/types/network"
|
||||
registrytypes "github.com/moby/moby/api/types/registry"
|
||||
"github.com/moby/moby/api/types/swarm"
|
||||
"github.com/moby/moby/v2/daemon/internal/nri"
|
||||
"github.com/moby/sys/user"
|
||||
"github.com/moby/sys/userns"
|
||||
"github.com/pkg/errors"
|
||||
@@ -116,6 +117,7 @@ type Daemon struct {
|
||||
shutdown bool
|
||||
idMapping user.IdentityMapping
|
||||
PluginStore *plugin.Store // TODO: remove
|
||||
nri *nri.NRI
|
||||
pluginManager *plugin.Manager
|
||||
linkIndex *linkIndex
|
||||
containerdClient *containerd.Client
|
||||
@@ -1096,6 +1098,14 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d.nri, err = nri.NewNRI(ctx, nri.Config{
|
||||
DaemonConfig: config.NRIOpts,
|
||||
ContainerLister: d.containers,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
driverName := getDriverOverride(ctx, cfgStore.GraphDriver, imgStoreChoice)
|
||||
|
||||
var migrationConfig migration.Config
|
||||
@@ -1486,6 +1496,10 @@ func (daemon *Daemon) Shutdown(ctx context.Context) error {
|
||||
// Shutdown plugins after containers and layerstore. Don't change the order.
|
||||
daemon.pluginShutdown()
|
||||
|
||||
if daemon.nri != nil {
|
||||
daemon.nri.Shutdown(ctx)
|
||||
}
|
||||
|
||||
// trigger libnetwork Stop only if it's initialized
|
||||
if daemon.netController != nil {
|
||||
daemon.netController.Stop()
|
||||
|
||||
@@ -1,7 +1,128 @@
|
||||
package nri
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/log"
|
||||
"github.com/containerd/nri/pkg/adaptation"
|
||||
"github.com/moby/moby/v2/daemon/container"
|
||||
"github.com/moby/moby/v2/daemon/internal/rootless"
|
||||
"github.com/moby/moby/v2/daemon/pkg/opts"
|
||||
"github.com/moby/moby/v2/dockerversion"
|
||||
"github.com/moby/moby/v2/pkg/homedir"
|
||||
)
|
||||
|
||||
var _ = *adaptation.Adaptation
|
||||
const (
|
||||
// defaultPluginSubdir is the default location for NRI plugins under libexec,
|
||||
// which is in a different location for rootful/rootless Docker.
|
||||
defaultPluginSubdir = "docker/nri-plugins"
|
||||
// defaultPluginConfigSubdir is the default location for NRI plugin config under etc,
|
||||
// which is in a different location for rootful/rootless Docker.
|
||||
defaultPluginConfigSubdir = "docker/nri/conf.d"
|
||||
)
|
||||
|
||||
type NRI struct {
|
||||
cfg Config
|
||||
|
||||
// mu protects nri - read lock for container operations, write lock for sync and shutdown.
|
||||
mu sync.RWMutex
|
||||
nri *adaptation.Adaptation
|
||||
}
|
||||
|
||||
type ContainerLister interface {
|
||||
List() []*container.Container
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
DaemonConfig opts.NRIOpts
|
||||
ContainerLister ContainerLister
|
||||
}
|
||||
|
||||
func NewNRI(ctx context.Context, cfg Config) (*NRI, error) {
|
||||
n := &NRI{cfg: cfg}
|
||||
if !n.cfg.DaemonConfig.Enable {
|
||||
log.G(ctx).Info("NRI is disabled")
|
||||
return n, nil
|
||||
}
|
||||
|
||||
if err := setDefaultPaths(&n.cfg.DaemonConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"pluginPath": n.cfg.DaemonConfig.PluginPath,
|
||||
"pluginConfigPath": n.cfg.DaemonConfig.PluginConfigPath,
|
||||
"socketPath": n.cfg.DaemonConfig.SocketPath,
|
||||
}).Info("Starting NRI")
|
||||
|
||||
var err error
|
||||
n.nri, err = adaptation.New("docker", dockerversion.Version, n.syncFn, n.updateFn, nriOptions(n.cfg.DaemonConfig)...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := n.nri.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (n *NRI) Shutdown(ctx context.Context) {
|
||||
n.mu.Lock()
|
||||
defer n.mu.Unlock()
|
||||
if n.nri == nil {
|
||||
return
|
||||
}
|
||||
log.G(ctx).Info("Shutting down NRI")
|
||||
n.nri.Stop()
|
||||
n.nri = nil
|
||||
}
|
||||
|
||||
func (n *NRI) syncFn(ctx context.Context, syncCB adaptation.SyncCB) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NRI) updateFn(context.Context, []*adaptation.ContainerUpdate) ([]*adaptation.ContainerUpdate, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func setDefaultPaths(cfg *opts.NRIOpts) error {
|
||||
if cfg.PluginPath != "" && cfg.PluginConfigPath != "" {
|
||||
return nil
|
||||
}
|
||||
libexecDir := "/usr/libexec"
|
||||
etcDir := "/etc"
|
||||
if rootless.RunningWithRootlessKit() {
|
||||
var err error
|
||||
libexecDir, err = homedir.GetLibexecHome()
|
||||
if err != nil {
|
||||
return fmt.Errorf("configuring NRI: %w", err)
|
||||
}
|
||||
etcDir, err = homedir.GetConfigHome()
|
||||
if err != nil {
|
||||
return fmt.Errorf("configuring NRI: %w", err)
|
||||
}
|
||||
}
|
||||
if cfg.PluginPath == "" {
|
||||
cfg.PluginPath = filepath.Join(libexecDir, defaultPluginSubdir)
|
||||
}
|
||||
if cfg.PluginConfigPath == "" {
|
||||
cfg.PluginConfigPath = filepath.Join(etcDir, defaultPluginConfigSubdir)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func nriOptions(cfg opts.NRIOpts) []adaptation.Option {
|
||||
res := []adaptation.Option{
|
||||
adaptation.WithPluginPath(cfg.PluginPath),
|
||||
adaptation.WithPluginConfigPath(cfg.PluginConfigPath),
|
||||
}
|
||||
if cfg.SocketPath == "" {
|
||||
res = append(res, adaptation.WithDisabledExternalConnections())
|
||||
} else {
|
||||
res = append(res, adaptation.WithSocketPath(cfg.SocketPath))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -103,3 +103,13 @@ func GetLibHome() (string, error) {
|
||||
}
|
||||
return filepath.Join(home, ".local/lib"), nil
|
||||
}
|
||||
|
||||
// GetLibexecHome returns $HOME/.local/libexec
|
||||
// If HOME is not set, getpwent(3) is consulted to determine the users home directory.
|
||||
func GetLibexecHome() (string, error) {
|
||||
home := Get()
|
||||
if home == "" {
|
||||
return "", errors.New("could not get HOME")
|
||||
}
|
||||
return filepath.Join(home, ".local/libexec"), nil
|
||||
}
|
||||
|
||||
@@ -30,3 +30,8 @@ func GetConfigHome() (string, error) {
|
||||
func GetLibHome() (string, error) {
|
||||
return "", errors.New("homedir.GetLibHome() is not supported on this system")
|
||||
}
|
||||
|
||||
// GetLibexecHome is unsupported on non-linux system.
|
||||
func GetLibexecHome() (string, error) {
|
||||
return "", errors.New("homedir.GetLibexecHome() is not supported on this system")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user