Skip to content

Commit

Permalink
libnetwork: add NetworkInfo() for get network information
Browse files Browse the repository at this point in the history
NetworkInfo() return the network binary path, package version
and program version.

Signed-off-by: Toshiki Sonoda <[email protected]>
  • Loading branch information
sstosh committed May 10, 2023
1 parent 08b0a5a commit 1c77e5f
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 1 deletion.
6 changes: 6 additions & 0 deletions libnetwork/cni/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,12 @@ func (n *cniNetwork) DefaultInterfaceName() string {
return cniDeviceName
}

// NetworkInfo return the network information about binary path,
// package version and program version.
func (n *cniNetwork) NetworkInfo() (map[string]interface{}, error) {
return nil, nil
}

func (n *cniNetwork) Network(nameOrID string) (*types.Network, error) {
network, err := n.getNetwork(nameOrID)
if err != nil {
Expand Down
25 changes: 25 additions & 0 deletions libnetwork/netavark/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/containers/common/libnetwork/internal/util"
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
cutil "github.com/containers/common/pkg/util"
"github.com/containers/storage/pkg/lockfile"
"github.com/containers/storage/pkg/unshare"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -336,6 +337,30 @@ func (n *netavarkNetwork) DefaultInterfaceName() string {
return defaultBridgeName
}

// NetworkInfo return the network information about binary path,
// package version and program version.
func (n *netavarkNetwork) NetworkInfo() (map[string]interface{}, error) {
info := make(map[string]interface{})

netavarkPath := n.netavarkBinary
netavarkPackageVersion := cutil.PackageVersion(netavarkPath)
netavarkProgramVersion, err := cutil.ProgramVersion(netavarkPath)

info["netavark-path"] = netavarkPath
info["netavark-package"] = netavarkPackageVersion
info["netavark-version"] = netavarkProgramVersion

aardvarkPath := n.aardvarkBinary
aardvarkPackageVersion := cutil.PackageVersion(aardvarkPath)
aardvarkProgramVersion, err := cutil.ProgramVersion(aardvarkPath)

info["aardvark-path"] = aardvarkPath
info["aardvark-package"] = aardvarkPackageVersion
info["aardvark-version"] = aardvarkProgramVersion

return info, err
}

func (n *netavarkNetwork) Network(nameOrID string) (*types.Network, error) {
network, err := n.getNetwork(nameOrID)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions libnetwork/types/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ type ContainerNetwork interface {
// DefaultNetworkName will return the default network name
// for this interface.
DefaultNetworkName() string

// NetworkInfo return the network information about binary path,
// package version and program version.
NetworkInfo() (map[string]interface{}, error)
}

// Network describes the Network attributes.
Expand Down
70 changes: 69 additions & 1 deletion pkg/util/util.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,74 @@
package util

import "regexp"
import (
"bytes"
"fmt"
"os/exec"
"regexp"
"strings"
)

const (
unknownPackage = "Unknown"
)

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) {
cmd := exec.Command(mountProgram, "--version")
var stdout bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr

err := cmd.Run()
if err != nil {
return "", fmt.Errorf("`%v --version` failed: %v %v (%v)", mountProgram, stderr.String(), stdout.String(), err)
}

return strings.TrimSuffix(stdout.String(), "\n"), nil
}

// StringInSlice determines if a string is in a string slice, returns bool
func StringInSlice(s string, sl []string) bool {
Expand Down

0 comments on commit 1c77e5f

Please sign in to comment.