Skip to content

Commit 6f98d75

Browse files
authored
Merge pull request moby#51636 from robmry/nri-import
NRI: import and instantiate containerd's NRI adaptation package
2 parents 08c3022 + 14906f8 commit 6f98d75

File tree

364 files changed

+112004
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

364 files changed

+112004
-0
lines changed

daemon/daemon.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
networktypes "github.com/moby/moby/api/types/network"
3838
registrytypes "github.com/moby/moby/api/types/registry"
3939
"github.com/moby/moby/api/types/swarm"
40+
"github.com/moby/moby/v2/daemon/internal/nri"
4041
"github.com/moby/sys/user"
4142
"github.com/moby/sys/userns"
4243
"github.com/pkg/errors"
@@ -116,6 +117,7 @@ type Daemon struct {
116117
shutdown bool
117118
idMapping user.IdentityMapping
118119
PluginStore *plugin.Store // TODO: remove
120+
nri *nri.NRI
119121
pluginManager *plugin.Manager
120122
linkIndex *linkIndex
121123
containerdClient *containerd.Client
@@ -1096,6 +1098,14 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
10961098
return nil, err
10971099
}
10981100

1101+
d.nri, err = nri.NewNRI(ctx, nri.Config{
1102+
DaemonConfig: config.NRIOpts,
1103+
ContainerLister: d.containers,
1104+
})
1105+
if err != nil {
1106+
return nil, err
1107+
}
1108+
10991109
driverName := getDriverOverride(ctx, cfgStore.GraphDriver, imgStoreChoice)
11001110

