// PluginInstall installs a plugin
343219
func (cli *Client) PluginInstall(ctx context.Context, name string, options types.PluginInstallOptions) (rc io.ReadCloser, err error) {
	query := url.Values{}
	if _, err := reference.ParseNormalizedNamed(options.RemoteRef); err != nil {
		return nil, errors.Wrap(err, "invalid remote reference")
	}
	query.Set("remote", options.RemoteRef)

	privileges, err := cli.checkPluginPermissions(ctx, query, options)
	if err != nil {
		return nil, err
	}

	// set name for plugin pull, if empty should default to remote reference
	query.Set("name", name)

	resp, err := cli.tryPluginPull(ctx, query, privileges, options.RegistryAuth)
	if err != nil {
		return nil, err
	}

	name = resp.header.Get("Docker-Plugin-Name")

	pr, pw := io.Pipe()
	go func() { // todo: the client should probably be designed more around the actual api
		_, err := io.Copy(pw, resp.body)
		if err != nil {
			pw.CloseWithError(err)
			return
		}
		defer func() {
			if err != nil {
				delResp, _ := cli.delete(ctx, "/plugins/"+name, nil, nil)
				ensureReaderClosed(delResp)
			}
		}()
		if len(options.Args) > 0 {
			if err := cli.PluginSet(ctx, name, options.Args); err != nil {
				pw.CloseWithError(err)
				return
			}
		}

		if options.Disabled {
			pw.Close()
			return
		}

		enableErr := cli.PluginEnable(ctx, name, types.PluginEnableOptions{Timeout: 0})
		pw.CloseWithError(enableErr)
	}()
	return pr, nil
}
644009
func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) {
	resp, err := cli.get(ctx, "/plugins/"+name, nil, nil)
	if err != nil {
		return nil, nil, err
	}

	defer ensureReaderClosed(resp)
	body, err := ioutil.ReadAll(resp.body)
	if err != nil {
		return nil, nil, err
	}
	var p types.Plugin
	rdr := bytes.NewReader(body)
	err = json.NewDecoder(rdr).Decode(&p)
	return &p, body, err
}
13400
func MustNewPluginInfo(group, product, version string, params ...PluginInfoParam) PluginInfo {
	cmd, err := NewPluginInfo(group, product, version, params...)
	if err != nil {
		panic(errors.Wrapf(err, "failed to create plugin info"))
	}
	return cmd
}
751646
func Init(ctx context.Context, cfg Config) (err error) {
	tiPlugins := pluginGlobal.plugins()
	if tiPlugins == nil {
		return nil
	}
	for kind := range tiPlugins.plugins {
		for i := range tiPlugins.plugins[kind] {
			p := tiPlugins.plugins[kind][i]
			if err = p.OnInit(ctx, p.Manifest); err != nil {
				if cfg.SkipWhenFail {
					logutil.Logger(ctx).Warn("call Plugin OnInit failure, err: %v",
						zap.String("plugin", p.Name), zap.Error(err))
					tiPlugins.plugins[kind][i].State = Disable
					err = nil
					continue
				}
				return
			}
			if p.OnFlush != nil && cfg.EtcdClient != nil {
				const pluginWatchPrefix = "/tidb/plugins/"
				ctx, cancel := context.WithCancel(context.Background())
				watcher := &flushWatcher{
					ctx:      ctx,
					cancel:   cancel,
					path:     pluginWatchPrefix + tiPlugins.plugins[kind][i].Name,
					etcd:     cfg.EtcdClient,
					manifest: tiPlugins.plugins[kind][i].Manifest,
				}
				tiPlugins.plugins[kind][i].flushWatcher = watcher
				go util.WithRecovery(watcher.watchLoop, nil)
			}
			tiPlugins.plugins[kind][i].State = Ready
		}
	}
	return
}
467752
func (_m *APIClient) PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) {
	ret := _m.Called(ctx, name)

	var r0 *types.Plugin
	if rf, ok := ret.Get(0).(func(context.Context, string) *types.Plugin); ok {
		r0 = rf(ctx, name)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*types.Plugin)
		}
	}

	var r1 []byte
	if rf, ok := ret.Get(1).(func(context.Context, string) []byte); ok {
		r1 = rf(ctx, name)
	} else {
		if ret.Get(1) != nil {
			r1 = ret.Get(1).([]byte)
		}
	}

	var r2 error
	if rf, ok := ret.Get(2).(func(context.Context, string) error); ok {
		r2 = rf(ctx, name)
	} else {
		r2 = ret.Error(2)
	}

	return r0, r1, r2
}
740009
func (l *listenerManager) postInitPlugins(event apid.Event) {
	var plinfoDetails []pluginDetail
	if pie, ok := event.(apid.PluginsInitializedEvent); ok {
		/*
		 * Store the plugin details in the heap. Needed during
		 * Bearer token generation request.
		 */
		for _, plugin := range pie.Plugins {
			name := plugin.Name
			version := plugin.Version
			if schemaVersion, ok := plugin.ExtraData["schemaVersion"].(string); ok {
				inf := pluginDetail{
					Name:          name,
					SchemaVersion: schemaVersion}
				plinfoDetails = append(plinfoDetails, inf)
				log.Debugf("plugin %s is version %s, schemaVersion: %s", name, version, schemaVersion)
			}
		}
		if plinfoDetails == nil {
			log.Panic("No Plugins registered!")
		}

		pgInfo, err := json.Marshal(plinfoDetails)
		if err != nil {
			log.Panicf("Unable to marshal plugin data: %v", err)
		}
		apidPluginDetails = string(pgInfo[:])

		log.Debug("start post plugin init")

		l.tokenMan.start()
		go l.bootstrap(apidInfo.LastSnapshot)

		log.Debug("Done post plugin init")
	}
}
1324003
func (p *Plugin) Init() error {
	p.registrations = make(map[string]*registration)
	return nil
}
1042259
func CheckIsPluginInstalled(name string, dependency PluginDependency) error {
	_, found, err := plugins.LoadPlugin(name)
	if err != nil {
		return err
	}

	currentVersion := ""
	installOrUpdate := false

	if !found {
		log.Warnf("Default plugin (%s) NOT found, installing...", name)
		installOrUpdate = true
		currentVersion = dependency.MinVersion
	} else {
		installedVersion, err := plugins.GetPluginVersion(name)
		if err != nil {
			return err
		}

		if installedVersion == nil {
			log.Warnf("Default plugin (%s) is not installed from git, no version info available.", name)
			currentVersion = ""
		} else {
			currentVersion = installedVersion.String()

			minVersion, err := ver.NewVersion(dependency.MinVersion)
			if err != nil {
				return err
			}

			if installedVersion.LessThan(minVersion) {
				log.Warnf("Default plugin (%s) version (%s) is lower than required (%s), updating...", name, installedVersion.String(), minVersion.String())
				installOrUpdate = true
				currentVersion = dependency.MinVersion
			}
		}
	}

	if installOrUpdate {
		var plugin plugins.Plugin
		err := retry.Times(2).Wait(5 * time.Second).Try(func(attempt uint) error {
			if attempt > 0 {
				log.Warnf("Download failed, retrying ...")
			}
			p, _, err := plugins.InstallPlugin(dependency.Source, dependency.MinVersion)
			plugin = p
			return err
		})
		if err != nil {
			return fmt.Errorf("Failed to install plugin, error: %s", err)
		}

		if len(plugin.Description) > 0 {
			fmt.Println(removeEmptyNewLines(plugin.Description))
		}
	}

	pluginDir := plugins.GetPluginDir(name)

	log.Printf("%s Plugin %s (%s): %s", colorstring.Green("[OK]"), name, currentVersion, pluginDir)

	return nil
}
903966
func Plugins(plugins ...infra.Plugin) Option {
	return func(o *Options) {
		o.Plugins = append(o.Plugins, plugins...)
	}
}
921574
func (p *Plugin) Init() (err error) {
	// Get GRPC configuration file
	if p.Config == nil {
		p.Config, err = p.getGrpcConfig()
		if err != nil || p.disabled {
			return err
		}
	}

	// Prepare GRPC server
	if p.grpcServer == nil {
		opts := p.Config.getGrpcOptions()
		if p.tlsConfig != nil {
			opts = append(opts, grpc.Creds(credentials.NewTLS(p.tlsConfig)))
		}
		if p.auther != nil {
			p.Log.Info("Token authentication for gRPC enabled")
			opts = append(opts, grpc.StreamInterceptor(grpc_auth.StreamServerInterceptor(p.auther.Authenticate)))
			opts = append(opts, grpc.UnaryInterceptor(grpc_auth.UnaryServerInterceptor(p.auther.Authenticate)))
		}
		p.grpcServer = grpc.NewServer(opts...)

		//grpclog.SetLogger(p.Log.NewLogger("grpc-server"))
	}

	return nil
}
743330
func (l *PluginLoader) init(config *PluginLoaderConfig) error {
	// Create a mapping of name to config
	configMap := configMap(config.Configs)

	// Initialize the internal plugins
	internal, err := l.initInternal(config.InternalPlugins, configMap)
	if err != nil {
		return fmt.Errorf("failed to fingerprint internal plugins: %v", err)
	}

	// Scan for eligibile binaries
	plugins, err := l.scan()
	if err != nil {
		return fmt.Errorf("failed to scan plugin directory %q: %v", l.pluginDir, err)
	}

	// Fingerprint the passed plugins
	external, err := l.fingerprintPlugins(plugins, configMap)
	if err != nil {
		return fmt.Errorf("failed to fingerprint plugins: %v", err)
	}

	// Merge external and internal plugins
	l.plugins = l.mergePlugins(internal, external)

	// Validate that the configs are valid for the plugins
	if err := l.validatePluginConfigs(); err != nil {
		return fmt.Errorf("parsing plugin configurations failed: %v", err)
	}

	return nil
}
1267907
func (p *Plugin) Init() error {
	// write initial status data into ETCD
	p.agentStat = &status.AgentStatus{
		State:        status.OperationalState_INIT,
		BuildVersion: agent.BuildVersion,
		BuildDate:    agent.BuildDate,
		CommitHash:   agent.CommitHash,
		StartTime:    time.Now().Unix(),
		LastChange:   time.Now().Unix(),
	}

	// initial empty interface status
	p.interfaceStat = &status.InterfaceStats{}

	// init pluginStat map
	p.pluginStat = make(map[string]*status.PluginStatus)

	// init map with plugin state probes
	p.pluginProbe = make(map[string]PluginStateProbe)

	// prepare context for all go routines
	p.ctx, p.cancel = context.WithCancel(context.Background())

	return nil
}
394559
func ValidateInitialization(plugin Interface) error {
	if validater, ok := plugin.(InitializationValidator); ok {
		err := validater.ValidateInitialization()
		if err != nil {
			return err
		}
	}
	return nil
}
65631
func NewPluginLoader(config *PluginLoaderConfig) (*PluginLoader, error) {
	if err := validateConfig(config); err != nil {
		return nil, fmt.Errorf("invalid plugin loader configuration passed: %v", err)
	}

	// Convert the versions
	supportedVersions := make(map[string][]*version.Version, len(config.SupportedVersions))
	for pType, versions := range config.SupportedVersions {
		converted, err := convertVersions(versions)
		if err != nil {
			return nil, err
		}
		supportedVersions[pType] = converted
	}

	logger := config.Logger.Named("plugin_loader").With("plugin_dir", config.PluginDir)
	l := &PluginLoader{
		logger:            logger,
		supportedVersions: supportedVersions,
		pluginDir:         config.PluginDir,
		plugins:           make(map[PluginID]*pluginInfo),
	}

	if err := l.init(config); err != nil {
		return nil, fmt.Errorf("failed to initialize plugin loader: %v", err)
	}

	return l, nil
}
50948
func newPlugins(names []string) []Plugin {
	plugins := []Plugin{}
	pluginsMap := make(map[string]struct{})
	for _, name := range names {
		if _, ok := pluginsMap[name]; ok {
			continue
		}
		pluginsMap[name] = struct{}{}
		plugins = append(plugins, newAuthorizationPlugin(name))
	}
	return plugins
}
321827
func (t PluginInterfaceType) String() string {
	return fmt.Sprintf("%s.%s/%s", t.Prefix, t.Capability, t.Version)
}
658779
func AllPlugins(plugins ...infra.Plugin) Option {
	return func(o *Options) {
		infraLogger.Debugf("AllPlugins with %d plugins", len(plugins))

		for _, plugin := range plugins {
			typ := reflect.TypeOf(plugin)
			infraLogger.Debugf("searching for all deps in: %v (type: %v)", plugin, typ)

			foundPlugins, err := findPlugins(reflect.ValueOf(plugin), o.pluginMap)
			if err != nil {
				panic(err)
			}

			infraLogger.Debugf("found %d plugins in: %v (type: %v)", len(foundPlugins), plugin, typ)
			for _, plug := range foundPlugins {
				infraLogger.Debugf(" - plugin: %v (%v)", plug, reflect.TypeOf(plug))

				if _, ok := o.pluginNames[plug.String()]; ok {
					infraLogger.Fatalf("plugin with name %q already registered", plug.String())
				}
				o.pluginNames[plug.String()] = struct{}{}
			}
			o.Plugins = append(o.Plugins, foundPlugins...)

			// TODO: perhaps set plugin name to typ.String() if it's empty
			/*p, ok := plugin.(core.PluginNamed)
			if !ok {
				p = core.NamePlugin(typ.String(), plugin)
			}*/

			if _, ok := o.pluginNames[plugin.String()]; ok {
				infraLogger.Fatalf("plugin with name %q already registered, custom name should be used", plugin.String())
			}
			o.pluginNames[plugin.String()] = struct{}{}
			o.Plugins = append(o.Plugins, plugin)
		}
	}
}