mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #41208 from thaJeztah/remove_shellwords
This commit is contained in:
commit
cadd72d37d
12 changed files with 60 additions and 409 deletions
|
@ -8,49 +8,51 @@ import (
|
|||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
shellwords "github.com/mattn/go-shellwords"
|
||||
)
|
||||
|
||||
// GetKernelVersion gets the current kernel version.
|
||||
func GetKernelVersion() (*VersionInfo, error) {
|
||||
release, err := getRelease()
|
||||
osName, err := getSPSoftwareDataType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
release, err := getRelease(osName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ParseRelease(release)
|
||||
}
|
||||
|
||||
// getRelease uses `system_profiler SPSoftwareDataType` to get OSX kernel version
|
||||
func getRelease() (string, error) {
|
||||
func getRelease(osName string) (string, error) {
|
||||
var release string
|
||||
data := strings.Split(osName, "\n")
|
||||
for _, line := range data {
|
||||
if !strings.Contains(line, "Kernel Version") {
|
||||
continue
|
||||
}
|
||||
// It has the format like ' Kernel Version: Darwin 14.5.0'
|
||||
content := strings.SplitN(line, ":", 2)
|
||||
if len(content) != 2 {
|
||||
return "", fmt.Errorf("Kernel Version is invalid")
|
||||
}
|
||||
|
||||
prettyNames := strings.SplitN(strings.TrimSpace(content[1]), " ", 2)
|
||||
|
||||
if len(prettyNames) != 2 {
|
||||
return "", fmt.Errorf("Kernel Version needs to be 'Darwin x.x.x' ")
|
||||
}
|
||||
release = prettyNames[1]
|
||||
}
|
||||
|
||||
return release, nil
|
||||
}
|
||||
|
||||
func getSPSoftwareDataType() (string, error) {
|
||||
cmd := exec.Command("system_profiler", "SPSoftwareDataType")
|
||||
osName, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var release string
|
||||
data := strings.Split(string(osName), "\n")
|
||||
for _, line := range data {
|
||||
if strings.Contains(line, "Kernel Version") {
|
||||
// It has the format like ' Kernel Version: Darwin 14.5.0'
|
||||
content := strings.SplitN(line, ":", 2)
|
||||
if len(content) != 2 {
|
||||
return "", fmt.Errorf("Kernel Version is invalid")
|
||||
}
|
||||
|
||||
prettyNames, err := shellwords.Parse(content[1])
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Kernel Version is invalid: %s", err.Error())
|
||||
}
|
||||
|
||||
if len(prettyNames) != 2 {
|
||||
return "", fmt.Errorf("Kernel Version needs to be 'Darwin x.x.x' ")
|
||||
}
|
||||
release = prettyNames[1]
|
||||
}
|
||||
}
|
||||
|
||||
return release, nil
|
||||
return string(osName), nil
|
||||
}
|
||||
|
|
28
pkg/parsers/kernel/kernel_darwin_test.go
Normal file
28
pkg/parsers/kernel/kernel_darwin_test.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package kernel
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestGetRelease(t *testing.T) {
|
||||
// example output of "system_profiler SPSoftwareDataType"
|
||||
const spSoftwareDataType = `Software:
|
||||
|
||||
System Software Overview:
|
||||
|
||||
System Version: macOS 10.14.6 (18G4032)
|
||||
Kernel Version: Darwin 18.7.0
|
||||
Boot Volume: fastfood
|
||||
Boot Mode: Normal
|
||||
Computer Name: Macintosh
|
||||
User Name: Foobar (foobar)
|
||||
Secure Virtual Memory: Enabled
|
||||
System Integrity Protection: Enabled
|
||||
Time since boot: 6 days 23:16
|
||||
`
|
||||
release, err := getRelease(spSoftwareDataType)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, release, "18.7.0")
|
||||
}
|
|
@ -9,8 +9,6 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
shellwords "github.com/mattn/go-shellwords"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -63,14 +61,7 @@ func getValueFromOsRelease(key string) (string, error) {
|
|||
line := scanner.Text()
|
||||
if strings.HasPrefix(line, keyWithTrailingEqual) {
|
||||
data := strings.SplitN(line, "=", 2)
|
||||
values, err := shellwords.Parse(data[1])
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("%s is invalid: %s", key, err.Error())
|
||||
}
|
||||
if len(values) != 1 {
|
||||
return "", fmt.Errorf("%s needs to be enclosed by quotes if they have spaces: %s", key, data[1])
|
||||
}
|
||||
value = values[0]
|
||||
value = strings.Trim(data[1], `"' `) // remove leading/trailing quotes and whitespace
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,26 +20,6 @@ type EtcReleaseParsingTest struct {
|
|||
|
||||
func TestGetOperatingSystem(t *testing.T) {
|
||||
tests := []EtcReleaseParsingTest{
|
||||
{
|
||||
content: `PRETTY_NAME=Source Mage GNU/Linux
|
||||
PRETTY_NAME=Ubuntu 14.04.LTS`,
|
||||
expectedErr: "PRETTY_NAME needs to be enclosed by quotes if they have spaces: Source Mage GNU/Linux",
|
||||
},
|
||||
{
|
||||
content: `PRETTY_NAME="Ubuntu Linux
|
||||
PRETTY_NAME=Ubuntu 14.04.LTS`,
|
||||
expectedErr: "PRETTY_NAME is invalid: invalid command line string",
|
||||
},
|
||||
{
|
||||
content: `PRETTY_NAME=Ubuntu'
|
||||
PRETTY_NAME=Ubuntu 14.04.LTS`,
|
||||
expectedErr: "PRETTY_NAME is invalid: invalid command line string",
|
||||
},
|
||||
{
|
||||
content: `PRETTY_NAME'
|
||||
PRETTY_NAME=Ubuntu 14.04.LTS`,
|
||||
expectedErr: "PRETTY_NAME needs to be enclosed by quotes if they have spaces: Ubuntu 14.04.LTS",
|
||||
},
|
||||
{
|
||||
content: `NAME="Ubuntu"
|
||||
PRETTY_NAME_AGAIN="Ubuntu 14.04.LTS"
|
||||
|
@ -111,12 +91,6 @@ PRETTY_NAME="Source Mage"`,
|
|||
|
||||
func TestGetOperatingSystemVersion(t *testing.T) {
|
||||
tests := []EtcReleaseParsingTest{
|
||||
{
|
||||
name: "invalid version id",
|
||||
content: `VERSION_ID="18.04
|
||||
VERSION_ID=18.04`,
|
||||
expectedErr: "VERSION_ID is invalid: invalid command line string",
|
||||
},
|
||||
{
|
||||
name: "ubuntu 14.04",
|
||||
content: `NAME="Ubuntu"
|
||||
|
|
|
@ -10,7 +10,6 @@ github.com/moby/term 73f35e472e8f0a3f91347164138c
|
|||
|
||||
github.com/creack/pty 3a6a957789163cacdfe0e291617a1c8e80612c11 # v1.1.9
|
||||
github.com/konsorten/go-windows-terminal-sequences edb144dfd453055e1e49a3d8b410a660b5a87613 # v1.0.3
|
||||
github.com/mattn/go-shellwords 36a9b3c57cb5caa559ff63fb7e9b585f1c00df75 # v1.0.6
|
||||
github.com/sirupsen/logrus 60c74ad9be0d874af0ab0daef6ab07c5c5911f0d # v1.6.0
|
||||
github.com/tchap/go-patricia a7f0089c6f496e8e70402f61733606daa326cac5 # v2.3.0
|
||||
golang.org/x/net 0de0cce0169b09b364e001f108dc0399ea8630b3
|
||||
|
|
21
vendor/github.com/mattn/go-shellwords/LICENSE
generated
vendored
21
vendor/github.com/mattn/go-shellwords/LICENSE
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Yasuhiro Matsumoto
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
47
vendor/github.com/mattn/go-shellwords/README.md
generated
vendored
47
vendor/github.com/mattn/go-shellwords/README.md
generated
vendored
|
@ -1,47 +0,0 @@
|
|||
# go-shellwords
|
||||
|
||||
[![codecov](https://codecov.io/gh/mattn/go-shellwords/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-shellwords)
|
||||
[![Build Status](https://travis-ci.org/mattn/go-shellwords.svg?branch=master)](https://travis-ci.org/mattn/go-shellwords)
|
||||
|
||||
Parse line as shell words.
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
args, err := shellwords.Parse("./foo --bar=baz")
|
||||
// args should be ["./foo", "--bar=baz"]
|
||||
```
|
||||
|
||||
```go
|
||||
os.Setenv("FOO", "bar")
|
||||
p := shellwords.NewParser()
|
||||
p.ParseEnv = true
|
||||
args, err := p.Parse("./foo $FOO")
|
||||
// args should be ["./foo", "bar"]
|
||||
```
|
||||
|
||||
```go
|
||||
p := shellwords.NewParser()
|
||||
p.ParseBacktick = true
|
||||
args, err := p.Parse("./foo `echo $SHELL`")
|
||||
// args should be ["./foo", "/bin/bash"]
|
||||
```
|
||||
|
||||
```go
|
||||
shellwords.ParseBacktick = true
|
||||
p := shellwords.NewParser()
|
||||
args, err := p.Parse("./foo `echo $SHELL`")
|
||||
// args should be ["./foo", "/bin/bash"]
|
||||
```
|
||||
|
||||
# Thanks
|
||||
|
||||
This is based on cpan module [Parse::CommandLine](https://metacpan.org/pod/Parse::CommandLine).
|
||||
|
||||
# License
|
||||
|
||||
under the MIT License: http://mattn.mit-license.org/2017
|
||||
|
||||
# Author
|
||||
|
||||
Yasuhiro Matsumoto (a.k.a mattn)
|
1
vendor/github.com/mattn/go-shellwords/go.mod
generated
vendored
1
vendor/github.com/mattn/go-shellwords/go.mod
generated
vendored
|
@ -1 +0,0 @@
|
|||
module github.com/mattn/go-shellwords
|
193
vendor/github.com/mattn/go-shellwords/shellwords.go
generated
vendored
193
vendor/github.com/mattn/go-shellwords/shellwords.go
generated
vendored
|
@ -1,193 +0,0 @@
|
|||
package shellwords
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ParseEnv bool = false
|
||||
ParseBacktick bool = false
|
||||
)
|
||||
|
||||
var envRe = regexp.MustCompile(`\$({[a-zA-Z0-9_]+}|[a-zA-Z0-9_]+)`)
|
||||
|
||||
func isSpace(r rune) bool {
|
||||
switch r {
|
||||
case ' ', '\t', '\r', '\n':
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func replaceEnv(getenv func(string) string, s string) string {
|
||||
if getenv == nil {
|
||||
getenv = os.Getenv
|
||||
}
|
||||
|
||||
return envRe.ReplaceAllStringFunc(s, func(s string) string {
|
||||
s = s[1:]
|
||||
if s[0] == '{' {
|
||||
s = s[1 : len(s)-1]
|
||||
}
|
||||
return getenv(s)
|
||||
})
|
||||
}
|
||||
|
||||
type Parser struct {
|
||||
ParseEnv bool
|
||||
ParseBacktick bool
|
||||
Position int
|
||||
Dir string
|
||||
|
||||
// If ParseEnv is true, use this for getenv.
|
||||
// If nil, use os.Getenv.
|
||||
Getenv func(string) string
|
||||
}
|
||||
|
||||
func NewParser() *Parser {
|
||||
return &Parser{
|
||||
ParseEnv: ParseEnv,
|
||||
ParseBacktick: ParseBacktick,
|
||||
Position: 0,
|
||||
Dir: "",
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) Parse(line string) ([]string, error) {
|
||||
args := []string{}
|
||||
buf := ""
|
||||
var escaped, doubleQuoted, singleQuoted, backQuote, dollarQuote bool
|
||||
backtick := ""
|
||||
|
||||
pos := -1
|
||||
got := false
|
||||
|
||||
loop:
|
||||
for i, r := range line {
|
||||
if escaped {
|
||||
buf += string(r)
|
||||
escaped = false
|
||||
continue
|
||||
}
|
||||
|
||||
if r == '\\' {
|
||||
if singleQuoted {
|
||||
buf += string(r)
|
||||
} else {
|
||||
escaped = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if isSpace(r) {
|
||||
if singleQuoted || doubleQuoted || backQuote || dollarQuote {
|
||||
buf += string(r)
|
||||
backtick += string(r)
|
||||
} else if got {
|
||||
if p.ParseEnv {
|
||||
buf = replaceEnv(p.Getenv, buf)
|
||||
}
|
||||
args = append(args, buf)
|
||||
buf = ""
|
||||
got = false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
switch r {
|
||||
case '`':
|
||||
if !singleQuoted && !doubleQuoted && !dollarQuote {
|
||||
if p.ParseBacktick {
|
||||
if backQuote {
|
||||
out, err := shellRun(backtick, p.Dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf = buf[:len(buf)-len(backtick)] + out
|
||||
}
|
||||
backtick = ""
|
||||
backQuote = !backQuote
|
||||
continue
|
||||
}
|
||||
backtick = ""
|
||||
backQuote = !backQuote
|
||||
}
|
||||
case ')':
|
||||
if !singleQuoted && !doubleQuoted && !backQuote {
|
||||
if p.ParseBacktick {
|
||||
if dollarQuote {
|
||||
out, err := shellRun(backtick, p.Dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf = buf[:len(buf)-len(backtick)-2] + out
|
||||
}
|
||||
backtick = ""
|
||||
dollarQuote = !dollarQuote
|
||||
continue
|
||||
}
|
||||
backtick = ""
|
||||
dollarQuote = !dollarQuote
|
||||
}
|
||||
case '(':
|
||||
if !singleQuoted && !doubleQuoted && !backQuote {
|
||||
if !dollarQuote && strings.HasSuffix(buf, "$") {
|
||||
dollarQuote = true
|
||||
buf += "("
|
||||
continue
|
||||
} else {
|
||||
return nil, errors.New("invalid command line string")
|
||||
}
|
||||
}
|
||||
case '"':
|
||||
if !singleQuoted && !dollarQuote {
|
||||
doubleQuoted = !doubleQuoted
|
||||
continue
|
||||
}
|
||||
case '\'':
|
||||
if !doubleQuoted && !dollarQuote {
|
||||
singleQuoted = !singleQuoted
|
||||
continue
|
||||
}
|
||||
case ';', '&', '|', '<', '>':
|
||||
if !(escaped || singleQuoted || doubleQuoted || backQuote || dollarQuote) {
|
||||
if r == '>' && len(buf) > 0 {
|
||||
if c := buf[0]; '0' <= c && c <= '9' {
|
||||
i -= 1
|
||||
got = false
|
||||
}
|
||||
}
|
||||
pos = i
|
||||
break loop
|
||||
}
|
||||
}
|
||||
|
||||
got = true
|
||||
buf += string(r)
|
||||
if backQuote || dollarQuote {
|
||||
backtick += string(r)
|
||||
}
|
||||
}
|
||||
|
||||
if got {
|
||||
if p.ParseEnv {
|
||||
buf = replaceEnv(p.Getenv, buf)
|
||||
}
|
||||
args = append(args, buf)
|
||||
}
|
||||
|
||||
if escaped || singleQuoted || doubleQuoted || backQuote || dollarQuote {
|
||||
return nil, errors.New("invalid command line string")
|
||||
}
|
||||
|
||||
p.Position = pos
|
||||
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func Parse(line string) ([]string, error) {
|
||||
return NewParser().Parse(line)
|
||||
}
|
29
vendor/github.com/mattn/go-shellwords/util_go15.go
generated
vendored
29
vendor/github.com/mattn/go-shellwords/util_go15.go
generated
vendored
|
@ -1,29 +0,0 @@
|
|||
// +build !go1.6
|
||||
|
||||
package shellwords
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func shellRun(line, dir string) (string, error) {
|
||||
var b []byte
|
||||
var err error
|
||||
var cmd *exec.Cmd
|
||||
if runtime.GOOS == "windows" {
|
||||
cmd = exec.Command(os.Getenv("COMSPEC"), "/c", line)
|
||||
} else {
|
||||
cmd = exec.Command(os.Getenv("SHELL"), "-c", line)
|
||||
}
|
||||
if dir != "" {
|
||||
cmd.Dir = dir
|
||||
}
|
||||
b, err = cmd.Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSpace(string(b)), nil
|
||||
}
|
26
vendor/github.com/mattn/go-shellwords/util_posix.go
generated
vendored
26
vendor/github.com/mattn/go-shellwords/util_posix.go
generated
vendored
|
@ -1,26 +0,0 @@
|
|||
// +build !windows,go1.6
|
||||
|
||||
package shellwords
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func shellRun(line, dir string) (string, error) {
|
||||
shell := os.Getenv("SHELL")
|
||||
cmd := exec.Command(shell, "-c", line)
|
||||
if dir != "" {
|
||||
cmd.Dir = dir
|
||||
}
|
||||
b, err := cmd.Output()
|
||||
if err != nil {
|
||||
if eerr, ok := err.(*exec.ExitError); ok {
|
||||
b = eerr.Stderr
|
||||
}
|
||||
return "", errors.New(err.Error() + ":" + string(b))
|
||||
}
|
||||
return strings.TrimSpace(string(b)), nil
|
||||
}
|
26
vendor/github.com/mattn/go-shellwords/util_windows.go
generated
vendored
26
vendor/github.com/mattn/go-shellwords/util_windows.go
generated
vendored
|
@ -1,26 +0,0 @@
|
|||
// +build windows,go1.6
|
||||
|
||||
package shellwords
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func shellRun(line, dir string) (string, error) {
|
||||
shell := os.Getenv("COMSPEC")
|
||||
cmd := exec.Command(shell, "/c", line)
|
||||
if dir != "" {
|
||||
cmd.Dir = dir
|
||||
}
|
||||
b, err := cmd.Output()
|
||||
if err != nil {
|
||||
if eerr, ok := err.(*exec.ExitError); ok {
|
||||
b = eerr.Stderr
|
||||
}
|
||||
return "", errors.New(err.Error() + ":" + string(b))
|
||||
}
|
||||
return strings.TrimSpace(string(b)), nil
|
||||
}
|
Loading…
Reference in a new issue