// InstallPlugin downloads the plugin code as a zip file from the Grafana.com API
// and then extracts the zip into the plugins directory.
978342
func InstallPlugin(pluginName, version string, c CommandLine) error {
	pluginFolder := c.PluginDirectory()
	downloadURL := c.PluginURL()
	if downloadURL == "" {
		plugin, err := s.GetPlugin(pluginName, c.RepoDirectory())
		if err != nil {
			return err
		}

		v, err := SelectVersion(plugin, version)
		if err != nil {
			return err
		}

		if version == "" {
			version = v.Version
		}
		downloadURL = fmt.Sprintf("%s/%s/versions/%s/download",
			c.GlobalString("repo"),
			pluginName,
			version)
	}

	logger.Infof("installing %v @ %v\n", pluginName, version)
	logger.Infof("from url: %v\n", downloadURL)
	logger.Infof("into: %v\n", pluginFolder)
	logger.Info("\n")

	err := downloadFile(pluginName, pluginFolder, downloadURL)
	if err != nil {
		return err
	}

	logger.Infof("%s Installed %s successfully \n", color.GreenString("✔"), pluginName)

	res, _ := s.ReadPlugin(pluginFolder, pluginName)
	for _, v := range res.Dependencies.Plugins {
		InstallPlugin(v.Id, "", c)
		logger.Infof("Installed dependency: %v ✔\n", v.Id)
	}

	return err
}
990914
func (p *Plugin) StartPlugin() error {
	p.App.Before = func(c *cli.Context) error {
		if p.BeforeFunc != nil {
			if err := p.BeforeFunc(c); err != nil {
				return err
			}
		}
		if p.Role == dcos.RoleMaster || p.Role == dcos.RoleAgent || p.Role == dcos.RoleAgentPublic {
			return p.createClient()
		}
		return fmt.Errorf(
			"--dcos-role %q was not recognized (valid roles: %s, %s, %s)",
			p.Role, dcos.RoleMaster, dcos.RoleAgent, dcos.RoleAgentPublic)
	}
	p.App.After = func(c *cli.Context) error {
		if p.AfterFunc != nil {
			if err := p.AfterFunc(c); err != nil {
				return err
			}
		}
		return nil
	}
	p.App.Action = func(c *cli.Context) error {
		for {
			metrics, err := p.Metrics()
			if err != nil {
				return err
			}

			if err := p.ConnectorFunc(metrics, c); err != nil {
				return err
			}

			p.Log.Infof("Polling complete, sleeping for %d seconds", p.PollingInterval)
			time.Sleep(time.Duration(p.PollingInterval) * time.Second)
		}
	}

	return p.App.Run(os.Args)
}
685506
func NewPlugin(opts ...Option) *Plugin {
	p := &Plugin{}

	p.PluginName = "etcd"
	p.StatusCheck = &statuscheck.DefaultPlugin
	p.Resync = &resync.DefaultPlugin

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

	p.PluginDeps.Setup()

	return p
}
490824
func (config *Config) AddPluginRepository(name string, url string) {
	config.ConfigFile.PluginRepositories = append(config.ConfigFile.PluginRepositories,
		PluginRepository{Name: name, URL: url})
}
365949
func NewExecutablePlugin(a Arg, commands ...string) (*ExecutablePlugin, error) {
	jsonArgs, err := json.Marshal(a)
	if err != nil {
		return nil, err
	}
	cmd := &exec.Cmd{
		Path: commands[0],
		Args: append(commands, string(jsonArgs)),
	}
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		return nil, err
	}
	return &ExecutablePlugin{
		cmd:    &commandWrapper{cmd},
		stdout: stdout,
		stderr: stderr,
	}, nil
}
231026
func (c *Client) CreatePlugin(opts CreatePluginOptions) (string, error) {
	path := "/plugins/create?" + queryString(opts)
	resp, err := c.do("POST", path, doOptions{
		data:    opts.Path,
		context: opts.Context})
	defer resp.Body.Close()
	if err != nil {
		return "", err
	}
	containerNameBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}
	return string(containerNameBytes), nil
}
1076602
func (c *Sys) RegisterPlugin(i *RegisterPluginInput) error {
	path := catalogPathByType(i.Type, i.Name)
	req := c.c.NewRequest(http.MethodPut, path)

	if err := req.SetJSONBody(i); err != nil {
		return err
	}

	ctx, cancelFunc := context.WithCancel(context.Background())
	defer cancelFunc()
	resp, err := c.c.RawRequestWithContext(ctx, req)
	if err == nil {
		defer resp.Body.Close()
	}
	return err
}
1090098
func (pm *PluginManager) loadPlugin(path, name string) error {
	libPath := path + "/" + name
	lib, err := dl.Open(libPath, dl.RTLD_LAZY)
	if err != nil {
		return err
	}
	// remove the .so from the file name
	name = name[:len(name)-3]

	p := &plugin{
		name: formatPluginName(name),
		lib:  lib,
	}

	// get the type of the plugin
	// and its associated interface definition
	t := p.getType()
	if _, exists := pm.interfaces[t]; !exists {
		return errors.New("Plugin loaded with an undefined type")
	}
	iface := pm.interfaces[t]
	p.iFace = &iface

	// ensure it implements the interface as defined
	// by the type and create a new instance of this plugin
	// via the defined factory, and map
	err = p.bootstrap()
	if err != nil {
		return err
	}

	// save our plugin
	err = pm.savePlugin(p)
	if err != nil {
		return err
	}

	// we're good!
	return nil
}
1335831
func (c *Client) LoadPlugin(p []string) *LoadPluginResult {
	r := new(LoadPluginResult)
	resp, err := c.pluginUploadRequest(p)
	if err != nil {
		r.Err = serror.New(err)
		return r
	}

	switch resp.Meta.Type {
	case rbody.PluginsLoadedType:
		pl := resp.Body.(*rbody.PluginsLoaded)
		r.LoadedPlugins = convertLoadedPlugins(pl.LoadedPlugins)
	case rbody.ErrorType:
		f := resp.Body.(*rbody.Error).Fields
		fields := make(map[string]interface{})
		for k, v := range f {
			fields[k] = v
		}
		r.Err = serror.New(resp.Body.(*rbody.Error), fields)
	default:
		r.Err = serror.New(ErrAPIResponseMetaType)
	}
	return r
}
427105
func NewPlugin(opts ...Option) *Plugin {
	p := &Plugin{}

	p.PluginName = "grpc"
	//p.HTTP= &rest.DefaultPlugin // turned off by default

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

	if p.Deps.Log == nil {
		p.Deps.Log = logging.ForPlugin(p.String())
	}
	if p.Deps.Cfg == nil {
		p.Deps.Cfg = config.ForPlugin(p.String(),
			config.WithExtraFlags(func(flags *config.FlagSet) {
				flags.String(grpcPortFlag(p.PluginName), "", fmt.Sprintf(
					"Configure %q server port", p.String()))
			}))
	}

	return p
}
666385
func loadPlugins(path string) error {
	abs, err := filepath.Abs(path)
	if err != nil {
		return err
	}
	pattern := filepath.Join(abs, fmt.Sprintf(
		"*-%s-%s.%s",
		runtime.GOOS,
		runtime.GOARCH,
		getLibExt(),
	))
	libs, err := filepath.Glob(pattern)
	if err != nil {
		return err
	}
	for _, lib := range libs {
		if _, err := plugin.Open(lib); err != nil {
			return err
		}
	}
	return nil
}
127107
func NewPlugin() *Plugin {
	return &Plugin{
		Handler:  admission.NewHandler(admission.Create),
		features: utilfeature.DefaultFeatureGate,
	}
}
52476
func NewLocalPlugin(name, addr string) *Plugin {
	return &Plugin{
		name: name,
		Addr: addr,
		// TODO: change to nil
		TLSConfig:    &tlsconfig.Options{InsecureSkipVerify: true},
		activateWait: sync.NewCond(&sync.Mutex{}),
	}
}
725161
func NewPlugin(opts ...Option) *Plugin {
	p := &Plugin{}

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

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

	return p
}
265933
func (m *Meta) storePluginPath(pluginPath []string) error {
	if len(pluginPath) == 0 {
		return nil
	}

	path := filepath.Join(m.DataDir(), PluginPathFile)

	// remove the plugin dir record if the path was set to an empty string
	if len(pluginPath) == 1 && (pluginPath[0] == "") {
		err := os.Remove(path)
		if !os.IsNotExist(err) {
			return err
		}
		return nil
	}

	js, err := json.MarshalIndent(pluginPath, "", "  ")
	if err != nil {
		return err
	}

	// if this fails, so will WriteFile
	os.MkdirAll(m.DataDir(), 0755)

	return ioutil.WriteFile(path, js, 0644)
}
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
	}
}
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
}