"include/ck/utility/amd_llvm_intrinsic.hpp" did not exist on "bbcb67d0aac81b51336981713662a726875ebd58"
find.go 4.48 KB
Newer Older
liming6's avatar
liming6 committed
1
2
3
package docker

import (
4
	"strconv"
liming6's avatar
liming6 committed
5
6
7
8
9
10
11

	"context"
	"errors"
	"regexp"
	"strings"
	"sync"
	"time"
12
13
14

	"github.com/moby/moby/api/types/container"
	"github.com/moby/moby/client"
liming6's avatar
liming6 committed
15
16
17
18
19
20
21
)

var (
	ReDocker                      = regexp.MustCompile(`^.*docker[-/]([0-9a-z]*)(?:|.*)`)
	ContainerInfo *ContainersInfo = nil
)

liming6's avatar
liming6 committed
22
23
24
25
26
27
28
29
30
31
32
33
34
func NewContainersInfo() *ContainersInfo {
	ContainerInfo = &ContainersInfo{
		inspectInfo: make(map[string]container.InspectResponse),
		listInfo:    make(map[string]container.Summary),
		topInfo:     make(map[string]container.TopResponse),
		time:        time.Now(),
		inspectLock: sync.RWMutex{},
		topLock:     sync.RWMutex{},
		listLock:    sync.RWMutex{},
	}
	return ContainerInfo
}

liming6's avatar
liming6 committed
35
type ContainersInfo struct {
liming6's avatar
liming6 committed
36
	time        time.Time // 记录写入Info的时间
liming6's avatar
liming6 committed
37
	inspectInfo map[string]container.InspectResponse
liming6's avatar
liming6 committed
38
	inspectLock sync.RWMutex
liming6's avatar
liming6 committed
39
	listInfo    map[string]container.Summary
liming6's avatar
liming6 committed
40
	listLock    sync.RWMutex
41
	topInfo     map[string]container.TopResponse
liming6's avatar
liming6 committed
42
	topLock     sync.RWMutex
43
44
45
}

type ContainerPsInfo struct {
46
	Pid  int32
47
	Ppid int32
48
	Uid  string
49
	Cmd  string
50
51
}

52
func ParsePsInfo(topInfo map[string]container.TopResponse) (map[string][]ContainerPsInfo, error) {
53
54
55
	if topInfo == nil {
		return nil, errors.New("topInfo is nil")
	}
56
	result := make(map[string][]ContainerPsInfo)
57
	for cid, topResp := range topInfo {
58
59
		indexMap, t := make(map[string]int), 0
		result[cid] = make([]ContainerPsInfo, 0)
60
61
62
		for index, key := range topResp.Titles {
			switch strings.TrimSpace(strings.ToLower(key)) {
			case "pid":
63
				indexMap["pid"] = index
64
65
				t++
			case "ppid":
66
				indexMap["ppid"] = index
67
68
				t++
			case "uid":
69
				indexMap["uid"] = index
70
71
				t++
			case "cmd":
72
				indexMap["cmd"] = index
73
74
75
76
77
78
79
				t++
			default:
			}
			if t >= 4 {
				break
			}
		}
80
81
82
		for _, fields := range topResp.Processes {
			item := ContainerPsInfo{}
			if v, ok := indexMap["pid"]; ok {
83
				pid, err := strconv.ParseInt(fields[v], 10, 64)
84
85
86
87
				if err != nil {
					return nil, err
				}
				item.Pid = int32(pid)
88
			}
89
			if v, ok := indexMap["ppid"]; ok {
90
				ppid, err := strconv.ParseInt(fields[v], 10, 64)
91
92
93
				if err != nil {
					return nil, err
				}
94
				item.Ppid = int32(ppid)
95
			}
96
97
98
99
100
101
102
			if v, ok := indexMap["uid"]; ok {
				item.Uid = fields[v]
			}
			if v, ok := indexMap["cmd"]; ok {
				item.Cmd = fields[v]
			}
			result[cid] = append(result[cid], item)
103
104
105
		}
	}
	return result, nil
liming6's avatar
liming6 committed
106
107
108
}

