summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/info.go182
-rw-r--r--libpod/info_freebsd.go40
-rw-r--r--libpod/info_linux.go132
-rw-r--r--libpod/info_unsupported.go4
4 files changed, 196 insertions, 162 deletions
diff --git a/libpod/info.go b/libpod/info.go
index 8db6df8cc..1990dc044 100644
--- a/libpod/info.go
+++ b/libpod/info.go
@@ -1,6 +1,3 @@
-//go:build linux
-// +build linux
-
package libpod
import (
@@ -8,27 +5,21 @@ import (
"bytes"
"errors"
"fmt"
- "io/ioutil"
"math"
"os"
- "os/exec"
"runtime"
- "strconv"
"strings"
"syscall"
"time"
"github.com/containers/buildah"
- "github.com/containers/common/pkg/apparmor"
- "github.com/containers/common/pkg/cgroups"
- "github.com/containers/common/pkg/seccomp"
+ "github.com/containers/buildah/pkg/util"
"github.com/containers/image/v5/pkg/sysregistriesv2"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/linkmode"
"github.com/containers/podman/v4/pkg/rootless"
"github.com/containers/storage"
"github.com/containers/storage/pkg/system"
- "github.com/opencontainers/selinux/go-selinux"
"github.com/sirupsen/logrus"
)
@@ -94,7 +85,7 @@ func (r *Runtime) hostInfo() (*define.HostInfo, error) {
hostDistributionInfo := r.GetHostDistributionInfo()
- kv, err := readKernelVersion()
+ kv, err := util.ReadKernelVersion()
if err != nil {
return nil, fmt.Errorf("error reading kernel version: %w", err)
}
@@ -104,94 +95,30 @@ func (r *Runtime) hostInfo() (*define.HostInfo, error) {
return nil, fmt.Errorf("error getting hostname: %w", err)
}
- seccompProfilePath, err := DefaultSeccompPath()
- if err != nil {
- return nil, fmt.Errorf("error getting Seccomp profile path: %w", err)
- }
-
- // Cgroups version
- unified, err := cgroups.IsCgroup2UnifiedMode()
- if err != nil {
- return nil, fmt.Errorf("error reading cgroups mode: %w", err)
- }
-
- // Get Map of all available controllers
- availableControllers, err := cgroups.GetAvailableControllers(nil, unified)
- if err != nil {
- return nil, fmt.Errorf("error getting available cgroup controllers: %w", err)
- }
cpuUtil, err := getCPUUtilization()
if err != nil {
return nil, err
}
info := define.HostInfo{
- Arch: runtime.GOARCH,
- BuildahVersion: buildah.Version,
- CgroupManager: r.config.Engine.CgroupManager,
- CgroupControllers: availableControllers,
- Linkmode: linkmode.Linkmode(),
- CPUs: runtime.NumCPU(),
- CPUUtilization: cpuUtil,
- Distribution: hostDistributionInfo,
- LogDriver: r.config.Containers.LogDriver,
- EventLogger: r.eventer.String(),
- Hostname: host,
- IDMappings: define.IDMappings{},
- Kernel: kv,
- MemFree: mi.MemFree,
- MemTotal: mi.MemTotal,
- NetworkBackend: r.config.Network.NetworkBackend,
- OS: runtime.GOOS,
- Security: define.SecurityInfo{
- AppArmorEnabled: apparmor.IsEnabled(),
- DefaultCapabilities: strings.Join(r.config.Containers.DefaultCapabilities, ","),
- Rootless: rootless.IsRootless(),
- SECCOMPEnabled: seccomp.IsEnabled(),
- SECCOMPProfilePath: seccompProfilePath,
- SELinuxEnabled: selinux.GetEnabled(),
- },
- Slirp4NetNS: define.SlirpInfo{},
- SwapFree: mi.SwapFree,
- SwapTotal: mi.SwapTotal,
- }
-
- 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 nil, fmt.Errorf("error reading uid mappings: %w", err)
- }
- gidmappings, err := rootless.ReadMappingsProc("/proc/self/gid_map")
- if err != nil {
- return nil, fmt.Errorf("error reading gid mappings: %w", err)
- }
- idmappings := define.IDMappings{
- GIDMap: gidmappings,
- UIDMap: uidmappings,
- }
- info.IDMappings = idmappings
+ Arch: runtime.GOARCH,
+ BuildahVersion: buildah.Version,
+ Linkmode: linkmode.Linkmode(),
+ CPUs: runtime.NumCPU(),
+ CPUUtilization: cpuUtil,
+ Distribution: hostDistributionInfo,
+ LogDriver: r.config.Containers.LogDriver,
+ EventLogger: r.eventer.String(),
+ Hostname: host,
+ Kernel: kv,
+ MemFree: mi.MemFree,
+ MemTotal: mi.MemTotal,
+ NetworkBackend: r.config.Network.NetworkBackend,
+ OS: runtime.GOOS,
+ SwapFree: mi.SwapFree,
+ SwapTotal: mi.SwapTotal,
+ }
+ if err := r.setPlatformHostInfo(&info); err != nil {
+ return nil, err
}
conmonInfo, ociruntimeInfo, err := r.defaultOCIRuntime.RuntimeInfo()
@@ -202,7 +129,7 @@ func (r *Runtime) hostInfo() (*define.HostInfo, error) {
info.OCIRuntime = ociruntimeInfo
}
- duration, err := procUptime()
+ duration, err := util.ReadUptime()
if err != nil {
return nil, fmt.Errorf("error reading up time: %w", err)
}
@@ -332,31 +259,6 @@ func (r *Runtime) storeInfo() (*define.StoreInfo, error) {
return &info, nil
}
-func readKernelVersion() (string, error) {
- buf, err := ioutil.ReadFile("/proc/version")
- if err != nil {
- return "", err
- }
- f := bytes.Fields(buf)
- if len(f) < 3 {
- return string(bytes.TrimSpace(buf)), nil
- }
- return string(f[2]), nil
-}
-
-func procUptime() (time.Duration, error) {
- var zero time.Duration
- buf, err := ioutil.ReadFile("/proc/uptime")
- if err != nil {
- return zero, err
- }
- f := bytes.Fields(buf)
- if len(f) < 1 {
- return zero, errors.New("unable to parse uptime from /proc/uptime")
- }
- return time.ParseDuration(string(f[0]) + "s")
-}
-
// GetHostDistributionInfo returns a map containing the host's distribution and version
func (r *Runtime) GetHostDistributionInfo() define.DistributionInfo {
// Populate values in case we cannot find the values
@@ -388,43 +290,3 @@ func (r *Runtime) GetHostDistributionInfo() define.DistributionInfo {
}
return dist
}
-
-// 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)
-}
-
-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
-}
diff --git a/libpod/info_freebsd.go b/libpod/info_freebsd.go
new file mode 100644
index 000000000..ef7b6817c
--- /dev/null
+++ b/libpod/info_freebsd.go
@@ -0,0 +1,40 @@
+package libpod
+
+import (
+ "fmt"
+ "unsafe"
+
+ "github.com/containers/podman/v4/libpod/define"
+ "golang.org/x/sys/unix"
+)
+
+func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error {
+ return nil
+}
+
+func timeToPercent(time uint64, total uint64) float64 {
+ return 100.0 * float64(time) / float64(total)
+}
+
+// getCPUUtilization Returns a CPUUsage object that summarizes CPU
+// usage for userspace, system, and idle time.
+func getCPUUtilization() (*define.CPUUsage, error) {
+ buf, err := unix.SysctlRaw("kern.cp_time")
+ if err != nil {
+ return nil, fmt.Errorf("error reading sysctl kern.cp_time: %w", err)
+ }
+
+ var total uint64 = 0
+ var times [unix.CPUSTATES]uint64
+
+ for i := 0; i < unix.CPUSTATES; i++ {
+ val := *(*uint64)(unsafe.Pointer(&buf[8*i]))
+ times[i] = val
+ total += val
+ }
+ return &define.CPUUsage{
+ UserPercent: timeToPercent(times[unix.CP_USER], total),
+ SystemPercent: timeToPercent(times[unix.CP_SYS], total),
+ IdlePercent: timeToPercent(times[unix.CP_IDLE], total),
+ }, nil
+}
diff --git a/libpod/info_linux.go b/libpod/info_linux.go
new file mode 100644
index 000000000..801dcdb43
--- /dev/null
+++ b/libpod/info_linux.go
@@ -0,0 +1,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("error getting Seccomp profile path: %w", err)
+ }
+
+ // Cgroups version
+ unified, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
+ return fmt.Errorf("error reading cgroups mode: %w", err)
+ }
+
+ // Get Map of all available controllers
+ availableControllers, err := cgroups.GetAvailableControllers(nil, unified)
+ if err != nil {
+ return fmt.Errorf("error 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("error reading uid mappings: %w", err)
+ }
+ gidmappings, err := rootless.ReadMappingsProc("/proc/self/gid_map")
+ if err != nil {
+ return fmt.Errorf("error 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)
+}
diff --git a/libpod/info_unsupported.go b/libpod/info_unsupported.go
index 53ee4b32f..0aed51247 100644
--- a/libpod/info_unsupported.go
+++ b/libpod/info_unsupported.go
@@ -1,5 +1,5 @@
-//go:build !linux
-// +build !linux
+//go:build !linux && !freebsd
+// +build !linux,!freebsd
package libpod