Merge pull request #18383 from sstosh/info-networkbackend

libpod: Podman info output more network information
This commit is contained in:
OpenShift Merge Robot
2023-06-13 04:33:35 -04:00
committed by GitHub
8 changed files with 83 additions and 105 deletions

View File

@ -77,6 +77,20 @@ host:
logDriver: journald logDriver: journald
memFree: 1833385984 memFree: 1833385984
memTotal: 16401895424 memTotal: 16401895424
networkBackend: cni
networkBackendInfo:
backend: cni
dns:
package: podman-plugins-3.4.4-1.fc34.x86_64
path: /usr/libexec/cni/dnsname
version: |-
CNI dnsname plugin
version: 1.3.1
commit: unknown
package: |-
containernetworking-plugins-1.0.1-1.fc34.x86_64
podman-plugins-3.4.4-1.fc34.x86_64
path: /usr/libexec/cni
ociRuntime: ociRuntime:
name: crun name: crun
package: crun-1.0-1.fc34.x86_64 package: crun-1.0-1.fc34.x86_64
@ -220,6 +234,17 @@ $ podman info --format json
"logDriver": "journald", "logDriver": "journald",
"memFree": 1785753600, "memFree": 1785753600,
"memTotal": 16401895424, "memTotal": 16401895424,
"networkBackend": "cni",
"networkBackendInfo": {
"backend": "cni",
"package": "containernetworking-plugins-1.0.1-1.fc34.x86_64\npodman-plugins-3.4.4-1.fc34.x86_64",
"path": "/usr/libexec/cni",
"dns": {
"version": "CNI dnsname plugin\nversion: 1.3.1\ncommit: unknown",
"package": "podman-plugins-3.4.4-1.fc34.x86_64",
"path": "/usr/libexec/cni/dnsname"
}
},
"ociRuntime": { "ociRuntime": {
"name": "crun", "name": "crun",
"package": "crun-1.0-1.fc34.x86_64", "package": "crun-1.0-1.fc34.x86_64",

View File

@ -1,6 +1,7 @@
package define package define
import ( import (
"github.com/containers/common/libnetwork/types"
"github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/idtools"
) )
@ -27,27 +28,28 @@ type SecurityInfo struct {
// HostInfo describes the libpod host // HostInfo describes the libpod host
type HostInfo struct { type HostInfo struct {
Arch string `json:"arch"` Arch string `json:"arch"`
BuildahVersion string `json:"buildahVersion"` BuildahVersion string `json:"buildahVersion"`
CgroupManager string `json:"cgroupManager"` CgroupManager string `json:"cgroupManager"`
CgroupsVersion string `json:"cgroupVersion"` CgroupsVersion string `json:"cgroupVersion"`
CgroupControllers []string `json:"cgroupControllers"` CgroupControllers []string `json:"cgroupControllers"`
Conmon *ConmonInfo `json:"conmon"` Conmon *ConmonInfo `json:"conmon"`
CPUs int `json:"cpus"` CPUs int `json:"cpus"`
CPUUtilization *CPUUsage `json:"cpuUtilization"` CPUUtilization *CPUUsage `json:"cpuUtilization"`
DatabaseBackend string `json:"databaseBackend"` DatabaseBackend string `json:"databaseBackend"`
Distribution DistributionInfo `json:"distribution"` Distribution DistributionInfo `json:"distribution"`
EventLogger string `json:"eventLogger"` EventLogger string `json:"eventLogger"`
FreeLocks *uint32 `json:"freeLocks,omitempty"` FreeLocks *uint32 `json:"freeLocks,omitempty"`
Hostname string `json:"hostname"` Hostname string `json:"hostname"`
IDMappings IDMappings `json:"idMappings,omitempty"` IDMappings IDMappings `json:"idMappings,omitempty"`
Kernel string `json:"kernel"` Kernel string `json:"kernel"`
LogDriver string `json:"logDriver"` LogDriver string `json:"logDriver"`
MemFree int64 `json:"memFree"` MemFree int64 `json:"memFree"`
MemTotal int64 `json:"memTotal"` MemTotal int64 `json:"memTotal"`
NetworkBackend string `json:"networkBackend"` NetworkBackend string `json:"networkBackend"`
OCIRuntime *OCIRuntimeInfo `json:"ociRuntime"` NetworkBackendInfo types.NetworkInfo `json:"networkBackendInfo"`
OS string `json:"os"` OCIRuntime *OCIRuntimeInfo `json:"ociRuntime"`
OS string `json:"os"`
// RemoteSocket returns the UNIX domain socket the Podman service is listening on // RemoteSocket returns the UNIX domain socket the Podman service is listening on
RemoteSocket *RemoteSocket `json:"remoteSocket,omitempty"` RemoteSocket *RemoteSocket `json:"remoteSocket,omitempty"`
RuntimeInfo map[string]interface{} `json:"runtimeInfo,omitempty"` RuntimeInfo map[string]interface{} `json:"runtimeInfo,omitempty"`

View File

@ -14,6 +14,7 @@ import (
"github.com/containers/buildah" "github.com/containers/buildah"
"github.com/containers/buildah/pkg/util" "github.com/containers/buildah/pkg/util"
cutil "github.com/containers/common/pkg/util"
"github.com/containers/image/v5/pkg/sysregistriesv2" "github.com/containers/image/v5/pkg/sysregistriesv2"
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/linkmode" "github.com/containers/podman/v4/libpod/linkmode"
@ -106,24 +107,25 @@ func (r *Runtime) hostInfo() (*define.HostInfo, error) {
} }
info := define.HostInfo{ info := define.HostInfo{
Arch: runtime.GOARCH, Arch: runtime.GOARCH,
BuildahVersion: buildah.Version, BuildahVersion: buildah.Version,
DatabaseBackend: r.config.Engine.DBBackend, DatabaseBackend: r.config.Engine.DBBackend,
Linkmode: linkmode.Linkmode(), Linkmode: linkmode.Linkmode(),
CPUs: runtime.NumCPU(), CPUs: runtime.NumCPU(),
CPUUtilization: cpuUtil, CPUUtilization: cpuUtil,
Distribution: hostDistributionInfo, Distribution: hostDistributionInfo,
FreeLocks: locksFree, LogDriver: r.config.Containers.LogDriver,
LogDriver: r.config.Containers.LogDriver, EventLogger: r.eventer.String(),
EventLogger: r.eventer.String(), FreeLocks: locksFree,
Hostname: host, Hostname: host,
Kernel: kv, Kernel: kv,
MemFree: mi.MemFree, MemFree: mi.MemFree,
MemTotal: mi.MemTotal, MemTotal: mi.MemTotal,
NetworkBackend: r.config.Network.NetworkBackend, NetworkBackend: r.config.Network.NetworkBackend,
OS: runtime.GOOS, NetworkBackendInfo: r.network.NetworkInfo(),
SwapFree: mi.SwapFree, OS: runtime.GOOS,
SwapTotal: mi.SwapTotal, SwapFree: mi.SwapFree,
SwapTotal: mi.SwapTotal,
} }
if err := r.setPlatformHostInfo(&info); err != nil { if err := r.setPlatformHostInfo(&info); err != nil {
return nil, err return nil, err
@ -241,14 +243,14 @@ func (r *Runtime) storeInfo() (*define.StoreInfo, error) {
for _, o := range r.store.GraphOptions() { for _, o := range r.store.GraphOptions() {
split := strings.SplitN(o, "=", 2) split := strings.SplitN(o, "=", 2)
if strings.HasSuffix(split[0], "mount_program") { if strings.HasSuffix(split[0], "mount_program") {
version, err := programVersion(split[1]) version, err := cutil.ProgramVersion(split[1])
if err != nil { if err != nil {
logrus.Warnf("Failed to retrieve program version for %s: %v", split[1], err) logrus.Warnf("Failed to retrieve program version for %s: %v", split[1], err)
} }
program := map[string]interface{}{} program := map[string]interface{}{}
program["Executable"] = split[1] program["Executable"] = split[1]
program["Version"] = version program["Version"] = version
program["Package"] = packageVersion(split[1]) program["Package"] = cutil.PackageVersion(split[1])
graphOptions[split[0]] = program graphOptions[split[0]] = program
} else { } else {
graphOptions[split[0]] = split[1] graphOptions[split[0]] = split[1]

View File

@ -11,6 +11,7 @@ import (
"github.com/containers/common/pkg/apparmor" "github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/cgroups"
"github.com/containers/common/pkg/seccomp" "github.com/containers/common/pkg/seccomp"
"github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/rootless" "github.com/containers/podman/v4/pkg/rootless"
"github.com/opencontainers/selinux/go-selinux" "github.com/opencontainers/selinux/go-selinux"
@ -59,13 +60,13 @@ func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error {
slirp4netnsPath, _ = r.config.FindHelperBinary(slirp4netnsBinaryName, true) slirp4netnsPath, _ = r.config.FindHelperBinary(slirp4netnsBinaryName, true)
} }
if slirp4netnsPath != "" { if slirp4netnsPath != "" {
version, err := programVersion(slirp4netnsPath) version, err := util.ProgramVersion(slirp4netnsPath)
if err != nil { if err != nil {
logrus.Warnf("Failed to retrieve program version for %s: %v", slirp4netnsPath, err) logrus.Warnf("Failed to retrieve program version for %s: %v", slirp4netnsPath, err)
} }
program := define.SlirpInfo{ program := define.SlirpInfo{
Executable: slirp4netnsPath, Executable: slirp4netnsPath,
Package: packageVersion(slirp4netnsPath), Package: util.PackageVersion(slirp4netnsPath),
Version: version, Version: version,
} }
info.Slirp4NetNS = program info.Slirp4NetNS = program
@ -73,13 +74,13 @@ func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error {
pastaPath, _ := r.config.FindHelperBinary(pastaBinaryName, true) pastaPath, _ := r.config.FindHelperBinary(pastaBinaryName, true)
if pastaPath != "" { if pastaPath != "" {
version, err := programVersion(pastaPath) version, err := util.ProgramVersion(pastaPath)
if err != nil { if err != nil {
logrus.Warnf("Failed to retrieve program version for %s: %v", pastaPath, err) logrus.Warnf("Failed to retrieve program version for %s: %v", pastaPath, err)
} }
program := define.PastaInfo{ program := define.PastaInfo{
Executable: pastaPath, Executable: pastaPath,
Package: packageVersion(pastaPath), Package: util.PackageVersion(pastaPath),
Version: version, Version: version,
} }
info.Pasta = program info.Pasta = program

View File

@ -945,8 +945,8 @@ func (r *ConmonOCIRuntime) ExitFilePath(ctr *Container) (string, error) {
// RuntimeInfo provides information on the runtime. // RuntimeInfo provides information on the runtime.
func (r *ConmonOCIRuntime) RuntimeInfo() (*define.ConmonInfo, *define.OCIRuntimeInfo, error) { func (r *ConmonOCIRuntime) RuntimeInfo() (*define.ConmonInfo, *define.OCIRuntimeInfo, error) {
runtimePackage := packageVersion(r.path) runtimePackage := cutil.PackageVersion(r.path)
conmonPackage := packageVersion(r.conmonPath) conmonPackage := cutil.PackageVersion(r.conmonPath)
runtimeVersion, err := r.getOCIRuntimeVersion() runtimeVersion, err := r.getOCIRuntimeVersion()
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("getting version of OCI runtime %s: %w", r.name, err) return nil, nil, fmt.Errorf("getting version of OCI runtime %s: %w", r.name, err)

View File

@ -7,7 +7,6 @@ import (
"io" "io"
"net/http" "net/http"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"sort" "sort"
"strings" "strings"
@ -16,18 +15,12 @@ import (
"github.com/containers/common/libnetwork/types" "github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config" "github.com/containers/common/pkg/config"
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/utils"
"github.com/fsnotify/fsnotify" "github.com/fsnotify/fsnotify"
spec "github.com/opencontainers/runtime-spec/specs-go" spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label" "github.com/opencontainers/selinux/go-selinux/label"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
// Runtime API constants
const (
unknownPackage = "Unknown"
)
// FuncTimer helps measure the execution time of a function // FuncTimer helps measure the execution time of a function
// For debug purposes, do not leave in code // For debug purposes, do not leave in code
// used like defer FuncTimer("foo") // used like defer FuncTimer("foo")
@ -145,57 +138,6 @@ func JSONDeepCopy(from, to interface{}) error {
return json.Unmarshal(tmp, to) return json.Unmarshal(tmp, to)
} }
func queryPackageVersion(cmdArg ...string) string {
output := unknownPackage
if 1 < len(cmdArg) {
cmd := exec.Command(cmdArg[0], cmdArg[1:]...)
if outp, err := cmd.Output(); err == nil {
output = string(outp)
if cmdArg[0] == "/usr/bin/dpkg" {
r := strings.Split(output, ": ")
queryFormat := `${Package}_${Version}_${Architecture}`
cmd = exec.Command("/usr/bin/dpkg-query", "-f", queryFormat, "-W", r[0])
if outp, err := cmd.Output(); err == nil {
output = string(outp)
}
}
}
if cmdArg[0] == "/sbin/apk" {
prefix := cmdArg[len(cmdArg)-1] + " is owned by "
output = strings.Replace(output, prefix, "", 1)
}
}
return strings.Trim(output, "\n")
}
func packageVersion(program string) string { // program is full path
packagers := [][]string{
{"/usr/bin/rpm", "-q", "-f"},
{"/usr/bin/dpkg", "-S"}, // Debian, Ubuntu
{"/usr/bin/pacman", "-Qo"}, // Arch
{"/usr/bin/qfile", "-qv"}, // Gentoo (quick)
{"/usr/bin/equery", "b"}, // Gentoo (slow)
{"/sbin/apk", "info", "-W"}, // Alpine
{"/usr/local/sbin/pkg", "which", "-q"}, // FreeBSD
}
for _, cmd := range packagers {
cmd = append(cmd, program)
if out := queryPackageVersion(cmd...); out != unknownPackage {
return out
}
}
return unknownPackage
}
func programVersion(mountProgram string) (string, error) {
output, err := utils.ExecCmd(mountProgram, "--version")
if err != nil {
return "", err
}
return strings.TrimSuffix(output, "\n"), nil
}
// DefaultSeccompPath returns the path to the default seccomp.json file // DefaultSeccompPath returns the path to the default seccomp.json file
// if it exists, first it checks OverrideSeccomp and then default. // if it exists, first it checks OverrideSeccomp and then default.
// If neither exist function returns "" // If neither exist function returns ""

View File

@ -160,6 +160,11 @@ var _ = Describe("Podman Info", func() {
session.WaitWithDefaultTimeout() session.WaitWithDefaultTimeout()
Expect(session).To(Exit(0)) Expect(session).To(Exit(0))
Expect(session.OutputToString()).To(Equal(want)) Expect(session.OutputToString()).To(Equal(want))
session = podmanTest.Podman([]string{"info", "--format", "{{.Host.NetworkBackendInfo.Backend}}"})
session.WaitWithDefaultTimeout()
Expect(session).To(Exit(0))
Expect(session.OutputToString()).To(Equal(want))
}) })
It("Podman info: check desired database backend", func() { It("Podman info: check desired database backend", func() {

View File

@ -42,6 +42,7 @@ host.conmon.path | $expr_path
host.conmon.package | .*conmon.* host.conmon.package | .*conmon.*
host.cgroupManager | \\\(systemd\\\|cgroupfs\\\) host.cgroupManager | \\\(systemd\\\|cgroupfs\\\)
host.cgroupVersion | v[12] host.cgroupVersion | v[12]
host.networkBackendInfo | .*dns.*package.*
host.ociRuntime.path | $expr_path host.ociRuntime.path | $expr_path
host.pasta | .*executable.*package.* host.pasta | .*executable.*package.*
store.configFile | $expr_path store.configFile | $expr_path