summaryrefslogtreecommitdiffstats
path: root/plugin
diff options
context:
space:
mode:
authorJesse Hallam <jesse.hallam@gmail.com>2018-07-31 16:29:52 -0400
committerGitHub <noreply@github.com>2018-07-31 16:29:52 -0400
commit0788cdcadfb5d76b08758f42f01521b45ea76362 (patch)
tree86efb424a0543571398866e3cb84ee38be101141 /plugin
parent8c56f52d17d73a431a060919c97fe8939f81a0d1 (diff)
downloadchat-0788cdcadfb5d76b08758f42f01521b45ea76362.tar.gz
chat-0788cdcadfb5d76b08758f42f01521b45ea76362.tar.bz2
chat-0788cdcadfb5d76b08758f42f01521b45ea76362.zip
MM-11420: plugins: compute bundle hash on load (#9172)
* plugins: compute bundle hash on load Use this hash to bust client caches whenever the plugin bundle changes. * eliminate redundant pluginHandler * switch to 64-bit FNV-1a * Fix test
Diffstat (limited to 'plugin')
-rw-r--r--plugin/environment.go46
1 files changed, 29 insertions, 17 deletions
diff --git a/plugin/environment.go b/plugin/environment.go
index 6f915fd80..5c3a98349 100644
--- a/plugin/environment.go
+++ b/plugin/environment.go
@@ -5,6 +5,7 @@ package plugin
import (
"fmt"
+ "hash/fnv"
"io/ioutil"
"os"
"path/filepath"
@@ -133,29 +134,27 @@ func (env *Environment) Statuses() (model.PluginStatuses, error) {
return pluginStatuses, nil
}
-// Activate activates the plugin with the given id.
-func (env *Environment) Activate(id string) (reterr error) {
-
+func (env *Environment) Activate(id string) (manifest *model.Manifest, activated bool, reterr error) {
// Check if we are already active
if _, ok := env.activePlugins.Load(id); ok {
- return nil
+ return nil, false, nil
}
plugins, err := env.Available()
if err != nil {
- return err
+ return nil, false, err
}
var pluginInfo *model.BundleInfo
for _, p := range plugins {
if p.Manifest != nil && p.Manifest.Id == id {
if pluginInfo != nil {
- return fmt.Errorf("multiple plugins found: %v", id)
+ return nil, false, fmt.Errorf("multiple plugins found: %v", id)
}
pluginInfo = p
}
}
if pluginInfo == nil {
- return fmt.Errorf("plugin not found: %v", id)
+ return nil, false, fmt.Errorf("plugin not found: %v", id)
}
activePlugin := activePlugin{BundleInfo: pluginInfo}
@@ -171,43 +170,54 @@ func (env *Environment) Activate(id string) (reterr error) {
if pluginInfo.Manifest.Webapp != nil {
bundlePath := filepath.Clean(pluginInfo.Manifest.Webapp.BundlePath)
if bundlePath == "" || bundlePath[0] == '.' {
- return fmt.Errorf("invalid webapp bundle path")
+ return nil, false, fmt.Errorf("invalid webapp bundle path")
}
bundlePath = filepath.Join(env.pluginDir, id, bundlePath)
destinationPath := filepath.Join(env.webappPluginDir, id)
if err := os.RemoveAll(destinationPath); err != nil {
- return errors.Wrapf(err, "unable to remove old webapp bundle directory: %v", destinationPath)
+ return nil, false, errors.Wrapf(err, "unable to remove old webapp bundle directory: %v", destinationPath)
}
if err := utils.CopyDir(filepath.Dir(bundlePath), destinationPath); err != nil {
- return errors.Wrapf(err, "unable to copy webapp bundle directory: %v", id)
+ return nil, false, errors.Wrapf(err, "unable to copy webapp bundle directory: %v", id)
}
+ sourceBundleFilepath := filepath.Join(destinationPath, filepath.Base(bundlePath))
+
+ sourceBundleFileContents, err := ioutil.ReadFile(sourceBundleFilepath)
+ if err != nil {
+ return nil, false, errors.Wrapf(err, "unable to read webapp bundle: %v", id)
+ }
+
+ hash := fnv.New64a()
+ hash.Write(sourceBundleFileContents)
+ pluginInfo.Manifest.Webapp.BundleHash = hash.Sum([]byte{})
+
if err := os.Rename(
- filepath.Join(destinationPath, filepath.Base(bundlePath)),
- filepath.Join(destinationPath, fmt.Sprintf("%s_bundle.js", id)),
+ sourceBundleFilepath,
+ filepath.Join(destinationPath, fmt.Sprintf("%s_%x_bundle.js", id, pluginInfo.Manifest.Webapp.BundleHash)),
); err != nil {
- return errors.Wrapf(err, "unable to rename webapp bundle: %v", id)
+ return nil, false, errors.Wrapf(err, "unable to rename webapp bundle: %v", id)
}
}
if pluginInfo.Manifest.HasServer() {
supervisor, err := newSupervisor(pluginInfo, env.logger, env.newAPIImpl(pluginInfo.Manifest))
if err != nil {
- return errors.Wrapf(err, "unable to start plugin: %v", id)
+ return nil, false, errors.Wrapf(err, "unable to start plugin: %v", id)
}
activePlugin.supervisor = supervisor
}
- return nil
+ return pluginInfo.Manifest, true, nil
}
// Deactivates the plugin with the given id.
-func (env *Environment) Deactivate(id string) {
+func (env *Environment) Deactivate(id string) bool {
p, ok := env.activePlugins.Load(id)
if !ok {
- return
+ return false
}
env.activePlugins.Delete(id)
@@ -219,6 +229,8 @@ func (env *Environment) Deactivate(id string) {
}
activePlugin.supervisor.Shutdown()
}
+
+ return true
}
// Shutdown deactivates all plugins and gracefully shuts down the environment.