/
client.go
70 lines (54 loc) · 1.55 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// SPDX-FileCopyrightText: 2023 Iván Szkiba
//
// SPDX-License-Identifier: MIT
package extension
import (
"errors"
"os/exec"
"path/filepath"
"strings"
"github.com/google/shlex"
"github.com/hashicorp/go-plugin"
"github.com/sirupsen/logrus"
"github.com/szkiba/xk6-output-plugin-go/output"
)
const pluginCommandPrefix = "xk6-output-plugin-"
func newPlugin(cmd string, logger logrus.FieldLogger) (output.Output, error) {
args, err := shlex.Split(cmd)
if err != nil {
return nil, err
}
dir, file := filepath.Split(args[0])
if !strings.HasPrefix(file, pluginCommandPrefix) {
file = pluginCommandPrefix + file
}
args[0] = filepath.Join(dir, file)
if dir == "./" {
args[0] = dir + args[0]
}
hclogger := wrapLogger(logger.WithField("plugin", strings.TrimPrefix(filepath.Base(args[0]), pluginCommandPrefix)))
if c, err := exec.LookPath(pluginCommandPrefix + args[0]); err == nil {
args[0] = c
}
client := plugin.NewClient(&plugin.ClientConfig{ // nolint:exhaustruct
HandshakeConfig: output.Handshake,
Plugins: output.PluginMap,
Cmd: exec.Command(args[0], args[1:]...), // nolint:gosec
AllowedProtocols: []plugin.Protocol{plugin.ProtocolNetRPC, plugin.ProtocolGRPC},
Logger: hclogger,
})
rpcClient, err := client.Client()
if err != nil {
return nil, err
}
// Request the plugin
raw, err := rpcClient.Dispense("output")
if err != nil {
return nil, err
}
if out, ok := raw.(output.Output); ok {
return out, nil
}
return nil, ErrInvalidPlugin
}
var ErrInvalidPlugin = errors.New("invalid plugin")