forked from DataDog/datadog-agent
-
Notifications
You must be signed in to change notification settings - Fork 2
/
util.go
151 lines (128 loc) · 3.57 KB
/
util.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package util
import (
"bufio"
"bytes"
"errors"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"github.com/StackVista/stackstate-agent/pkg/config"
"github.com/StackVista/stackstate-agent/pkg/util/docker"
)
// ErrNotImplemented is the "not implemented" error given by `gopsutil` when an
// OS doesn't support and API. Unfortunately it's in an internal package so
// we can't import it so we'll copy it here.
var ErrNotImplemented = errors.New("not implemented yet")
// ReadLines reads contents from a file and splits them by new lines.
func ReadLines(filename string) ([]string, error) {
f, err := os.Open(filename)
if err != nil {
return []string{""}, err
}
defer f.Close()
var ret []string
scanner := bufio.NewScanner(f)
for scanner.Scan() {
ret = append(ret, scanner.Text())
}
return ret, scanner.Err()
}
// GetEnv retrieves the environment variable key. If it does not exist it returns the default.
func GetEnv(key string, dfault string, combineWith ...string) string {
value := os.Getenv(key)
if value == "" {
value = dfault
}
switch len(combineWith) {
case 0:
return value
case 1:
return filepath.Join(value, combineWith[0])
default:
var b bytes.Buffer
b.WriteString(value)
for _, v := range combineWith {
b.WriteRune('/')
b.WriteString(v)
}
return b.String()
}
}
// HostProc returns the location of a host's procfs. This can and will be
// overridden when running inside a container.
func HostProc(combineWith ...string) string {
return GetEnv("HOST_PROC", "/proc", combineWith...)
}
// HostSys returns the location of a host's /sys. This can and will be overridden
// when running inside a container.
func HostSys(combineWith ...string) string {
return GetEnv("HOST_SYS", "/sys", combineWith...)
}
// PathExists returns a boolean indicating if the given path exists on the file system.
func PathExists(filename string) bool {
if _, err := os.Stat(filename); err == nil {
return true
}
return false
}
// StringInSlice returns true if the given searchString is in the given slice, false otherwise.
func StringInSlice(slice []string, searchString string) bool {
for _, curString := range slice {
if curString == searchString {
return true
}
}
return false
}
// GetDockerSocketPath is only for exposing the sockpath out of the module
func GetDockerSocketPath() (string, error) {
// If we don't have a docker.sock then return a known error.
sockPath := GetEnv("DOCKER_SOCKET_PATH", "/var/run/docker.sock")
if !PathExists(sockPath) {
return "", docker.ErrDockerNotAvailable
}
return sockPath, nil
}
// GetProcRoot retrieves the current procfs dir we should use
func GetProcRoot() string {
if v := os.Getenv("HOST_PROC"); v != "" {
return v
}
if config.IsContainerized() && PathExists("/host") {
return "/host/proc"
}
return "/proc"
}
// GetSysRoot retrieves the current sysfs dir we should use
func GetSysRoot() string {
if v := os.Getenv("HOST_SYS"); v != "" {
return v
}
if config.IsContainerized() && PathExists("/host") {
return "/host/sys"
}
return "/sys"
}
// WithAllProcs will execute `fn` for every pid under procRoot. `fn` is
// passed the `pid`. If `fn` returns an error the iteration aborts,
// returning the last error returned from `fn`.
func WithAllProcs(procRoot string, fn func(int) error) error {
files, err := ioutil.ReadDir(procRoot)
if err != nil {
return err
}
for _, f := range files {
if !f.IsDir() || f.Name() == "." || f.Name() == ".." {
continue
}
var pid int
if pid, err = strconv.Atoi(f.Name()); err != nil {
continue
}
if err = fn(pid); err != nil {
return err
}
}
return nil
}