vendor of containers/common

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2023-09-20 08:09:54 -04:00
parent e80d9b7f85
commit 73dc72f80d
24 changed files with 257 additions and 230 deletions

2
go.mod
View File

@ -13,7 +13,7 @@ require (
github.com/containernetworking/cni v1.1.2
github.com/containernetworking/plugins v1.3.0
github.com/containers/buildah v1.32.0
github.com/containers/common v0.56.1-0.20230919073449-d1d9d38d8282
github.com/containers/common v0.56.1-0.20230920110729-eb4ad859f309
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/gvisor-tap-vsock v0.7.1-0.20230907154503-507f56851e8b
github.com/containers/image/v5 v5.28.0

4
go.sum
View File

@ -249,8 +249,8 @@ github.com/containernetworking/plugins v1.3.0 h1:QVNXMT6XloyMUoO2wUOqWTC1hWFV62Q
github.com/containernetworking/plugins v1.3.0/go.mod h1:Pc2wcedTQQCVuROOOaLBPPxrEXqqXBFt3cZ+/yVg6l0=
github.com/containers/buildah v1.32.0 h1:uz5Rcf7lGeStj7iPTBgO4UdhQYZqMMzyt9suDf16k1k=
github.com/containers/buildah v1.32.0/go.mod h1:sN3rA3DbnqekNz3bNdkqWduuirYDuMs54LUCOZOomBE=
github.com/containers/common v0.56.1-0.20230919073449-d1d9d38d8282 h1:GkMoKMmH4EhjdCNk1jYGWC0pTa+SFdp6fas64nPOPyY=
github.com/containers/common v0.56.1-0.20230919073449-d1d9d38d8282/go.mod h1:NKWo6OWVItRwJjqu30vd4uFG3bBKUL9q+B38GNwY/bo=
github.com/containers/common v0.56.1-0.20230920110729-eb4ad859f309 h1:ZuP6m9Ps9bBR/3TlR4AqzobAvtYstKkoYmKIg3R7O84=
github.com/containers/common v0.56.1-0.20230920110729-eb4ad859f309/go.mod h1:ABFEglmyt48WWWQv80kGhitfbVfR1Br35wk3gBQdrIk=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/gvisor-tap-vsock v0.7.1-0.20230907154503-507f56851e8b h1:1nH+VNnclNbAXwcsK2MkLT3gFWfbxasQOPBkj1DUmCI=

View File

@ -5,7 +5,7 @@ import (
"fmt"
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/util"
"github.com/containers/common/pkg/detach"
)
var (
@ -93,7 +93,7 @@ var (
// ErrDetach indicates that an attach session was manually detached by
// the user.
ErrDetach = util.ErrDetach
ErrDetach = detach.ErrDetach
// ErrWillDeadlock indicates that the requested operation will cause a
// deadlock. This is usually caused by upgrade issues, and is resolved

View File

@ -14,7 +14,7 @@ import (
"github.com/containers/buildah"
"github.com/containers/buildah/pkg/util"
cutil "github.com/containers/common/pkg/util"
"github.com/containers/common/pkg/version"
"github.com/containers/image/v5/pkg/sysregistriesv2"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/linkmode"
@ -243,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 := cutil.ProgramVersion(split[1])
ver, err := version.Program(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"] = cutil.PackageVersion(split[1])
program["Version"] = ver
program["Package"] = version.Package(split[1])
graphOptions[split[0]] = program
} else {
graphOptions[split[0]] = split[1]

View File

@ -13,7 +13,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/common/pkg/version"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/rootless"
"github.com/opencontainers/selinux/go-selinux"
@ -62,28 +62,28 @@ func (r *Runtime) setPlatformHostInfo(info *define.HostInfo) error {
slirp4netnsPath, _ = r.config.FindHelperBinary(libpod.BinaryName, true)
}
if slirp4netnsPath != "" {
version, err := util.ProgramVersion(slirp4netnsPath)
ver, err := version.Program(slirp4netnsPath)
if err != nil {
logrus.Warnf("Failed to retrieve program version for %s: %v", slirp4netnsPath, err)
}
program := define.SlirpInfo{
Executable: slirp4netnsPath,
Package: util.PackageVersion(slirp4netnsPath),
Version: version,
Package: version.Package(slirp4netnsPath),
Version: ver,
}
info.Slirp4NetNS = program
}
pastaPath, _ := r.config.FindHelperBinary(pasta.BinaryName, true)
if pastaPath != "" {
version, err := util.ProgramVersion(pastaPath)
ver, err := version.Program(pastaPath)
if err != nil {
logrus.Warnf("Failed to retrieve program version for %s: %v", pastaPath, err)
}
program := define.PastaInfo{
Executable: pastaPath,
Package: util.PackageVersion(pastaPath),
Version: version,
Package: version.Package(pastaPath),
Version: ver,
}
info.Pasta = program
}

View File

@ -14,8 +14,8 @@ import (
"syscall"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/detach"
"github.com/containers/common/pkg/resize"
"github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/errorhandling"
"github.com/moby/term"
@ -235,7 +235,7 @@ func setupStdioChannels(streams *define.AttachStreams, conn *net.UnixConn, detac
go func() {
var err error
if streams.AttachInput {
_, err = util.CopyDetachable(conn, streams.InputStream, detachKeys)
_, err = detach.Copy(conn, streams.InputStream, detachKeys)
}
stdinDone <- err
}()

View File

@ -23,8 +23,9 @@ import (
"time"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/detach"
"github.com/containers/common/pkg/resize"
cutil "github.com/containers/common/pkg/util"
"github.com/containers/common/pkg/version"
conmonConfig "github.com/containers/conmon/runner/config"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/logs"
@ -583,7 +584,7 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
if detachKeys != nil {
detachString = *detachKeys
}
detach, err := processDetachKeys(detachString)
isDetach, err := processDetachKeys(detachString)
if err != nil {
return err
}
@ -735,7 +736,7 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http.
// Next, STDIN. Avoid entirely if attachStdin unset.
if attachStdin {
go func() {
_, err := cutil.CopyDetachable(conn, httpBuf, detach)
_, err := detach.Copy(conn, httpBuf, isDetach)
logrus.Debugf("STDIN copy completed")
stdinChan <- err
}()
@ -943,8 +944,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 := cutil.PackageVersion(r.path)
conmonPackage := cutil.PackageVersion(r.conmonPath)
runtimePackage := version.Package(r.path)
conmonPackage := version.Package(r.conmonPath)
runtimeVersion, err := r.getOCIRuntimeVersion()
if err != nil {
return nil, nil, fmt.Errorf("getting version of OCI runtime %s: %w", r.name, err)

View File

@ -12,8 +12,8 @@ import (
"time"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/detach"
"github.com/containers/common/pkg/resize"
cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/errorhandling"
"github.com/containers/podman/v4/pkg/lookup"
@ -606,7 +606,7 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp
if attachStdin {
go func() {
logrus.Debugf("Beginning STDIN copy")
_, err := cutil.CopyDetachable(conn, httpBuf, detachKeys)
_, err := detach.Copy(conn, httpBuf, detachKeys)
logrus.Debugf("STDIN copy completed")
stdinChan <- err
}()

View File

@ -15,7 +15,7 @@ import (
"strconv"
"time"
"github.com/containers/common/pkg/util"
"github.com/containers/common/pkg/detach"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/bindings"
"github.com/moby/term"
@ -159,7 +159,7 @@ func Attach(ctx context.Context, nameOrID string, stdin io.Reader, stdout io.Wri
go func() {
logrus.Debugf("Copying STDIN to socket")
_, err := util.CopyDetachable(socket, stdin, detachKeysInBytes)
_, err := detach.Copy(socket, stdin, detachKeysInBytes)
if err != nil && err != define.ErrDetach {
logrus.Errorf("Failed to write input to service: %v", err)
}
@ -497,7 +497,7 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar
if options.GetAttachInput() {
go func() {
logrus.Debugf("Copying STDIN to socket")
_, err := util.CopyDetachable(socket, options.InputStream, []byte{})
_, err := detach.Copy(socket, options.InputStream, []byte{})
if err != nil {
logrus.Errorf("Failed to write input to service: %v", err)
}
@ -518,7 +518,7 @@ func ExecStartAndAttach(ctx context.Context, sessionID string, options *ExecStar
return fmt.Errorf("exec session %s has a terminal and must have STDOUT enabled", sessionID)
}
// If not multiplex'ed, read from server and write to stdout
_, err := util.CopyDetachable(options.GetOutputStream(), socket, []byte{})
_, err := detach.Copy(options.GetOutputStream(), socket, []byte{})
if err != nil {
return err
}

View File

@ -18,7 +18,7 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
switch filter {
case "id":
return func(c *libpod.Container) bool {
return util.FilterID(c.ID(), filterValues)
return filters.FilterID(c.ID(), filterValues)
}, nil
case "label":
// we have to match that all given labels exits on that container

View File

@ -25,7 +25,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
return false
}
for _, id := range ctrIds {
if util.FilterID(id, filterValues) {
if filters.FilterID(id, filterValues) {
return true
}
}
@ -90,7 +90,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
}, nil
case "id":
return func(p *libpod.Pod) bool {
return util.FilterID(p.ID(), filterValues)
return filters.FilterID(p.ID(), filterValues)
}, nil
case "name":
return func(p *libpod.Pod) bool {

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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

View File

@ -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)
}

View File

@ -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)

View File

@ -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
}

View 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
}

View 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
}

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View 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
}

5
vendor/modules.txt vendored
View File

@ -164,7 +164,7 @@ github.com/containers/buildah/pkg/sshagent
github.com/containers/buildah/pkg/util
github.com/containers/buildah/pkg/volumes
github.com/containers/buildah/util
# github.com/containers/common v0.56.1-0.20230919073449-d1d9d38d8282
# github.com/containers/common v0.56.1-0.20230920110729-eb4ad859f309
## explicit; go 1.18
github.com/containers/common/libimage
github.com/containers/common/libimage/define
@ -189,6 +189,7 @@ github.com/containers/common/pkg/cgroupv2
github.com/containers/common/pkg/chown
github.com/containers/common/pkg/completion
github.com/containers/common/pkg/config
github.com/containers/common/pkg/detach
github.com/containers/common/pkg/download
github.com/containers/common/pkg/filters
github.com/containers/common/pkg/flag
@ -200,6 +201,7 @@ github.com/containers/common/pkg/machine
github.com/containers/common/pkg/manifests
github.com/containers/common/pkg/netns
github.com/containers/common/pkg/parse
github.com/containers/common/pkg/password
github.com/containers/common/pkg/report
github.com/containers/common/pkg/report/camelcase
github.com/containers/common/pkg/resize
@ -219,6 +221,7 @@ github.com/containers/common/pkg/sysinfo
github.com/containers/common/pkg/timetype
github.com/containers/common/pkg/umask
github.com/containers/common/pkg/util
github.com/containers/common/pkg/version
github.com/containers/common/version
# github.com/containers/conmon v2.0.20+incompatible
## explicit