Skip to content

Commit eb4ad85

Browse files
Merge pull request #1657 from rhatdan/run
Split up util package into pkg/password, pkg/copy, pkg/version
2 parents ab4b95b + 54cdbd0 commit eb4ad85

File tree

12 files changed

+220
-197
lines changed

12 files changed

+220
-197
lines changed

libnetwork/cni/network.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
"github.com/containernetworking/cni/libcni"
1818
"github.com/containers/common/libnetwork/types"
1919
"github.com/containers/common/pkg/config"
20-
cutil "github.com/containers/common/pkg/util"
20+
"github.com/containers/common/pkg/version"
2121
"github.com/containers/storage/pkg/lockfile"
2222
"github.com/containers/storage/pkg/unshare"
2323
"github.com/sirupsen/logrus"
@@ -302,8 +302,8 @@ func (n *cniNetwork) NetworkInfo() types.NetworkInfo {
302302
path := ""
303303
packageVersion := ""
304304
for _, p := range n.cniPluginDirs {
305-
ver := cutil.PackageVersion(p)
306-
if ver != cutil.UnknownPackage {
305+
ver := version.Package(p)
306+
if ver != version.UnknownPackage {
307307
path = p
308308
packageVersion = ver
309309
break
@@ -317,8 +317,8 @@ func (n *cniNetwork) NetworkInfo() types.NetworkInfo {
317317
}
318318

319319
dnsPath := filepath.Join(path, "dnsname")
320-
dnsPackage := cutil.PackageVersion(dnsPath)
321-
dnsProgram, err := cutil.ProgramVersionDnsname(dnsPath)
320+
dnsPackage := version.Package(dnsPath)
321+
dnsProgram, err := version.ProgramDnsname(dnsPath)
322322
if err != nil {
323323
logrus.Infof("Failed to get the dnsname plugin version: %v", err)
324324
}

libnetwork/netavark/network.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
"github.com/containers/common/libnetwork/internal/util"
1616
"github.com/containers/common/libnetwork/types"
1717
"github.com/containers/common/pkg/config"
18-
cutil "github.com/containers/common/pkg/util"
18+
"github.com/containers/common/pkg/version"
1919
"github.com/containers/storage/pkg/lockfile"
2020
"github.com/containers/storage/pkg/unshare"
2121
"github.com/sirupsen/logrus"
@@ -341,8 +341,8 @@ func (n *netavarkNetwork) DefaultInterfaceName() string {
341341
// package version and program version.
342342
func (n *netavarkNetwork) NetworkInfo() types.NetworkInfo {
343343
path := n.netavarkBinary
344-
packageVersion := cutil.PackageVersion(path)
345-
programVersion, err := cutil.ProgramVersion(path)
344+
packageVersion := version.Package(path)
345+
programVersion, err := version.Program(path)
346346
if err != nil {
347347
logrus.Infof("Failed to get the netavark version: %v", err)
348348
}
@@ -354,8 +354,8 @@ func (n *netavarkNetwork) NetworkInfo() types.NetworkInfo {
354354
}
355355

356356
dnsPath := n.aardvarkBinary
357-
dnsPackage := cutil.PackageVersion(dnsPath)
358-
dnsProgram, err := cutil.ProgramVersion(dnsPath)
357+
dnsPackage := version.Package(dnsPath)
358+
dnsProgram, err := version.Program(dnsPath)
359359
if err != nil {
360360
logrus.Infof("Failed to get the aardvark version: %v", err)
361361
}

libnetwork/util/filters.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func createFilterFuncs(key string, filterValues []string) (types.FilterFunc, err
3838
case "id":
3939
// matches part of one id
4040
return func(net types.Network) bool {
41-
return util.FilterID(net.ID, filterValues)
41+
return filters.FilterID(net.ID, filterValues)
4242
}, nil
4343

4444
// TODO: add dns enabled, internal filter

pkg/auth/auth.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"path/filepath"
1111
"strings"
1212

13-
"github.com/containers/common/pkg/util"
13+
passwd "github.com/containers/common/pkg/password"
1414
"github.com/containers/image/v5/docker"
1515
"github.com/containers/image/v5/docker/reference"
1616
"github.com/containers/image/v5/pkg/docker/config"
@@ -269,7 +269,7 @@ func getUserAndPass(opts *LoginOptions, password, userFromAuthFile string) (user
269269
}
270270
if password == "" {
271271
fmt.Fprint(opts.Stdout, "Password: ")
272-
pass, err := util.ReadPassword(int(os.Stdin.Fd()))
272+
pass, err := passwd.Read(int(os.Stdin.Fd()))
273273
if err != nil {
274274
return "", "", fmt.Errorf("reading password: %w", err)
275275
}

pkg/util/copy.go renamed to pkg/detach/copy.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package util
1+
package detach
22

33
import (
44
"errors"
@@ -9,8 +9,8 @@ import (
99
// the user.
1010
var ErrDetach = errors.New("detached from container")
1111

12-
// CopyDetachable is similar to io.Copy but support a detach key sequence to break out.
13-
func CopyDetachable(dst io.Writer, src io.Reader, keys []byte) (written int64, err error) {
12+
// Copy is similar to io.Copy but support a detach key sequence to break out.
13+
func Copy(dst io.Writer, src io.Reader, keys []byte) (written int64, err error) {
1414
buf := make([]byte, 32*1024)
1515
for {
1616
nr, er := src.Read(buf)

pkg/filters/filters.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import (
55
"fmt"
66
"net/http"
77
"path/filepath"
8+
"regexp"
89
"strings"
910
"time"
1011

12+
"github.com/containers/common/libnetwork/types"
1113
"github.com/containers/common/pkg/timetype"
1214
)
1315

@@ -134,3 +136,22 @@ func matchPattern(pattern string, value string) bool {
134136
}
135137
return false
136138
}
139+
140+
// FilterID is a function used to compare an id against a set of ids, if the
141+
// input is hex we check if the prefix matches. Otherwise we assume it is a
142+
// regex and try to match that.
143+
// see https://github.com/containers/podman/issues/18471 for why we do this
144+
func FilterID(id string, filters []string) bool {
145+
for _, want := range filters {
146+
isRegex := types.NotHexRegex.MatchString(want)
147+
if isRegex {
148+
match, err := regexp.MatchString(want, id)
149+
if err == nil && match {
150+
return true
151+
}
152+
} else if strings.HasPrefix(id, strings.ToLower(want)) {
153+
return true
154+
}
155+
}
156+
return false
157+
}

pkg/password/password_supported.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//go:build linux || darwin || freebsd
2+
// +build linux darwin freebsd
3+
4+
package password
5+
6+
import (
7+
"errors"
8+
"os"
9+
"os/signal"
10+
"syscall"
11+
12+
terminal "golang.org/x/term"
13+
)
14+
15+
var ErrInterrupt = errors.New("interrupted")
16+
17+
// Read reads a password from the terminal without echo.
18+
func Read(fd int) ([]byte, error) {
19+
// Store and restore the terminal status on interruptions to
20+
// avoid that the terminal remains in the password state
21+
// This is necessary as for https://github.com/golang/go/issues/31180
22+
23+
oldState, err := terminal.GetState(fd)
24+
if err != nil {
25+
return make([]byte, 0), err
26+
}
27+
28+
type Buffer struct {
29+
Buffer []byte
30+
Error error
31+
}
32+
errorChannel := make(chan Buffer, 1)
33+
34+
// SIGINT and SIGTERM restore the terminal, otherwise the no-echo mode would remain intact
35+
interruptChannel := make(chan os.Signal, 1)
36+
signal.Notify(interruptChannel, syscall.SIGINT, syscall.SIGTERM)
37+
defer func() {
38+
signal.Stop(interruptChannel)
39+
close(interruptChannel)
40+
}()
41+
go func() {
42+
for range interruptChannel {
43+
if oldState != nil {
44+
_ = terminal.Restore(fd, oldState)
45+
}
46+
errorChannel <- Buffer{Buffer: make([]byte, 0), Error: ErrInterrupt}
47+
}
48+
}()
49+
50+
go func() {
51+
buf, err := terminal.ReadPassword(fd)
52+
errorChannel <- Buffer{Buffer: buf, Error: err}
53+
}()
54+
55+
buf := <-errorChannel
56+
return buf.Buffer, buf.Error
57+
}

pkg/password/password_windows.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//go:build windows
2+
// +build windows
3+
4+
package password
5+
6+
import (
7+
terminal "golang.org/x/term"
8+
)
9+
10+
// Read reads a password from the terminal.
11+
func Read(fd int) ([]byte, error) {
12+
oldState, err := terminal.GetState(fd)
13+
if err != nil {
14+
return make([]byte, 0), err
15+
}
16+
buf, err := terminal.ReadPassword(fd)
17+
if oldState != nil {
18+
_ = terminal.Restore(fd, oldState)
19+
}
20+
return buf, err
21+
}

pkg/util/util.go

Lines changed: 0 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,16 @@
11
package util
22

33
import (
4-
"bytes"
5-
"errors"
64
"fmt"
75
"os"
8-
"os/exec"
96
"path/filepath"
107
"regexp"
11-
"strings"
128
"time"
139

14-
"github.com/containers/common/libnetwork/types"
1510
"github.com/fsnotify/fsnotify"
1611
"github.com/sirupsen/logrus"
1712
)
1813

19-
const (
20-
UnknownPackage = "Unknown"
21-
)
22-
23-
var ErrInterrupt = errors.New("interrupted")
24-
25-
// Note: This function is copied from containers/podman libpod/util.go
26-
// Please see https://github.com/containers/common/pull/1460
27-
func queryPackageVersion(cmdArg ...string) string {
28-
output := UnknownPackage
29-
if 1 < len(cmdArg) {
30-
cmd := exec.Command(cmdArg[0], cmdArg[1:]...)
31-
if outp, err := cmd.Output(); err == nil {
32-
output = string(outp)
33-
deb := false
34-
if cmdArg[0] == "/usr/bin/dlocate" {
35-
// can return multiple matches
36-
l := strings.Split(output, "\n")
37-
output = l[0]
38-
deb = true
39-
} else if cmdArg[0] == "/usr/bin/dpkg" {
40-
deb = true
41-
}
42-
if deb {
43-
r := strings.Split(output, ": ")
44-
queryFormat := `${Package}_${Version}_${Architecture}`
45-
cmd = exec.Command("/usr/bin/dpkg-query", "-f", queryFormat, "-W", r[0])
46-
if outp, err := cmd.Output(); err == nil {
47-
output = string(outp)
48-
}
49-
}
50-
}
51-
if cmdArg[0] == "/sbin/apk" {
52-
prefix := cmdArg[len(cmdArg)-1] + " is owned by "
53-
output = strings.Replace(output, prefix, "", 1)
54-
}
55-
}
56-
return strings.Trim(output, "\n")
57-
}
58-
59-
// Note: This function is copied from containers/podman libpod/util.go
60-
// Please see https://github.com/containers/common/pull/1460
61-
func PackageVersion(program string) string { // program is full path
62-
_, err := os.Stat(program)
63-
if err != nil {
64-
return UnknownPackage
65-
}
66-
packagers := [][]string{
67-
{"/usr/bin/rpm", "-q", "-f"},
68-
{"/usr/bin/dlocate", "-F"}, // Debian, Ubuntu (quick)
69-
{"/usr/bin/dpkg", "-S"}, // Debian, Ubuntu (slow)
70-
{"/usr/bin/pacman", "-Qo"}, // Arch
71-
{"/usr/bin/qfile", "-qv"}, // Gentoo (quick)
72-
{"/usr/bin/equery", "b"}, // Gentoo (slow)
73-
{"/sbin/apk", "info", "-W"}, // Alpine
74-
{"/usr/local/sbin/pkg", "which", "-q"}, // FreeBSD
75-
}
76-
77-
for _, cmd := range packagers {
78-
cmd = append(cmd, program)
79-
if out := queryPackageVersion(cmd...); out != UnknownPackage {
80-
return out
81-
}
82-
}
83-
return UnknownPackage
84-
}
85-
86-
// Note: This function is copied from containers/podman libpod/util.go
87-
// Please see https://github.com/containers/common/pull/1460
88-
func ProgramVersion(program string) (string, error) {
89-
return programVersion(program, false)
90-
}
91-
92-
func ProgramVersionDnsname(program string) (string, error) {
93-
return programVersion(program, true)
94-
}
95-
96-
func programVersion(program string, dnsname bool) (string, error) {
97-
cmd := exec.Command(program, "--version")
98-
var stdout bytes.Buffer
99-
var stderr bytes.Buffer
100-
cmd.Stdout = &stdout
101-
cmd.Stderr = &stderr
102-
103-
err := cmd.Run()
104-
if err != nil {
105-
return "", fmt.Errorf("`%v --version` failed: %v %v (%v)", program, stderr.String(), stdout.String(), err)
106-
}
107-
108-
output := strings.TrimSuffix(stdout.String(), "\n")
109-
// dnsname --version returns the information to stderr
110-
if dnsname {
111-
output = strings.TrimSuffix(stderr.String(), "\n")
112-
}
113-
114-
return output, nil
115-
}
116-
11714
// StringInSlice determines if a string is in a string slice, returns bool
11815
func StringInSlice(s string, sl []string) bool {
11916
for _, i := range sl {
@@ -135,25 +32,6 @@ func StringMatchRegexSlice(s string, re []string) bool {
13532
return false
13633
}
13734

138-
// FilterID is a function used to compare an id against a set of ids, if the
139-
// input is hex we check if the prefix matches. Otherwise we assume it is a
140-
// regex and try to match that.
141-
// see https://github.com/containers/podman/issues/18471 for why we do this
142-
func FilterID(id string, filters []string) bool {
143-
for _, want := range filters {
144-
isRegex := types.NotHexRegex.MatchString(want)
145-
if isRegex {
146-
match, err := regexp.MatchString(want, id)
147-
if err == nil && match {
148-
return true
149-
}
150-
} else if strings.HasPrefix(id, strings.ToLower(want)) {
151-
return true
152-
}
153-
}
154-
return false
155-
}
156-
15735
// WaitForFile waits until a file has been created or the given timeout has occurred
15836
func WaitForFile(path string, chWait chan error, timeout time.Duration) (bool, error) {
15937
var inotifyEvents chan fsnotify.Event

0 commit comments

Comments
 (0)