mirror of
https://github.com/containers/podman.git
synced 2025-10-19 04:03:23 +08:00
vendor of containers/common
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
10
vendor/github.com/containers/common/libnetwork/cni/network.go
generated
vendored
10
vendor/github.com/containers/common/libnetwork/cni/network.go
generated
vendored
@ -17,7 +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/common/pkg/version"
|
||||
"github.com/containers/storage/pkg/lockfile"
|
||||
"github.com/containers/storage/pkg/unshare"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -302,8 +302,8 @@ func (n *cniNetwork) NetworkInfo() types.NetworkInfo {
|
||||
path := ""
|
||||
packageVersion := ""
|
||||
for _, p := range n.cniPluginDirs {
|
||||
ver := cutil.PackageVersion(p)
|
||||
if ver != cutil.UnknownPackage {
|
||||
ver := version.Package(p)
|
||||
if ver != version.UnknownPackage {
|
||||
path = p
|
||||
packageVersion = ver
|
||||
break
|
||||
@ -317,8 +317,8 @@ func (n *cniNetwork) NetworkInfo() types.NetworkInfo {
|
||||
}
|
||||
|
||||
dnsPath := filepath.Join(path, "dnsname")
|
||||
dnsPackage := cutil.PackageVersion(dnsPath)
|
||||
dnsProgram, err := cutil.ProgramVersionDnsname(dnsPath)
|
||||
dnsPackage := version.Package(dnsPath)
|
||||
dnsProgram, err := version.ProgramDnsname(dnsPath)
|
||||
if err != nil {
|
||||
logrus.Infof("Failed to get the dnsname plugin version: %v", err)
|
||||
}
|
||||
|
10
vendor/github.com/containers/common/libnetwork/netavark/network.go
generated
vendored
10
vendor/github.com/containers/common/libnetwork/netavark/network.go
generated
vendored
@ -15,7 +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/common/pkg/version"
|
||||
"github.com/containers/storage/pkg/lockfile"
|
||||
"github.com/containers/storage/pkg/unshare"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -341,8 +341,8 @@ func (n *netavarkNetwork) DefaultInterfaceName() string {
|
||||
// package version and program version.
|
||||
func (n *netavarkNetwork) NetworkInfo() types.NetworkInfo {
|
||||
path := n.netavarkBinary
|
||||
packageVersion := cutil.PackageVersion(path)
|
||||
programVersion, err := cutil.ProgramVersion(path)
|
||||
packageVersion := version.Package(path)
|
||||
programVersion, err := version.Program(path)
|
||||
if err != nil {
|
||||
logrus.Infof("Failed to get the netavark version: %v", err)
|
||||
}
|
||||
@ -354,8 +354,8 @@ func (n *netavarkNetwork) NetworkInfo() types.NetworkInfo {
|
||||
}
|
||||
|
||||
dnsPath := n.aardvarkBinary
|
||||
dnsPackage := cutil.PackageVersion(dnsPath)
|
||||
dnsProgram, err := cutil.ProgramVersion(dnsPath)
|
||||
dnsPackage := version.Package(dnsPath)
|
||||
dnsProgram, err := version.Program(dnsPath)
|
||||
if err != nil {
|
||||
logrus.Infof("Failed to get the aardvark version: %v", err)
|
||||
}
|
||||
|
2
vendor/github.com/containers/common/libnetwork/util/filters.go
generated
vendored
2
vendor/github.com/containers/common/libnetwork/util/filters.go
generated
vendored
@ -38,7 +38,7 @@ func createFilterFuncs(key string, filterValues []string) (types.FilterFunc, err
|
||||
case "id":
|
||||
// matches part of one id
|
||||
return func(net types.Network) bool {
|
||||
return util.FilterID(net.ID, filterValues)
|
||||
return filters.FilterID(net.ID, filterValues)
|
||||
}, nil
|
||||
|
||||
// TODO: add dns enabled, internal filter
|
||||
|
4
vendor/github.com/containers/common/pkg/auth/auth.go
generated
vendored
4
vendor/github.com/containers/common/pkg/auth/auth.go
generated
vendored
@ -10,7 +10,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/common/pkg/util"
|
||||
passwd "github.com/containers/common/pkg/password"
|
||||
"github.com/containers/image/v5/docker"
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/pkg/docker/config"
|
||||
@ -269,7 +269,7 @@ func getUserAndPass(opts *LoginOptions, password, userFromAuthFile string) (user
|
||||
}
|
||||
if password == "" {
|
||||
fmt.Fprint(opts.Stdout, "Password: ")
|
||||
pass, err := util.ReadPassword(int(os.Stdin.Fd()))
|
||||
pass, err := passwd.Read(int(os.Stdin.Fd()))
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("reading password: %w", err)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package util
|
||||
package detach
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@ -9,8 +9,8 @@ import (
|
||||
// the user.
|
||||
var ErrDetach = errors.New("detached from container")
|
||||
|
||||
// CopyDetachable is similar to io.Copy but support a detach key sequence to break out.
|
||||
func CopyDetachable(dst io.Writer, src io.Reader, keys []byte) (written int64, err error) {
|
||||
// Copy is similar to io.Copy but support a detach key sequence to break out.
|
||||
func Copy(dst io.Writer, src io.Reader, keys []byte) (written int64, err error) {
|
||||
buf := make([]byte, 32*1024)
|
||||
for {
|
||||
nr, er := src.Read(buf)
|
21
vendor/github.com/containers/common/pkg/filters/filters.go
generated
vendored
21
vendor/github.com/containers/common/pkg/filters/filters.go
generated
vendored
@ -5,9 +5,11 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containers/common/libnetwork/types"
|
||||
"github.com/containers/common/pkg/timetype"
|
||||
)
|
||||
|
||||
@ -134,3 +136,22 @@ func matchPattern(pattern string, value string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// FilterID is a function used to compare an id against a set of ids, if the
|
||||
// input is hex we check if the prefix matches. Otherwise we assume it is a
|
||||
// regex and try to match that.
|
||||
// see https://github.com/containers/podman/issues/18471 for why we do this
|
||||
func FilterID(id string, filters []string) bool {
|
||||
for _, want := range filters {
|
||||
isRegex := types.NotHexRegex.MatchString(want)
|
||||
if isRegex {
|
||||
match, err := regexp.MatchString(want, id)
|
||||
if err == nil && match {
|
||||
return true
|
||||
}
|
||||
} else if strings.HasPrefix(id, strings.ToLower(want)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
57
vendor/github.com/containers/common/pkg/password/password_supported.go
generated
vendored
Normal file
57
vendor/github.com/containers/common/pkg/password/password_supported.go
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
//go:build linux || darwin || freebsd
|
||||
// +build linux darwin freebsd
|
||||
|
||||
package password
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
terminal "golang.org/x/term"
|
||||
)
|
||||
|
||||
var ErrInterrupt = errors.New("interrupted")
|
||||
|
||||
// Read reads a password from the terminal without echo.
|
||||
func Read(fd int) ([]byte, error) {
|
||||
// Store and restore the terminal status on interruptions to
|
||||
// avoid that the terminal remains in the password state
|
||||
// This is necessary as for https://github.com/golang/go/issues/31180
|
||||
|
||||
oldState, err := terminal.GetState(fd)
|
||||
if err != nil {
|
||||
return make([]byte, 0), err
|
||||
}
|
||||
|
||||
type Buffer struct {
|
||||
Buffer []byte
|
||||
Error error
|
||||
}
|
||||
errorChannel := make(chan Buffer, 1)
|
||||
|
||||
// SIGINT and SIGTERM restore the terminal, otherwise the no-echo mode would remain intact
|
||||
interruptChannel := make(chan os.Signal, 1)
|
||||
signal.Notify(interruptChannel, syscall.SIGINT, syscall.SIGTERM)
|
||||
defer func() {
|
||||
signal.Stop(interruptChannel)
|
||||
close(interruptChannel)
|
||||
}()
|
||||
go func() {
|
||||
for range interruptChannel {
|
||||
if oldState != nil {
|
||||
_ = terminal.Restore(fd, oldState)
|
||||
}
|
||||
errorChannel <- Buffer{Buffer: make([]byte, 0), Error: ErrInterrupt}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
buf, err := terminal.ReadPassword(fd)
|
||||
errorChannel <- Buffer{Buffer: buf, Error: err}
|
||||
}()
|
||||
|
||||
buf := <-errorChannel
|
||||
return buf.Buffer, buf.Error
|
||||
}
|
21
vendor/github.com/containers/common/pkg/password/password_windows.go
generated
vendored
Normal file
21
vendor/github.com/containers/common/pkg/password/password_windows.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package password
|
||||
|
||||
import (
|
||||
terminal "golang.org/x/term"
|
||||
)
|
||||
|
||||
// Read reads a password from the terminal.
|
||||
func Read(fd int) ([]byte, error) {
|
||||
oldState, err := terminal.GetState(fd)
|
||||
if err != nil {
|
||||
return make([]byte, 0), err
|
||||
}
|
||||
buf, err := terminal.ReadPassword(fd)
|
||||
if oldState != nil {
|
||||
_ = terminal.Restore(fd, oldState)
|
||||
}
|
||||
return buf, err
|
||||
}
|
122
vendor/github.com/containers/common/pkg/util/util.go
generated
vendored
122
vendor/github.com/containers/common/pkg/util/util.go
generated
vendored
@ -1,119 +1,16 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containers/common/libnetwork/types"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
UnknownPackage = "Unknown"
|
||||
)
|
||||
|
||||
var ErrInterrupt = errors.New("interrupted")
|
||||
|
||||
// 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)
|
||||
deb := false
|
||||
if cmdArg[0] == "/usr/bin/dlocate" {
|
||||
// can return multiple matches
|
||||
l := strings.Split(output, "\n")
|
||||
output = l[0]
|
||||
deb = true
|
||||
} else if cmdArg[0] == "/usr/bin/dpkg" {
|
||||
deb = true
|
||||
}
|
||||
if deb {
|
||||
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
|
||||
_, err := os.Stat(program)
|
||||
if err != nil {
|
||||
return UnknownPackage
|
||||
}
|
||||
packagers := [][]string{
|
||||
{"/usr/bin/rpm", "-q", "-f"},
|
||||
{"/usr/bin/dlocate", "-F"}, // Debian, Ubuntu (quick)
|
||||
{"/usr/bin/dpkg", "-S"}, // Debian, Ubuntu (slow)
|
||||
{"/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 {
|
||||
for _, i := range sl {
|
||||
@ -135,25 +32,6 @@ func StringMatchRegexSlice(s string, re []string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// FilterID is a function used to compare an id against a set of ids, if the
|
||||
// input is hex we check if the prefix matches. Otherwise we assume it is a
|
||||
// regex and try to match that.
|
||||
// see https://github.com/containers/podman/issues/18471 for why we do this
|
||||
func FilterID(id string, filters []string) bool {
|
||||
for _, want := range filters {
|
||||
isRegex := types.NotHexRegex.MatchString(want)
|
||||
if isRegex {
|
||||
match, err := regexp.MatchString(want, id)
|
||||
if err == nil && match {
|
||||
return true
|
||||
}
|
||||
} else if strings.HasPrefix(id, strings.ToLower(want)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// WaitForFile waits until a file has been created or the given timeout has occurred
|
||||
func WaitForFile(path string, chWait chan error, timeout time.Duration) (bool, error) {
|
||||
var inotifyEvents chan fsnotify.Event
|
||||
|
44
vendor/github.com/containers/common/pkg/util/util_supported.go
generated
vendored
44
vendor/github.com/containers/common/pkg/util/util_supported.go
generated
vendored
@ -7,7 +7,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"syscall"
|
||||
@ -15,7 +14,6 @@ import (
|
||||
"github.com/containers/storage/pkg/homedir"
|
||||
"github.com/containers/storage/pkg/unshare"
|
||||
"github.com/sirupsen/logrus"
|
||||
terminal "golang.org/x/term"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -91,45 +89,3 @@ func GetRuntimeDir() (string, error) {
|
||||
}
|
||||
return rootlessRuntimeDir, nil
|
||||
}
|
||||
|
||||
// ReadPassword reads a password from the terminal without echo.
|
||||
func ReadPassword(fd int) ([]byte, error) {
|
||||
// Store and restore the terminal status on interruptions to
|
||||
// avoid that the terminal remains in the password state
|
||||
// This is necessary as for https://github.com/golang/go/issues/31180
|
||||
|
||||
oldState, err := terminal.GetState(fd)
|
||||
if err != nil {
|
||||
return make([]byte, 0), err
|
||||
}
|
||||
|
||||
type Buffer struct {
|
||||
Buffer []byte
|
||||
Error error
|
||||
}
|
||||
errorChannel := make(chan Buffer, 1)
|
||||
|
||||
// SIGINT and SIGTERM restore the terminal, otherwise the no-echo mode would remain intact
|
||||
interruptChannel := make(chan os.Signal, 1)
|
||||
signal.Notify(interruptChannel, syscall.SIGINT, syscall.SIGTERM)
|
||||
defer func() {
|
||||
signal.Stop(interruptChannel)
|
||||
close(interruptChannel)
|
||||
}()
|
||||
go func() {
|
||||
for range interruptChannel {
|
||||
if oldState != nil {
|
||||
_ = terminal.Restore(fd, oldState)
|
||||
}
|
||||
errorChannel <- Buffer{Buffer: make([]byte, 0), Error: ErrInterrupt}
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
buf, err := terminal.ReadPassword(fd)
|
||||
errorChannel <- Buffer{Buffer: buf, Error: err}
|
||||
}()
|
||||
|
||||
buf := <-errorChannel
|
||||
return buf.Buffer, buf.Error
|
||||
}
|
||||
|
15
vendor/github.com/containers/common/pkg/util/util_windows.go
generated
vendored
15
vendor/github.com/containers/common/pkg/util/util_windows.go
generated
vendored
@ -5,24 +5,9 @@ package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
terminal "golang.org/x/term"
|
||||
)
|
||||
|
||||
// getRuntimeDir returns the runtime directory
|
||||
func GetRuntimeDir() (string, error) {
|
||||
return "", errors.New("this function is not implemented for windows")
|
||||
}
|
||||
|
||||
// ReadPassword reads a password from the terminal.
|
||||
func ReadPassword(fd int) ([]byte, error) {
|
||||
oldState, err := terminal.GetState(fd)
|
||||
if err != nil {
|
||||
return make([]byte, 0), err
|
||||
}
|
||||
buf, err := terminal.ReadPassword(fd)
|
||||
if oldState != nil {
|
||||
_ = terminal.Restore(fd, oldState)
|
||||
}
|
||||
return buf, err
|
||||
}
|
||||
|
105
vendor/github.com/containers/common/pkg/version/version.go
generated
vendored
Normal file
105
vendor/github.com/containers/common/pkg/version/version.go
generated
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"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)
|
||||
deb := false
|
||||
if cmdArg[0] == "/usr/bin/dlocate" {
|
||||
// can return multiple matches
|
||||
l := strings.Split(output, "\n")
|
||||
output = l[0]
|
||||
deb = true
|
||||
} else if cmdArg[0] == "/usr/bin/dpkg" {
|
||||
deb = true
|
||||
}
|
||||
if deb {
|
||||
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 Package(program string) string { // program is full path
|
||||
_, err := os.Stat(program)
|
||||
if err != nil {
|
||||
return UnknownPackage
|
||||
}
|
||||
packagers := [][]string{
|
||||
{"/usr/bin/rpm", "-q", "-f"},
|
||||
{"/usr/bin/dlocate", "-F"}, // Debian, Ubuntu (quick)
|
||||
{"/usr/bin/dpkg", "-S"}, // Debian, Ubuntu (slow)
|
||||
{"/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 Program(name string) (string, error) {
|
||||
return program(name, false)
|
||||
}
|
||||
|
||||
func ProgramDnsname(name string) (string, error) {
|
||||
return program(name, true)
|
||||
}
|
||||
|
||||
func program(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
|
||||
}
|
Reference in New Issue
Block a user