* Move plugins under Channels

We move all plugin related fields under *Channels.
This essentially migrates several methods from being under
*Server to under *Channels.

We also move the plugin startup and shutdown code
to be under Channels.Start and Channels.Shutdown.

While here, we remove the getPluginPublicKeyFiles
method which was a one-line method which uselessly
returned an error.

Lastly, we fix the product initialization order which
was incorrect previously. Products are dependent on
the main server.

So startup should be products -> server.
And shutdown should be server -> products.

```release-note
NONE
```

* Added app layer

```release-note
NONE
```

* Incorporate suggestions

```release-note
NONE
```
Этот коммит содержится в:
Agniva De Sarker
2021-11-08 11:57:22 +05:30
коммит произвёл GitHub
родитель 24248dc764
Коммит 25257d6ef6
14 изменённых файлов: 288 добавлений и 290 удалений

Просмотреть файл

@@ -42,15 +42,15 @@ type pluginSignaturePath struct {
//
// To get the plugins environment when the plugins are disabled, manually acquire the plugins
// lock instead.
func (s *Server) GetPluginsEnvironment() *plugin.Environment {
if !*s.Config().PluginSettings.Enable {
func (ch *Channels) GetPluginsEnvironment() *plugin.Environment {
if !*ch.srv.Config().PluginSettings.Enable {
return nil
}
s.PluginsLock.RLock()
defer s.PluginsLock.RUnlock()
ch.pluginsLock.RLock()
defer ch.pluginsLock.RUnlock()
return s.PluginsEnvironment
return ch.pluginsEnvironment
}
// GetPluginsEnvironment returns the plugin environment for use if plugins are enabled and
@@ -59,36 +59,36 @@ func (s *Server) GetPluginsEnvironment() *plugin.Environment {
// To get the plugins environment when the plugins are disabled, manually acquire the plugins
// lock instead.
func (a *App) GetPluginsEnvironment() *plugin.Environment {
return a.Srv().GetPluginsEnvironment()
return a.ch.GetPluginsEnvironment()
}
func (a *App) SetPluginsEnvironment(pluginsEnvironment *plugin.Environment) {
a.Srv().PluginsLock.Lock()
defer a.Srv().PluginsLock.Unlock()
a.ch.pluginsLock.Lock()
defer a.ch.pluginsLock.Unlock()
a.Srv().PluginsEnvironment = pluginsEnvironment
a.ch.pluginsEnvironment = pluginsEnvironment
}
func (a *App) SyncPluginsActiveState() {
a.Srv().syncPluginsActiveState()
a.ch.syncPluginsActiveState()
}
func (s *Server) syncPluginsActiveState() {
func (ch *Channels) syncPluginsActiveState() {
// Acquiring lock manually, as plugins might be disabled. See GetPluginsEnvironment.
s.PluginsLock.RLock()
pluginsEnvironment := s.PluginsEnvironment
s.PluginsLock.RUnlock()
ch.pluginsLock.RLock()
pluginsEnvironment := ch.pluginsEnvironment
ch.pluginsLock.RUnlock()
if pluginsEnvironment == nil {
return
}
config := s.Config().PluginSettings
config := ch.srv.Config().PluginSettings
if *config.Enable {
availablePlugins, err := pluginsEnvironment.Available()
if err != nil {
s.Log.Error("Unable to get available plugins", mlog.Err(err))
ch.srv.Log.Error("Unable to get available plugins", mlog.Err(err))
return
}
@@ -104,7 +104,7 @@ func (s *Server) syncPluginsActiveState() {
// Tie Apps proxy disabled status to the feature flag.
if pluginID == "com.mattermost.apps" {
if !s.Config().FeatureFlags.AppsEnabled {
if !ch.srv.Config().FeatureFlags.AppsEnabled {
pluginEnabled = false
}
}
@@ -129,7 +129,7 @@ func (s *Server) syncPluginsActiveState() {
if deactivated && plugin.Manifest.HasClient() {
message := model.NewWebSocketEvent(model.WebsocketEventPluginDisabled, "", "", "", nil)
message.Add("manifest", plugin.Manifest.ClientManifest())
s.Publish(message)
ch.srv.Publish(message)
}
}(plugin)
}
@@ -143,14 +143,14 @@ func (s *Server) syncPluginsActiveState() {
pluginID := plugin.Manifest.Id
updatedManifest, activated, err := pluginsEnvironment.Activate(pluginID)
if err != nil {
plugin.WrapLogger(s.Log).Error("Unable to activate plugin", mlog.Err(err))
plugin.WrapLogger(ch.srv.Log).Error("Unable to activate plugin", mlog.Err(err))
return
}
if activated {
// Notify all cluster clients if ready
if err := s.notifyPluginEnabled(updatedManifest); err != nil {
s.Log.Error("Failed to notify cluster on plugin enable", mlog.Err(err))
if err := ch.notifyPluginEnabled(updatedManifest); err != nil {
ch.srv.Log.Error("Failed to notify cluster on plugin enable", mlog.Err(err))
}
}
}(plugin)
@@ -160,7 +160,7 @@ func (s *Server) syncPluginsActiveState() {
pluginsEnvironment.Shutdown()
}
if err := s.notifyPluginStatusesChanged(); err != nil {
if err := ch.notifyPluginStatusesChanged(); err != nil {
mlog.Warn("failed to notify plugin status changed", mlog.Err(err))
}
}
@@ -170,21 +170,21 @@ func (a *App) NewPluginAPI(c *request.Context, manifest *model.Manifest) plugin.
}
func (a *App) InitPlugins(c *request.Context, pluginDir, webappPluginDir string) {
a.Srv().initPlugins(c, pluginDir, webappPluginDir)
a.ch.initPlugins(c, pluginDir, webappPluginDir)
}
func (s *Server) initPlugins(c *request.Context, pluginDir, webappPluginDir string) {
func (ch *Channels) initPlugins(c *request.Context, pluginDir, webappPluginDir string) {
// Acquiring lock manually, as plugins might be disabled. See GetPluginsEnvironment.
s.PluginsLock.RLock()
pluginsEnvironment := s.PluginsEnvironment
s.PluginsLock.RUnlock()
if pluginsEnvironment != nil || !*s.Config().PluginSettings.Enable {
s.syncPluginsActiveState()
pluginsEnvironment.TogglePluginHealthCheckJob(*s.Config().PluginSettings.EnableHealthCheck)
ch.pluginsLock.RLock()
pluginsEnvironment := ch.pluginsEnvironment
ch.pluginsLock.RUnlock()
if pluginsEnvironment != nil || !*ch.srv.Config().PluginSettings.Enable {
ch.syncPluginsActiveState()
pluginsEnvironment.TogglePluginHealthCheckJob(*ch.srv.Config().PluginSettings.EnableHealthCheck)
return
}
s.Log.Info("Starting up plugins")
ch.srv.Log.Info("Starting up plugins")
if err := os.Mkdir(pluginDir, 0744); err != nil && !os.IsExist(err) {
mlog.Error("Failed to start up plugins", mlog.Err(err))
@@ -197,70 +197,70 @@ func (s *Server) initPlugins(c *request.Context, pluginDir, webappPluginDir stri
}
newAPIFunc := func(manifest *model.Manifest) plugin.API {
return New(ServerConnector(s.Channels())).NewPluginAPI(c, manifest)
return New(ServerConnector(ch)).NewPluginAPI(c, manifest)
}
env, err := plugin.NewEnvironment(newAPIFunc, NewDriverImpl(s), pluginDir, webappPluginDir, s.Log, s.Metrics)
env, err := plugin.NewEnvironment(newAPIFunc, NewDriverImpl(ch.srv), pluginDir, webappPluginDir, ch.srv.Log, ch.srv.Metrics)
if err != nil {
mlog.Error("Failed to start up plugins", mlog.Err(err))
return
}
s.PluginsLock.Lock()
s.PluginsEnvironment = env
s.PluginsLock.Unlock()
ch.pluginsLock.Lock()
ch.pluginsEnvironment = env
ch.pluginsLock.Unlock()
s.PluginsEnvironment.TogglePluginHealthCheckJob(*s.Config().PluginSettings.EnableHealthCheck)
ch.pluginsEnvironment.TogglePluginHealthCheckJob(*ch.srv.Config().PluginSettings.EnableHealthCheck)
if err := s.syncPlugins(); err != nil {
if err := ch.syncPlugins(); err != nil {
mlog.Error("Failed to sync plugins from the file store", mlog.Err(err))
}
plugins := s.processPrepackagedPlugins(prepackagedPluginsDir)
pluginsEnvironment = s.GetPluginsEnvironment()
plugins := ch.processPrepackagedPlugins(prepackagedPluginsDir)
pluginsEnvironment = ch.GetPluginsEnvironment()
if pluginsEnvironment == nil {
mlog.Info("Plugins environment not found, server is likely shutting down")
return
}
pluginsEnvironment.SetPrepackagedPlugins(plugins)
s.installFeatureFlagPlugins()
ch.installFeatureFlagPlugins()
// Sync plugin active state when config changes. Also notify plugins.
s.PluginsLock.Lock()
s.RemoveConfigListener(s.PluginConfigListenerId)
s.PluginConfigListenerId = s.AddConfigListener(func(old, new *model.Config) {
ch.pluginsLock.Lock()
ch.RemoveConfigListener(ch.pluginConfigListenerID)
ch.pluginConfigListenerID = ch.AddConfigListener(func(old, new *model.Config) {
// If plugin status remains unchanged, only then run this.
// Because (*App).InitPlugins is already run as a config change hook.
if *old.PluginSettings.Enable == *new.PluginSettings.Enable {
s.installFeatureFlagPlugins()
s.syncPluginsActiveState()
ch.installFeatureFlagPlugins()
ch.syncPluginsActiveState()
}
if pluginsEnvironment := s.GetPluginsEnvironment(); pluginsEnvironment != nil {
if pluginsEnvironment := ch.GetPluginsEnvironment(); pluginsEnvironment != nil {
pluginsEnvironment.RunMultiPluginHook(func(hooks plugin.Hooks) bool {
if err := hooks.OnConfigurationChange(); err != nil {
s.Log.Error("Plugin OnConfigurationChange hook failed", mlog.Err(err))
ch.srv.Log.Error("Plugin OnConfigurationChange hook failed", mlog.Err(err))
}
return true
}, plugin.OnConfigurationChangeID)
}
})
s.PluginsLock.Unlock()
ch.pluginsLock.Unlock()
s.syncPluginsActiveState()
ch.syncPluginsActiveState()
}
// SyncPlugins synchronizes the plugins installed locally
// with the plugin bundles available in the file store.
func (a *App) SyncPlugins() *model.AppError {
return a.Srv().syncPlugins()
return a.ch.syncPlugins()
}
// SyncPlugins synchronizes the plugins installed locally
// with the plugin bundles available in the file store.
func (s *Server) syncPlugins() *model.AppError {
func (ch *Channels) syncPlugins() *model.AppError {
mlog.Info("Syncing plugins from the file store")
pluginsEnvironment := s.GetPluginsEnvironment()
pluginsEnvironment := ch.GetPluginsEnvironment()
if pluginsEnvironment == nil {
return model.NewAppError("SyncPlugins", "app.plugin.disabled.app_error", nil, "", http.StatusNotImplemented)
}
@@ -276,14 +276,14 @@ func (s *Server) syncPlugins() *model.AppError {
go func(pluginID string) {
defer wg.Done()
// Only handle managed plugins with .filestore flag file.
_, err := os.Stat(filepath.Join(*s.Config().PluginSettings.Directory, pluginID, managedPluginFileName))
_, err := os.Stat(filepath.Join(*ch.srv.Config().PluginSettings.Directory, pluginID, managedPluginFileName))
if os.IsNotExist(err) {
mlog.Warn("Skipping sync for unmanaged plugin", mlog.String("plugin_id", pluginID))
} else if err != nil {
mlog.Error("Skipping sync for plugin after failure to check if managed", mlog.String("plugin_id", pluginID), mlog.Err(err))
} else {
mlog.Debug("Removing local installation of managed plugin before sync", mlog.String("plugin_id", pluginID))
if err := s.removePluginLocally(pluginID); err != nil {
if err := ch.removePluginLocally(pluginID); err != nil {
mlog.Error("Failed to remove local installation of managed plugin before sync", mlog.String("plugin_id", pluginID), mlog.Err(err))
}
}
@@ -292,7 +292,7 @@ func (s *Server) syncPlugins() *model.AppError {
wg.Wait()
// Install plugins from the file store.
pluginSignaturePathMap, appErr := s.getPluginsFromFolder()
pluginSignaturePathMap, appErr := ch.getPluginsFromFolder()
if appErr != nil {
return appErr
}
@@ -301,7 +301,7 @@ func (s *Server) syncPlugins() *model.AppError {
wg.Add(1)
go func(plugin *pluginSignaturePath) {
defer wg.Done()
reader, appErr := s.fileReader(plugin.path)
reader, appErr := ch.srv.fileReader(plugin.path)
if appErr != nil {
mlog.Error("Failed to open plugin bundle from file store.", mlog.String("bundle", plugin.path), mlog.Err(appErr))
return
@@ -309,8 +309,8 @@ func (s *Server) syncPlugins() *model.AppError {
defer reader.Close()
var signature filestore.ReadCloseSeeker
if *s.Config().PluginSettings.RequirePluginSignature {
signature, appErr = s.fileReader(plugin.signaturePath)
if *ch.srv.Config().PluginSettings.RequirePluginSignature {
signature, appErr = ch.srv.fileReader(plugin.signaturePath)
if appErr != nil {
mlog.Error("Failed to open plugin signature from file store.", mlog.Err(appErr))
return
@@ -319,7 +319,7 @@ func (s *Server) syncPlugins() *model.AppError {
}
mlog.Info("Syncing plugin from file store", mlog.String("bundle", plugin.path))
if _, err := s.installPluginLocally(reader, signature, installPluginLocallyAlways); err != nil {
if _, err := ch.installPluginLocally(reader, signature, installPluginLocallyAlways); err != nil {
mlog.Error("Failed to sync plugin from file store", mlog.String("bundle", plugin.path), mlog.Err(err))
}
}(plugin)
@@ -329,11 +329,11 @@ func (s *Server) syncPlugins() *model.AppError {
return nil
}
func (s *Server) ShutDownPlugins() {
func (ch *Channels) ShutDownPlugins() {
// Acquiring lock manually, as plugins might be disabled. See GetPluginsEnvironment.
s.PluginsLock.RLock()
pluginsEnvironment := s.PluginsEnvironment
s.PluginsLock.RUnlock()
ch.pluginsLock.RLock()
pluginsEnvironment := ch.pluginsEnvironment
ch.pluginsLock.RUnlock()
if pluginsEnvironment == nil {
return
}
@@ -342,14 +342,14 @@ func (s *Server) ShutDownPlugins() {
pluginsEnvironment.Shutdown()
s.RemoveConfigListener(s.PluginConfigListenerId)
s.PluginConfigListenerId = ""
ch.RemoveConfigListener(ch.pluginConfigListenerID)
ch.pluginConfigListenerID = ""
// Acquiring lock manually before cleaning up PluginsEnvironment.
s.PluginsLock.Lock()
defer s.PluginsLock.Unlock()
if s.PluginsEnvironment == pluginsEnvironment {
s.PluginsEnvironment = nil
ch.pluginsLock.Lock()
defer ch.pluginsLock.Unlock()
if ch.pluginsEnvironment == pluginsEnvironment {
ch.pluginsEnvironment = nil
} else {
mlog.Warn("Another PluginsEnvironment detected while shutting down plugins.")
}
@@ -375,11 +375,11 @@ func (a *App) GetActivePluginManifests() ([]*model.Manifest, *model.AppError) {
// activation if inactive anywhere in the cluster.
// Notifies cluster peers through config change.
func (a *App) EnablePlugin(id string) *model.AppError {
return a.Srv().enablePlugin(id)
return a.ch.enablePlugin(id)
}
func (s *Server) enablePlugin(id string) *model.AppError {
pluginsEnvironment := s.GetPluginsEnvironment()
func (ch *Channels) enablePlugin(id string) *model.AppError {
pluginsEnvironment := ch.GetPluginsEnvironment()
if pluginsEnvironment == nil {
return model.NewAppError("EnablePlugin", "app.plugin.disabled.app_error", nil, "", http.StatusNotImplemented)
}
@@ -403,12 +403,12 @@ func (s *Server) enablePlugin(id string) *model.AppError {
return model.NewAppError("EnablePlugin", "app.plugin.not_installed.app_error", nil, "", http.StatusNotFound)
}
s.UpdateConfig(func(cfg *model.Config) {
ch.srv.UpdateConfig(func(cfg *model.Config) {
cfg.PluginSettings.PluginStates[id] = &model.PluginState{Enable: true}
})
// This call will implicitly invoke SyncPluginsActiveState which will activate enabled plugins.
if _, _, err := s.SaveConfig(s.Config(), true); err != nil {
if _, _, err := ch.srv.SaveConfig(ch.srv.Config(), true); err != nil {
if err.Id == "ent.cluster.save_config.error" {
return model.NewAppError("EnablePlugin", "app.plugin.cluster.save_config.app_error", nil, "", http.StatusInternalServerError)
}
@@ -421,11 +421,11 @@ func (s *Server) enablePlugin(id string) *model.AppError {
// DisablePlugin will set the config for an installed plugin to disabled, triggering deactivation if active.
// Notifies cluster peers through config change.
func (a *App) DisablePlugin(id string) *model.AppError {
return a.Srv().disablePlugin(id)
return a.ch.disablePlugin(id)
}
func (s *Server) disablePlugin(id string) *model.AppError {
pluginsEnvironment := s.GetPluginsEnvironment()
func (ch *Channels) disablePlugin(id string) *model.AppError {
pluginsEnvironment := ch.GetPluginsEnvironment()
if pluginsEnvironment == nil {
return model.NewAppError("DisablePlugin", "app.plugin.disabled.app_error", nil, "", http.StatusNotImplemented)
}
@@ -449,13 +449,13 @@ func (s *Server) disablePlugin(id string) *model.AppError {
return model.NewAppError("DisablePlugin", "app.plugin.not_installed.app_error", nil, "", http.StatusNotFound)
}
s.UpdateConfig(func(cfg *model.Config) {
ch.srv.UpdateConfig(func(cfg *model.Config) {
cfg.PluginSettings.PluginStates[id] = &model.PluginState{Enable: false}
})
s.unregisterPluginCommands(id)
ch.srv.unregisterPluginCommands(id)
// This call will implicitly invoke SyncPluginsActiveState which will deactivate disabled plugins.
if _, _, err := s.SaveConfig(s.Config(), true); err != nil {
if _, _, err := ch.srv.SaveConfig(ch.srv.Config(), true); err != nil {
return model.NewAppError("DisablePlugin", "app.plugin.config.app_error", nil, err.Error(), http.StatusInternalServerError)
}
@@ -540,8 +540,8 @@ func (a *App) GetMarketplacePlugins(filter *model.MarketplacePluginFilter) ([]*m
}
// getPrepackagedPlugin returns a pre-packaged plugin.
func (s *Server) getPrepackagedPlugin(pluginID, version string) (*plugin.PrepackagedPlugin, *model.AppError) {
pluginsEnvironment := s.GetPluginsEnvironment()
func (ch *Channels) getPrepackagedPlugin(pluginID, version string) (*plugin.PrepackagedPlugin, *model.AppError) {
pluginsEnvironment := ch.GetPluginsEnvironment()
if pluginsEnvironment == nil {
return nil, model.NewAppError("getPrepackagedPlugin", "app.plugin.config.app_error", nil, "plugin environment is nil", http.StatusInternalServerError)
}
@@ -557,16 +557,16 @@ func (s *Server) getPrepackagedPlugin(pluginID, version string) (*plugin.Prepack
}
// getRemoteMarketplacePlugin returns plugin from marketplace-server.
func (s *Server) getRemoteMarketplacePlugin(pluginID, version string) (*model.BaseMarketplacePlugin, *model.AppError) {
func (ch *Channels) getRemoteMarketplacePlugin(pluginID, version string) (*model.BaseMarketplacePlugin, *model.AppError) {
marketplaceClient, err := marketplace.NewClient(
*s.Config().PluginSettings.MarketplaceURL,
s.HTTPService(),
*ch.srv.Config().PluginSettings.MarketplaceURL,
ch.srv.HTTPService(),
)
if err != nil {
return nil, model.NewAppError("GetMarketplacePlugin", "app.plugin.marketplace_client.app_error", nil, err.Error(), http.StatusInternalServerError)
}
filter := s.getBaseMarketplaceFilter()
filter := ch.getBaseMarketplaceFilter()
filter.PluginId = pluginID
filter.ReturnAllVersions = true
@@ -717,15 +717,15 @@ func (a *App) mergeLocalPlugins(remoteMarketplacePlugins map[string]*model.Marke
}
func (a *App) getBaseMarketplaceFilter() *model.MarketplacePluginFilter {
return a.Srv().getBaseMarketplaceFilter()
return a.ch.getBaseMarketplaceFilter()
}
func (s *Server) getBaseMarketplaceFilter() *model.MarketplacePluginFilter {
func (ch *Channels) getBaseMarketplaceFilter() *model.MarketplacePluginFilter {
filter := &model.MarketplacePluginFilter{
ServerVersion: model.CurrentVersion,
}
license := s.License()
license := ch.srv.License()
if license != nil && license.HasEnterpriseMarketplacePlugins() {
filter.EnterprisePlugins = true
}
@@ -772,8 +772,8 @@ func pluginMatchesFilter(manifest *model.Manifest, filter string) bool {
// it will notify all connected websocket clients (across all peers) to trigger the (re-)installation.
// There is a small chance that this never occurs, because the last server to finish installing dies before it can announce.
// There is also a chance that multiple servers notify, but the webapp handles this idempotently.
func (s *Server) notifyPluginEnabled(manifest *model.Manifest) error {
pluginsEnvironment := s.GetPluginsEnvironment()
func (ch *Channels) notifyPluginEnabled(manifest *model.Manifest) error {
pluginsEnvironment := ch.GetPluginsEnvironment()
if pluginsEnvironment == nil {
return errors.New("pluginsEnvironment is nil")
}
@@ -783,15 +783,15 @@ func (s *Server) notifyPluginEnabled(manifest *model.Manifest) error {
var statuses model.PluginStatuses
if s.Cluster != nil {
if ch.srv.Cluster != nil {
var err *model.AppError
statuses, err = s.Cluster.GetPluginStatuses()
statuses, err = ch.srv.Cluster.GetPluginStatuses()
if err != nil {
return err
}
}
localStatus, err := s.GetPluginStatus(manifest.Id)
localStatus, err := ch.GetPluginStatus(manifest.Id)
if err != nil {
return err
}
@@ -811,26 +811,26 @@ func (s *Server) notifyPluginEnabled(manifest *model.Manifest) error {
// Notify all cluster peer clients.
message := model.NewWebSocketEvent(model.WebsocketEventPluginEnabled, "", "", "", nil)
message.Add("manifest", manifest.ClientManifest())
s.Publish(message)
ch.srv.Publish(message)
return nil
}
func (s *Server) getPluginsFromFolder() (map[string]*pluginSignaturePath, *model.AppError) {
fileStorePaths, appErr := s.listDirectory(fileStorePluginFolder)
func (ch *Channels) getPluginsFromFolder() (map[string]*pluginSignaturePath, *model.AppError) {
fileStorePaths, appErr := ch.srv.listDirectory(fileStorePluginFolder)
if appErr != nil {
return nil, model.NewAppError("getPluginsFromDir", "app.plugin.sync.list_filestore.app_error", nil, appErr.Error(), http.StatusInternalServerError)
}
return s.getPluginsFromFilePaths(fileStorePaths), nil
return ch.getPluginsFromFilePaths(fileStorePaths), nil
}
func (s *Server) getPluginsFromFilePaths(fileStorePaths []string) map[string]*pluginSignaturePath {
func (ch *Channels) getPluginsFromFilePaths(fileStorePaths []string) map[string]*pluginSignaturePath {
pluginSignaturePathMap := make(map[string]*pluginSignaturePath)
fsPrefix := ""
if *s.Config().FileSettings.DriverName == model.ImageDriverS3 {
ptr := s.Config().FileSettings.AmazonS3PathPrefix
if *ch.srv.Config().FileSettings.DriverName == model.ImageDriverS3 {
ptr := ch.srv.Config().FileSettings.AmazonS3PathPrefix
if ptr != nil && *ptr != "" {
fsPrefix = *ptr + "/"
}
@@ -863,7 +863,7 @@ func (s *Server) getPluginsFromFilePaths(fileStorePaths []string) map[string]*pl
return pluginSignaturePathMap
}
func (s *Server) processPrepackagedPlugins(pluginsDir string) []*plugin.PrepackagedPlugin {
func (ch *Channels) processPrepackagedPlugins(pluginsDir string) []*plugin.PrepackagedPlugin {
prepackagedPluginsDir, found := fileutils.FindDir(pluginsDir)
if !found {
return nil
@@ -879,7 +879,7 @@ func (s *Server) processPrepackagedPlugins(pluginsDir string) []*plugin.Prepacka
return nil
}
pluginSignaturePathMap := s.getPluginsFromFilePaths(fileStorePaths)
pluginSignaturePathMap := ch.getPluginsFromFilePaths(fileStorePaths)
plugins := make([]*plugin.PrepackagedPlugin, 0, len(pluginSignaturePathMap))
prepackagedPlugins := make(chan *plugin.PrepackagedPlugin, len(pluginSignaturePathMap))
@@ -888,7 +888,7 @@ func (s *Server) processPrepackagedPlugins(pluginsDir string) []*plugin.Prepacka
wg.Add(1)
go func(psPath *pluginSignaturePath) {
defer wg.Done()
p, err := s.processPrepackagedPlugin(psPath)
p, err := ch.processPrepackagedPlugin(psPath)
if err != nil {
mlog.Error("Failed to install prepackaged plugin", mlog.String("path", psPath.path), mlog.Err(err))
return
@@ -909,7 +909,7 @@ func (s *Server) processPrepackagedPlugins(pluginsDir string) []*plugin.Prepacka
// processPrepackagedPlugin will return the prepackaged plugin metadata and will also
// install the prepackaged plugin if it had been previously enabled and AutomaticPrepackagedPlugins is true.
func (s *Server) processPrepackagedPlugin(pluginPath *pluginSignaturePath) (*plugin.PrepackagedPlugin, error) {
func (ch *Channels) processPrepackagedPlugin(pluginPath *pluginSignaturePath) (*plugin.PrepackagedPlugin, error) {
mlog.Debug("Processing prepackaged plugin", mlog.String("path", pluginPath.path))
fileReader, err := os.Open(pluginPath.path)
@@ -930,18 +930,18 @@ func (s *Server) processPrepackagedPlugin(pluginPath *pluginSignaturePath) (*plu
}
// Skip installing the plugin at all if automatic prepackaged plugins is disabled
if !*s.Config().PluginSettings.AutomaticPrepackagedPlugins {
if !*ch.srv.Config().PluginSettings.AutomaticPrepackagedPlugins {
return plugin, nil
}
// Skip installing if the plugin is has not been previously enabled.
pluginState := s.Config().PluginSettings.PluginStates[plugin.Manifest.Id]
pluginState := ch.srv.Config().PluginSettings.PluginStates[plugin.Manifest.Id]
if pluginState == nil || !pluginState.Enable {
return plugin, nil
}
mlog.Debug("Installing prepackaged plugin", mlog.String("path", pluginPath.path))
if _, err := s.installExtractedPlugin(plugin.Manifest, pluginDir, installPluginLocallyOnlyIfNewOrUpgrade); err != nil {
if _, err := ch.installExtractedPlugin(plugin.Manifest, pluginDir, installPluginLocallyOnlyIfNewOrUpgrade); err != nil {
return nil, errors.Wrapf(err, "Failed to install extracted prepackaged plugin %s", pluginPath.path)
}
@@ -949,24 +949,24 @@ func (s *Server) processPrepackagedPlugin(pluginPath *pluginSignaturePath) (*plu
}
// installFeatureFlagPlugins handles the automatic installation/upgrade of plugins from feature flags
func (s *Server) installFeatureFlagPlugins() {
ffControledPlugins := s.Config().FeatureFlags.Plugins()
func (ch *Channels) installFeatureFlagPlugins() {
ffControledPlugins := ch.srv.Config().FeatureFlags.Plugins()
// Respect the automatic prepackaged disable setting
if !*s.Config().PluginSettings.AutomaticPrepackagedPlugins {
if !*ch.srv.Config().PluginSettings.AutomaticPrepackagedPlugins {
return
}
for pluginID, version := range ffControledPlugins {
// Skip installing if the plugin has been previously disabled.
pluginState := s.Config().PluginSettings.PluginStates[pluginID]
pluginState := ch.srv.Config().PluginSettings.PluginStates[pluginID]
if pluginState != nil && !pluginState.Enable {
s.Log.Debug("Not auto installing/upgrade because plugin was disabled", mlog.String("plugin_id", pluginID), mlog.String("version", version))
ch.srv.Log.Debug("Not auto installing/upgrade because plugin was disabled", mlog.String("plugin_id", pluginID), mlog.String("version", version))
continue
}
// Check if we already installed this version as InstallMarketplacePlugin can't handle re-installs well.
pluginStatus, err := s.GetPluginStatus(pluginID)
pluginStatus, err := ch.GetPluginStatus(pluginID)
pluginExists := err == nil
if pluginExists && pluginStatus.Version == version {
continue
@@ -974,37 +974,37 @@ func (s *Server) installFeatureFlagPlugins() {
if version != "" && version != "control" {
// If we are on-prem skip installation if this is a downgrade
license := s.License()
license := ch.srv.License()
inCloud := license != nil && *license.Features.Cloud
if !inCloud && pluginExists {
parsedVersion, err := semver.Parse(version)
if err != nil {
s.Log.Debug("Bad version from feature flag", mlog.String("plugin_id", pluginID), mlog.Err(err), mlog.String("version", version))
ch.srv.Log.Debug("Bad version from feature flag", mlog.String("plugin_id", pluginID), mlog.Err(err), mlog.String("version", version))
return
}
parsedExistingVersion, err := semver.Parse(pluginStatus.Version)
if err != nil {
s.Log.Debug("Bad version from plugin manifest", mlog.String("plugin_id", pluginID), mlog.Err(err), mlog.String("version", pluginStatus.Version))
ch.srv.Log.Debug("Bad version from plugin manifest", mlog.String("plugin_id", pluginID), mlog.Err(err), mlog.String("version", pluginStatus.Version))
return
}
if parsedVersion.LTE(parsedExistingVersion) {
s.Log.Debug("Skip installation because given version was a downgrade and on-prem installations should not downgrade.", mlog.String("plugin_id", pluginID), mlog.Err(err), mlog.String("version", pluginStatus.Version))
ch.srv.Log.Debug("Skip installation because given version was a downgrade and on-prem installations should not downgrade.", mlog.String("plugin_id", pluginID), mlog.Err(err), mlog.String("version", pluginStatus.Version))
return
}
}
_, err := s.installMarketplacePlugin(&model.InstallMarketplacePluginRequest{
_, err := ch.installMarketplacePlugin(&model.InstallMarketplacePluginRequest{
Id: pluginID,
Version: version,
})
if err != nil {
s.Log.Debug("Unable to install plugin from FF manifest", mlog.String("plugin_id", pluginID), mlog.Err(err), mlog.String("version", version))
ch.srv.Log.Debug("Unable to install plugin from FF manifest", mlog.String("plugin_id", pluginID), mlog.Err(err), mlog.String("version", version))
} else {
if err := s.enablePlugin(pluginID); err != nil {
s.Log.Debug("Unable to enable plugin installed from feature flag.", mlog.String("plugin_id", pluginID), mlog.Err(err), mlog.String("version", version))
if err := ch.enablePlugin(pluginID); err != nil {
ch.srv.Log.Debug("Unable to enable plugin installed from feature flag.", mlog.String("plugin_id", pluginID), mlog.Err(err), mlog.String("version", version))
} else {
s.Log.Debug("Installed and enabled plugin.", mlog.String("plugin_id", pluginID), mlog.String("version", version))
ch.srv.Log.Debug("Installed and enabled plugin.", mlog.String("plugin_id", pluginID), mlog.String("version", version))
}
}
}