Skip to content
This repository has been archived by the owner on Nov 8, 2022. It is now read-only.

Commit

Permalink
Fixes #1502
Browse files Browse the repository at this point in the history
- plugins are run from tmp dir on all code paths
  • Loading branch information
rashmigottipati committed Feb 24, 2017
1 parent 00d1c24 commit 1a415fa
Show file tree
Hide file tree
Showing 24 changed files with 267 additions and 176 deletions.
7 changes: 5 additions & 2 deletions control/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ func (p *pluginControl) Start() error {
}).Warn("Auto-loading of plugin '", fileName, "' skipped (plugin not executable)")
continue
}
rp, err := core.NewRequestedPlugin(path.Join(fullPath, fileName))
rp, err := core.NewRequestedPlugin(path.Join(fullPath, fileName), GetDefaultConfig().TempDirPath, nil)
if err != nil {
controlLogger.WithFields(log.Fields{
"_block": "start",
Expand Down Expand Up @@ -582,7 +582,6 @@ func (p *pluginControl) returnPluginDetails(rp *core.RequestedPlugin) (*pluginDe
details.Path = rp.Path()
details.CheckSum = rp.CheckSum()
details.Signature = rp.Signature()
details.IsAutoLoaded = rp.AutoLoaded()

if filepath.Ext(rp.Path()) == ".aci" {
f, err := os.Open(rp.Path())
Expand Down Expand Up @@ -1066,6 +1065,10 @@ func (p *pluginControl) GetAutodiscoverPaths() []string {
return p.autodiscoverPaths
}

func (p *pluginControl) GetTempDir() string {
return p.Config.TempDirPath
}

func (p *pluginControl) SetPluginTrustLevel(trust int) {
p.pluginTrust = trust
}
Expand Down
6 changes: 3 additions & 3 deletions control/control_grpc_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func TestGRPCServerScheduler(t *testing.T) {
// collector -- mock
// processor -- passthru
// publisher -- file
mock, err := core.NewRequestedPlugin(fixtures.PluginPathMock1)
mock, err := core.NewRequestedPlugin(fixtures.PluginPathMock1, GetDefaultConfig().TempDirPath, nil)
if err != nil {
log.Fatal(err)
}
Expand All @@ -99,7 +99,7 @@ func TestGRPCServerScheduler(t *testing.T) {
})
})
<-lpe.done
passthru, err := core.NewRequestedPlugin(helper.PluginFilePath("snap-plugin-processor-passthru"))
passthru, err := core.NewRequestedPlugin(helper.PluginFilePath("snap-plugin-processor-passthru"), GetDefaultConfig().TempDirPath, nil)
if err != nil {
log.Fatal(err)
}
Expand All @@ -115,7 +115,7 @@ func TestGRPCServerScheduler(t *testing.T) {
typeName: catalogedPassthru.TypeName(),
}
<-lpe.done
filepub, err := core.NewRequestedPlugin(helper.PluginFilePath("snap-plugin-publisher-mock-file"))
filepub, err := core.NewRequestedPlugin(helper.PluginFilePath("snap-plugin-publisher-mock-file"), GetDefaultConfig().TempDirPath, nil)
if err != nil {
log.Fatal(err)
}
Expand Down
14 changes: 7 additions & 7 deletions control/control_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// +build legacy

/*
http://www.apache.org/licenses/LICENSE-2.0.txt
Expand Down Expand Up @@ -94,7 +93,8 @@ func load(c *pluginControl, paths ...string) (core.CatalogedPlugin, serror.SnapE
// 3 times before letting the error through. Hopefully this cuts down on the number of Travis failures
var e serror.SnapError
var p core.CatalogedPlugin
rp, err := core.NewRequestedPlugin(paths[0])

rp, err := core.NewRequestedPlugin(paths[0], GetDefaultConfig().TempDirPath, nil)
if err != nil {
return nil, serror.New(err)
}
Expand Down Expand Up @@ -191,7 +191,7 @@ func TestSwapPlugin(t *testing.T) {
})
})

mockRP, mErr := core.NewRequestedPlugin(fixtures.PluginPathMock1)
mockRP, mErr := core.NewRequestedPlugin(fixtures.PluginPathMock1, GetDefaultConfig().TempDirPath, nil)
Convey("Requested collector plugin should not error", func() {
So(mErr, ShouldBeNil)
})
Expand Down Expand Up @@ -235,7 +235,7 @@ func TestSwapPlugin(t *testing.T) {
Convey("Swap plugin with a different type of plugin", func() {
filePath := helper.PluginFilePath("snap-plugin-publisher-mock-file")
So(filePath, ShouldNotBeEmpty)
fileRP, pErr := core.NewRequestedPlugin(fixtures.PluginPathMock1)
fileRP, pErr := core.NewRequestedPlugin(fixtures.PluginPathMock1, GetDefaultConfig().TempDirPath, nil)
Convey("Requested publisher plugin should not error", func() {
So(pErr, ShouldBeNil)
Convey("Swapping collector and publisher plugins", func() {
Expand All @@ -258,7 +258,7 @@ func TestSwapPlugin(t *testing.T) {
pm.ExistingPlugin = lp
c.pluginManager = pm

mockRP, mErr := core.NewRequestedPlugin(fixtures.PluginPathMock1)
mockRP, mErr := core.NewRequestedPlugin(fixtures.PluginPathMock1, GetDefaultConfig().TempDirPath, nil)
So(mErr, ShouldBeNil)
err := c.SwapPlugins(mockRP, lp)
Convey("So err should be received if rollback fails", func() {
Expand Down Expand Up @@ -1677,8 +1677,8 @@ func TestMetricSubscriptionToNewVersion(t *testing.T) {
c.eventManager.RegisterHandler("TestMetricSubscriptionToNewVersion", lpe)
c.Start()
_, err := load(c, helper.PluginFilePath("snap-plugin-collector-mock1"))
<-lpe.load
So(err, ShouldBeNil)
<-lpe.load
So(len(c.pluginManager.all()), ShouldEqual, 1)
lp, err2 := c.pluginManager.get("collector" + core.Separator + "mock" + core.Separator + "1")
So(err2, ShouldBeNil)
Expand Down Expand Up @@ -1752,8 +1752,8 @@ func TestMetricSubscriptionToOlderVersion(t *testing.T) {
c.eventManager.RegisterHandler("TestMetricSubscriptionToOlderVersion", lpe)
c.Start()
_, err := load(c, helper.PluginFilePath("snap-plugin-collector-mock2"))
<-lpe.load
So(err, ShouldBeNil)
<-lpe.load
So(len(c.pluginManager.all()), ShouldEqual, 1)
lp, err2 := c.pluginManager.get("collector" + core.Separator + "mock" + core.Separator + "2")
So(err2, ShouldBeNil)
Expand Down
58 changes: 26 additions & 32 deletions control/plugin_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,14 @@ func (l *loadedPlugins) findLatest(typeName, name string) (*loadedPlugin, error)

// the struct representing a plugin that is loaded into snap
type pluginDetails struct {
CheckSum [sha256.Size]byte
Exec []string
ExecPath string
IsPackage bool
IsAutoLoaded bool
Manifest *schema.ImageManifest
Path string
Signed bool
Signature []byte
CheckSum [sha256.Size]byte
Exec []string
ExecPath string
IsPackage bool
Manifest *schema.ImageManifest
Path string
Signed bool
Signature []byte
}

type loadedPlugin struct {
Expand Down Expand Up @@ -318,13 +317,15 @@ func (p *pluginManager) LoadPlugin(details *pluginDetails, emitter gomit.Emitter
"_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())),
commands...)
Expand Down Expand Up @@ -575,35 +576,28 @@ func (p *pluginManager) UnloadPlugin(pl core.Plugin) (*loadedPlugin, serror.Snap
return nil, se
}

// If the plugin has been uploaded via REST API
// aka, was not auto loaded from auto_discover_path
// nor loaded from tests
// then do clean up
if !plugin.Details.IsAutoLoaded {
pmLogger.WithFields(log.Fields{
"plugin-type": plugin.TypeName(),
"plugin-name": plugin.Name(),
"plugin-version": plugin.Version(),
"plugin-path": plugin.Details.Path,
}).Debugf("Removing plugin")
if err := os.RemoveAll(filepath.Dir(plugin.Details.Path)); err != nil {
pmLogger.WithFields(log.Fields{
"plugin-type": plugin.TypeName(),
"plugin-name": plugin.Name(),
"plugin-version": plugin.Version(),
"plugin-path": plugin.Details.Path,
}).Debugf("Removing plugin")
if err := os.RemoveAll(filepath.Dir(plugin.Details.Path)); err != nil {
pmLogger.WithFields(log.Fields{
"plugin-type": plugin.TypeName(),
"plugin-name": plugin.Name(),
"plugin-version": plugin.Version(),
"plugin-path": plugin.Details.Path,
}).Error(err)
se := serror.New(err)
se.SetFields(map[string]interface{}{
"plugin-type": plugin.TypeName(),
"plugin-name": plugin.Name(),
"plugin-version": plugin.Version(),
"plugin-path": plugin.Details.Path,
})
return nil, se
}
}).Error(err)
se := serror.New(err)
se.SetFields(map[string]interface{}{
"plugin-type": plugin.TypeName(),
"plugin-name": plugin.Name(),
"plugin-version": plugin.Version(),
"plugin-path": plugin.Details.Path,
})
return nil, se
}

p.loadedPlugins.remove(plugin.Key())

// Remove any metrics from the catalog if this was a collector
Expand Down
39 changes: 32 additions & 7 deletions control/plugin_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,20 @@ limitations under the License.
package control

import (
"bufio"
"errors"
"os"
"path/filepath"
"testing"
"time"

. "github.com/smartystreets/goconvey/convey"

"github.com/intelsdi-x/snap/control/fixtures"
"github.com/intelsdi-x/snap/control/plugin"
"github.com/intelsdi-x/snap/core"
"github.com/intelsdi-x/snap/core/ctypes"
"github.com/intelsdi-x/snap/core/serror"
"github.com/intelsdi-x/snap/pkg/fileutils"
. "github.com/smartystreets/goconvey/convey"
)

func TestLoadedPlugins(t *testing.T) {
Expand Down Expand Up @@ -65,18 +67,41 @@ func TestLoadedPlugins(t *testing.T) {
})
}

func loadPlugin(p *pluginManager, path string) (*loadedPlugin, serror.SnapError) {
func loadPlugin(p *pluginManager, fileName string) (*loadedPlugin, serror.SnapError) {
// This is a Travis optimized loading of plugins. From time to time, tests will error in Travis
// due to a timeout when waiting for a response from a plugin. We are going to attempt loading a plugin
// 3 times before letting the error through. Hopefully this cuts down on the number of Travis failures
var e serror.SnapError
var lp *loadedPlugin
file, err := os.Open(fileName)
if err != nil {
return nil, serror.New(err)
}
defer file.Close()

info, err := file.Stat()
if err != nil {
return nil, serror.New(err)
}
size := info.Size()
bytes := make([]byte, size)
buffer := bufio.NewReader(file)
_, err = buffer.Read(bytes)
if err != nil {
return nil, serror.New(err)
}

path, err := fileutils.WriteFile(filepath.Base(fileName), GetDefaultConfig().TempDirPath, bytes)
if err != nil {
return nil, serror.New(err)
}

details := &pluginDetails{
Path: path,
ExecPath: filepath.Dir(path),
Exec: []string{filepath.Base(path)},
IsAutoLoaded: true,
Path: path,
ExecPath: filepath.Dir(path),
Exec: []string{filepath.Base(path)},
}

for i := 0; i < 3; i++ {
lp, e = p.LoadPlugin(details, nil)
if e == nil {
Expand Down
2 changes: 1 addition & 1 deletion control/subscription_group_medium_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,7 @@ func loadPlg(c *pluginControl, paths ...string) (core.CatalogedPlugin, serror.Sn
// 3 times before letting the error through. Hopefully this cuts down on the number of Travis failures
var e serror.SnapError
var p core.CatalogedPlugin
rp, err := core.NewRequestedPlugin(paths[0])
rp, err := core.NewRequestedPlugin(paths[0], GetDefaultConfig().TempDirPath, nil)
if err != nil {
return nil, serror.New(err)
}
Expand Down
Loading

0 comments on commit 1a415fa

Please sign in to comment.