Example #1
0
func main() {
	log.SetPrefix("[master log] ")

	path := "plugin_provider"
	if runtime.GOOS == "windows" {
		path = path + ".exe"
	}

	client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, path)
	if err != nil {
		log.Fatalf("Error running plugin: %s", err)
	}
	defer client.Close()
	p := plug{client}
	res, err := p.SayHi("master")
	if err != nil {
		log.Fatalf("error calling SayHi: %s", err)
	}
	log.Printf("Response from plugin: %q", res)

	res, err = p.SayBye("master")
	if err != nil {
		log.Fatalf("error calling SayBye: %s", err)
	}
	log.Printf("Response from plugin2: %q", res)

}
Example #2
0
func executeTests(config Config, tests []string) error {
	var commands []string
	var err error
	codec := jsonrpc.NewClientCodec

	plugin, err := pie.StartProviderCodec(codec, os.Stderr, config.Executor.Command, config.Executor.Args...)

	if err != nil {
		return err
	}

	if err = plugin.Call("Executor.GetCommands", tests, commands); err != nil {
		return err
	}

	for _, command := range commands {
		// FIXME this only works on Unixes
		cmd := exec.Command("sh", "-c", command)
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		err = cmd.Run()
		if err != nil {
			return err
		}
	}
	return nil
}
Example #3
0
func (p *rpcPlugin) newClient() error {
	client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, p.path)
	if err != nil {
		log.Fatalf("Error running plugin: %s", err)
	}
	p.client = client
	return nil
}
Example #4
0
// This function should be called from the master program that wants to run
// plugins to extend its functionality.
//
// This example shows the master program starting a plugin at path
// "/var/lib/foo", using JSON-RPC, and writing its output to this application's
// Stderr.  The application can then call methods on the rpc client returned
// using the standard rpc pattern.
func ExampleStartProviderCodec() {
	client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, "/var/lib/foo")
	if err != nil {
		log.Fatalf("failed to load foo plugin: %s", err)
	}
	var reply string
	client.Call("Foo.ToUpper", "something", &reply)
}
Example #5
0
func createClient() *plug {
	log.Printf("Creating plugin")
	client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, path)
	if err != nil {
		log.Printf("Create error: %v", err)
	}
	p := &plug{client}
	return p
}
Example #6
0
func LoadProvisioner(name string) *ProvisionerPlugin {
	if provisioner == nil {
		driverPath := fmt.Sprintf("anvil-provisioner-%s", name)
		client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, driverPath)
		if err != nil {
			log.Fatalf("Can't load provisioner %s", name)
		}
		provisioner = &ProvisionerPlugin{client}
	}
	return provisioner
}
Example #7
0
func LoadVerifier(name string) *VerifierPlugin {
	if verifier == nil {
		driverPath := fmt.Sprintf("anvil-verifier-%s", name)
		client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, driverPath)
		if err != nil {
			log.Fatalf("Can't load verifier %s", name)
		}
		verifier = &VerifierPlugin{client}
	}
	return verifier
}
Example #8
0
func LoadVerifyResultFormatter(name string) *VerifyResultFormatterPlugin {
	if formatterPlugin == nil {
		driverPath := fmt.Sprintf("anvil-formatter-%s", name)
		client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, driverPath)
		if err != nil {
			log.Fatalf("Can't load verify result formatter %s", name)
		}
		formatterPlugin = &VerifyResultFormatterPlugin{client}
	}
	return formatterPlugin
}
Example #9
0
func LoadDriver(name string) *DriverPlugin {
	if driver == nil {
		driverPath := fmt.Sprintf("anvil-driver-%s", name)
		client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, driverPath)
		if err != nil {
			log.Fatalf("Can't load driver %s", name)
		}
		driver = &DriverPlugin{client}
		driver.Init(config.Cfg.Driver.Options)
	}
	return driver
}
Example #10
0
func (p *pi) newClient() {
	// note if the client is still running we can't p.client.Close() without a data-race
	// TODO investigate if there is a better way to clean-up
	if p.useJSON {
		p.client, p.err = pie.StartProviderCodec(
			jsonrpc.NewClientCodec, os.Stderr, p.cmdPath, p.args...)
	} else {
		p.client, p.err = pie.StartProvider(os.Stderr, p.cmdPath, p.args...)
	}
	if p.err != nil {
		p.err = fmt.Errorf("plugin %#v failed, error %v", *p, p.err)
	}
}
Example #11
0
func NewCephPlugin() *CephPlugin {

	//ceph plugin
	path := "./plugin_provider"
	cephclient, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, path)
	if err != nil {
		fmt.Println("Error running plugin:")
	}

	cplug := &CephPlugin{}
	cplug.Name = "ceph"
	cplug.Client = cephclient
	return cplug
}
Example #12
0
func NewGlusterPlugin() *GlusterPlugin {

	//gluster plugin
	path := "./plugin_provider"

	glusterclient, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, path)
	if err != nil {
		fmt.Println("Error running plugin:")
	}

	gplug := &GlusterPlugin{}
	gplug.Name = "gluster"
	gplug.Client = glusterclient
	return gplug
}
Example #13
0
func determineTestsToExecute(config Config, changedFiles []string) ([]string, error) {
	var testsToRun []string
	var err error
	codec := jsonrpc.NewClientCodec

	plugin, err := pie.StartProviderCodec(codec, os.Stderr, config.Locator.Command, config.Locator.Args...)

	if err != nil {
		return nil, err
	}

	if err = plugin.Call("Locator.Locate", changedFiles, testsToRun); err != nil {
		return nil, err
	}
	return testsToRun, nil
}
Example #14
0
// StartComputationPlugin starts the plugin process
func StartComputationPlugin(name string, compID StreamID) (ComputationPlugin, error) {
	log.Printf("[computations] Launching computation plugin '%s'", name)
	path := path.Join(os.Getenv("DAGGER_PLUGIN_PATH"), "computation-"+name)
	client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec,
		os.Stderr,
		path,
	)
	if err != nil {
		return nil, fmt.Errorf("Error starting plugin %s: %s", name, err)
	}
	plugin := &computationPlugin{
		name:   name,
		compID: compID,
		client: client,
	}
	return plugin, nil
}
Example #15
0
func findChangedFiles(config Config) ([]string, error) {
	var changedFiles []string
	var err error
	var workingDir string
	codec := jsonrpc.NewClientCodec

	plugin, err := pie.StartProviderCodec(codec, os.Stderr, config.Differ.Command, config.Differ.Args...)

	if err != nil {
		return nil, err
	}

	if workingDir, err = os.Getwd(); err != nil {
		return nil, err
	}
	if err = plugin.Call("Differ.Diff", workingDir, changedFiles); err != nil {
		return nil, err
	}
	return changedFiles, nil
}
Example #16
0
func (a *App) StartProviders(configDir string, binDir string) error {
	key, err := ioutil.ReadFile(models.SKYRING_ENC_KEY_FILE)
	if err != nil {
		panic(fmt.Sprintf("Unable to read enc key file. err: %v", err))
	}

	providerBinaryPath := path.Join(binDir, conf.ProviderBinaryDir)

	configs := conf.LoadProviderConfig(path.Join(configDir, conf.ProviderConfDir))
	logger.Get().Info("Config:", configs)

	for _, config := range configs {
		logger.Get().Debug("Config:", config)

		//check if the routes are unique
		//Load the routes later after the provider starts
		//successfully, otherwise we have to remove the routes if the provider
		//fails to start
		var found bool
		for _, element := range config.Routes {
			if _, ok := a.routes[element.Name]; ok {
				logger.Get().Error("Error in Route configuration, Duplicate route: %s", element.Name)
				//Dont proceed further
				found = true
				break
			}
		}
		//If duplicate routes are detected, dont proceed loading this provider
		if found {
			logger.Get().Error("Duplicate routes detected, skipping the provider", config)
			continue
		}
		//Start the provider if configured
		if config.Provider != (conf.ProviderConfig{}) {

			if config.Provider.Name == "" {
				logger.Get().Error("Provider Name Empty, skipping the provider", config)
				continue
			}
			//check whether the plugin is initialized already
			if _, ok := a.providers[config.Provider.Name]; ok {
				//Provider already initialized
				logger.Get().Info("Provider already initialized, skipping the provider", config)
				continue
			}
			//Initilaize the provisioner
			prov, err := provisioner.InitializeProvisioner(config.Provisioner)
			if err != nil {
				logger.Get().Error("Unable to initialize the provisioner, skipping the provider:%v", config)
				continue
			}
			if config.Provider.ProviderBinary == "" {
				//set the default if not provided in config file
				config.Provider.ProviderBinary = path.Join(providerBinaryPath, config.Provider.Name)
			} else {
				config.Provider.ProviderBinary = path.Join(providerBinaryPath, config.Provider.ProviderBinary)
			}

			confStr, _ := json.Marshal(conf.SystemConfig)
			enConfStr, err := crypto.Encrypt(key, []byte(confStr))
			if err != nil {
				logger.Get().Error("Error encrypting the configurations. err: %v", err)
				continue
			}
			enConfStr1 := make([]byte, base64.StdEncoding.EncodedLen(len(enConfStr)))
			base64.StdEncoding.Encode(enConfStr1, []byte(enConfStr))

			eventTypesStr, _ := json.Marshal(EventTypes)
			providerConfStr, _ := json.Marshal(config)
			client, err := pie.StartProviderCodec(
				jsonrpc.NewClientCodec,
				os.Stderr,
				config.Provider.ProviderBinary,
				string(enConfStr1),
				string(eventTypesStr),
				string(providerConfStr))
			if err != nil {
				logger.Get().Error("Error starting provider for %s. error: %v", config.Provider.Name, err)
				continue
			}
			//Load the routes
			for _, element := range config.Routes {
				//prefix the provider name to the route
				element.Pattern = fmt.Sprintf("%s/%s", config.Provider.Name, element.Pattern)
				a.routes[element.Name] = element
			}

			//add the provider to the map
			a.providers[config.Provider.Name] = Provider{Name: config.Provider.Name, Client: client, ProvisionerName: prov}
		}
	}
	if len(a.providers) < 1 {
		return errors.New("None of the providers are initialized successfully")
	}
	return nil
}
Example #17
0
// Takes a Lua state and a term Output (should be nil if not in a REPL)
func exportPluginFunctions(L *lua.LState, o *term.TextOutput) {

	// Expose the functionality of a given plugin (executable file).
	// If on Windows, ".exe" is added to the path.
	// Returns true of successful.
	L.SetGlobal("Plugin", L.NewFunction(func(L *lua.LState) int {
		path := L.ToString(1)
		givenPath := path
		if runtime.GOOS == "windows" {
			path = path + ".exe"
		}
		if !fs.exists(path) {
			path = filepath.Join(serverDir, path)
		}

		// Connect with the Plugin
		client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, path)
		if err != nil {
			if o != nil {
				o.Err("[Plugin] Could not run plugin!")
				o.Err("Error: " + err.Error())
			}
			L.Push(lua.LBool(false)) // Fail
			return 1                 // number of results
		}
		// May cause a data race
		//defer client.Close()
		p := &luaPlugin{client}

		// Retrieve the Lua code
		luacode, err := p.LuaCode(givenPath)
		if err != nil {
			if o != nil {
				o.Err("[Plugin] Could not call the LuaCode function!")
				o.Err("Error: " + err.Error())
			}
			L.Push(lua.LBool(false)) // Fail
			return 1                 // number of results
		}

		// Retrieve the help text
		luahelp, err := p.LuaHelp()
		if err != nil {
			if o != nil {
				o.Err("[Plugin] Could not call the LuaHelp function!")
				o.Err("Error: " + err.Error())
			}
			L.Push(lua.LBool(false)) // Fail
			return 1                 // number of results
		}

		// Run luacode on the current LuaState
		luacode = strings.TrimSpace(luacode)
		if L.DoString(luacode) != nil {
			if o != nil {
				o.Err("[Plugin] Error in Lua code provided by plugin!")
				o.Err("Error: " + err.Error())
			}
			L.Push(lua.LBool(false)) // Fail
			return 1                 // number of results
		}

		// If in a REPL, output the Plugin help text
		if o != nil {
			luahelp = strings.TrimSpace(luahelp)
			// Add syntax highlighting and output the text
			o.Println(highlight(o, luahelp))
		}

		L.Push(lua.LBool(true)) // Success
		return 1                // number of results
	}))

	// Retrieve the code from the Lua.Code function of the plugin
	L.SetGlobal("PluginCode", L.NewFunction(func(L *lua.LState) int {
		path := L.ToString(1)
		givenPath := path
		if runtime.GOOS == "windows" {
			path = path + ".exe"
		}
		if !fs.exists(path) {
			path = filepath.Join(serverDir, path)
		}

		// Connect with the Plugin
		client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, path)
		if err != nil {
			if o != nil {
				o.Err("[PluginCode] Could not run plugin!")
				o.Err("Error: " + err.Error())
			}
			L.Push(lua.LString("")) // Fail
			return 1                // number of results
		}
		// May cause a data race
		//defer client.Close()
		p := &luaPlugin{client}

		// Retrieve the Lua code
		luacode, err := p.LuaCode(givenPath)
		if err != nil {
			if o != nil {
				o.Err("[PluginCode] Could not call the LuaCode function!")
				o.Err("Error: " + err.Error())
			}
			L.Push(lua.LString("")) // Fail
			return 1                // number of results
		}

		L.Push(lua.LString(luacode))
		return 1 // number of results
	}))

	// Call a function exposed by a plugin (executable file)
	// Returns either nil (fail) or a string (success)
	L.SetGlobal("CallPlugin", L.NewFunction(func(L *lua.LState) int {
		if L.GetTop() < 2 {
			if o != nil {
				o.Err("[CallPlugin] Needs at least 2 arguments")
			}
			L.Push(lua.LString("")) // Fail
			return 1                // number of results
		}

		path := L.ToString(1)
		if runtime.GOOS == "windows" {
			path = path + ".exe"
		}
		if !fs.exists(path) {
			path = filepath.Join(serverDir, path)
		}

		fn := L.ToString(2)

		var args []lua.LValue
		if L.GetTop() > 2 {
			for i := 3; i <= L.GetTop(); i++ {
				args = append(args, L.Get(i))
			}
		}

		// Connect with the Plugin
		logto := os.Stderr
		if o != nil {
			logto = os.Stdout
		}
		client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, logto, path)
		if err != nil {
			if o != nil {
				o.Err("[CallPlugin] Could not run plugin!")
				o.Err("Error: " + err.Error())
			}
			L.Push(lua.LString("")) // Fail
			return 1                // number of results
		}
		// May cause a data race
		//defer client.Close()

		jsonargs, err := json.Marshal(args)
		if err != nil {
			if o != nil {
				o.Err("[CallPlugin] Error when marshalling arguments to JSON")
				o.Err("Error: " + err.Error())
			}
			L.Push(lua.LString("")) // Fail
			return 1                // number of results
		}

		// Attempt to call the given function name
		var jsonreply []byte
		if err := client.Call(namespace+"."+fn, jsonargs, &jsonreply); err != nil {
			if o != nil {
				o.Err("[CallPlugin] Error when calling function!")
				o.Err("Function: " + namespace + "." + fn)
				o.Err("JSON Arguments: " + string(jsonargs))
				o.Err("Error: " + err.Error())
			}
			L.Push(lua.LString("")) // Fail
			return 1                // number of results
		}

		L.Push(lua.LString(jsonreply)) // Resulting string
		return 1                       // number of results
	}))

}
Example #18
0
func (a *App) StartProviders(configDir string, binDir string) error {

	providerBinaryPath := path.Join(binDir, ProviderBinaryDir)

	configs := conf.LoadProviderConfig(path.Join(configDir, ProviderConfDir))
	logger.Get().Info("Config:", configs)

	for _, config := range configs {
		logger.Get().Debug("Config:", config)

		//check if the routes are unique
		//Load the routes later after the provider starts
		//successfully, otherwise we have to remove the routes if the provider
		//fails to start
		var found bool
		for _, element := range config.Routes {
			if _, ok := a.routes[element.Name]; ok {
				logger.Get().Error("Error in Route configuration, Duplicate route: %s", element.Name)
				//Dont proceed further
				found = true
				break
			}
		}
		//If duplicate routes are detected, dont proceed loading this provider
		if found {
			logger.Get().Error("Duplicate routes detected, skipping the provider", config)
			continue
		}
		//Start the provider if configured
		if config.Provider != (conf.ProviderConfig{}) {

			if config.Provider.Name == "" {
				logger.Get().Error("Provider Name Empty, skipping the provider", config)
				continue
			}
			//check whether the plugin is initialized already
			if _, ok := a.providers[config.Provider.Name]; ok {
				//Provider already initialized
				logger.Get().Info("Provider already initialized, skipping the provider", config)
				continue
			}
			if config.Provider.ProviderBinary == "" {
				//set the default if not provided in config file
				config.Provider.ProviderBinary = path.Join(providerBinaryPath, config.Provider.Name)
			} else {
				config.Provider.ProviderBinary = path.Join(providerBinaryPath, config.Provider.ProviderBinary)
			}

			confStr, _ := json.Marshal(conf.SystemConfig)
			client, err := pie.StartProviderCodec(jsonrpc.NewClientCodec, os.Stderr, config.Provider.ProviderBinary, string(confStr))
			if err != nil {
				logger.Get().Error("Error starting provider for %s. error: %v", config.Provider.Name, err)
				continue
			}
			//Load the routes
			for _, element := range config.Routes {
				//prefix the provider name to the route
				element.Pattern = fmt.Sprintf("%s/%s", config.Provider.Name, element.Pattern)
				a.routes[element.Name] = element
			}
			//add the provider to the map
			a.providers[config.Provider.Name] = Provider{Name: config.Provider.Name, Client: client}
		}
	}
	if len(a.providers) < 1 {
		return errors.New("None of the providers are initialized successfully")
	}
	return nil
}