Skip to content

Commit

Permalink
libpod: Podman info output more network information
Browse files Browse the repository at this point in the history
podman info prints the network information about binary path,
package version, program version and DNS information.

Fixes: containers#18443

Signed-off-by: Toshiki Sonoda <sonoda.toshiki@fujitsu.com>
  • Loading branch information
sstosh committed Jun 13, 2023
1 parent 3cae574 commit 6f82163
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 105 deletions.
25 changes: 25 additions & 0 deletions docs/source/markdown/podman-info.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,20 @@ host:
logDriver: journald
memFree: 1833385984
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:
name: crun
package: crun-1.0-1.fc34.x86_64
Expand Down Expand Up @@ -220,6 +234,17 @@ $ podman info --format json
"logDriver": "journald",
"memFree": 1785753600,
"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": {
"name": "crun",
"package": "crun-1.0-1.fc34.x86_64",
Expand Down
44 changes: 23 additions & 21 deletions libpod/define/info.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package define

import (
"github.com/containers/common/libnetwork/types"
"github.com/containers/storage/pkg/idtools"
)

Expand All @@ -27,27 +28,28 @@ type SecurityInfo struct {

// HostInfo describes the libpod host
type HostInfo struct {
Arch string `json:"arch"`
BuildahVersion string `json:"buildahVersion"`
CgroupManager string `json:"cgroupManager"`
CgroupsVersion string `json:"cgroupVersion"`
CgroupControllers []string `json:"cgroupControllers"`
Conmon *ConmonInfo `json:"conmon"`
CPUs int `json:"cpus"`
CPUUtilization *CPUUsage `json:"cpuUtilization"`
DatabaseBackend string `json:"databaseBackend"`
Distribution DistributionInfo `json:"distribution"`
EventLogger string `json:"eventLogger"`
FreeLocks *uint32 `json:"freeLocks,omitempty"`
Hostname string `json:"hostname"`
IDMappings IDMappings `json:"idMappings,omitempty"`
Kernel string `json:"kernel"`
LogDriver string `json:"logDriver"`
MemFree int64 `json:"memFree"`
MemTotal int64 `json:"memTotal"`
NetworkBackend string `json:"networkBackend"`
OCIRuntime *OCIRuntimeInfo `json:"ociRuntime"`
OS string `json:"os"`
Arch string `json:"arch"`
BuildahVersion string `json:"buildahVersion"`
CgroupManager string `json:"cgroupManager"`
CgroupsVersion string `json:"cgroupVersion"`
CgroupControllers []string `json:"cgroupControllers"`
Conmon *ConmonInfo `json:"conmon"`
CPUs int `json:"cpus"`
CPUUtilization *CPUUsage `json:"cpuUtilization"`
DatabaseBackend string `json:"databaseBackend"`
Distribution DistributionInfo `json:"distribution"`
EventLogger string `json:"eventLogger"`
FreeLocks *uint32 `json:"freeLocks,omitempty"`
Hostname string `json:"hostname"`
IDMappings IDMappings `json:"idMappings,omitempty"`
Kernel string `json:"kernel"`
LogDriver string `json:"logDriver"`
MemFree int64 `json:"memFree"`
MemTotal int64 `json:"memTotal"`
NetworkBackend string `json:"networkBackend"`
NetworkBackendInfo types.NetworkInfo `json:"networkBackendInfo"`
OCIRuntime *OCIRuntimeInfo `json:"ociRuntime"`
OS string `json:"os"`
// RemoteSocket returns the UNIX domain socket the Podman service is listening on
RemoteSocket *RemoteSocket `json:"remoteSocket,omitempty"`
RuntimeInfo map[string]interface{} `json:"runtimeInfo,omitempty"`
Expand Down
42 changes: 22 additions & 20 deletions libpod/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/containers/buildah"
"github.com/containers/buildah/pkg/util"
cutil "github.com/containers/common/pkg/util"
"github.com/containers/image/v5/pkg/sysregistriesv2"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/linkmode"
Expand Down Expand Up @@ -106,24 +107,25 @@ func (r *Runtime) hostInfo() (*define.HostInfo, error) {
}

info := define.HostInfo{
Arch: runtime.GOARCH,
BuildahVersion: buildah.Version,
DatabaseBackend: r.config.Engine.DBBackend,
Linkmode: linkmode.Linkmode(),
CPUs: runtime.NumCPU(),
CPUUtilization: cpuUtil,
Distribution: hostDistributionInfo,
FreeLocks: locksFree,
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,
Arch: runtime.GOARCH,
BuildahVersion: buildah.Version,
DatabaseBackend: r.config.Engine.DBBackend,
Linkmode: linkmode.Linkmode(),
CPUs: runtime.NumCPU(),
CPUUtilization: cpuUtil,
Distribution: hostDistributionInfo,
LogDriver: r.config.Containers.LogDriver,
EventLogger: r.eventer.String(),
FreeLocks: locksFree,
Hostname: host,
Kernel: kv,
MemFree: mi.MemFree,
MemTotal: mi.MemTotal,
NetworkBackend: r.config.Network.NetworkBackend,
NetworkBackendInfo: r.network.NetworkInfo(),
OS: runtime.GOOS,
SwapFree: mi.SwapFree,
SwapTotal: mi.SwapTotal,
}
if err := r.setPlatformHostInfo(&info); err != nil {
return nil, err
Expand Down Expand Up @@ -241,14 +243,14 @@ func (r *Runtime) storeInfo() (*define.StoreInfo, error) {
for _, o := range r.store.GraphOptions() {
split := strings.SplitN(o, "=", 2)
if strings.HasSuffix(split[0], "mount_program") {
version, err := programVersion(split[1])
version, err := cutil.ProgramVersion(split[1])
if err != nil {
logrus.Warnf("Failed to retrieve program version for %s: %v", split[1], err)
}
program := map[string]interface{}{}
program["Executable"] = split[1]
program["Version"] = version
program["Package"] = packageVersion(split[1])
program["Package"] = cutil.PackageVersion(split[1])
graphOptions[split[0]] = program
} else {
graphOptions[split[0]] = split[1]
Expand Down
9 changes: 5 additions & 4 deletions libpod/info_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/cgroups"
"github.com/containers/common/pkg/seccomp"
"github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/rootless"
"github.com/opencontainers/selinux/go-selinux"
Expand Down Expand Up @@ -59,27 +60,27 @@ func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error {
slirp4netnsPath, _ = r.config.FindHelperBinary(slirp4netnsBinaryName, true)
}
if slirp4netnsPath != "" {
version, err := programVersion(slirp4netnsPath)
version, err := util.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),
Package: util.PackageVersion(slirp4netnsPath),
Version: version,
}
info.Slirp4NetNS = program
}

pastaPath, _ := r.config.FindHelperBinary(pastaBinaryName, true)
if pastaPath != "" {
version, err := programVersion(pastaPath)
version, err := util.ProgramVersion(pastaPath)
if err != nil {
logrus.Warnf("Failed to retrieve program version for %s: %v", pastaPath, err)
}
program := define.PastaInfo{
Executable: pastaPath,
Package: packageVersion(pastaPath),
Package: util.PackageVersion(pastaPath),
Version: version,
}
info.Pasta = program
Expand Down
4 changes: 2 additions & 2 deletions libpod/oci_conmon_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -945,8 +945,8 @@ func (r *ConmonOCIRuntime) ExitFilePath(ctr *Container) (string, error) {

// RuntimeInfo provides information on the runtime.
func (r *ConmonOCIRuntime) RuntimeInfo() (*define.ConmonInfo, *define.OCIRuntimeInfo, error) {
runtimePackage := packageVersion(r.path)
conmonPackage := packageVersion(r.conmonPath)
runtimePackage := cutil.PackageVersion(r.path)
conmonPackage := cutil.PackageVersion(r.conmonPath)
runtimeVersion, err := r.getOCIRuntimeVersion()
if err != nil {
return nil, nil, fmt.Errorf("getting version of OCI runtime %s: %w", r.name, err)
Expand Down
58 changes: 0 additions & 58 deletions libpod/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"io"
"net/http"
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
Expand All @@ -16,18 +15,12 @@ import (
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/utils"
"github.com/fsnotify/fsnotify"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/sirupsen/logrus"
)

// Runtime API constants
const (
unknownPackage = "Unknown"
)

// FuncTimer helps measure the execution time of a function
// For debug purposes, do not leave in code
// used like defer FuncTimer("foo")
Expand Down Expand Up @@ -145,57 +138,6 @@ func JSONDeepCopy(from, to interface{}) error {
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
// if it exists, first it checks OverrideSeccomp and then default.
// If neither exist function returns ""
Expand Down
5 changes: 5 additions & 0 deletions test/e2e/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ var _ = Describe("Podman Info", func() {
session.WaitWithDefaultTimeout()
Expect(session).To(Exit(0))
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() {
Expand Down
1 change: 1 addition & 0 deletions test/system/005-info.bats
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ host.conmon.path | $expr_path
host.conmon.package | .*conmon.*
host.cgroupManager | \\\(systemd\\\|cgroupfs\\\)
host.cgroupVersion | v[12]
host.networkBackendInfo | .*dns.*package.*
host.ociRuntime.path | $expr_path
host.pasta | .*executable.*package.*
store.configFile | $expr_path
Expand Down

0 comments on commit 6f82163

Please sign in to comment.