Merge pull request #33511 from vdemeester/remove-more-opts-runconfig

Remove some more `opts` from runconfig (not used anymore)
This commit is contained in:
Akihiro Suda 2017-06-04 13:17:05 +09:00 committed by GitHub
commit 7cf17f95f8
3 changed files with 0 additions and 289 deletions

View File

@ -1,81 +0,0 @@
package opts
import (
"bufio"
"bytes"
"fmt"
"os"
"strings"
"unicode"
"unicode/utf8"
)
// ParseEnvFile reads a file with environment variables enumerated by lines
//
// ``Environment variable names used by the utilities in the Shell and
// Utilities volume of IEEE Std 1003.1-2001 consist solely of uppercase
// letters, digits, and the '_' (underscore) from the characters defined in
// Portable Character Set and do not begin with a digit. *But*, other
// characters may be permitted by an implementation; applications shall
// tolerate the presence of such names.''
// -- http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
//
// As of #16585, it's up to application inside docker to validate or not
// environment variables, that's why we just strip leading whitespace and
// nothing more.
func ParseEnvFile(filename string) ([]string, error) {
fh, err := os.Open(filename)
if err != nil {
return []string{}, err
}
defer fh.Close()
lines := []string{}
scanner := bufio.NewScanner(fh)
currentLine := 0
utf8bom := []byte{0xEF, 0xBB, 0xBF}
for scanner.Scan() {
scannedBytes := scanner.Bytes()
if !utf8.Valid(scannedBytes) {
return []string{}, fmt.Errorf("env file %s contains invalid utf8 bytes at line %d: %v", filename, currentLine+1, scannedBytes)
}
// We trim UTF8 BOM
if currentLine == 0 {
scannedBytes = bytes.TrimPrefix(scannedBytes, utf8bom)
}
// trim the line from all leading whitespace first
line := strings.TrimLeftFunc(string(scannedBytes), unicode.IsSpace)
currentLine++
// line is not empty, and not starting with '#'
if len(line) > 0 && !strings.HasPrefix(line, "#") {
data := strings.SplitN(line, "=", 2)
// trim the front of a variable, but nothing else
variable := strings.TrimLeft(data[0], whiteSpaces)
if strings.ContainsAny(variable, whiteSpaces) {
return []string{}, ErrBadEnvVariable{fmt.Sprintf("variable '%s' has white spaces", variable)}
}
if len(data) > 1 {
// pass the value through, no trimming
lines = append(lines, fmt.Sprintf("%s=%s", variable, data[1]))
} else {
// if only a pass-through variable is given, clean it up.
lines = append(lines, fmt.Sprintf("%s=%s", strings.TrimSpace(line), os.Getenv(line)))
}
}
}
return lines, scanner.Err()
}
var whiteSpaces = " \t"
// ErrBadEnvVariable typed error for bad environment variable
type ErrBadEnvVariable struct {
msg string
}
func (e ErrBadEnvVariable) Error() string {
return fmt.Sprintf("poorly formatted environment: %s", e.msg)
}

View File

