Repository navigation
Expand file tree
/
Copy pathruntime.go
More file actions
102 lines (96 loc) · 3.02 KB
/
Copy pathruntime.go
File metadata and controls
102 lines (96 loc) · 3.02 KB
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
package sysinfo
import (
"fmt"
"os"
"runtime"
"sort"
"strconv"
"strings"
)
// RuntimeInfo records facts visible to this process, not a compatibility verdict.
// Limits are inherited from the caller; another service may have different limits.
type RuntimeInfo struct {
PageSizeBytes int `json:"page_size_bytes"`
ProcessArch string `json:"process_architecture"`
Translation string `json:"translation,omitempty"`
GoVersion string `json:"go_version"`
Libc []Libc `json:"libc"`
Limits []ResourceLimit `json:"resource_limits"`
Memory map[string]string `json:"memory"`
VM map[string]string `json:"vm"`
Cgroup string `json:"cgroup_membership,omitempty"`
Notes []string `json:"notes,omitempty"`
Errors map[string]string `json:"errors,omitempty"`
}
type ResourceLimit struct {
Name string `json:"name"`
Soft string `json:"soft"`
Hard string `json:"hard"`
Unit string `json:"unit,omitempty"`
}
func (si *SysInfo) getRuntimeInfo() {
r := &si.Runtime
*r = RuntimeInfo{
// Getpagesize uses the runtime's actual OS page size, not Hugepagesize
// or a compile-time architecture default. ARM64 can use 4K, 16K or 64K.
PageSizeBytes: os.Getpagesize(),
ProcessArch: runtime.GOARCH,
GoVersion: runtime.Version(),
Libc: []Libc{}, Limits: []ResourceLimit{},
Memory: map[string]string{}, VM: map[string]string{},
Errors: map[string]string{},
}
si.getPlatformRuntime()
}
func parseLimits(data string) ([]ResourceLimit, error) {
limits := []ResourceLimit{}
for _, line := range strings.Split(data, "\n") {
fields := strings.Fields(line)
if len(fields) == 0 || fields[0] == "Limit" {
continue
}
// The limit name contains spaces; the first numeric/unlimited column
// marks its end. Some rows (nice/realtime priority) have no unit.
i := 0
for ; i < len(fields); i++ {
if _, err := strconv.ParseUint(fields[i], 10, 64); err == nil || fields[i] == "unlimited" {
break
}
}
if i == 0 || i+2 > len(fields) || i+3 < len(fields) {
return limits, fmt.Errorf("cannot parse resource limit: %q", line)
}
if _, err := strconv.ParseUint(fields[i+1], 10, 64); err != nil && fields[i+1] != "unlimited" {
return limits, fmt.Errorf("invalid hard limit: %q", fields[i+1])
}
limit := ResourceLimit{Name: strings.Join(fields[:i], " "), Soft: fields[i], Hard: fields[i+1]}
if i+2 < len(fields) {
limit.Unit = fields[i+2]
}
limits = append(limits, limit)
}
if len(limits) == 0 {
return limits, fmt.Errorf("no resource limits found")
}
return limits, nil
}
func commonFeatures(previous, current []string) []string {
result := []string{}
seen := map[string]bool{}
for _, feature := range current {
seen[feature] = true
}
if previous == nil {
for feature := range seen {
result = append(result, feature)
}
} else {
for _, feature := range previous {
if seen[feature] {
result = append(result, feature)
}
}
}
sort.Strings(result)
return result
}