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
|
package libpod
import (
"bufio"
"fmt"
"math"
"os"
"os/exec"
"strconv"
"strings"
"github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/cgroups"
"github.com/containers/common/pkg/seccomp"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/rootless"
"github.com/opencontainers/selinux/go-selinux"
"github.com/sirupsen/logrus"
)
func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error {
seccompProfilePath, err := DefaultSeccompPath()
if err != nil {
return fmt.Errorf("getting Seccomp profile path: %w", err)
}
// Cgroups version
unified, err := cgroups.IsCgroup2UnifiedMode()
if err != nil {
return fmt.Errorf("reading cgroups mode: %w", err)
}
// Get Map of all available controllers
availableControllers, err := cgroups.GetAvailableControllers(nil, unified)
if err != nil {
return fmt.Errorf("getting available cgroup controllers: %w", err)
}
info.CgroupManager = r.config.Engine.CgroupManager
info.CgroupControllers = availableControllers
info.IDMappings = define.IDMappings{}
info.Security = define.SecurityInfo{
AppArmorEnabled: apparmor.IsEnabled(),
DefaultCapabilities: strings.Join(r.config.Containers.DefaultCapabilities, ","),
Rootless: rootless.IsRootless(),
SECCOMPEnabled: seccomp.IsEnabled(),
SECCOMPProfilePath: seccompProfilePath,
SELinuxEnabled: selinux.GetEnabled(),
}
info.Slirp4NetNS = define.SlirpInfo{}
cgroupVersion := "v1"
if unified {
cgroupVersion = "v2"
}
info.CgroupsVersion = cgroupVersion
slirp4netnsPath := r.config.Engine.NetworkCmdPath
if slirp4netnsPath == "" {
slirp4netnsPath, _ = exec.LookPath("slirp4netns")
}
if slirp4netnsPath != "" {
version, err := programVersion(slirp4netnsPath)
if err != nil {
logrus.Warnf("Failed to retrieve program version for %s: %v", slirp4netnsPath, err)
}
program := define.SlirpInfo{
Executable: slirp4netnsPath,
Package: packageVersion(slirp4netnsPath),
Version: version,
}
info.Slirp4NetNS = program
}
if rootless.IsRootless() {
uidmappings, err := rootless.ReadMappingsProc("/proc/self/uid_map")
if err != nil {
return fmt.Errorf("reading uid mappings: %w", err)
}
gidmappings, err := rootless.ReadMappingsProc("/proc/self/gid_map")
if err != nil {
return fmt.Errorf("reading gid mappings: %w", err)
}
idmappings := define.IDMappings{
GIDMap: gidmappings,
UIDMap: uidmappings,
}
info.IDMappings = idmappings
}
return nil
}
func statToPercent(stats []string) (*define.CPUUsage, error) {
userTotal, err := strconv.ParseFloat(stats[1], 64)
if err != nil {
return nil, fmt.Errorf("unable to parse user value %q: %w", stats[1], err)
}
systemTotal, err := strconv.ParseFloat(stats[3], 64)
if err != nil {
return nil, fmt.Errorf("unable to parse system value %q: %w", stats[3], err)
}
idleTotal, err := strconv.ParseFloat(stats[4], 64)
if err != nil {
return nil, fmt.Errorf("unable to parse idle value %q: %w", stats[4], err)
}
total := userTotal + systemTotal + idleTotal
s := define.CPUUsage{
UserPercent: math.Round((userTotal/total*100)*100) / 100,
SystemPercent: math.Round((systemTotal/total*100)*100) / 100,
IdlePercent: math.Round((idleTotal/total*100)*100) / 100,
}
return &s, nil
}
// getCPUUtilization Returns a CPUUsage object that summarizes CPU
// usage for userspace, system, and idle time.
func getCPUUtilization() (*define.CPUUsage, error) {
f, err := os.Open("/proc/stat")
if err != nil {
return nil, err
}
defer f.Close()
scanner := bufio.NewScanner(f)
// Read first line of /proc/stat that has entries for system ("cpu" line)
for scanner.Scan() {
break
}
// column 1 is user, column 3 is system, column 4 is idle
stats := strings.Fields(scanner.Text())
return statToPercent(stats)
}
|