mirror of
https://github.com/moby/moby.git
synced 2026-01-11 10:41:43 +00:00
129 lines
3.2 KiB
Go
129 lines
3.2 KiB
Go
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"
|
|
)
|
|
|
|
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
|
|
}
|