forked from newrelic/nri-flex
/
docker.go
88 lines (79 loc) · 2.09 KB
/
docker.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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
* Copyright 2019 New Relic Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package discovery
import (
"bufio"
"context"
"fmt"
"github.com/newrelic/nri-flex/internal/load"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
)
var cli *client.Client
// setDockerClient Sets the docker client
// There can be edge cases when the integration API version may need a matching or lower API version then the hosts docker API version
func setDockerClient() (*client.Client, error) {
// var out []byte
var err error
if load.Args.DockerAPIVersion != "" {
load.Logrus.Debug(fmt.Sprintf("docker: setting client via argument %v", load.Args.DockerAPIVersion))
cli, err = client.NewClientWithOpts(client.WithVersion(load.Args.DockerAPIVersion))
} else {
load.Logrus.Debug("docker: setting client with API version negotiation")
cli, err = client.NewClientWithOpts(client.WithAPIVersionNegotiation())
}
return cli, err
}
// ExecContainerCommand execute command against a container
func ExecContainerCommand(containerID string, command []string) (string, error) {
if cli == nil {
var err error
cli, err = setDockerClient()
if err != nil {
return "", err
}
}
ctx := context.Background()
execConfig := types.ExecConfig{
AttachStderr: true,
AttachStdin: true,
AttachStdout: true,
Cmd: command,
Tty: true,
Detach: false,
}
//set target container
exec, err := cli.ContainerExecCreate(ctx, containerID, execConfig)
if err != nil {
return "", err
}
execAttachConfig := types.ExecStartCheck{
Detach: false,
Tty: true,
}
containerConn, err := cli.ContainerExecAttach(ctx, exec.ID, execAttachConfig)
if err != nil {
return "", err
}
defer containerConn.Close()
data, err := Readln(containerConn.Reader)
if err != nil {
return "", err
}
return data, nil
}
// Readln from bufioReader
func Readln(r *bufio.Reader) (string, error) {
var (
isPrefix = true
err error
line, ln []byte
)
for isPrefix && err == nil {
line, isPrefix, err = r.ReadLine()
ln = append(ln, line...)
}
return string(ln), err
}