11011111
var migrationConfig migration.Config
@@ -1486,6 +1496,10 @@ func (daemon *Daemon) Shutdown(ctx context.Context) error {
14861496
// Shutdown plugins after containers and layerstore. Don't change the order.
14871497
daemon.pluginShutdown()
14881498

1499+
if daemon.nri != nil {
1500+
daemon.nri.Shutdown(ctx)
1501+
}
1502+
14891503
// trigger libnetwork Stop only if it's initialized
14901504
if daemon.netController != nil {
14911505
daemon.netController.Stop()

daemon/internal/nri/logshim.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package nri
2+
3+
import (
4+
"context"
5+
6+
"github.com/containerd/log"
7+
nrilog "github.com/containerd/nri/pkg/log"
8+
)
9+
10+
type logShim struct{}
11+
12+
// logShim implements interface nrilog.Logger.
13+
var _ nrilog.Logger = (*logShim)(nil)
14+
15+
func (nls *logShim) Debugf(ctx context.Context, format string, args ...any) {
16+
log.G(ctx).Debugf("NRI: "+format, args...)
17+
}
18+
19+
func (nls *logShim) Infof(ctx context.Context, format string, args ...any) {
20+
log.G(ctx).Infof("NRI: "+format, args...)
21+
}
22+
23+
func (nls *logShim) Warnf(ctx context.Context, format string, args ...any) {
24+
log.G(ctx).Warnf("NRI: "+format, args...)
25+
}
26+
27+
func (nls *logShim) Errorf(ctx context.Context, format string, args ...any) {
28+
log.G(ctx).Errorf("NRI: "+format, args...)
29+
}

daemon/internal/nri/nri.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package nri
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"path/filepath"
8+
"sync"
9+
10+
"github.com/containerd/log"
11+
"github.com/containerd/nri/pkg/adaptation"
12+
nrilog "github.com/containerd/nri/pkg/log"
13+
"github.com/moby/moby/v2/daemon/container"
14+
"github.com/moby/moby/v2/daemon/internal/rootless"
15+
"github.com/moby/moby/v2/daemon/pkg/opts"
16+
"github.com/moby/moby/v2/dockerversion"
17+
"github.com/moby/moby/v2/pkg/homedir"
18+
)
19+
20+
const (
21+
// defaultPluginSubdir is the default location for NRI plugins under libexec,
22+
// which is in a different location for rootful/rootless Docker.
23+
defaultPluginSubdir = "docker/nri-plugins"
24+
// defaultPluginConfigSubdir is the default location for NRI plugin config under etc,
25+
// which is in a different location for rootful/rootless Docker.
26+
defaultPluginConfigSubdir = "docker/nri/conf.d"
27+
)
28+
29+
type NRI struct {
30+
cfg Config
31+
32+
// mu protects nri - read lock for container operations, write lock for sync and shutdown.
33+
mu sync.RWMutex
34+
nri *adaptation.Adaptation
35+
}
36+
37+
type ContainerLister interface {
38+
List() []*container.Container
39+
}
40+
41+
type Config struct {
42+
DaemonConfig opts.NRIOpts
43+
ContainerLister ContainerLister
44+
}
45+
46+
func NewNRI(ctx context.Context, cfg Config) (*NRI, error) {
47+
n := &NRI{cfg: cfg}
48+
if !n.cfg.DaemonConfig.Enable {
49+
log.G(ctx).Info("NRI is disabled")
50+
return n, nil
51+
}
52+
53+
if err := setDefaultPaths(&n.cfg.DaemonConfig); err != nil {
54+
return nil, err
55+
}
56+
log.G(ctx).WithFields(log.Fields{
57+
"pluginPath": n.cfg.DaemonConfig.PluginPath,
58+
"pluginConfigPath": n.cfg.DaemonConfig.PluginConfigPath,
59+
"socketPath": n.cfg.DaemonConfig.SocketPath,
60+
}).Info("Starting NRI")
61+
nrilog.Set(&logShim{})
62+
63+
var err error
64+
n.nri, err = adaptation.New("docker", dockerversion.Version, n.syncFn, n.updateFn, nriOptions(n.cfg.DaemonConfig)...)
65+
if err != nil {
66+
return nil, err
67+
}
68+
if err := n.nri.Start(); err != nil {
69+
return nil, err
70+
}
71+
return n, nil
72+
}
73+
74+
func (n *NRI) Shutdown(ctx context.Context) {
75+
n.mu.Lock()
76+
defer n.mu.Unlock()
77+
if n.nri == nil {
78+
return
79+
}
80+
log.G(ctx).Info("Shutting down NRI")
81+
n.nri.Stop()
82+
n.nri = nil
83+
}
84+
85+
func (n *NRI) syncFn(ctx context.Context, syncCB adaptation.SyncCB) error {
86+
return nil
87+
}
88+
89+
func (n *NRI) updateFn(context.Context, []*adaptation.ContainerUpdate) ([]*adaptation.ContainerUpdate, error) {
90+
return nil, errors.New("not implemented")
91+
}
92+
93+
func setDefaultPaths(cfg *opts.NRIOpts) error {
94+
if cfg.PluginPath != "" && cfg.PluginConfigPath != "" {
95+
return nil
96+
}
97+
libexecDir := "/usr/libexec"
98+
etcDir := "/etc"
99+
if rootless.RunningWithRootlessKit() {
100+
var err error
101+
libexecDir, err = homedir.GetLibexecHome()
102+
if err != nil {
103+
return fmt.Errorf("configuring NRI: %w", err)
104+
}
105+
etcDir, err = homedir.GetConfigHome()
106+
if err != nil {
107+
return fmt.Errorf("configuring NRI: %w", err)
108+
}
109+
}
110+
if cfg.PluginPath == "" {
111+
cfg.PluginPath = filepath.Join(libexecDir, defaultPluginSubdir)
112+
}
113+
if cfg.PluginConfigPath == "" {
114+
cfg.PluginConfigPath = filepath.Join(etcDir, defaultPluginConfigSubdir)
115+
}
116+
return nil
117+
}
118+
119+
func nriOptions(cfg opts.NRIOpts) []adaptation.Option {
120+
res := []adaptation.Option{
121+
adaptation.WithPluginPath(cfg.PluginPath),
122+
adaptation.WithPluginConfigPath(cfg.PluginConfigPath),
123+
}
124+
if cfg.SocketPath == "" {
125+
res = append(res, adaptation.WithDisabledExternalConnections())
126+
} else {
127+
res = append(res, adaptation.WithSocketPath(cfg.SocketPath))
128+
}
129+
return res
130+
}

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ require (
2727
github.com/containerd/errdefs v1.0.0
2828
github.com/containerd/fifo v1.1.0
2929
github.com/containerd/log v0.1.0
30+
github.com/containerd/nri v0.10.0
3031
github.com/containerd/platforms v1.0.0-rc.2
3132
github.com/containerd/typeurl/v2 v2.2.3
3233
github.com/coreos/go-systemd/v22 v22.6.0
@@ -194,6 +195,7 @@ require (
194195
github.com/inconshreveable/mousetrap v1.1.0 // indirect
195196
github.com/jmoiron/sqlx v1.3.3 // indirect
196197
github.com/klauspost/compress v1.18.2 // indirect
198+
github.com/knqyf263/go-plugin v0.9.0 // indirect
197199
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
198200
github.com/mitchellh/reflectwalk v1.0.2 // indirect
199201
github.com/moby/sys/capability v0.4.0 // indirect
@@ -215,6 +217,7 @@ require (
215217
github.com/shibumi/go-pathspec v1.3.0 // indirect
216218
github.com/spdx/tools-golang v0.5.5 // indirect
217219
github.com/stretchr/testify v1.11.1 // indirect
220+
github.com/tetratelabs/wazero v1.9.0 // indirect
218221
github.com/tinylib/msgp v1.3.0 // indirect
219222
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 // indirect
220223
github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f // indirect

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ github.com/containerd/go-runc v1.1.0 h1:OX4f+/i2y5sUT7LhmcJH7GYrjjhHa1QI4e8yO0gG
154154
github.com/containerd/go-runc v1.1.0/go.mod h1:xJv2hFF7GvHtTJd9JqTS2UVxMkULUYw4JN5XAUZqH5U=
155155
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
156156
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
157+
github.com/containerd/nri v0.10.0 h1:bt2NzfvlY6OJE0i+fB5WVeGQEycxY7iFVQpEbh7J3Go=
158+
github.com/containerd/nri v0.10.0/go.mod h1:5VyvLa/4uL8FjyO8nis1UjbCutXDpngil17KvBSL6BU=
157159
github.com/containerd/nydus-snapshotter v0.15.4 h1:l59kGRVMtwMLDLh322HsWhEsBCkRKMkGWYV5vBeLYCE=
158160
github.com/containerd/nydus-snapshotter v0.15.4/go.mod h1:eRJqnxQDr48HNop15kZdLZpFF5B6vf6Q11Aq1K0E4Ms=
159161
github.com/containerd/platforms v1.0.0-rc.2 h1:0SPgaNZPVWGEi4grZdV8VRYQn78y+nm6acgLGv/QzE4=
@@ -377,6 +379,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
377379
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
378380
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
379381
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
382+
github.com/knqyf263/go-plugin v0.9.0 h1:CQs2+lOPIlkZVtcb835ZYDEoyyWJWLbSTWeCs0EwTwI=
383+
github.com/knqyf263/go-plugin v0.9.0/go.mod h1:2z5lCO1/pez6qGo8CvCxSlBFSEat4MEp1DrnA+f7w8Q=
380384
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
381385
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
382386
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -598,6 +602,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
598602
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
599603
github.com/tedsuo/ifrit v0.0.0-20230516164442-7862c310ad26 h1:mWCRvpoEMVlslxEvvptKgIUb35va9yj9Oq5wGw/er5I=
600604
github.com/tedsuo/ifrit v0.0.0-20230516164442-7862c310ad26/go.mod h1:0uD3VMXkZ7Bw0ojGCwDzebBBzPBXtzEZeXai+56BLX4=
605+
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
606+
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
601607
github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww=
602608
github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
603609
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 h1:r0p7fK56l8WPequOaR3i9LBqfPtEdXIQbUTzT55iqT4=

pkg/homedir/homedir_linux.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,13 @@ func GetLibHome() (string, error) {
103103
}
104104
return filepath.Join(home, ".local/lib"), nil
105105
}
106+
107+
// GetLibexecHome returns $HOME/.local/libexec
108+
// If HOME is not set, getpwent(3) is consulted to determine the users home directory.
109+
func GetLibexecHome() (string, error) {
110+
home := Get()
111+
if home == "" {
112+
return "", errors.New("could not get HOME")
113+
}
114+
return filepath.Join(home, ".local/libexec"), nil
115+
}

pkg/homedir/homedir_others.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,8 @@ func GetConfigHome() (string, error) {
3030
func GetLibHome() (string, error) {
3131
return "", errors.New("homedir.GetLibHome() is not supported on this system")
3232
}
33+
34+
// GetLibexecHome is unsupported on non-linux system.
35+
func GetLibexecHome() (string, error) {
36+
return "", errors.New("homedir.GetLibexecHome() is not supported on this system")
37+
}

0 commit comments

Comments
 (0)