blob: 656d9b2ee3ddf1146d6d4e5c1cfca088b240b44b [file] [edit]
/*
Based on https://github.com/containerd/nri/blob/main/plugins/template/ - which is ...
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package nri
import (
"context"
"errors"
"testing"
"github.com/containerd/log"
"github.com/containerd/nri/pkg/api"
"github.com/containerd/nri/pkg/stub"
"gotest.tools/v3/assert"
)
type builtinPluginConfig struct {
pluginName string
pluginIdx string
sockPath string
ctrCreateAdj *api.ContainerAdjustment
}
type builtinPlugin struct {
stub stub.Stub
logG func(context.Context) *log.Entry
config builtinPluginConfig
}
// startBuiltinPlugin turns the test binary into an NRI plugin, or fails the test.
// It is the caller's responsibility to call the returned function to stop the plugin.
func startBuiltinPlugin(ctx context.Context, t *testing.T, cfg builtinPluginConfig) func() {
p := &builtinPlugin{
logG: func(ctx context.Context) *log.Entry {
return log.G(ctx).WithField("nri-plugin", cfg.pluginIdx+"-"+cfg.pluginName)
},
config: cfg,
}
stub, err := stub.New(p,
stub.WithOnClose(p.onClose),
stub.WithPluginName(cfg.pluginName),
stub.WithPluginIdx(cfg.pluginIdx),
stub.WithSocketPath(cfg.sockPath),
)
assert.Assert(t, err)
p.stub = stub
err = p.stub.Start(ctx)
assert.Assert(t, err)
return p.stub.Stop
}
func (p *builtinPlugin) Configure(ctx context.Context, config, runtime, version string) (stub.EventMask, error) {
p.logG(ctx).Infof("Connected to %s/%s...", runtime, version)
if config != "" {
return 0, errors.New("plugin config from yaml is not implemented")
}
return 0, nil
}
func (p *builtinPlugin) Synchronize(ctx context.Context, pods []*api.PodSandbox, containers []*api.Container) ([]*api.ContainerUpdate, error) {
p.logG(ctx).Infof("Synchronized state with the runtime (%d pods, %d containers)...",
len(pods), len(containers))
return nil, nil
}
func (p *builtinPlugin) Shutdown(ctx context.Context) {
p.logG(ctx).Info("Runtime shutting down...")
}
func (p *builtinPlugin) RunPodSandbox(ctx context.Context, pod *api.PodSandbox) error {
p.logG(ctx).Infof("Started pod %s/%s...", pod.GetNamespace(), pod.GetName())
return nil
}
func (p *builtinPlugin) StopPodSandbox(ctx context.Context, pod *api.PodSandbox) error {
p.logG(ctx).Infof("Stopped pod %s/%s...", pod.GetNamespace(), pod.GetName())
return nil
}
func (p *builtinPlugin) RemovePodSandbox(ctx context.Context, pod *api.PodSandbox) error {
p.logG(ctx).Infof("Removed pod %s/%s...", pod.GetNamespace(), pod.GetName())
return nil
}
func (p *builtinPlugin) CreateContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
p.logG(ctx).Infof("Creating container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
//
// This is the container creation request handler. Because the container
// has not been created yet, this is the lifecycle event which allows you
// the largest set of changes to the container's configuration, including
// some of the later immutable parameters. Take a look at the adjustment
// functions in pkg/api/adjustment.go to see the available controls.
//
// In addition to reconfiguring the container being created, you are also
// allowed to update other existing containers. Take a look at the update
// functions in pkg/api/update.go to see the available controls.
//
return p.config.ctrCreateAdj, []*api.ContainerUpdate{}, nil
}
func (p *builtinPlugin) PostCreateContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) error {
p.logG(ctx).Infof("Created container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
return nil
}
func (p *builtinPlugin) StartContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) error {
p.logG(ctx).Infof("Starting container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
return nil
}
func (p *builtinPlugin) PostStartContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) error {
p.logG(ctx).Infof("Started container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
return nil
}
func (p *builtinPlugin) UpdateContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container, r *api.LinuxResources) ([]*api.ContainerUpdate, error) {
p.logG(ctx).Infof("Updating container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
//
// This is the container update request handler. You can make changes to
// the container update before it is applied. Take a look at the functions
// in pkg/api/update.go to see the available controls.
//
// In addition to altering the pending update itself, you are also allowed
// to update other existing containers.
//
updates := []*api.ContainerUpdate{}
return updates, nil
}
func (p *builtinPlugin) PostUpdateContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) error {
p.logG(ctx).Infof("Updated container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
return nil
}
func (p *builtinPlugin) StopContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) ([]*api.ContainerUpdate, error) {
p.logG(ctx).Infof("Stopped container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
//
// This is the container (post-)stop request handler. You can update any
// of the remaining running containers. Take a look at the functions in
// pkg/api/update.go to see the available controls.
//
return []*api.ContainerUpdate{}, nil
}
func (p *builtinPlugin) RemoveContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) error {
p.logG(ctx).Infof("Removed container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
return nil
}
func (p *builtinPlugin) onClose() {
p.logG(context.Background()).Infof("Connection to the runtime lost.")
}