func (info *ContainersInfo) Update() error {
liming6's avatar
liming6 committed
109
110
111
112
113
114
115
116
117
	info.listLock.Lock()
	info.topLock.Lock()
	info.inspectLock.Lock()
	defer func() {
		info.inspectLock.Unlock()
		info.topLock.Unlock()
		info.listLock.Unlock()
	}()
	i, s, t, err := getRunningContainerInfo()
liming6's avatar
liming6 committed
118
119
120
121
122
	if err != nil {
		return err
	}
	info.inspectInfo = i
	info.listInfo = s
123
	info.topInfo = t
liming6's avatar
liming6 committed
124
125
126
127
	info.time = time.Now()
	return nil
}

liming6's avatar
liming6 committed
128
129
130
func (info *ContainersInfo) GetInspectInfo(update bool) (map[string]container.InspectResponse, sync.Locker) {
	if update {
		info.Update()
liming6's avatar
liming6 committed
131
	}
liming6's avatar
liming6 committed
132
133
134
135
	rl := info.inspectLock.RLocker()
	rl.Lock()
	if info.inspectInfo == nil {
		return make(map[string]container.InspectResponse), rl
liming6's avatar
liming6 committed
136
	}
liming6's avatar
liming6 committed
137
	return info.inspectInfo, rl
liming6's avatar
liming6 committed
138
139
}

140
// GetProcessIdInDocker 获取所用容器的进程信息
liming6's avatar
liming6 committed
141
func (info *ContainersInfo) GetProcessIdInDocker(update bool) (map[string][]ContainerPsInfo, error) {
142
143
144
	if update {
		err := info.Update()
		if err != nil {
liming6's avatar
liming6 committed
145
			return nil, err
146
147
		}
	}
liming6's avatar
liming6 committed
148
	rl := info.topLock.RLocker()
149
150
151
152
	rl.Lock()
	i, err := ParsePsInfo(info.topInfo)
	rl.Unlock()
	rl = nil
liming6's avatar
liming6 committed
153
154
155
	if err != nil {
		return nil, err
	}
liming6's avatar
liming6 committed
156
	return i, nil
liming6's avatar
liming6 committed
157
158
}

liming6's avatar
liming6 committed
159
160
// getRunningContainerInfo 获取所有正在运行的docker容器的详细信息
func getRunningContainerInfo() (map[string]container.InspectResponse, map[string]container.Summary, map[string]container.TopResponse, error) {
liming6's avatar
liming6 committed
161
162
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
163
		return nil, nil, nil, err
liming6's avatar
liming6 committed
164
165
166
167
168
169
	}
	defer func() {
		_ = cli.Close()
	}()
	containerSum, err := cli.ContainerList(context.Background(), client.ContainerListOptions{All: false})
	if err != nil {
170
		return nil, nil, nil, err
liming6's avatar
liming6 committed
171
172
173
	}
	inspects := make(map[string]container.InspectResponse)
	lists := make(map[string]container.Summary)
174
	tops := make(map[string]container.TopResponse)
liming6's avatar
liming6 committed
175
176
177
	for _, c := range containerSum {
		inspect, innerErr := cli.ContainerInspect(context.Background(), c.ID)
		if innerErr != nil {
178
			return nil, nil, nil, innerErr
liming6's avatar
liming6 committed
179
180
181
		}
		inspects[c.ID] = inspect
		lists[c.ID] = c
182
183
184
185
186
		topInfo, innerErr := cli.ContainerTop(context.Background(), c.ID, nil)
		if innerErr != nil {
			return nil, nil, nil, innerErr
		}
		tops[c.ID] = topInfo
liming6's avatar
liming6 committed
187
	}
188
	return inspects, lists, tops, nil
liming6's avatar
liming6 committed
189
}