// dispense is used to dispense a plugin.
493464
func (i *instanceManager) dispense() (plugin drivers.DriverPlugin, err error) {
	i.pluginLock.Lock()
	defer i.pluginLock.Unlock()

	// See if we already have a running instance
	if i.plugin != nil && !i.plugin.Exited() {
		return i.driver, nil
	}

	var pluginInstance loader.PluginInstance

	if reattach, ok := i.fetchReattach(); ok {
		// Reattach to existing plugin
		pluginInstance, err = i.loader.Reattach(i.id.Name, i.id.PluginType, reattach)
	} else {
		// Get an instance of the plugin
		pluginInstance, err = i.loader.Dispense(i.id.Name, i.id.PluginType, i.pluginConfig, i.logger)
	}
	if err != nil {
		// Retry as the error just indicates the singleton has exited
		if err == singleton.SingletonPluginExited {
			pluginInstance, err = i.loader.Dispense(i.id.Name, i.id.PluginType, i.pluginConfig, i.logger)
		}

		// If we still have an error there is a real problem
		if err != nil {
			return nil, fmt.Errorf("failed to start plugin: %v", err)
		}
	}

	// Convert to a driver plugin
	driver, ok := pluginInstance.Plugin().(drivers.DriverPlugin)
	if !ok {
		pluginInstance.Kill()
		return nil, fmt.Errorf("plugin loaded does not implement the driver interface")
	}

	// Store the plugin and driver
	i.plugin = pluginInstance
	i.driver = driver

	// Store the reattach config
	if c, ok := pluginInstance.ReattachConfig(); ok {
		if err := i.storeReattach(c); err != nil {
			i.logger.Error("error storing driver plugin reattach config", "error", err)
		}
	}

	return driver, nil
}
543924
func (p *Plugin) Close() error {
	for _, pr := range p.processes {
		if pr.cancelChan != nil {
			close(pr.cancelChan)
		}
	}
	return nil
}
632164
func NewDispenserTokens(filename string, tokens []Token) Dispenser {
	return Dispenser{
		filename: filename,
		tokens:   tokens,
		cursor:   -1,
	}
}
37149
func (ph *Manager) Handle(pl Plugin) {
	if _, ok := ph.plugins[pl.Name()]; ok {
		//Already exists
		panic(DuplicatePlugin)
	}

	ph.plugins[pl.Name()] = pl

	for _, sub := range pl.Subscribes() {
		if ph.subscriptions[sub] == nil {
			ph.subscriptions[sub] = make(plugins)
		}
		ph.subscriptions[sub][pl.Name()] = pl
	}

	f, ch, closer := generatefunc(pl)
	ph.closers[pl.Name()] = closer

	go f()

	rch := reflect.ValueOf(ch)
	ph.selects = append(ph.selects,
		reflect.SelectCase{
			Dir:  reflect.SelectRecv,
			Chan: rch,
		})
}
190144
func (a *availablePlugin) Kill(r string) error {
	log.WithFields(log.Fields{
		"_module":     "control-aplugin",
		"block":       "kill",
		"plugin_name": a,
	}).Info("hard killing available plugin")
	if a.fromPackage {
		log.WithFields(log.Fields{
			"_module":     "control-aplugin",
			"block":       "kill",
			"plugin_name": a,
			"pluginPath":  a.execPath,
		}).Debug("deleting available plugin package")
		os.RemoveAll(filepath.Dir(a.execPath))
	}

	// If it's a streaming plugin, we need to signal the scheduler that
	// this plugin is being killed.
	if c, ok := a.client.(client.PluginStreamCollectorClient); ok {
		c.Killed()
	}

	if a.ePlugin != nil {
		return a.ePlugin.Kill()
	}
	return nil
}
1300845
func (p *Plugin) Put(key string, data proto.Message, opts ...datasync.PutOption) error {
	if p.Messaging.Disabled() {
		return nil
	}

	if p.adapter != nil {
		return p.adapter.Put(key, data, opts...)
	}

	return errors.New("Transport adapter is not ready yet. (Probably called before AfterInit)")
}
709373
func (p *Plugin) Put(key string, data proto.Message, opts ...datasync.PutOption) error {
	if !p.isKvEnabled() {
		return nil
	}

	if p.adapter != nil {
		return p.adapter.db.Put(key, data, opts...)
	}

	return ErrNotReady
}
258673
func (l *loadedPlugins) add(lp *loadedPlugin) serror.SnapError {
	l.Lock()
	defer l.Unlock()

	if _, exists := l.table[lp.Key()]; exists {
		return serror.New(ErrPluginAlreadyLoaded, map[string]interface{}{
			"plugin-name":    lp.Meta.Name,
			"plugin-version": lp.Meta.Version,
			"plugin-type":    lp.Type.String(),
		})
	}
	l.table[lp.Key()] = lp
	return nil
}
703352
func (l *PluginLoader) Dispense(name, pluginType string, config *base.AgentConfig, logger log.Logger) (PluginInstance, error) {
	id := PluginID{
		Name:       name,
		PluginType: pluginType,
	}
	pinfo, ok := l.plugins[id]
	if !ok {
		return nil, fmt.Errorf("unknown plugin with name %q and type %q", name, pluginType)
	}

	// If the plugin is internal, launch via the factory
	var instance PluginInstance
	if pinfo.factory != nil {
		instance = &internalPluginInstance{
			instance:   pinfo.factory(logger),
			apiVersion: pinfo.apiVersion,
		}
	} else {
		var err error
		instance, err = l.dispensePlugin(pinfo.baseInfo.Type, pinfo.apiVersion, pinfo.exePath, pinfo.args, nil, logger)
		if err != nil {
			return nil, fmt.Errorf("failed to launch plugin: %v", err)
		}
	}

	// Cast to the base type and set the config
	b, ok := instance.Plugin().(base.BasePlugin)
	if !ok {
		return nil, fmt.Errorf("plugin %s doesn't implement base plugin interface", id)
	}

	c := &base.Config{
		PluginConfig: pinfo.msgpackConfig,
		AgentConfig:  config,
		ApiVersion:   pinfo.apiVersion,
	}

	if err := b.SetConfig(c); err != nil {
		return nil, fmt.Errorf("setting config for plugin %s failed: %v", id, err)
	}

	return instance, nil
}
233799
func Disable() p.Plugin {
	return p.NewRequestPlugin(func(ctx *c.Context, h c.Handler) {
		// Assert http.Transport to work with the instance
		transport, ok := ctx.Client.Transport.(*http.Transport)
		if !ok {
			h.Next(ctx)
			return
		}

		// Override the http.Client transport
		transport.DisableCompression = true
		ctx.Client.Transport = transport

		h.Next(ctx)
	})
}
151782
func (p *Plugin) Close() error {
	p.cancel()
	p.wg.Wait()

	return nil
}
1188218
func (c *Client) DisablePlugin(opts DisablePluginOptions) error {
	path := "/plugins/" + opts.Name + "/disable"
	resp, err := c.do("POST", path, doOptions{context: opts.Context})
	defer resp.Body.Close()
	if err != nil {
		return err
	}
	resp.Body.Close()
	return nil
}
873055
func (s *SingletonLoader) dispense(f *future, name, pluginType string, config *base.AgentConfig, logger log.Logger) {
	i, err := s.loader.Dispense(name, pluginType, config, logger)
	f.set(i, err)
}
875934
func (p *Plugin) Close() error {
	if p.boltClient != nil {
		return p.boltClient.Close()
	}
	return nil
}
243488
func Serve(dev DevicePlugin, logger log.Logger) {
	plugin.Serve(&plugin.ServeConfig{
		HandshakeConfig: base.Handshake,
		Plugins: map[string]plugin.Plugin{
			base.PluginTypeBase:   &base.PluginBase{Impl: dev},
			base.PluginTypeDevice: &PluginDevice{Impl: dev},
		},
		GRPCServer: plugin.DefaultGRPCServer,
		Logger:     logger,
	})
}
793300
func (p *Plugin) Stop(ctx context.Context) {
	p.logInfo("Stopping decision log uploader.")
	done := make(chan struct{})
	p.stop <- done
	_ = <-done
}
454771
func (m *ServeMux) Plugin(plugin interface{}) {
	p, ok := plugin.(*pluginContainer)
	if !ok {
		p = &pluginContainer{base: plugin}
	}
	p.check()
	m.plugins = append(m.plugins, p)
}