/
description.go
104 lines (88 loc) · 2.43 KB
/
description.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
package process
import (
"context"
"fmt"
psprocess "github.com/shirou/gopsutil/v3/process"
"golang.org/x/sync/errgroup"
"github.com/deref/exo/internal/core/api"
"github.com/deref/exo/internal/util/jsonutil"
)
// TODO: Make part of the resource controller?
func GetProcessDescription(ctx context.Context, component api.ComponentDescription) (api.ProcessDescription, error) {
var state State
if err := jsonutil.UnmarshalStringOrEmpty(component.State, &state); err != nil {
return api.ProcessDescription{}, fmt.Errorf("unmarshalling container state: %v\n", err)
}
process := api.ProcessDescription{
ID: component.ID,
Name: component.Name,
Provider: "unix",
EnvVars: state.FullEnvironment,
Spec: component.Spec,
}
proc, err := psprocess.NewProcess(int32(state.Pid))
if err != nil {
// Assume this has failed because the process isn't running.
return process, nil
}
process.Running = true
var eg errgroup.Group
eg.Go(func() error {
memoryInfo, err := proc.MemoryInfoWithContext(ctx)
if err != nil {
return fmt.Errorf("getting process memory information: %w", err)
}
process.ResidentMemory = &memoryInfo.RSS
return nil
})
eg.Go(func() error {
connections, err := proc.ConnectionsWithContext(ctx)
if err != nil {
return fmt.Errorf("getting process connections information: %w", err)
}
ports := []uint32{}
for _, conn := range connections {
if conn.Laddr.Port != 0 {
ports = append(ports, conn.Laddr.Port)
}
}
process.Ports = ports
return nil
})
eg.Go(func() error {
createTime, err := proc.CreateTimeWithContext(ctx)
if err != nil {
return fmt.Errorf("getting process createTime information: %w", err)
}
process.CreateTime = &createTime
return nil
})
eg.Go(func() error {
children, err := proc.ChildrenWithContext(ctx)
if err != nil {
// Assume that this has failed because the process doesn't have any
// children.
return nil
}
var childrenExecutables []string
for _, child := range children {
exe, err := child.Exe()
if err != nil {
continue
}
childrenExecutables = append(childrenExecutables, exe)
}
process.ChildrenExecutables = childrenExecutables
return nil
})
eg.Go(func() error {
cpuPercent, err := proc.CPUPercentWithContext(ctx)
if err != nil {
return fmt.Errorf("getting process cpuPercent information: %w", err)
}
process.CPUPercent = &cpuPercent
return nil
})
err = eg.Wait()
return process, err
}