Kaynağa Gözat

Merge pull request #24760 from anusha-ragunathan/plugin-events

Make daemon events listen for plugin lifecycle events.
Michael Crosby 9 yıl önce
ebeveyn
işleme
297745b1cd

+ 0 - 4
cmd/dockerd/daemon.go

@@ -262,10 +262,6 @@ func (cli *DaemonCli) start() (err error) {
 		<-stopc // wait for daemonCli.start() to return
 	})
 
-	if err := pluginInit(cli.Config, containerdRemote, registryService); err != nil {
-		return err
-	}
-
 	d, err := daemon.NewDaemon(cli.Config, registryService, containerdRemote)
 	if err != nil {
 		return fmt.Errorf("Error starting daemon: %v", err)

+ 0 - 13
cmd/dockerd/daemon_no_plugin_support.go

@@ -1,13 +0,0 @@
-// +build !experimental !linux
-
-package main
-
-import (
-	"github.com/docker/docker/daemon"
-	"github.com/docker/docker/libcontainerd"
-	"github.com/docker/docker/registry"
-)
-
-func pluginInit(config *daemon.Config, remote libcontainerd.Remote, rs registry.Service) error {
-	return nil
-}

+ 0 - 14
cmd/dockerd/daemon_plugin_support.go

@@ -1,14 +0,0 @@
-// +build linux,experimental
-
-package main
-
-import (
-	"github.com/docker/docker/daemon"
-	"github.com/docker/docker/libcontainerd"
-	"github.com/docker/docker/plugin"
-	"github.com/docker/docker/registry"
-)
-
-func pluginInit(config *daemon.Config, remote libcontainerd.Remote, rs registry.Service) error {
-	return plugin.Init(config.Root, remote, rs, config.LiveRestore)
-}

+ 4 - 0
daemon/daemon.go

@@ -604,6 +604,10 @@ func NewDaemon(config *Config, registryService registry.Service, containerdRemot
 		return nil, err
 	}
 
+	if err := pluginInit(d, config, containerdRemote); err != nil {
+		return nil, err
+	}
+
 	return d, nil
 }
 

+ 11 - 1
daemon/daemon_experimental.go

@@ -3,6 +3,7 @@
 package daemon
 
 import (
+	"github.com/docker/docker/libcontainerd"
 	"github.com/docker/docker/plugin"
 	"github.com/docker/engine-api/types/container"
 )
@@ -11,6 +12,15 @@ func (daemon *Daemon) verifyExperimentalContainerSettings(hostConfig *container.
 	return nil, nil
 }
 
+func pluginInit(d *Daemon, cfg *Config, remote libcontainerd.Remote) error {
+	return plugin.Init(cfg.Root, remote, d.RegistryService, cfg.LiveRestore, d.LogPluginEvent)
+}
+
 func pluginShutdown() {
-	plugin.GetManager().Shutdown()
+	manager := plugin.GetManager()
+	// Check for a valid manager object. In error conditions, daemon init can fail
+	// and shutdown called, before plugin manager is initialized.
+	if manager != nil {
+		manager.Shutdown()
+	}
 }

+ 8 - 1
daemon/daemon_stub.go

@@ -2,11 +2,18 @@
 
 package daemon
 
-import "github.com/docker/engine-api/types/container"
+import (
+	"github.com/docker/docker/libcontainerd"
+	"github.com/docker/engine-api/types/container"
+)
 
 func (daemon *Daemon) verifyExperimentalContainerSettings(hostConfig *container.HostConfig, config *container.Config) ([]string, error) {
 	return nil, nil
 }
 
+func pluginInit(d *Daemon, config *Config, remote libcontainerd.Remote) error {
+	return nil
+}
+
 func pluginShutdown() {
 }

+ 15 - 0
daemon/events.go

@@ -55,6 +55,21 @@ func (daemon *Daemon) LogImageEventWithAttributes(imageID, refName, action strin
 	daemon.EventsService.Log(action, events.ImageEventType, actor)
 }
 
