// dispensePlugin is used to launch or reattach to an external plugin.
554017
func (l *PluginLoader) dispensePlugin(
	pluginType, apiVersion, cmd string, args []string, reattach *plugin.ReattachConfig,
	logger log.Logger) (PluginInstance, error) {

	var pluginCmd *exec.Cmd
	if cmd != "" && reattach != nil {
		return nil, fmt.Errorf("both launch command and reattach config specified")
	} else if cmd == "" && reattach == nil {
		return nil, fmt.Errorf("one of launch command or reattach config must be specified")
	} else if cmd != "" {
		pluginCmd = exec.Command(cmd, args...)
	}

	client := plugin.NewClient(&plugin.ClientConfig{
		HandshakeConfig:  base.Handshake,
		Plugins:          getPluginMap(pluginType, logger),
		Cmd:              pluginCmd,
		AllowedProtocols: []plugin.Protocol{plugin.ProtocolGRPC},
		Logger:           logger,
		Reattach:         reattach,
	})

	// Connect via RPC
	rpcClient, err := client.Client()
	if err != nil {
		client.Kill()
		return nil, err
	}

	// Request the plugin
	raw, err := rpcClient.Dispense(pluginType)
	if err != nil {
		client.Kill()
		return nil, err
	}

	instance := &externalPluginInstance{
		client:   client,
		instance: raw,
	}

	if apiVersion != "" {
		instance.apiVersion = apiVersion
	} else {
		// We do not know the API version since we are reattaching, so discover
		// it
		bplugin := raw.(base.BasePlugin)

		// Retrieve base plugin information
		i, err := bplugin.PluginInfo()
		if err != nil {
			return nil, fmt.Errorf("failed to get plugin info for plugin: %v", err)
		}

		apiVersion, err := l.selectApiVersion(i)
		if err != nil {
			return nil, fmt.Errorf("failed to validate API versions %v for plugin %s: %v", i.PluginApiVersions, i.Name, err)
		}
		if apiVersion == "" {
			return nil, fmt.Errorf("failed to reattach to plugin because supported API versions for the plugin and Nomad do not overlap")
		}

		instance.apiVersion = apiVersion
	}

	return instance, nil
}
1260017
func MsgToCorePlugin(msg *Plugin) core.Plugin {
	pl := &SubPlugin{
		typeName: msg.TypeName,
		name:     msg.Name,
		version:  int(msg.Version),
	}
	return core.Plugin(pl)
}
1004873
func NewPlugin(name, prefix string, newFunc func(typesMap TypesMap, p Printer, deps map[string]Dependency) Generator) Plugin {
	return &plugin{
		name:    name,
		prefix:  prefix,
		newFunc: newFunc,
	}
}
679680
func (p *pluginManager) LoadPlugin(details *pluginDetails, emitter gomit.Emitter) (*loadedPlugin, serror.SnapError) {
	type result struct {
		lp  *loadedPlugin
		err serror.SnapError
	}
	resultChan := make(chan result)
	go func() {
		lPlugin := new(loadedPlugin)
		lPlugin.Details = details
		lPlugin.State = DetectedState

		var (
			ePlugin *plugin.ExecutablePlugin
			resp    plugin.Response
			err     error
		)

		if lPlugin.Details.Uri == nil {
			pmLogger.WithFields(log.Fields{
				"_block": "load-plugin",
				"path":   filepath.Base(lPlugin.Details.Exec[0]),
			}).Info("plugin load called")
			// We will create commands by appending the ExecPath to the actual command.
			// The ExecPath is a temporary location where the plugin/package will be
			// run from.
			commands := make([]string, len(lPlugin.Details.Exec))
			for i, e := range lPlugin.Details.Exec {
				commands[i] = filepath.Join(lPlugin.Details.ExecPath, e)
			}

			ePlugin, err = plugin.NewExecutablePlugin(
				p.GenerateArgs(int(log.GetLevel())).
					SetCertPath(details.CertPath).
					SetKeyPath(details.KeyPath).
					SetCACertPaths(details.CACertPaths).
					SetTLSEnabled(details.TLSEnabled),
				commands...)
			if err != nil {
				pmLogger.WithFields(log.Fields{
					"_block": "load-plugin",
					"error":  err.Error(),
				}).Error("load plugin error while creating executable plugin")
				resultChan <- result{nil, serror.New(err)}
				return
			}
			pmLogger.WithFields(log.Fields{
				"_block": "load-plugin",
				"path":   lPlugin.Details.Exec,
			}).Debug(fmt.Sprintf("plugin load timeout set to %ds", p.pluginLoadTimeout))
			resp, err = ePlugin.Run(time.Second * time.Duration(p.pluginLoadTimeout))
			if err != nil {
				pmLogger.WithFields(log.Fields{
					"_block": "load-plugin",
					"error":  err.Error(),
				}).Error("load plugin error when starting plugin")
				resultChan <- result{nil, serror.New(err)}
				return
			}

			ePlugin.SetName(resp.Meta.Name)

			key := fmt.Sprintf("%s"+core.Separator+"%s"+core.Separator+"%d", resp.Meta.Type.String(), resp.Meta.Name, resp.Meta.Version)
			if _, exists := p.loadedPlugins.table[key]; exists {
				resultChan <- result{nil, serror.New(ErrPluginAlreadyLoaded, map[string]interface{}{
					"plugin-name":    resp.Meta.Name,
					"plugin-version": resp.Meta.Version,
					"plugin-type":    resp.Type.String(),
				})}
			}
		} else {
			pmLogger.WithFields(log.Fields{
				"_block": "load-plugin",
				"uri":    lPlugin.Details.Uri.String(),
			}).Info("plugin load called")
			res, err := http.Get(lPlugin.Details.Uri.String())
			if err != nil {
				resultChan <- result{nil, serror.New(err)}
				return
			}

			body, err := ioutil.ReadAll(res.Body)
			if err != nil {
				resultChan <- result{nil, serror.New(err)}
				return
			}
			err = json.Unmarshal(body, &resp)
			if err != nil {
				pmLogger.WithFields(log.Fields{
					"_block": "load-plugin",
					"error":  err.Error(),
				}).Error("error during json unmarshal")
			}
		}
		ap, err := newAvailablePlugin(resp, emitter, ePlugin, p.grpcSecurity)
		if err != nil {
			pmLogger.WithFields(log.Fields{
				"_block": "load-plugin",
				"error":  err.Error(),
			}).Error("load plugin error while creating available plugin")
			resultChan <- result{nil, serror.New(err)}
			return
		}

		if lPlugin.Details.Uri != nil {
			ap.SetIsRemote(true)
		}

		if resp.Meta.Unsecure {
			err = ap.client.Ping()
		} else {
			err = ap.client.SetKey()
		}

		if err != nil {
			pmLogger.WithFields(log.Fields{
				"_block": "load-plugin",
				"error":  err.Error(),
			}).Error("load plugin error while pinging the plugin")
			resultChan <- result{nil, serror.New(err)}
			return
		}

		// Get the ConfigPolicy and add it to the loaded plugin
		c, ok := ap.client.(plugin.Plugin)
		if !ok {
			resultChan <- result{nil, serror.New(errors.New("missing GetConfigPolicy function"))}
			return
		}
		cp, err := c.GetConfigPolicy()
		if err != nil {
			pmLogger.WithFields(log.Fields{
				"_block":         "load-plugin",
				"plugin-type":    "collector",
				"error":          err.Error(),
				"plugin-name":    ap.Name(),
				"plugin-version": ap.Version(),
				"plugin-id":      ap.ID(),
			}).Error("error in getting config policy")
			resultChan <- result{nil, serror.New(err)}
			return
		}

		lPlugin.ConfigPolicy = cp
		lPlugin.Meta = resp.Meta
		lPlugin.Type = resp.Type
		lPlugin.Token = resp.Token
		lPlugin.LoadedTime = time.Now()
		lPlugin.State = LoadedState

		if resp.Type == plugin.CollectorPluginType || resp.Type == plugin.StreamCollectorPluginType {
			cfgNode := p.pluginConfig.getPluginConfigDataNode(core.PluginType(resp.Type), resp.Meta.Name, resp.Meta.Version)

			if lPlugin.ConfigPolicy != nil {
				// Get plugin config defaults
				defaults := cdata.NewNode()
				for _, cpolicy := range lPlugin.ConfigPolicy.GetAll() {
					_, errs := cpolicy.AddDefaults(defaults.Table())
					if len(errs.Errors()) > 0 {
						for _, err := range errs.Errors() {
							pmLogger.WithFields(log.Fields{
								"_block":         "load-plugin",
								"plugin-type":    "collector",
								"plugin-name":    ap.Name(),
								"plugin-version": ap.Version(),
								"plugin-id":      ap.ID(),
							}).Error(err.Error())
						}
						resultChan <- result{nil, serror.New(errors.New("error getting default config"))}
						return

					}
				}

				// Update config policy with defaults
				cfgNode = cfgNode.ReverseMerge(defaults)
				cp, err = c.GetConfigPolicy()
				if err != nil {
					pmLogger.WithFields(log.Fields{
						"_block":         "load-plugin",
						"plugin-type":    "collector",
						"error":          err.Error(),
						"plugin-name":    ap.Name(),
						"plugin-version": ap.Version(),
						"plugin-id":      ap.ID(),
					}).Error("error in getting config policy")
					resultChan <- result{nil, serror.New(err)}
					return
				}
				lPlugin.ConfigPolicy = cp
			}

			colClient := ap.client.(client.PluginCollectorClient)
			if !ap.isRemote {
				defer ap.client.(client.PluginCollectorClient).Close()
			}

			cfg := plugin.ConfigType{
				ConfigDataNode: cfgNode,
			}

			metricTypes, err := colClient.GetMetricTypes(cfg)
			if err != nil {
				pmLogger.WithFields(log.Fields{
					"_block":         "load-plugin",
					"plugin-type":    resp.Type.String(),
					"error":          err.Error(),
					"plugin-name":    ap.Name(),
					"plugin-version": ap.Version(),
				}).Error("error in getting metric types")
				resultChan <- result{nil, serror.New(err)}
				return
			}

			// Add metric types to metric catalog
			for _, nmt := range metricTypes {
				// If the version is 0 default it to the plugin version
				// This honors the plugins explicit version but falls back
				// to the plugin version as default
				if nmt.Version() < 1 {
					// Since we have to override version we convert to a internal struct
					nmt = &metricType{
						namespace:          nmt.Namespace(),
						version:            resp.Meta.Version,
						lastAdvertisedTime: nmt.LastAdvertisedTime(),
						config:             nmt.Config(),
						data:               nmt.Data(),
						tags:               nmt.Tags(),
						description:        nmt.Description(),
						unit:               nmt.Unit(),
					}
				}
				// We quit and throw an error on bad metric versions (<1)
				// the is a safety catch otherwise the catalog will be corrupted
				if nmt.Version() < 1 {
					err := errors.New("Bad metric version from plugin")
					pmLogger.WithFields(log.Fields{
						"_block":           "load-plugin",
						"plugin-name":      resp.Meta.Name,
						"plugin-version":   resp.Meta.Version,
						"plugin-type":      resp.Meta.Type.String(),
						"plugin-path":      filepath.Base(lPlugin.Details.ExecPath),
						"metric-namespace": nmt.Namespace(),
						"metric-version":   nmt.Version(),
						"error":            err.Error(),
					}).Error("received metric with bad version")
					resultChan <- result{nil, serror.New(err)}
					return
				}

				//Add standard tags
				nmt = p.AddStandardAndWorkflowTags(nmt, nil)

				if err := p.metricCatalog.AddLoadedMetricType(lPlugin, nmt); err != nil {
					pmLogger.WithFields(log.Fields{
						"_block":           "load-plugin",
						"plugin-name":      resp.Meta.Name,
						"plugin-version":   resp.Meta.Version,
						"plugin-type":      resp.Meta.Type.String(),
						"plugin-path":      filepath.Base(lPlugin.Details.ExecPath),
						"metric-namespace": nmt.Namespace(),
						"metric-version":   nmt.Version(),
						"error":            err.Error(),
					}).Error("error adding loaded metric type")
					resultChan <- result{nil, serror.New(err)}
					return
				}
			}
		}

		if lPlugin.Details.Uri == nil {
			// Added so clients can adequately clean up connections
			ap.client.Kill("Retrieved necessary plugin info")
			err = ePlugin.Kill()
			if err != nil {
				pmLogger.WithFields(log.Fields{
					"_block": "load-plugin",
					"error":  err.Error(),
				}).Error("load plugin error while killing plugin executable plugin")
				resultChan <- result{nil, serror.New(err)}
				return
			}
		}

		if resp.State != plugin.PluginSuccess {
			e := fmt.Errorf("plugin loading did not succeed: %s\n", resp.ErrorMessage)
			pmLogger.WithFields(log.Fields{
				"_block":          "load-plugin",
				"error":           e,
				"plugin response": resp.ErrorMessage,
			}).Error("load plugin error")
			resultChan <- result{nil, serror.New(e)}
			return
		}

		aErr := p.loadedPlugins.add(lPlugin)
		if aErr != nil {
			pmLogger.WithFields(log.Fields{
				"_block": "load-plugin",
				"error":  aErr,
			}).Error("load plugin error while adding loaded plugin to load plugins collection")
			resultChan <- result{nil, aErr}
		}
		if ap.isRemote && aErr == nil {
			// monitor standalone plugins. Unload them from the plugin catalog and metrics list
			// when we detect they are no longer online.
			go func() {
				defer ap.client.(client.PluginCollectorClient).Close()
				for {
					time.Sleep(5 * time.Second)
					go ap.CheckHealth()
					if ap.failedHealthChecks > 3 {
						p.UnloadPlugin(lPlugin)
						return
					}
					if _, err := p.loadedPlugins.get(lPlugin.Key()); err != nil {
						// prevent leaking routine when plugin is unloaded normally
						return
					}

				}
			}()

		}
		resultChan <- result{lPlugin, nil}
		return
	}()

	select {
	case results := <-resultChan:
		return results.lp, results.err
	case <-time.After(time.Second * time.Duration(p.pluginLoadTimeout)):
		e := serror.New(errors.New("timed out waiting for plugin to load"))
		return nil, e
	}
}
126503
func (j *Jenkins) InstallPlugin(name string, version string) error {
	xml := fmt.Sprintf(`<jenkins><install plugin="%s@%s" /></jenkins>`, name, version)
	resp, err := j.Requester.PostXML("/pluginManager/installNecessaryPlugins", xml, j.Raw, map[string]string{})

	if resp.StatusCode != 200 {
		return fmt.Errorf("Invalid status code returned: %d", resp.StatusCode)
	}
	return err
}
1052563
func (c *Client) InstallPlugins(opts InstallPluginOptions) error {
	path := "/plugins/pull?" + queryString(opts)
	resp, err := c.do("POST", path, doOptions{
		data:    opts.Plugins,
		context: opts.Context,
	})
	defer resp.Body.Close()
	if err != nil {
		return err
	}
	return nil
}
1221280
func (h *handler) savePlugin(c echo.Context) (err error) {
	p := new(store.Plugin)
	if err = c.Bind(p); err != nil {
		return
	}
	p.Host = c.Param("host")
	p.Path = decodePath(c)
	p.Source = store.API
	p.UpdatedAt = time.Now()
	err = h.store.UpdatePlugin(p)
	if err != nil {
		return
	}
	h.cluster.UserEvent(armor.EventPluginUpdate, []byte(p.ID), true)
	return c.NoContent(http.StatusNoContent)
}
1206911
func (cli *Client) PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) {
	headers := map[string][]string{"X-Registry-Auth": {registryAuth}}
	resp, err := cli.post(ctx, "/plugins/"+name+"/push", nil, nil, headers)
	if err != nil {
		return nil, err
	}
	return resp.body, nil
}
962819
func randUseForPlugin(plugin *dt.Plugin) string {
	if plugin.Config.Usage == nil {
		return ""
	}
	return plugin.Config.Usage[rand.Intn(len(plugin.Config.Usage))]
}
725161
func NewPlugin(opts ...Option) *Plugin {
	p := &Plugin{}

	p.PluginName = "grpcsync"
	p.GRPC = &grpc.DefaultPlugin

	for _, o := range opts {
		o(p)
	}

	return p
}
1113959
func (l *PluginLoader) mergePlugins(internal, external map[PluginID]*pluginInfo) map[PluginID]*pluginInfo {
	finalized := make(map[PluginID]*pluginInfo, len(internal))

	// Load the internal plugins
	for k, v := range internal {
		finalized[k] = v
	}

	for k, extPlugin := range external {
		internal, ok := finalized[k]
		if ok {
			// We have overlapping plugins, determine if we should keep the
			// internal version or override
			if extPlugin.version.LessThan(internal.version) {
				l.logger.Info("preferring internal version of plugin",
					"plugin", extPlugin.baseInfo.Name, "internal_version", internal.version,
					"external_version", extPlugin.version)
				continue
			}
		}

		// Add external plugin
		finalized[k] = extPlugin
	}

	return finalized
}
510889
func (config *Config) PluginHome() string {
	if config.ENV.CFPluginHome != "" {
		return filepath.Join(config.ENV.CFPluginHome, ".cf", "plugins")
	}

	return filepath.Join(homeDirectory(), ".cf", "plugins")
}
245596
func (i *instanceManager) dispense() (plugin device.DevicePlugin, 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.device, nil
	}

	// 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 fingerprint plugin
	device, ok := pluginInstance.Plugin().(device.DevicePlugin)
	if !ok {
		pluginInstance.Kill()
		return nil, fmt.Errorf("plugin loaded does not implement the driver interface")
	}

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

	// Store the reattach config
	if c, ok := pluginInstance.ReattachConfig(); ok {
		i.storeReattach(c)
	}

	return device, nil
}
352709
func (w *mlWriter) deactivatePlugin() {
	w.stack = w.stack[:len(w.stack)-1]
}
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)
}
1003695
func (p *pluginContainer) HandlersScanner() HandlersScannerPlugin {
	if v, ok := p.base.(HandlersScannerPlugin); ok {
		return v
	}

	return nil
}
195311
func (config *Config) RemovePlugin(pluginName string) {
	delete(config.pluginsConfig.Plugins, pluginName)
}