Merge pull request #9088 from samuelkarp/nri

vendor: update github.com/containerd/nri@v0.4.0
This commit is contained in:
Phil Estes 2023-09-13 10:26:02 -04:00 committed by GitHub
commit 0f52935a53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 956 additions and 657 deletions

2
go.mod
View File

@ -17,7 +17,7 @@ require (
github.com/containerd/go-cni v1.1.9
github.com/containerd/go-runc v1.1.0
github.com/containerd/imgcrypt v1.1.7
github.com/containerd/nri v0.3.0
github.com/containerd/nri v0.4.0
github.com/containerd/ttrpc v1.2.2
github.com/containerd/typeurl/v2 v2.1.1
github.com/containerd/zfs v1.1.0

4
go.sum
View File

@ -270,8 +270,8 @@ github.com/containerd/imgcrypt v1.1.7/go.mod h1:FD8gqIcX5aTotCtOmjeCsi3A1dHmTZpn
github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c=
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
github.com/containerd/nri v0.3.0 h1:2ZM4WImye1ypSnE7COjOvPAiLv84kaPILBDvb1tbDK8=
github.com/containerd/nri v0.3.0/go.mod h1:Zw9q2lP16sdg0zYybemZ9yTDy8g7fPCIB3KXOGlggXI=
github.com/containerd/nri v0.4.0 h1:PjgIBm0RtUiFyEO6JqPBQZRQicbsIz41Fz/5VSC0zgw=
github.com/containerd/nri v0.4.0/go.mod h1:Zw9q2lP16sdg0zYybemZ9yTDy8g7fPCIB3KXOGlggXI=
github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=

View File

@ -898,7 +898,7 @@ github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDX
github.com/containerd/go-runc v1.1.0 h1:OX4f+/i2y5sUT7LhmcJH7GYrjjhHa1QI4e8yO0gGleA=
github.com/containerd/go-runc v1.1.0/go.mod h1:xJv2hFF7GvHtTJd9JqTS2UVxMkULUYw4JN5XAUZqH5U=
github.com/containerd/imgcrypt v1.1.7/go.mod h1:FD8gqIcX5aTotCtOmjeCsi3A1dHmTZpnMISGKSczt4k=
github.com/containerd/nri v0.3.0/go.mod h1:Zw9q2lP16sdg0zYybemZ9yTDy8g7fPCIB3KXOGlggXI=
github.com/containerd/nri v0.4.0/go.mod h1:Zw9q2lP16sdg0zYybemZ9yTDy8g7fPCIB3KXOGlggXI=
github.com/containerd/protobuild v0.3.0/go.mod h1:5mNMFKKAwCIAkFBPiOdtRx2KiQlyEJeMXnL5R1DsWu8=
github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM=
github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=

View File

@ -29,15 +29,17 @@ import (
"testing"
"time"
cri "github.com/containerd/containerd/integration/cri-api/pkg/apis"
"github.com/containerd/nri/pkg/api"
"github.com/containerd/nri/pkg/stub"
"github.com/opencontainers/selinux/go-selinux"
runtime "k8s.io/cri-api/pkg/apis/runtime/v1"
"github.com/containerd/containerd/integration/images"
cri "github.com/containerd/containerd/integration/cri-api/pkg/apis"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/containerd/containerd/integration/images"
)
const (
@ -808,11 +810,11 @@ func (m *mockPlugin) Log(format string, args ...interface{}) {
m.logf(fmt.Sprintf("[plugin:%s-%s] ", m.idx, m.name)+format, args...)
}
func (m *mockPlugin) Configure(cfg string) (stub.EventMask, error) {
func (m *mockPlugin) Configure(ctx context.Context, cfg string) (stub.EventMask, error) {
return m.mask, nil
}
func (m *mockPlugin) Synchronize(pods []*api.PodSandbox, ctrs []*api.Container) ([]*api.ContainerUpdate, error) {
func (m *mockPlugin) Synchronize(ctx context.Context, pods []*api.PodSandbox, ctrs []*api.Container) ([]*api.ContainerUpdate, error) {
m.Log("Synchronize")
for _, pod := range pods {
m.Log(" - pod %s", pod.Id)
@ -828,11 +830,11 @@ func (m *mockPlugin) Synchronize(pods []*api.PodSandbox, ctrs []*api.Container)
return m.synchronize(m, pods, ctrs)
}
func (m *mockPlugin) Shutdown() {
func (m *mockPlugin) Shutdown(ctx context.Context) {
m.Log("Shutdown")
}
func (m *mockPlugin) RunPodSandbox(pod *api.PodSandbox) error {
func (m *mockPlugin) RunPodSandbox(ctx context.Context, pod *api.PodSandbox) error {
if !m.inNamespace(pod.Namespace) {
return nil
}
@ -843,7 +845,7 @@ func (m *mockPlugin) RunPodSandbox(pod *api.PodSandbox) error {
return nil
}
func (m *mockPlugin) StopPodSandbox(pod *api.PodSandbox) error {
func (m *mockPlugin) StopPodSandbox(ctx context.Context, pod *api.PodSandbox) error {
if !m.inNamespace(pod.Namespace) {
return nil
}
@ -854,7 +856,7 @@ func (m *mockPlugin) StopPodSandbox(pod *api.PodSandbox) error {
return nil
}
func (m *mockPlugin) RemovePodSandbox(pod *api.PodSandbox) error {
func (m *mockPlugin) RemovePodSandbox(ctx context.Context, pod *api.PodSandbox) error {
if !m.inNamespace(pod.Namespace) {
return nil
}
@ -865,7 +867,7 @@ func (m *mockPlugin) RemovePodSandbox(pod *api.PodSandbox) error {
return nil
}
func (m *mockPlugin) CreateContainer(pod *api.PodSandbox, ctr *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
func (m *mockPlugin) CreateContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
if !m.inNamespace(pod.Namespace) {
return nil, nil, nil
}
@ -878,7 +880,7 @@ func (m *mockPlugin) CreateContainer(pod *api.PodSandbox, ctr *api.Container) (*
return m.createContainer(m, pod, ctr)
}
func (m *mockPlugin) PostCreateContainer(pod *api.PodSandbox, ctr *api.Container) error {
func (m *mockPlugin) PostCreateContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) error {
if !m.inNamespace(pod.Namespace) {
return nil
}
@ -891,7 +893,7 @@ func (m *mockPlugin) PostCreateContainer(pod *api.PodSandbox, ctr *api.Container
return nil
}
func (m *mockPlugin) StartContainer(pod *api.PodSandbox, ctr *api.Container) error {
func (m *mockPlugin) StartContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) error {
if !m.inNamespace(pod.Namespace) {
return nil
}
@ -903,7 +905,7 @@ func (m *mockPlugin) StartContainer(pod *api.PodSandbox, ctr *api.Container) err
return nil
}
func (m *mockPlugin) PostStartContainer(pod *api.PodSandbox, ctr *api.Container) error {
func (m *mockPlugin) PostStartContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) error {
if !m.inNamespace(pod.Namespace) {
return nil
}
@ -915,7 +917,7 @@ func (m *mockPlugin) PostStartContainer(pod *api.PodSandbox, ctr *api.Container)
return nil
}
func (m *mockPlugin) UpdateContainer(pod *api.PodSandbox, ctr *api.Container) ([]*api.ContainerUpdate, error) {
func (m *mockPlugin) UpdateContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) ([]*api.ContainerUpdate, error) {
if !m.inNamespace(pod.Namespace) {
return nil, nil
}
@ -927,7 +929,7 @@ func (m *mockPlugin) UpdateContainer(pod *api.PodSandbox, ctr *api.Container) ([
return m.updateContainer(m, pod, ctr)
}
func (m *mockPlugin) PostUpdateContainer(pod *api.PodSandbox, ctr *api.Container) error {
func (m *mockPlugin) PostUpdateContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) error {
if !m.inNamespace(pod.Namespace) {
return nil
}
@ -940,7 +942,7 @@ func (m *mockPlugin) PostUpdateContainer(pod *api.PodSandbox, ctr *api.Container
return nil
}
func (m *mockPlugin) StopContainer(pod *api.PodSandbox, ctr *api.Container) ([]*api.ContainerUpdate, error) {
func (m *mockPlugin) StopContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) ([]*api.ContainerUpdate, error) {
if !m.inNamespace(pod.Namespace) {
return nil, nil
}
@ -952,7 +954,7 @@ func (m *mockPlugin) StopContainer(pod *api.PodSandbox, ctr *api.Container) ([]*
return m.stopContainer(m, pod, ctr)
}
func (m *mockPlugin) RemoveContainer(pod *api.PodSandbox, ctr *api.Container) error {
func (m *mockPlugin) RemoveContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) error {
if !m.inNamespace(pod.Namespace) {
return nil
}

1
vendor/github.com/containerd/nri/.gitignore generated vendored Normal file
View File

@ -0,0 +1 @@
build/

View File

@ -117,7 +117,9 @@ $(BIN_PATH)/template: $(wildcard plugins/template/*.go)
# test targets
#
test-gopkgs: ginkgo-tests
test-gopkgs: ginkgo-tests test-ulimits
SKIPPED_PKGS="ulimit-adjuster"
ginkgo-tests:
$(Q)$(GINKGO) run \
@ -129,9 +131,13 @@ ginkgo-tests:
--junit-report junit.xml \
--coverprofile coverprofile \
--succinct \
--skip-package $(SKIPPED_PKGS) \
-r .; \
$(GO_CMD) tool cover -html=$(COVERAGE_PATH)/coverprofile -o $(COVERAGE_PATH)/coverage.html
test-ulimits:
$(Q)$(GO_TEST) -v ./plugins/ulimit-adjuster
codecov: SHELL := $(shell which bash)
codecov:
bash <(curl -s https://codecov.io/bash) -f $(COVERAGE_PATH)/coverprofile
@ -165,13 +171,13 @@ golangci-lint:
#
install-protoc install-protobuf:
$(Q)./scripts/install-protobuf && \
$(Q)./scripts/install-protobuf
install-ttrpc-plugin:
$(Q)$(GO_INSTALL) github.com/containerd/ttrpc/cmd/protoc-gen-go-ttrpc@74421d10189e8c118870d294c9f7f62db2d33ec1
$(Q)$(GO_INSTALL) -mod=mod github.com/containerd/ttrpc/cmd/protoc-gen-go-ttrpc@74421d10189e8c118870d294c9f7f62db2d33ec1
install-protoc-dependencies:
$(Q)$(GO_INSTALL) google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.0
$(Q)$(GO_INSTALL) -mod=mod google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.0
install-ginkgo:
$(Q)$(GO_INSTALL) -mod=mod github.com/onsi/ginkgo/v2/ginkgo

View File

@ -175,6 +175,7 @@ The following pieces of container metadata are available to plugins in NRI:
- environment variables
- mounts
- OCI hooks
- rlimits
- linux
- namespace IDs
- devices
@ -212,6 +213,7 @@ container parameters:
- mounts
- environment variables
- OCI hooks
- rlimits
- linux
- devices
- resources
@ -307,11 +309,65 @@ The following sample plugins exist for NRI:
- [differ](plugins/differ)
- [device injector](plugins/device-injector)
- [OCI hook injector](plugins/hook-injector)
- [ulimit adjuster](plugins/ulimit-adjuster)
- [NRI v0.1.0 plugin adapter](plugins/v010-adapter)
Please see the documentation of these plugins for further details
about what and how each of these plugins can be used for.
## Security Considerations
From a security perspective NRI plugins should be considered part of the
container runtime. NRI does not implement granular access control to the
functionality it offers. Access to NRI is controlled by restricting access
to the systemwide NRI socket. If a process can connect to the NRI socket
and send data, it has access to the full scope of functionality available
via NRI.
In particular this includes
- injection of OCI hooks, which allow for arbitrary execution of processes with the same privilege level as the container runtime
- arbitrary changes to mounts, including new bind-mounts, changes to the proc, sys, mqueue, shm, and tmpfs mounts
- the addition or removal of arbitrary devices
- arbitrary changes to the limits for memory, CPU, block I/O, and RDT resources available, including the ability to deny service by setting limits very low
The same precautions and principles apply to protecting the NRI socket as
to protecting the socket of the runtime itself. Unless it already exists,
NRI itself creates the directory to hold its socket with permissions that
allow access only for the user ID of the runtime process. By default this
limits NRI access to processes running as root (UID 0). Changing the default
socket permissions is strongly advised against. Enabling more permissive
access control to NRI should never be done without fully understanding the
full implications and potential consequences to container security.
### Plugins as Kubernetes DaemonSets
When the runtime manages pods and containers in a Kubernetes cluster, it
is convenient to deploy and manage NRI plugins using Kubernetes DaemonSets.
Among other things, this requires bind-mounting the NRI socket into the
filesystem of a privileged container running the plugin. Similar precautions
apply and the same care should be taken for protecting the NRI socket and
NRI plugins as for the kubelet DeviceManager socket and Kubernetes Device
Plugins.
The cluster configuration should make sure that unauthorized users cannot
bind-mount host directories and create privileged containers which gain
access to these sockets and can act as NRI or Device Plugins. See the
[related documentation](https://kubernetes.io/docs/concepts/security/)
and [best practices](https://kubernetes.io/docs/setup/best-practices/enforcing-pod-security-standards/)
about Kubernetes security.
## API Stability
NRI APIs should not be considered stable yet. We try to avoid unnecessarily
breaking APIs, especially the Stub API which plugins use to interact with NRI.
However, before NRI reaches a stable 1.0.0 release, this is only best effort
and cannot be guaranteed. Meanwhile we do our best to document any API breaking
changes for each release in the [release notes](RELEASES.md).
The current target for a stable v1 API through a 1.0.0 release is the end of
this year.
## Project details
nri is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE).

33
vendor/github.com/containerd/nri/RELEASES.md generated vendored Normal file
View File

@ -0,0 +1,33 @@
# Release Notes
## 0.4.0
- Pass the ttRPC receiving context from the Stub to each NRI request handler
of the plugin.
- Fix Stub/Plugin UpdateContainer interface to pass the resource update to
the UpdateContainer NRI request handler of the plugin as the last argument.
- All plugins need to be updated to reflect the above changes in any NRI
request handler they implement.
- NRI plugins can now add rlimits
## 0.3.0
- Eliminate the global NRI configuration file, replacing any remaining
configuration options with corresponding programmatic options for runtimes.
- Change default socket path from /var/run/nri.sock to /var/run/nri/nri.sock.
- Make plugin timeouts configurable on the runtime side.
- Plugins should be API-compatible between 0.2.0 and 0.3.0, but either the
runtime needs to be configured to use the old NRI socket path, or 0.2.0 plugins
need to be configured to use the new default NRI socket path.
## 0.2.0
- Replace the v0.1.0 CNI like plugin interface with JSON message exchange on
stdin and stdout with external daemon-like plugins and a protobuf-defined
protocol with ttRPC bindings for communicating with the runtime.
- Allow plugins to track the state of (CRI) pods and containers.
- Allow plugins to make changes to a selected subset of container parameters
during container creation, update, and stopping of (other) containers.
- All 0.1.0 plugins are incompatible with 0.2.0, although
[an experimental adapter plugin](plugins/v010-adapter) is provided to bridge
between any existing 0.1.0 plugins and the current NRI APIs.

View File

@ -81,6 +81,7 @@ type (
HugepageLimit = api.HugepageLimit
Hooks = api.Hooks
Hook = api.Hook
POSIXRlimit = api.POSIXRlimit
EventMask = api.EventMask
)

View File

@ -119,7 +119,7 @@ func (r *Adaptation) newLaunchedPlugin(dir, idx, base, cfg string) (p *plugin, r
cmd := exec.Command(filepath.Join(dir, name))
cmd.ExtraFiles = []*os.File{peerFile}
cmd.Env = []string{
api.PluginNameEnvVar + "=" + name,
api.PluginNameEnvVar + "=" + base,
api.PluginIdxEnvVar + "=" + idx,
api.PluginSocketEnvVar + "=3",
}

View File

@ -56,6 +56,9 @@ func collectCreateContainerResult(request *CreateContainerRequest) *result {
if request.Container.Hooks == nil {
request.Container.Hooks = &Hooks{}
}
if request.Container.Rlimits == nil {
request.Container.Rlimits = []*POSIXRlimit{}
}
if request.Container.Linux == nil {
request.Container.Linux = &LinuxContainer{}
}
@ -85,6 +88,7 @@ func collectCreateContainerResult(request *CreateContainerRequest) *result {
Mounts: []*Mount{},
Env: []*KeyValue{},
Hooks: &Hooks{},
Rlimits: []*POSIXRlimit{},
Linux: &LinuxContainerAdjustment{
Devices: []*LinuxDevice{},
Resources: &LinuxResources{
@ -210,6 +214,9 @@ func (r *result) adjust(rpl *ContainerAdjustment, plugin string) error {
return err
}
}
if err := r.adjustRlimits(rpl.Rlimits, plugin); err != nil {
return err
}
return nil
}
@ -659,6 +666,19 @@ func (r *result) adjustCgroupsPath(path, plugin string) error {
return nil
}
func (r *result) adjustRlimits(rlimits []*POSIXRlimit, plugin string) error {
create, id, adjust := r.request.create, r.request.create.Container.Id, r.reply.adjust
for _, l := range rlimits {
if err := r.owners.claimRlimits(id, l.Type, plugin); err != nil {
return err
}
create.Container.Rlimits = append(create.Container.Rlimits, l)
adjust.Rlimits = append(adjust.Rlimits, l)
}
return nil
}
func (r *result) updateResources(reply, u *ContainerUpdate, plugin string) error {
if u.Linux == nil || u.Linux.Resources == nil {
return nil
@ -873,6 +893,7 @@ type owners struct {
rdtClass string
unified map[string]string
cgroupsPath string
rlimits map[string]string
}
func (ro resultOwners) ownersFor(id string) *owners {
@ -980,6 +1001,10 @@ func (ro resultOwners) claimCgroupsPath(id, plugin string) error {
return ro.ownersFor(id).claimCgroupsPath(plugin)
}
func (ro resultOwners) claimRlimits(id, typ, plugin string) error {
return ro.ownersFor(id).claimRlimit(typ, plugin)
}
func (o *owners) claimAnnotation(key, plugin string) error {
if o.annotations == nil {
o.annotations = make(map[string]string)
@ -1183,6 +1208,17 @@ func (o *owners) claimUnified(key, plugin string) error {
return nil
}
func (o *owners) claimRlimit(typ, plugin string) error {
if o.rlimits == nil {
o.rlimits = make(map[string]string)
}
if other, taken := o.rlimits[typ]; taken {
return conflict(plugin, other, "rlimit", typ)
}
o.rlimits[typ] = plugin
return nil
}
func (o *owners) claimCgroupsPath(plugin string) error {
if other := o.cgroupsPath; other != "" {
return conflict(plugin, other, "cgroups path")

View File

@ -103,6 +103,15 @@ func (a *ContainerAdjustment) AddHooks(h *Hooks) {
}
}
func (a *ContainerAdjustment) AddRlimit(typ string, hard, soft uint64) {
a.initRlimits()
a.Rlimits = append(a.Rlimits, &POSIXRlimit{
Type: typ,
Hard: hard,
Soft: soft,
})
}
// AddDevice records the addition of the given device to a container.
func (a *ContainerAdjustment) AddDevice(d *LinuxDevice) {
a.initLinux()
@ -260,6 +269,12 @@ func (a *ContainerAdjustment) initHooks() {
}
}
func (a *ContainerAdjustment) initRlimits() {
if a.Rlimits == nil {
a.Rlimits = []*POSIXRlimit{}
}
}
func (a *ContainerAdjustment) initLinux() {
if a.Linux == nil {
a.Linux = &LinuxContainerAdjustment{}

File diff suppressed because it is too large Load Diff

View File

@ -246,6 +246,7 @@ message Container {
Hooks hooks = 10;
LinuxContainer linux = 11;
uint32 pid = 12; // for NRI v1 emulation
repeated POSIXRlimit rlimits = 13;
}
// Possible container states.
@ -358,6 +359,13 @@ message HugepageLimit {
uint64 limit = 2;
}
// Container rlimits
message POSIXRlimit {
string type = 1;
uint64 hard = 2;
uint64 soft = 3;
}
// Requested adjustments to a container being created.
message ContainerAdjustment {
map<string, string> annotations = 2;
@ -365,6 +373,7 @@ message ContainerAdjustment {
repeated KeyValue env = 4;
Hooks hooks = 5;
LinuxContainerAdjustment linux = 6;
repeated POSIXRlimit rlimits = 7;
}
// Adjustments to (linux) resources.

View File

@ -8,25 +8,27 @@ import (
)
type RuntimeService interface {
RegisterPlugin(ctx context.Context, req *RegisterPluginRequest) (*Empty, error)
UpdateContainers(ctx context.Context, req *UpdateContainersRequest) (*UpdateContainersResponse, error)
RegisterPlugin(context.Context, *RegisterPluginRequest) (*Empty, error)
UpdateContainers(context.Context, *UpdateContainersRequest) (*UpdateContainersResponse, error)
}
func RegisterRuntimeService(srv *ttrpc.Server, svc RuntimeService) {
srv.Register("nri.pkg.api.v1alpha1.Runtime", map[string]ttrpc.Method{
"RegisterPlugin": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req RegisterPluginRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.RegisterPlugin(ctx, &req)
},
"UpdateContainers": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req UpdateContainersRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.UpdateContainers(ctx, &req)
srv.RegisterService("nri.pkg.api.v1alpha1.Runtime", &ttrpc.ServiceDesc{
Methods: map[string]ttrpc.Method{
"RegisterPlugin": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req RegisterPluginRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.RegisterPlugin(ctx, &req)
},
"UpdateContainers": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req UpdateContainersRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.UpdateContainers(ctx, &req)
},
},
})
}
@ -40,6 +42,7 @@ func NewRuntimeClient(client *ttrpc.Client) RuntimeService {
client: client,
}
}
func (c *runtimeClient) RegisterPlugin(ctx context.Context, req *RegisterPluginRequest) (*Empty, error) {
var resp Empty
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Runtime", "RegisterPlugin", req, &resp); err != nil {
@ -47,6 +50,7 @@ func (c *runtimeClient) RegisterPlugin(ctx context.Context, req *RegisterPluginR
}
return &resp, nil
}
func (c *runtimeClient) UpdateContainers(ctx context.Context, req *UpdateContainersRequest) (*UpdateContainersResponse, error) {
var resp UpdateContainersResponse
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Runtime", "UpdateContainers", req, &resp); err != nil {
@ -56,65 +60,67 @@ func (c *runtimeClient) UpdateContainers(ctx context.Context, req *UpdateContain
}
type PluginService interface {
Configure(ctx context.Context, req *ConfigureRequest) (*ConfigureResponse, error)
Synchronize(ctx context.Context, req *SynchronizeRequest) (*SynchronizeResponse, error)
Shutdown(ctx context.Context, req *Empty) (*Empty, error)
CreateContainer(ctx context.Context, req *CreateContainerRequest) (*CreateContainerResponse, error)
UpdateContainer(ctx context.Context, req *UpdateContainerRequest) (*UpdateContainerResponse, error)
StopContainer(ctx context.Context, req *StopContainerRequest) (*StopContainerResponse, error)
StateChange(ctx context.Context, req *StateChangeEvent) (*Empty, error)
Configure(context.Context, *ConfigureRequest) (*ConfigureResponse, error)
Synchronize(context.Context, *SynchronizeRequest) (*SynchronizeResponse, error)
Shutdown(context.Context, *Empty) (*Empty, error)
CreateContainer(context.Context, *CreateContainerRequest) (*CreateContainerResponse, error)
UpdateContainer(context.Context, *UpdateContainerRequest) (*UpdateContainerResponse, error)
StopContainer(context.Context, *StopContainerRequest) (*StopContainerResponse, error)
StateChange(context.Context, *StateChangeEvent) (*Empty, error)
}
func RegisterPluginService(srv *ttrpc.Server, svc PluginService) {
srv.Register("nri.pkg.api.v1alpha1.Plugin", map[string]ttrpc.Method{
"Configure": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req ConfigureRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.Configure(ctx, &req)
},
"Synchronize": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req SynchronizeRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.Synchronize(ctx, &req)
},
"Shutdown": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req Empty
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.Shutdown(ctx, &req)
},
"CreateContainer": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req CreateContainerRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.CreateContainer(ctx, &req)
},
"UpdateContainer": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req UpdateContainerRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.UpdateContainer(ctx, &req)
},
"StopContainer": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req StopContainerRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.StopContainer(ctx, &req)
},
"StateChange": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req StateChangeEvent
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.StateChange(ctx, &req)
srv.RegisterService("nri.pkg.api.v1alpha1.Plugin", &ttrpc.ServiceDesc{
Methods: map[string]ttrpc.Method{
"Configure": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req ConfigureRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.Configure(ctx, &req)
},
"Synchronize": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req SynchronizeRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.Synchronize(ctx, &req)
},
"Shutdown": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req Empty
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.Shutdown(ctx, &req)
},
"CreateContainer": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req CreateContainerRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.CreateContainer(ctx, &req)
},
"UpdateContainer": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req UpdateContainerRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.UpdateContainer(ctx, &req)
},
"StopContainer": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req StopContainerRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.StopContainer(ctx, &req)
},
"StateChange": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req StateChangeEvent
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.StateChange(ctx, &req)
},
},
})
}
@ -128,6 +134,7 @@ func NewPluginClient(client *ttrpc.Client) PluginService {
client: client,
}
}
func (c *pluginClient) Configure(ctx context.Context, req *ConfigureRequest) (*ConfigureResponse, error) {
var resp ConfigureResponse
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "Configure", req, &resp); err != nil {
@ -135,6 +142,7 @@ func (c *pluginClient) Configure(ctx context.Context, req *ConfigureRequest) (*C
}
return &resp, nil
}
func (c *pluginClient) Synchronize(ctx context.Context, req *SynchronizeRequest) (*SynchronizeResponse, error) {
var resp SynchronizeResponse
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "Synchronize", req, &resp); err != nil {
@ -142,6 +150,7 @@ func (c *pluginClient) Synchronize(ctx context.Context, req *SynchronizeRequest)
}
return &resp, nil
}
func (c *pluginClient) Shutdown(ctx context.Context, req *Empty) (*Empty, error) {
var resp Empty
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "Shutdown", req, &resp); err != nil {
@ -149,6 +158,7 @@ func (c *pluginClient) Shutdown(ctx context.Context, req *Empty) (*Empty, error)
}
return &resp, nil
}
func (c *pluginClient) CreateContainer(ctx context.Context, req *CreateContainerRequest) (*CreateContainerResponse, error) {
var resp CreateContainerResponse
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "CreateContainer", req, &resp); err != nil {
@ -156,6 +166,7 @@ func (c *pluginClient) CreateContainer(ctx context.Context, req *CreateContainer
}
return &resp, nil
}
func (c *pluginClient) UpdateContainer(ctx context.Context, req *UpdateContainerRequest) (*UpdateContainerResponse, error) {
var resp UpdateContainerResponse
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "UpdateContainer", req, &resp); err != nil {
@ -163,6 +174,7 @@ func (c *pluginClient) UpdateContainer(ctx context.Context, req *UpdateContainer
}
return &resp, nil
}
func (c *pluginClient) StopContainer(ctx context.Context, req *StopContainerRequest) (*StopContainerResponse, error) {
var resp StopContainerResponse
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "StopContainer", req, &resp); err != nil {
@ -170,6 +182,7 @@ func (c *pluginClient) StopContainer(ctx context.Context, req *StopContainerRequ
}
return &resp, nil
}
func (c *pluginClient) StateChange(ctx context.Context, req *StateChangeEvent) (*Empty, error) {
var resp Empty
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "StateChange", req, &resp); err != nil {

View File

@ -82,14 +82,14 @@ func ParseEventMask(events ...string) (EventMask, error) {
continue
case "pod", "podsandbox":
for name, bit := range bits {
if strings.Contains(name, "Pod") {
if strings.Contains(name, "pod") {
mask.Set(bit)
}
}
continue
case "container":
for name, bit := range bits {
if strings.Contains(name, "Container") {
if strings.Contains(name, "container") {
mask.Set(bit)
}
}

View File

@ -100,7 +100,10 @@ func (r *LinuxResources) ToOCI() *rspec.LinuxResources {
if r == nil {
return nil
}
o := &rspec.LinuxResources{}
o := &rspec.LinuxResources{
CPU: &rspec.LinuxCPU{},
Memory: &rspec.LinuxMemory{},
}
if r.Memory != nil {
o.Memory = &rspec.LinuxMemory{
Limit: r.Memory.Limit.Get(),

View File

@ -119,6 +119,9 @@ func (g *Generator) Adjust(adjust *nri.ContainerAdjustment) error {
if err := g.AdjustMounts(adjust.GetMounts()); err != nil {
return err
}
if err := g.AdjustRlimits(adjust.GetRlimits()); err != nil {
return err
}
return nil
}
@ -320,6 +323,20 @@ func (g *Generator) AdjustDevices(devices []*nri.LinuxDevice) {
}
}
func (g *Generator) AdjustRlimits(rlimits []*nri.POSIXRlimit) error {
for _, l := range rlimits {
if l == nil {
continue
}
g.Config.Process.Rlimits = append(g.Config.Process.Rlimits, rspec.POSIXRlimit{
Type: l.Type,
Hard: l.Hard,
Soft: l.Soft,
})
}
return nil
}
// AdjustMounts adjusts the mounts in the OCI Spec.
func (g *Generator) AdjustMounts(mounts []*nri.Mount) error {
if len(mounts) == 0 {

View File

@ -47,38 +47,38 @@ type ConfigureInterface interface {
// Configure the plugin with the given NRI-supplied configuration.
// If a non-zero EventMask is returned, the plugin will be subscribed
// to the corresponding.
Configure(config, runtime, version string) (api.EventMask, error)
Configure(ctx context.Context, config, runtime, version string) (api.EventMask, error)
}
// SynchronizeInterface handles Synchronize API requests.
type SynchronizeInterface interface {
// Synchronize the state of the plugin with the runtime.
// The plugin can request updates to containers in response.
Synchronize([]*api.PodSandbox, []*api.Container) ([]*api.ContainerUpdate, error)
Synchronize(context.Context, []*api.PodSandbox, []*api.Container) ([]*api.ContainerUpdate, error)
}
// ShutdownInterface handles a Shutdown API request.
type ShutdownInterface interface {
// Shutdown notifies the plugin about the runtime shutting down.
Shutdown(*api.ShutdownRequest)
Shutdown(context.Context)
}
// RunPodInterface handles RunPodSandbox API events.
type RunPodInterface interface {
// RunPodSandbox relays a RunPodSandbox event to the plugin.
RunPodSandbox(*api.PodSandbox) error
RunPodSandbox(context.Context, *api.PodSandbox) error
}
// StopPodInterface handles StopPodSandbox API events.
type StopPodInterface interface {
// StopPodSandbox relays a StopPodSandbox event to the plugin.
StopPodSandbox(*api.PodSandbox) error
StopPodSandbox(context.Context, *api.PodSandbox) error
}
// RemovePodInterface handles RemovePodSandbox API events.
type RemovePodInterface interface {
// RemovePodSandbox relays a RemovePodSandbox event to the plugin.
RemovePodSandbox(*api.PodSandbox) error
RemovePodSandbox(context.Context, *api.PodSandbox) error
}
// CreateContainerInterface handles CreateContainer API requests.
@ -86,13 +86,13 @@ type CreateContainerInterface interface {
// CreateContainer relays a CreateContainer request to the plugin.
// The plugin can request adjustments to the container being created
// and updates to other unstopped containers in response.
CreateContainer(*api.PodSandbox, *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error)
CreateContainer(context.Context, *api.PodSandbox, *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error)
}
// StartContainerInterface handles StartContainer API requests.
type StartContainerInterface interface {
// StartContainer relays a StartContainer event to the plugin.
StartContainer(*api.PodSandbox, *api.Container) error
StartContainer(context.Context, *api.PodSandbox, *api.Container) error
}
// UpdateContainerInterface handles UpdateContainer API requests.
@ -101,38 +101,38 @@ type UpdateContainerInterface interface {
// The plugin can request updates both to the container being updated
// (which then supersedes the original update) and to other unstopped
// containers in response.
UpdateContainer(*api.PodSandbox, *api.Container) ([]*api.ContainerUpdate, error)
UpdateContainer(context.Context, *api.PodSandbox, *api.Container, *api.LinuxResources) ([]*api.ContainerUpdate, error)
}
// StopContainerInterface handles StopContainer API requests.
type StopContainerInterface interface {
// StopContainer relays a StopContainer request to the plugin.
// The plugin can request updates to unstopped containers in response.
StopContainer(*api.PodSandbox, *api.Container) ([]*api.ContainerUpdate, error)
StopContainer(context.Context, *api.PodSandbox, *api.Container) ([]*api.ContainerUpdate, error)
}
// RemoveContainerInterface handles RemoveContainer API events.
type RemoveContainerInterface interface {
// RemoveContainer relays a RemoveContainer event to the plugin.
RemoveContainer(*api.PodSandbox, *api.Container) error
RemoveContainer(context.Context, *api.PodSandbox, *api.Container) error
}
// PostCreateContainerInterface handles PostCreateContainer API events.
type PostCreateContainerInterface interface {
// PostCreateContainer relays a PostCreateContainer event to the plugin.
PostCreateContainer(*api.PodSandbox, *api.Container) error
PostCreateContainer(context.Context, *api.PodSandbox, *api.Container) error
}
// PostStartContainerInterface handles PostStartContainer API events.
type PostStartContainerInterface interface {
// PostStartContainer relays a PostStartContainer event to the plugin.
PostStartContainer(*api.PodSandbox, *api.Container) error
PostStartContainer(context.Context, *api.PodSandbox, *api.Container) error
}
// PostUpdateContainerInterface handles PostUpdateContainer API events.
type PostUpdateContainerInterface interface {
// PostUpdateContainer relays a PostUpdateContainer event to the plugin.
PostUpdateContainer(*api.PodSandbox, *api.Container) error
PostUpdateContainer(context.Context, *api.PodSandbox, *api.Container) error
}
// Stub is the interface the stub provides for the plugin implementation.
@ -253,20 +253,20 @@ type stub struct {
// Handlers for NRI plugin event and request.
type handlers struct {
Configure func(string, string, string) (api.EventMask, error)
Synchronize func([]*api.PodSandbox, []*api.Container) ([]*api.ContainerUpdate, error)
Shutdown func(*api.ShutdownRequest)
RunPodSandbox func(*api.PodSandbox) error
StopPodSandbox func(*api.PodSandbox) error
RemovePodSandbox func(*api.PodSandbox) error
CreateContainer func(*api.PodSandbox, *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error)
StartContainer func(*api.PodSandbox, *api.Container) error
UpdateContainer func(*api.PodSandbox, *api.Container) ([]*api.ContainerUpdate, error)
StopContainer func(*api.PodSandbox, *api.Container) ([]*api.ContainerUpdate, error)
RemoveContainer func(*api.PodSandbox, *api.Container) error
PostCreateContainer func(*api.PodSandbox, *api.Container) error
PostStartContainer func(*api.PodSandbox, *api.Container) error
PostUpdateContainer func(*api.PodSandbox, *api.Container) error
Configure func(context.Context, string, string, string) (api.EventMask, error)
Synchronize func(context.Context, []*api.PodSandbox, []*api.Container) ([]*api.ContainerUpdate, error)
Shutdown func(context.Context)
RunPodSandbox func(context.Context, *api.PodSandbox) error
StopPodSandbox func(context.Context, *api.PodSandbox) error
RemovePodSandbox func(context.Context, *api.PodSandbox) error
CreateContainer func(context.Context, *api.PodSandbox, *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error)
StartContainer func(context.Context, *api.PodSandbox, *api.Container) error
UpdateContainer func(context.Context, *api.PodSandbox, *api.Container, *api.LinuxResources) ([]*api.ContainerUpdate, error)
StopContainer func(context.Context, *api.PodSandbox, *api.Container) ([]*api.ContainerUpdate, error)
RemoveContainer func(context.Context, *api.PodSandbox, *api.Container) error
PostCreateContainer func(context.Context, *api.PodSandbox, *api.Container) error
PostStartContainer func(context.Context, *api.PodSandbox, *api.Container) error
PostUpdateContainer func(context.Context, *api.PodSandbox, *api.Container) error
}
// New creates a stub with the given plugin and options.
@ -290,7 +290,7 @@ func New(p interface{}, opts ...Option) (Stub, error) {
return nil, err
}
if err := stub.getIdentity(); err != nil {
if err := stub.ensureIdentity(); err != nil {
return nil, err
}
@ -552,7 +552,7 @@ func (stub *stub) Configure(ctx context.Context, req *api.ConfigureRequest) (rpl
if handler := stub.handlers.Configure; handler == nil {
events = stub.events
} else {
events, err = handler(req.Config, req.RuntimeName, req.RuntimeVersion)
events, err = handler(ctx, req.Config, req.RuntimeName, req.RuntimeVersion)
if err != nil {
log.Errorf(ctx, "Plugin configuration failed: %v", err)
return nil, err
@ -585,7 +585,7 @@ func (stub *stub) Synchronize(ctx context.Context, req *api.SynchronizeRequest)
if handler == nil {
return &api.SynchronizeResponse{}, nil
}
update, err := handler(req.Pods, req.Containers)
update, err := handler(ctx, req.Pods, req.Containers)
return &api.SynchronizeResponse{
Update: update,
}, err
@ -595,7 +595,7 @@ func (stub *stub) Synchronize(ctx context.Context, req *api.SynchronizeRequest)
func (stub *stub) Shutdown(ctx context.Context, req *api.ShutdownRequest) (*api.ShutdownResponse, error) {
handler := stub.handlers.Shutdown
if handler != nil {
handler(req)
handler(ctx)
}
return &api.ShutdownResponse{}, nil
}
@ -606,7 +606,7 @@ func (stub *stub) CreateContainer(ctx context.Context, req *api.CreateContainerR
if handler == nil {
return nil, nil
}
adjust, update, err := handler(req.Pod, req.Container)
adjust, update, err := handler(ctx, req.Pod, req.Container)
return &api.CreateContainerResponse{
Adjust: adjust,
Update: update,
@ -619,7 +619,7 @@ func (stub *stub) UpdateContainer(ctx context.Context, req *api.UpdateContainerR
if handler == nil {
return nil, nil
}
update, err := handler(req.Pod, req.Container)
update, err := handler(ctx, req.Pod, req.Container, req.LinuxResources)
return &api.UpdateContainerResponse{
Update: update,
}, err
@ -631,7 +631,7 @@ func (stub *stub) StopContainer(ctx context.Context, req *api.StopContainerReque
if handler == nil {
return nil, nil
}
update, err := handler(req.Pod, req.Container)
update, err := handler(ctx, req.Pod, req.Container)
return &api.StopContainerResponse{
Update: update,
}, err
@ -643,43 +643,43 @@ func (stub *stub) StateChange(ctx context.Context, evt *api.StateChangeEvent) (*
switch evt.Event {
case api.Event_RUN_POD_SANDBOX:
if handler := stub.handlers.RunPodSandbox; handler != nil {
err = handler(evt.Pod)
err = handler(ctx, evt.Pod)
}
case api.Event_STOP_POD_SANDBOX:
if handler := stub.handlers.StopPodSandbox; handler != nil {
err = handler(evt.Pod)
err = handler(ctx, evt.Pod)
}
case api.Event_REMOVE_POD_SANDBOX:
if handler := stub.handlers.RemovePodSandbox; handler != nil {
err = handler(evt.Pod)
err = handler(ctx, evt.Pod)
}
case api.Event_POST_CREATE_CONTAINER:
if handler := stub.handlers.PostCreateContainer; handler != nil {
err = handler(evt.Pod, evt.Container)
err = handler(ctx, evt.Pod, evt.Container)
}
case api.Event_START_CONTAINER:
if handler := stub.handlers.StartContainer; handler != nil {
err = handler(evt.Pod, evt.Container)
err = handler(ctx, evt.Pod, evt.Container)
}
case api.Event_POST_START_CONTAINER:
if handler := stub.handlers.PostStartContainer; handler != nil {
err = handler(evt.Pod, evt.Container)
err = handler(ctx, evt.Pod, evt.Container)
}
case api.Event_POST_UPDATE_CONTAINER:
if handler := stub.handlers.PostUpdateContainer; handler != nil {
err = handler(evt.Pod, evt.Container)
err = handler(ctx, evt.Pod, evt.Container)
}
case api.Event_REMOVE_CONTAINER:
if handler := stub.handlers.RemoveContainer; handler != nil {
err = handler(evt.Pod, evt.Container)
err = handler(ctx, evt.Pod, evt.Container)
}
}
return &api.StateChangeResponse{}, err
}
// getIdentity gets plugin index and name from the binary if those are unset.
func (stub *stub) getIdentity() error {
// ensureIdentity sets plugin index and name from the binary if those are unset.
func (stub *stub) ensureIdentity() error {
if stub.idx != "" && stub.name != "" {
return nil
}

2
vendor/modules.txt vendored
View File

@ -127,7 +127,7 @@ github.com/containerd/go-runc
## explicit; go 1.16
github.com/containerd/imgcrypt
github.com/containerd/imgcrypt/images/encryption
# github.com/containerd/nri v0.3.0
# github.com/containerd/nri v0.4.0
## explicit; go 1.19
github.com/containerd/nri
github.com/containerd/nri/pkg/adaptation