+// LogPluginEvent generates an event related to a plugin with only the default attributes.
+func (daemon *Daemon) LogPluginEvent(pluginID, refName, action string) {
+	daemon.LogPluginEventWithAttributes(pluginID, refName, action, map[string]string{})
+}
+
+// LogPluginEventWithAttributes generates an event related to a plugin with specific given attributes.
+func (daemon *Daemon) LogPluginEventWithAttributes(pluginID, refName, action string, attributes map[string]string) {
+	attributes["name"] = refName
+	actor := events.Actor{
+		ID:         pluginID,
+		Attributes: attributes,
+	}
+	daemon.EventsService.Log(action, events.PluginEventType, actor)
+}
+
 // LogVolumeEvent generates an event related to a volume.
 func (daemon *Daemon) LogVolumeEvent(volumeID, action string, attributes map[string]string) {
 	actor := events.Actor{

+ 5 - 0
daemon/events/filter.go

@@ -22,6 +22,7 @@ func (ef *Filter) Include(ev events.Message) bool {
 		ef.filter.ExactMatch("type", ev.Type) &&
 		ef.matchDaemon(ev) &&
 		ef.matchContainer(ev) &&
+		ef.matchPlugin(ev) &&
 		ef.matchVolume(ev) &&
 		ef.matchNetwork(ev) &&
 		ef.matchImage(ev) &&
@@ -43,6 +44,10 @@ func (ef *Filter) matchContainer(ev events.Message) bool {
 	return ef.fuzzyMatchName(ev, events.ContainerEventType)
 }
 
+func (ef *Filter) matchPlugin(ev events.Message) bool {
+	return ef.fuzzyMatchName(ev, events.PluginEventType)
+}
+
 func (ef *Filter) matchVolume(ev events.Message) bool {
 	return ef.fuzzyMatchName(ev, events.VolumeEventType)
 }

+ 9 - 0
docs/reference/commandline/events.md

@@ -30,6 +30,10 @@ Docker images report the following events:
 
     delete, import, load, pull, push, save, tag, untag
 
+Docker plugins(experimental) report the following events:
+
+    install, enable, disable, remove
+
 Docker volumes report the following events:
 
     create, mount, unmount, destroy
@@ -74,6 +78,7 @@ The currently supported filters are:
 * container (`container=<name or id>`)
 * event (`event=<event action>`)
 * image (`image=<tag or id>`)
+* plugin (experimental) (`plugin=<name or id>`)
 * label (`label=<key>` or `label=<key>=<value>`)
 * type (`type=<container or image or volume or network or daemon>`)
 * volume (`volume=<name or id>`)
@@ -171,3 +176,7 @@ relative to the current time on the client machine:
     $ docker events --filter 'type=network'
     2015-12-23T21:38:24.705709133Z network create 8b111217944ba0ba844a65b13efcd57dc494932ee2527577758f939315ba2c5b (name=test-event-network-local, type=bridge)
     2015-12-23T21:38:25.119625123Z network connect 8b111217944ba0ba844a65b13efcd57dc494932ee2527577758f939315ba2c5b (name=test-event-network-local, container=b4be644031a3d90b400f88ab3d4bdf4dc23adb250e696b6328b85441abe2c54e, type=bridge)
+
+    $ docker events --filter 'type=plugin' (experimental)
+    2016-07-25T17:30:14.825557616Z plugin pull ec7b87f2ce84330fe076e666f17dfc049d2d7ae0b8190763de94e1f2d105993f (name=tiborvass/no-remove:latest)
+    2016-07-25T17:30:14.888127370Z plugin enable ec7b87f2ce84330fe076e666f17dfc049d2d7ae0b8190763de94e1f2d105993f (name=tiborvass/no-remove:latest)

+ 26 - 0
integration-cli/docker_cli_events_test.go

@@ -297,6 +297,32 @@ func (s *DockerSuite) TestEventsImageLoad(c *check.C) {
 	c.Assert(matches["action"], checker.Equals, "save", check.Commentf("matches: %v\nout:\n%s\n", matches, out))
 }
 
+func (s *DockerSuite) TestEventsPluginOps(c *check.C) {
+	testRequires(c, DaemonIsLinux, ExperimentalDaemon)
+
+	pluginName := "tiborvass/no-remove:latest"
+	since := daemonUnixTime(c)
+
+	dockerCmd(c, "plugin", "install", pluginName, "--grant-all-permissions")
+	dockerCmd(c, "plugin", "disable", pluginName)
+	dockerCmd(c, "plugin", "remove", pluginName)
+
+	out, _ := dockerCmd(c, "events", "--since", since, "--until", daemonUnixTime(c))
+	events := strings.Split(out, "\n")
+	events = events[:len(events)-1]
+
+	nEvents := len(events)
+	c.Assert(nEvents, checker.GreaterOrEqualThan, 4)
+
+	pluginEvents := eventActionsByIDAndType(c, events, pluginName, "plugin")
+	c.Assert(pluginEvents, checker.HasLen, 4, check.Commentf("events: %v", events))
+
+	c.Assert(pluginEvents[0], checker.Equals, "pull", check.Commentf(out))
+	c.Assert(pluginEvents[1], checker.Equals, "enable", check.Commentf(out))
+	c.Assert(pluginEvents[2], checker.Equals, "disable", check.Commentf(out))
+	c.Assert(pluginEvents[3], checker.Equals, "remove", check.Commentf(out))
+}
+
 func (s *DockerSuite) TestEventsFilters(c *check.C) {
 	since := daemonUnixTime(c)
 	dockerCmd(c, "run", "--rm", "busybox", "true")

+ 21 - 8
plugin/backend.go

@@ -22,7 +22,11 @@ func (pm *Manager) Disable(name string) error {
 	if err != nil {
 		return err
 	}
-	return pm.disable(p)
+	if err := pm.disable(p); err != nil {
+		return err
+	}
+	pm.pluginEventLogger(p.PluginObj.ID, name, "disable")
+	return nil
 }
 
 // Enable activates a plugin, which implies that they are ready to be used by containers.
@@ -31,7 +35,11 @@ func (pm *Manager) Enable(name string) error {
 	if err != nil {
 		return err
 	}
-	return pm.enable(p)
+	if err := pm.enable(p); err != nil {
+		return err
+	}
+	pm.pluginEventLogger(p.PluginObj.ID, name, "enable")
+	return nil
 }
 
 // Inspect examines a plugin manifest
@@ -40,10 +48,10 @@ func (pm *Manager) Inspect(name string) (tp types.Plugin, err error) {
 	if err != nil {
 		return tp, err
 	}
-	return p.P, nil
+	return p.PluginObj, nil
 }
 
-// Pull pulls a plugin and enables it.
+// Pull pulls a plugin and computes the privileges required to install it.
 func (pm *Manager) Pull(name string, metaHeader http.Header, authConfig *types.AuthConfig) (types.PluginPrivileges, error) {
 	ref, err := reference.ParseNamed(name)
 	if err != nil {
@@ -86,14 +94,15 @@ func (pm *Manager) Pull(name string, metaHeader http.Header, authConfig *types.A
 	pm.save()
 	pm.Unlock()
 
-	return computePrivileges(&p.P.Manifest), nil
+	pm.pluginEventLogger(pluginID, name, "pull")
+	return computePrivileges(&p.PluginObj.Manifest), nil
 }
 
 // List displays the list of plugins and associated metadata.
 func (pm *Manager) List() ([]types.Plugin, error) {
 	out := make([]types.Plugin, 0, len(pm.plugins))
 	for _, p := range pm.plugins {
-		out = append(out, p.P)
+		out = append(out, p.PluginObj)
 	}
 	return out, nil
 }
@@ -104,7 +113,7 @@ func (pm *Manager) Push(name string, metaHeader http.Header, authConfig *types.A
 	if err != nil {
 		return err
 	}
-	dest := filepath.Join(pm.libRoot, p.P.ID)
+	dest := filepath.Join(pm.libRoot, p.PluginObj.ID)
 	config, err := os.Open(filepath.Join(dest, "manifest.json"))
 	if err != nil {
 		return err
@@ -127,7 +136,11 @@ func (pm *Manager) Remove(name string) error {
 	if err != nil {
 		return err
 	}
-	return pm.remove(p)
+	if err := pm.remove(p); err != nil {
+		return err
+	}
+	pm.pluginEventLogger(p.PluginObj.ID, name, "remove")
+	return nil
 }
 
 // Set sets plugin args

+ 47 - 44
plugin/manager.go

@@ -43,7 +43,7 @@ func (e ErrInadequateCapability) Error() string {
 
 type plugin struct {
 	//sync.RWMutex TODO
-	P                 types.Plugin `json:"plugin"`
+	PluginObj         types.Plugin `json:"plugin"`
 	client            *plugins.Client
 	restartManager    restartmanager.RestartManager
 	runtimeSourcePath string
@@ -60,51 +60,53 @@ func (p *plugin) IsLegacy() bool {
 }
 
 func (p *plugin) Name() string {
-	name := p.P.Name
-	if len(p.P.Tag) > 0 {
+	name := p.PluginObj.Name
+	if len(p.PluginObj.Tag) > 0 {
 		// TODO: this feels hacky, maybe we should be storing the distribution reference rather than splitting these
-		name += ":" + p.P.Tag
+		name += ":" + p.PluginObj.Tag
 	}
 	return name
 }
 
 func (pm *Manager) newPlugin(ref reference.Named, id string) *plugin {
 	p := &plugin{
-		P: types.Plugin{
+		PluginObj: types.Plugin{
 			Name: ref.Name(),
 			ID:   id,
 		},
 		runtimeSourcePath: filepath.Join(pm.runRoot, id),
 	}
 	if ref, ok := ref.(reference.NamedTagged); ok {
-		p.P.Tag = ref.Tag()
+		p.PluginObj.Tag = ref.Tag()
 	}
 	return p
 }
 
 func (pm *Manager) restorePlugin(p *plugin) error {
-	p.runtimeSourcePath = filepath.Join(pm.runRoot, p.P.ID)
-	if p.P.Active {
+	p.runtimeSourcePath = filepath.Join(pm.runRoot, p.PluginObj.ID)
+	if p.PluginObj.Active {
 		return pm.restore(p)
 	}
 	return nil
 }
 
 type pluginMap map[string]*plugin
+type eventLogger func(id, name, action string)
 
 // Manager controls the plugin subsystem.
 type Manager struct {
 	sync.RWMutex
-	libRoot          string
-	runRoot          string
-	plugins          pluginMap // TODO: figure out why save() doesn't json encode *plugin object
-	nameToID         map[string]string
-	handlers         map[string]func(string, *plugins.Client)
-	containerdClient libcontainerd.Client
-	registryService  registry.Service
-	handleLegacy     bool
-	liveRestore      bool
-	shutdown         bool
+	libRoot           string
+	runRoot           string
+	plugins           pluginMap // TODO: figure out why save() doesn't json encode *plugin object
+	nameToID          map[string]string
+	handlers          map[string]func(string, *plugins.Client)
+	containerdClient  libcontainerd.Client
+	registryService   registry.Service
+	handleLegacy      bool
+	liveRestore       bool
+	shutdown          bool
+	pluginEventLogger eventLogger
 }
 
 // GetManager returns the singleton plugin Manager
@@ -114,21 +116,22 @@ func GetManager() *Manager {
 
 // Init (was NewManager) instantiates the singleton Manager.
 // TODO: revert this to NewManager once we get rid of all the singletons.
-func Init(root string, remote libcontainerd.Remote, rs registry.Service, liveRestore bool) (err error) {
+func Init(root string, remote libcontainerd.Remote, rs registry.Service, liveRestore bool, evL eventLogger) (err error) {
 	if manager != nil {
 		return nil
 	}
 
 	root = filepath.Join(root, "plugins")
 	manager = &Manager{
-		libRoot:         root,
-		runRoot:         "/run/docker",
-		plugins:         make(map[string]*plugin),
-		nameToID:        make(map[string]string),
-		handlers:        make(map[string]func(string, *plugins.Client)),
-		registryService: rs,
-		handleLegacy:    true,
-		liveRestore:     liveRestore,
+		libRoot:           root,
+		runRoot:           "/run/docker",
+		plugins:           make(map[string]*plugin),
+		nameToID:          make(map[string]string),
+		handlers:          make(map[string]func(string, *plugins.Client)),
+		registryService:   rs,
+		handleLegacy:      true,
+		liveRestore:       liveRestore,
+		pluginEventLogger: evL,
 	}
 	if err := os.MkdirAll(manager.runRoot, 0700); err != nil {
 		return err
@@ -180,7 +183,7 @@ func FindWithCapability(capability string) ([]Plugin, error) {
 		defer manager.RUnlock()
 	pluginLoop:
 		for _, p := range manager.plugins {
-			for _, typ := range p.P.Manifest.Interface.Types {
+			for _, typ := range p.PluginObj.Manifest.Interface.Types {
 				if typ.Capability != capability || typ.Prefix != "docker" {
 					continue pluginLoop
 				}
@@ -242,7 +245,7 @@ func LookupWithCapability(name, capability string) (Plugin, error) {
 	}
 
 	capability = strings.ToLower(capability)
-	for _, typ := range p.P.Manifest.Interface.Types {
+	for _, typ := range p.PluginObj.Manifest.Interface.Types {
 		if typ.Capability == capability && typ.Prefix == "docker" {
 			return p, nil
 		}
@@ -312,8 +315,8 @@ func (pm *Manager) init() error {
 			}
 
 			pm.Lock()
-			pm.nameToID[p.Name()] = p.P.ID
-			requiresManualRestore := !pm.liveRestore && p.P.Active
+			pm.nameToID[p.Name()] = p.PluginObj.ID
+			requiresManualRestore := !pm.liveRestore && p.PluginObj.Active
 			pm.Unlock()
 
 			if requiresManualRestore {
@@ -329,44 +332,44 @@ func (pm *Manager) init() error {
 }
 
 func (pm *Manager) initPlugin(p *plugin) error {
-	dt, err := os.Open(filepath.Join(pm.libRoot, p.P.ID, "manifest.json"))
+	dt, err := os.Open(filepath.Join(pm.libRoot, p.PluginObj.ID, "manifest.json"))
 	if err != nil {
 		return err
 	}
-	err = json.NewDecoder(dt).Decode(&p.P.Manifest)
+	err = json.NewDecoder(dt).Decode(&p.PluginObj.Manifest)
 	dt.Close()
 	if err != nil {
 		return err
 	}
 
-	p.P.Config.Mounts = make([]types.PluginMount, len(p.P.Manifest.Mounts))
-	for i, mount := range p.P.Manifest.Mounts {
-		p.P.Config.Mounts[i] = mount
+	p.PluginObj.Config.Mounts = make([]types.PluginMount, len(p.PluginObj.Manifest.Mounts))
+	for i, mount := range p.PluginObj.Manifest.Mounts {
+		p.PluginObj.Config.Mounts[i] = mount
 	}
-	p.P.Config.Env = make([]string, 0, len(p.P.Manifest.Env))
-	for _, env := range p.P.Manifest.Env {
+	p.PluginObj.Config.Env = make([]string, 0, len(p.PluginObj.Manifest.Env))
+	for _, env := range p.PluginObj.Manifest.Env {
 		if env.Value != nil {
-			p.P.Config.Env = append(p.P.Config.Env, fmt.Sprintf("%s=%s", env.Name, *env.Value))
+			p.PluginObj.Config.Env = append(p.PluginObj.Config.Env, fmt.Sprintf("%s=%s", env.Name, *env.Value))
 		}
 	}
-	copy(p.P.Config.Args, p.P.Manifest.Args.Value)
+	copy(p.PluginObj.Config.Args, p.PluginObj.Manifest.Args.Value)
 
-	f, err := os.Create(filepath.Join(pm.libRoot, p.P.ID, "plugin-config.json"))
+	f, err := os.Create(filepath.Join(pm.libRoot, p.PluginObj.ID, "plugin-config.json"))
 	if err != nil {
 		return err
 	}
-	err = json.NewEncoder(f).Encode(&p.P.Config)
+	err = json.NewEncoder(f).Encode(&p.PluginObj.Config)
 	f.Close()
 	return err
 }
 
 func (pm *Manager) remove(p *plugin) error {
-	if p.P.Active {
+	if p.PluginObj.Active {
 		return fmt.Errorf("plugin %s is active", p.Name())
 	}
 	pm.Lock() // fixme: lock single record
 	defer pm.Unlock()
-	delete(pm.plugins, p.P.ID)
+	delete(pm.plugins, p.PluginObj.ID)
 	delete(pm.nameToID, p.Name())
 	pm.save()
 	return nil

+ 20 - 20
plugin/manager_linux.go

@@ -21,7 +21,7 @@ import (
 )
 
 func (pm *Manager) enable(p *plugin) error {
-	if p.P.Active {
+	if p.PluginObj.Active {
 		return fmt.Errorf("plugin %s is already enabled", p.Name())
 	}
 	spec, err := pm.initSpec(p)
@@ -30,14 +30,14 @@ func (pm *Manager) enable(p *plugin) error {
 	}
 
 	p.restartManager = restartmanager.New(container.RestartPolicy{Name: "always"}, 0)
-	if err := pm.containerdClient.Create(p.P.ID, libcontainerd.Spec(*spec), libcontainerd.WithRestartManager(p.restartManager)); err != nil { // POC-only
+	if err := pm.containerdClient.Create(p.PluginObj.ID, libcontainerd.Spec(*spec), libcontainerd.WithRestartManager(p.restartManager)); err != nil { // POC-only
 		if err := p.restartManager.Cancel(); err != nil {
 			logrus.Errorf("enable: restartManager.Cancel failed due to %v", err)
 		}
 		return err
 	}
 
-	socket := p.P.Manifest.Interface.Socket
+	socket := p.PluginObj.Manifest.Interface.Socket
 	p.client, err = plugins.NewClient("unix://"+filepath.Join(p.runtimeSourcePath, socket), nil)
 	if err != nil {
 		if err := p.restartManager.Cancel(); err != nil {
@@ -47,11 +47,11 @@ func (pm *Manager) enable(p *plugin) error {
 	}
 
 	pm.Lock() // fixme: lock single record
-	p.P.Active = true
+	p.PluginObj.Active = true
 	pm.save()
 	pm.Unlock()
 
-	for _, typ := range p.P.Manifest.Interface.Types {
+	for _, typ := range p.PluginObj.Manifest.Interface.Types {
 		if handler := pm.handlers[typ.String()]; handler != nil {
 			handler(p.Name(), p.Client())
 		}
@@ -62,19 +62,19 @@ func (pm *Manager) enable(p *plugin) error {
 
 func (pm *Manager) restore(p *plugin) error {
 	p.restartManager = restartmanager.New(container.RestartPolicy{Name: "always"}, 0)
-	return pm.containerdClient.Restore(p.P.ID, libcontainerd.WithRestartManager(p.restartManager))
+	return pm.containerdClient.Restore(p.PluginObj.ID, libcontainerd.WithRestartManager(p.restartManager))
 }
 
 func (pm *Manager) initSpec(p *plugin) (*specs.Spec, error) {
 	s := oci.DefaultSpec()
 
-	rootfs := filepath.Join(pm.libRoot, p.P.ID, "rootfs")
+	rootfs := filepath.Join(pm.libRoot, p.PluginObj.ID, "rootfs")
 	s.Root = specs.Root{
 		Path:     rootfs,
 		Readonly: false, // TODO: all plugins should be readonly? settable in manifest?
 	}
 
-	mounts := append(p.P.Config.Mounts, types.PluginMount{
+	mounts := append(p.PluginObj.Config.Mounts, types.PluginMount{
 		Source:      &p.runtimeSourcePath,
 		Destination: defaultPluginRuntimeDestination,
 		Type:        "bind",
@@ -104,12 +104,12 @@ func (pm *Manager) initSpec(p *plugin) (*specs.Spec, error) {
 		s.Mounts = append(s.Mounts, m)
 	}
 
-	envs := make([]string, 1, len(p.P.Config.Env)+1)
+	envs := make([]string, 1, len(p.PluginObj.Config.Env)+1)
 	envs[0] = "PATH=" + system.DefaultPathEnv
-	envs = append(envs, p.P.Config.Env...)
+	envs = append(envs, p.PluginObj.Config.Env...)
 
-	args := append(p.P.Manifest.Entrypoint, p.P.Config.Args...)
-	cwd := p.P.Manifest.Workdir
+	args := append(p.PluginObj.Manifest.Entrypoint, p.PluginObj.Config.Args...)
+	cwd := p.PluginObj.Manifest.Workdir
 	if len(cwd) == 0 {
 		cwd = "/"
 	}
@@ -124,19 +124,19 @@ func (pm *Manager) initSpec(p *plugin) (*specs.Spec, error) {
 }
 
 func (pm *Manager) disable(p *plugin) error {
-	if !p.P.Active {
+	if !p.PluginObj.Active {
 		return fmt.Errorf("plugin %s is already disabled", p.Name())
 	}
 	if err := p.restartManager.Cancel(); err != nil {
 		logrus.Error(err)
 	}
-	if err := pm.containerdClient.Signal(p.P.ID, int(syscall.SIGKILL)); err != nil {
+	if err := pm.containerdClient.Signal(p.PluginObj.ID, int(syscall.SIGKILL)); err != nil {
 		logrus.Error(err)
 	}
 	os.RemoveAll(p.runtimeSourcePath)
 	pm.Lock() // fixme: lock single record
 	defer pm.Unlock()
-	p.P.Active = false
+	p.PluginObj.Active = false
 	pm.save()
 	return nil
 }
@@ -148,7 +148,7 @@ func (pm *Manager) Shutdown() {
 
 	pm.shutdown = true
 	for _, p := range pm.plugins {
-		if pm.liveRestore && p.P.Active {
+		if pm.liveRestore && p.PluginObj.Active {
 			logrus.Debug("Plugin active when liveRestore is set, skipping shutdown")
 			continue
 		}
@@ -157,9 +157,9 @@ func (pm *Manager) Shutdown() {
 				logrus.Error(err)
 			}
 		}
-		if pm.containerdClient != nil && p.P.Active {
+		if pm.containerdClient != nil && p.PluginObj.Active {
 			p.exitChan = make(chan bool)
-			err := pm.containerdClient.Signal(p.P.ID, int(syscall.SIGTERM))
+			err := pm.containerdClient.Signal(p.PluginObj.ID, int(syscall.SIGTERM))
 			if err != nil {
 				logrus.Errorf("Sending SIGTERM to plugin failed with error: %v", err)
 			} else {
@@ -168,14 +168,14 @@ func (pm *Manager) Shutdown() {
 					logrus.Debug("Clean shutdown of plugin")
 				case <-time.After(time.Second * 10):
 					logrus.Debug("Force shutdown plugin")
-					if err := pm.containerdClient.Signal(p.P.ID, int(syscall.SIGKILL)); err != nil {
+					if err := pm.containerdClient.Signal(p.PluginObj.ID, int(syscall.SIGKILL)); err != nil {
 						logrus.Errorf("Sending SIGKILL to plugin failed with error: %v", err)
 					}
 				}
 			}
 			close(p.exitChan)
 			pm.Lock()
-			p.P.Active = false
+			p.PluginObj.Active = false
 			pm.save()
 			pm.Unlock()
 		}