mirror of
https://github.com/mudler/luet.git
synced 2025-09-16 15:19:24 +00:00
110 lines
3.4 KiB
Markdown
110 lines
3.4 KiB
Markdown
# :bento: go-pluggable
|
|
[](https://pkg.go.dev/github.com/mudler/go-pluggable) [](https://goreportcard.com/report/github.com/mudler/go-pluggable) [](https://github.com/mudler/go-pluggable/actions?query=workflow%3ATest)
|
|
|
|
:bento: *go-pluggable* is a light Bus-event driven plugin library for Golang.
|
|
|
|
`go-pluggable` implements the event/sub pattern to extend your Golang project with external binary plugins that can be written in any language.
|
|
|
|
```golang
|
|
import "github.com/mudler/go-pluggable"
|
|
|
|
|
|
func main() {
|
|
|
|
var myEv pluggableEventType = "something.to.hook.on"
|
|
temp := "/usr/custom/bin"
|
|
|
|
m = pluggable.NewManager(
|
|
[]pluggable.EventType{
|
|
myEv,
|
|
},
|
|
)
|
|
|
|
// Load plugins
|
|
m.Autoload("test", temp) // Scan for binary plugins with the "test" prefix. E.g. 'test-foo'
|
|
m.Plugin = append(m.Plugin, pluggable.Plugin{ Name: "foo" , Executable: "path" }) // manually add a Plugin
|
|
m.Load("my-binary", "my-binary-2"...) // Load individually, scanning $PATH
|
|
|
|
// Register to events and initialize the manager
|
|
m.Register()
|
|
|
|
// Optionally process plugin results response
|
|
// The plugins has to return as output a json in stdout in the format { 'state': "somestate", data: "some data", error: "some error" }
|
|
// e.g. with jq:
|
|
// jq --arg key0 'state' \
|
|
// --arg value0 '' \
|
|
// --arg key1 'data' \
|
|
// --arg value1 "" \
|
|
// --arg key2 'error' \
|
|
// --arg value2 '' \
|
|
// '. | .[$key0]=$value0 | .[$key1]=$value1 | .[$key2]=$value2' \
|
|
// <<<'{}'
|
|
m.Response(myEv, func(p *pluggable.Plugin, r *pluggable.EventResponse) { ... })
|
|
|
|
// Emit events, they are encoded and passed as JSON payloads to the plugins.
|
|
// In our case, test-foo will receive the map as JSON
|
|
m.Publish(myEv, map[string]string{"foo": "bar"})
|
|
}
|
|
|
|
```
|
|
|
|
# Plugin processed data
|
|
|
|
The interface passed to `Publish` gets marshalled in JSON in a event struct of the following form:
|
|
|
|
```go
|
|
type Event struct {
|
|
Name EventType `json:"name"`
|
|
Data string `json:"data"`
|
|
File string `json:"file"`
|
|
}
|
|
```
|
|
|
|
|
|
An example bash plugin could be, for example:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
|
|
event="$1"
|
|
payload="$2"
|
|
if [ "$event" == "something.to.hook.on" ]; then
|
|
custom_data=$(echo "$payload" | jq -r .data | jq -r .foo )
|
|
...
|
|
fi
|
|
```
|
|
|
|
Which can be called by
|
|
```golang
|
|
m.Publish(myEv, map[string]string{"foo": "bar"})
|
|
```
|
|
|
|
To note, when the payload exceeds the [threshold size](https://github.com/mudler/go-pluggable/blob/master/plugin.go#L35) the payload published with `Publish` is written into a temporary file and the file location is sent to the plugin with the Event `file` field, so for example, a plugin should expect data in a file if the publisher expects to send big chunk of data:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
data_file="$(echo $2 | jq -r .file)"
|
|
if [ -n "${data_file}" ]; then
|
|
payload="$(cat $data_file)"
|
|
|
|
...
|
|
fi
|
|
```
|
|
|
|
## Writing plugin in golang
|
|
|
|
It is present a `FactoryPlugin` which allows to create plugins in golang, consider:
|
|
|
|
```golang
|
|
import "github.com/mudler/go-pluggable"
|
|
|
|
func main() {
|
|
var myEv pluggableEventType = "event"
|
|
|
|
factory := pluggable.NewPluginFactory()
|
|
factory.Add(myEv, func(e *Event) EventResponse { return EventResponse{ ... })
|
|
|
|
factory.Run(os.Args[1], os.Args[2], os.Stdout)
|
|
}
|
|
|
|
``` |