Skip to content

Commit

Permalink
Merge pull request #1460 from sstosh/networkinfo
Browse files Browse the repository at this point in the history
libnetwork: add NetworkInfo() for get network information
  • Loading branch information
openshift-merge-robot authored May 16, 2023
2 parents 0263ee6 + 6595ffb commit 51d4c4b
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 1 deletion.
38 changes: 38 additions & 0 deletions libnetwork/cni/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/containernetworking/cni/libcni"
"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 @@ -295,6 +296,43 @@ func (n *cniNetwork) DefaultInterfaceName() string {
return cniDeviceName
}

// NetworkInfo return the network information about binary path,
// package version and program version.
func (n *cniNetwork) NetworkInfo() types.NetworkInfo {
path := ""
packageVersion := ""
for _, p := range n.cniPluginDirs {
ver := cutil.PackageVersion(p)
if ver != cutil.UnknownPackage {
path = p
packageVersion = ver
break
}
}

info := types.NetworkInfo{
Backend: types.CNI,
Package: packageVersion,
Path: path,
}

dnsPath := filepath.Join(path, "dnsname")
dnsPackage := cutil.PackageVersion(dnsPath)
dnsProgram, err := cutil.ProgramVersionDnsname(dnsPath)
if err != nil {
logrus.Infof("Failed to get the dnsname plugin version: %v", err)
}
if _, err := os.Stat(dnsPath); err == nil {
info.DNS = types.DNSNetworkInfo{
Path: dnsPath,
Package: dnsPackage,
Version: dnsProgram,
}
}

return info
}

func (n *cniNetwork) Network(nameOrID string) (*types.Network, error) {
network, err := n.getNetwork(nameOrID)
if err != nil {
Expand Down
32 changes: 32 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,37 @@ func (n *netavarkNetwork) DefaultInterfaceName() string {
return defaultBridgeName
}

// NetworkInfo return the network information about binary path,
// package version and program version.
func (n *netavarkNetwork) NetworkInfo() types.NetworkInfo {
path := n.netavarkBinary
packageVersion := cutil.PackageVersion(path)
programVersion, err := cutil.ProgramVersion(path)
if err != nil {
logrus.Infof("Failed to get the netavark version: %v", err)
}
info := types.NetworkInfo{
Backend: types.Netavark,
Version: programVersion,
Package: packageVersion,
Path: path,
}

dnsPath := n.aardvarkBinary
dnsPackage := cutil.PackageVersion(dnsPath)
dnsProgram, err := cutil.ProgramVersion(dnsPath)
if err != nil {
logrus.Infof("Failed to get the aardvark version: %v", err)
}
info.DNS = types.DNSNetworkInfo{
Package: dnsPackage,
Path: dnsPath,
Version: dnsProgram,
}

return info
}

func (n *netavarkNetwork) Network(nameOrID string) (*types.Network, error) {
network, err := n.getNetwork(nameOrID)
if err != nil {
Expand Down
20 changes: 20 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 backend type,
// binary path, package version and so on.
NetworkInfo() NetworkInfo
}

// Network describes the Network attributes.
Expand Down Expand Up @@ -80,6 +84,22 @@ type NetworkUpdateOptions struct {
RemoveDNSServers []string `json:"remove_dns_servers,omitempty"`
}

// NetworkInfo contains the network information.
type NetworkInfo struct {
Backend NetworkBackend `json:"backend"`
Version string `json:"version,omitempty"`
Package string `json:"package,omitempty"`
Path string `json:"path,omitempty"`
DNS DNSNetworkInfo `json:"dns,omitempty"`
}

// NetworkInfo contains the DNS information.
type DNSNetworkInfo struct {
Version string `json:"version,omitempty"`
Package string `json:"package,omitempty"`
Path string `json:"path,omitempty"`
}

// IPNet is used as custom net.IPNet type to add Marshal/Unmarshal methods.
type IPNet struct {
net.IPNet
Expand Down
90 changes: 89 additions & 1 deletion pkg/util/util.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,94 @@
package util

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

const (
UnknownPackage = "Unknown"
)

// Note: This function is copied from containers/podman libpod/util.go
// Please see https://github.com/containers/common/pull/1460
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")
}

// Note: This function is copied from containers/podman libpod/util.go
// Please see https://github.com/containers/common/pull/1460
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
}

// Note: This function is copied from containers/podman libpod/util.go
// Please see https://github.com/containers/common/pull/1460
func ProgramVersion(program string) (string, error) {
return programVersion(program, false)
}

func ProgramVersionDnsname(program string) (string, error) {
return programVersion(program, true)
}

func programVersion(program string, dnsname bool) (string, error) {
cmd := exec.Command(program, "--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)", program, stderr.String(), stdout.String(), err)
}

output := strings.TrimSuffix(stdout.String(), "\n")
// dnsname --version returns the information to stderr
if dnsname {
output = strings.TrimSuffix(stderr.String(), "\n")
}

return output, 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 51d4c4b

Please sign in to comment.