@ -1,141 +0,0 @@
package opts
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"reflect"
"strings"
"testing"
)
func tmpFileWithContent(content string, t *testing.T) string {
tmpFile, err := ioutil.TempFile("", "envfile-test")
if err != nil {
t.Fatal(err)
}
defer tmpFile.Close()
tmpFile.WriteString(content)
return tmpFile.Name()
}
// Test ParseEnvFile for a file with a few well formatted lines
func TestParseEnvFileGoodFile(t *testing.T) {
content := `foo=bar
baz=quux
# comment
_foobar=foobaz
with.dots=working
and_underscore=working too
`
// Adding a newline + a line with pure whitespace.
// This is being done like this instead of the block above
// because it's common for editors to trim trailing whitespace
// from lines, which becomes annoying since that's the
// exact thing we need to test.
content += "\n \t "
tmpFile := tmpFileWithContent(content, t)
defer os.Remove(tmpFile)
lines, err := ParseEnvFile(tmpFile)
if err != nil {
t.Fatal(err)
}
expectedLines := []string{
"foo=bar",
"baz=quux",
"_foobar=foobaz",
"with.dots=working",
"and_underscore=working too",
}
if !reflect.DeepEqual(lines, expectedLines) {
t.Fatal("lines not equal to expectedLines")
}
}
// Test ParseEnvFile for an empty file
func TestParseEnvFileEmptyFile(t *testing.T) {
tmpFile := tmpFileWithContent("", t)
defer os.Remove(tmpFile)
lines, err := ParseEnvFile(tmpFile)
if err != nil {
t.Fatal(err)
}
if len(lines) != 0 {
t.Fatal("lines not empty; expected empty")
}
}
// Test ParseEnvFile for a non existent file
func TestParseEnvFileNonExistentFile(t *testing.T) {
_, err := ParseEnvFile("foo_bar_baz")
if err == nil {
t.Fatal("ParseEnvFile succeeded; expected failure")
}
if _, ok := err.(*os.PathError); !ok {
t.Fatalf("Expected a PathError, got [%v]", err)
}
}
// Test ParseEnvFile for a badly formatted file
func TestParseEnvFileBadlyFormattedFile(t *testing.T) {
content := `foo=bar
f =quux
`
tmpFile := tmpFileWithContent(content, t)
defer os.Remove(tmpFile)
_, err := ParseEnvFile(tmpFile)
if err == nil {
t.Fatalf("Expected an ErrBadEnvVariable, got nothing")
}
if _, ok := err.(ErrBadEnvVariable); !ok {
t.Fatalf("Expected an ErrBadEnvVariable, got [%v]", err)
}
expectedMessage := "poorly formatted environment: variable 'f ' has white spaces"
if err.Error() != expectedMessage {
t.Fatalf("Expected [%v], got [%v]", expectedMessage, err.Error())
}
}
// Test ParseEnvFile for a file with a line exceeding bufio.MaxScanTokenSize
func TestParseEnvFileLineTooLongFile(t *testing.T) {
content := strings.Repeat("a", bufio.MaxScanTokenSize+42)
content = fmt.Sprint("foo=", content)
tmpFile := tmpFileWithContent(content, t)
defer os.Remove(tmpFile)
_, err := ParseEnvFile(tmpFile)
if err == nil {
t.Fatal("ParseEnvFile succeeded; expected failure")
}
}
// ParseEnvFile with a random file, pass through
func TestParseEnvFileRandomFile(t *testing.T) {
content := `first line
another invalid line`
tmpFile := tmpFileWithContent(content, t)
defer os.Remove(tmpFile)
_, err := ParseEnvFile(tmpFile)
if err == nil {
t.Fatalf("Expected an ErrBadEnvVariable, got nothing")
}
if _, ok := err.(ErrBadEnvVariable); !ok {
t.Fatalf("Expected an ErrBadEnvVariable, got [%v]", err)
}
expectedMessage := "poorly formatted environment: variable 'first line' has white spaces"
if err.Error() != expectedMessage {
t.Fatalf("Expected [%v], got [%v]", expectedMessage, err.Error())
}
}

View File

@ -1,30 +1,9 @@
package opts
import (
"fmt"
"strconv"
"strings"
"github.com/docker/docker/api/types/container"
)
// ReadKVStrings reads a file of line terminated key=value pairs, and overrides any keys
// present in the file with additional pairs specified in the override parameter
func ReadKVStrings(files []string, override []string) ([]string, error) {
envVariables := []string{}
for _, ef := range files {
parsedVars, err := ParseEnvFile(ef)
if err != nil {
return nil, err
}
envVariables = append(envVariables, parsedVars...)
}
// parse the '-e' and '--env' after, to allow override
envVariables = append(envVariables, override...)
return envVariables, nil
}
// ConvertKVStringsToMap converts ["key=value"] to {"key":"value"}
func ConvertKVStringsToMap(values []string) map[string]string {
result := make(map[string]string, len(values))
@ -39,49 +18,3 @@ func ConvertKVStringsToMap(values []string) map[string]string {
return result
}
// ConvertKVStringsToMapWithNil converts ["key=value"] to {"key":"value"}
// but set unset keys to nil - meaning the ones with no "=" in them.
// We use this in cases where we need to distinguish between
// FOO= and FOO
// where the latter case just means FOO was mentioned but not given a value
func ConvertKVStringsToMapWithNil(values []string) map[string]*string {
result := make(map[string]*string, len(values))
for _, value := range values {
kv := strings.SplitN(value, "=", 2)
if len(kv) == 1 {
result[kv[0]] = nil
} else {
result[kv[0]] = &kv[1]
}
}
return result
}
// ParseRestartPolicy returns the parsed policy or an error indicating what is incorrect
func ParseRestartPolicy(policy string) (container.RestartPolicy, error) {
p := container.RestartPolicy{}
if policy == "" {
return p, nil
}
parts := strings.Split(policy, ":")
if len(parts) > 2 {
return p, fmt.Errorf("invalid restart policy format")
}
if len(parts) == 2 {
count, err := strconv.Atoi(parts[1])
if err != nil {
return p, fmt.Errorf("maximum retry count must be an integer")
}
p.MaximumRetryCount = count
}
p.Name = parts[0]
return p, nil
}