Merge pull request #15913 from mountkin/abstract
abstract the string slice struct to stringutils package
This commit is contained in:
commit
4bb2449188
11 changed files with 218 additions and 340 deletions
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/Sirupsen/logrus"
|
||||
flag "github.com/docker/docker/pkg/mflag"
|
||||
"github.com/docker/docker/pkg/nat"
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
"github.com/docker/docker/runconfig"
|
||||
)
|
||||
|
||||
|
@ -352,7 +353,7 @@ func run(b *builder, args []string, attributes map[string]bool, original string)
|
|||
b.Config.Cmd = config.Cmd
|
||||
runconfig.Merge(b.Config, config)
|
||||
|
||||
defer func(cmd *runconfig.Command) { b.Config.Cmd = cmd }(cmd)
|
||||
defer func(cmd *stringutils.StrSlice) { b.Config.Cmd = cmd }(cmd)
|
||||
|
||||
logrus.Debugf("[BUILDER] Command to be executed: %v", b.Config.Cmd)
|
||||
|
||||
|
@ -405,7 +406,7 @@ func cmd(b *builder, args []string, attributes map[string]bool, original string)
|
|||
}
|
||||
}
|
||||
|
||||
b.Config.Cmd = runconfig.NewCommand(cmdSlice...)
|
||||
b.Config.Cmd = stringutils.NewStrSlice(cmdSlice...)
|
||||
|
||||
if err := b.commit("", b.Config.Cmd, fmt.Sprintf("CMD %q", cmdSlice)); err != nil {
|
||||
return err
|
||||
|
@ -436,16 +437,16 @@ func entrypoint(b *builder, args []string, attributes map[string]bool, original
|
|||
switch {
|
||||
case attributes["json"]:
|
||||
// ENTRYPOINT ["echo", "hi"]
|
||||
b.Config.Entrypoint = runconfig.NewEntrypoint(parsed...)
|
||||
b.Config.Entrypoint = stringutils.NewStrSlice(parsed...)
|
||||
case len(parsed) == 0:
|
||||
// ENTRYPOINT []
|
||||
b.Config.Entrypoint = nil
|
||||
default:
|
||||
// ENTRYPOINT echo hi
|
||||
if runtime.GOOS != "windows" {
|
||||
b.Config.Entrypoint = runconfig.NewEntrypoint("/bin/sh", "-c", parsed[0])
|
||||
b.Config.Entrypoint = stringutils.NewStrSlice("/bin/sh", "-c", parsed[0])
|
||||
} else {
|
||||
b.Config.Entrypoint = runconfig.NewEntrypoint("cmd", "/S /C", parsed[0])
|
||||
b.Config.Entrypoint = stringutils.NewStrSlice("cmd", "/S /C", parsed[0])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/docker/docker/pkg/parsers"
|
||||
"github.com/docker/docker/pkg/progressreader"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/docker/docker/pkg/tarsum"
|
||||
"github.com/docker/docker/pkg/urlutil"
|
||||
|
@ -73,7 +74,7 @@ func (b *builder) readContext(context io.Reader) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (b *builder) commit(id string, autoCmd *runconfig.Command, comment string) error {
|
||||
func (b *builder) commit(id string, autoCmd *stringutils.StrSlice, comment string) error {
|
||||
if b.disableCommit {
|
||||
return nil
|
||||
}
|
||||
|
@ -84,11 +85,11 @@ func (b *builder) commit(id string, autoCmd *runconfig.Command, comment string)
|
|||
if id == "" {
|
||||
cmd := b.Config.Cmd
|
||||
if runtime.GOOS != "windows" {
|
||||
b.Config.Cmd = runconfig.NewCommand("/bin/sh", "-c", "#(nop) "+comment)
|
||||
b.Config.Cmd = stringutils.NewStrSlice("/bin/sh", "-c", "#(nop) "+comment)
|
||||
} else {
|
||||
b.Config.Cmd = runconfig.NewCommand("cmd", "/S /C", "REM (nop) "+comment)
|
||||
b.Config.Cmd = stringutils.NewStrSlice("cmd", "/S /C", "REM (nop) "+comment)
|
||||
}
|
||||
defer func(cmd *runconfig.Command) { b.Config.Cmd = cmd }(cmd)
|
||||
defer func(cmd *stringutils.StrSlice) { b.Config.Cmd = cmd }(cmd)
|
||||
|
||||
hit, err := b.probeCache()
|
||||
if err != nil {
|
||||
|
@ -215,11 +216,11 @@ func (b *builder) runContextCommand(args []string, allowRemote bool, allowDecomp
|
|||
|
||||
cmd := b.Config.Cmd
|
||||
if runtime.GOOS != "windows" {
|
||||
b.Config.Cmd = runconfig.NewCommand("/bin/sh", "-c", fmt.Sprintf("#(nop) %s %s in %s", cmdName, srcHash, dest))
|
||||
b.Config.Cmd = stringutils.NewStrSlice("/bin/sh", "-c", fmt.Sprintf("#(nop) %s %s in %s", cmdName, srcHash, dest))
|
||||
} else {
|
||||
b.Config.Cmd = runconfig.NewCommand("cmd", "/S /C", fmt.Sprintf("REM (nop) %s %s in %s", cmdName, srcHash, dest))
|
||||
b.Config.Cmd = stringutils.NewStrSlice("cmd", "/S /C", fmt.Sprintf("REM (nop) %s %s in %s", cmdName, srcHash, dest))
|
||||
}
|
||||
defer func(cmd *runconfig.Command) { b.Config.Cmd = cmd }(cmd)
|
||||
defer func(cmd *stringutils.StrSlice) { b.Config.Cmd = cmd }(cmd)
|
||||
|
||||
hit, err := b.probeCache()
|
||||
if err != nil {
|
||||
|
@ -630,7 +631,7 @@ func (b *builder) create() (*daemon.Container, error) {
|
|||
c.Path = s[0]
|
||||
c.Args = s[1:]
|
||||
} else {
|
||||
config.Cmd = runconfig.NewCommand()
|
||||
config.Cmd = stringutils.NewStrSlice()
|
||||
}
|
||||
|
||||
return c, nil
|
||||
|
|
|
@ -39,6 +39,7 @@ import (
|
|||
"github.com/docker/docker/pkg/nat"
|
||||
"github.com/docker/docker/pkg/signal"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
"github.com/docker/docker/pkg/sysinfo"
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/docker/docker/pkg/truncindex"
|
||||
|
@ -443,7 +444,7 @@ func (daemon *Daemon) generateHostname(id string, config *runconfig.Config) {
|
|||
}
|
||||
}
|
||||
|
||||
func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint *runconfig.Entrypoint, configCmd *runconfig.Command) (string, []string) {
|
||||
func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint *stringutils.StrSlice, configCmd *stringutils.StrSlice) (string, []string) {
|
||||
var (
|
||||
entrypoint string
|
||||
args []string
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/pools"
|
||||
"github.com/docker/docker/pkg/stringid"
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
"github.com/docker/docker/runconfig"
|
||||
)
|
||||
|
||||
|
@ -143,8 +144,8 @@ func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, erro
|
|||
return "", err
|
||||
}
|
||||
|
||||
cmd := runconfig.NewCommand(config.Cmd...)
|
||||
entrypoint, args := d.getEntrypointAndArgs(runconfig.NewEntrypoint(), cmd)
|
||||
cmd := stringutils.NewStrSlice(config.Cmd...)
|
||||
entrypoint, args := d.getEntrypointAndArgs(stringutils.NewStrSlice(), cmd)
|
||||
|
||||
user := config.User
|
||||
if len(user) == 0 {
|
||||
|
|
71
pkg/stringutils/strslice.go
Normal file
71
pkg/stringutils/strslice.go
Normal file
|
@ -0,0 +1,71 @@
|
|||
package stringutils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// StrSlice representes a string or an array of strings.
|
||||
// We need to override the json decoder to accept both options.
|
||||
type StrSlice struct {
|
||||
parts []string
|
||||
}
|
||||
|
||||
// MarshalJSON Marshals (or serializes) the StrSlice into the json format.
|
||||
// This method is needed to implement json.Marshaller.
|
||||
func (e *StrSlice) MarshalJSON() ([]byte, error) {
|
||||
if e == nil {
|
||||
return []byte{}, nil
|
||||
}
|
||||
return json.Marshal(e.Slice())
|
||||
}
|
||||
|
||||
// UnmarshalJSON decodes the byte slice whether it's a string or an array of strings.
|
||||
// This method is needed to implement json.Unmarshaler.
|
||||
func (e *StrSlice) UnmarshalJSON(b []byte) error {
|
||||
if len(b) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
p := make([]string, 0, 1)
|
||||
if err := json.Unmarshal(b, &p); err != nil {
|
||||
var s string
|
||||
if err := json.Unmarshal(b, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
p = append(p, s)
|
||||
}
|
||||
|
||||
e.parts = p
|
||||
return nil
|
||||
}
|
||||
|
||||
// Len returns the number of parts of the StrSlice.
|
||||
func (e *StrSlice) Len() int {
|
||||
if e == nil {
|
||||
return 0
|
||||
}
|
||||
return len(e.parts)
|
||||
}
|
||||
|
||||
// Slice gets the parts of the StrSlice as a Slice of string.
|
||||
func (e *StrSlice) Slice() []string {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
return e.parts
|
||||
}
|
||||
|
||||
// ToString gets space separated string of all the parts.
|
||||
func (e *StrSlice) ToString() string {
|
||||
s := e.Slice()
|
||||
if s == nil {
|
||||
return ""
|
||||
}
|
||||
return strings.Join(s, " ")
|
||||
}
|
||||
|
||||
// NewStrSlice creates an StrSlice based on the specified parts (as strings).
|
||||
func NewStrSlice(parts ...string) *StrSlice {
|
||||
return &StrSlice{parts}
|
||||
}
|
105
pkg/stringutils/strslice_test.go
Normal file
105
pkg/stringutils/strslice_test.go
Normal file
|
@ -0,0 +1,105 @@
|
|||
package stringutils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStrSliceMarshalJSON(t *testing.T) {
|
||||
strss := map[*StrSlice]string{
|
||||
nil: "",
|
||||
&StrSlice{}: "null",
|
||||
&StrSlice{[]string{"/bin/sh", "-c", "echo"}}: `["/bin/sh","-c","echo"]`,
|
||||
}
|
||||
|
||||
for strs, expected := range strss {
|
||||
data, err := strs.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(data) != expected {
|
||||
t.Fatalf("Expected %v, got %v", expected, string(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrSliceUnmarshalJSON(t *testing.T) {
|
||||
parts := map[string][]string{
|
||||
"": {"default", "values"},
|
||||
"[]": {},
|
||||
`["/bin/sh","-c","echo"]`: {"/bin/sh", "-c", "echo"},
|
||||
}
|
||||
for json, expectedParts := range parts {
|
||||
strs := &StrSlice{
|
||||
[]string{"default", "values"},
|
||||
}
|
||||
if err := strs.UnmarshalJSON([]byte(json)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
actualParts := strs.Slice()
|
||||
if len(actualParts) != len(expectedParts) {
|
||||
t.Fatalf("Expected %v parts, got %v (%v)", len(expectedParts), len(actualParts), expectedParts)
|
||||
}
|
||||
for index, part := range actualParts {
|
||||
if part != expectedParts[index] {
|
||||
t.Fatalf("Expected %v, got %v", expectedParts, actualParts)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrSliceUnmarshalString(t *testing.T) {
|
||||
var e *StrSlice
|
||||
echo, err := json.Marshal("echo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := json.Unmarshal(echo, &e); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
slice := e.Slice()
|
||||
if len(slice) != 1 {
|
||||
t.Fatalf("expected 1 element after unmarshal: %q", slice)
|
||||
}
|
||||
|
||||
if slice[0] != "echo" {
|
||||
t.Fatalf("expected `echo`, got: %q", slice[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrSliceUnmarshalSlice(t *testing.T) {
|
||||
var e *StrSlice
|
||||
echo, err := json.Marshal([]string{"echo"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := json.Unmarshal(echo, &e); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
slice := e.Slice()
|
||||
if len(slice) != 1 {
|
||||
t.Fatalf("expected 1 element after unmarshal: %q", slice)
|
||||
}
|
||||
|
||||
if slice[0] != "echo" {
|
||||
t.Fatalf("expected `echo`, got: %q", slice[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestStrSliceToString(t *testing.T) {
|
||||
slices := map[*StrSlice]string{
|
||||
NewStrSlice(""): "",
|
||||
NewStrSlice("one"): "one",
|
||||
NewStrSlice("one", "two"): "one two",
|
||||
}
|
||||
for s, expected := range slices {
|
||||
toString := s.ToString()
|
||||
if toString != expected {
|
||||
t.Fatalf("Expected %v, got %v", expected, toString)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/docker/docker/pkg/nat"
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
)
|
||||
|
||||
// Just to make life easier
|
||||
|
@ -32,12 +33,12 @@ func TestCompare(t *testing.T) {
|
|||
volumes3["/test3"] = struct{}{}
|
||||
envs1 := []string{"ENV1=value1", "ENV2=value2"}
|
||||
envs2 := []string{"ENV1=value1", "ENV3=value3"}
|
||||
entrypoint1 := &Entrypoint{parts: []string{"/bin/sh", "-c"}}
|
||||
entrypoint2 := &Entrypoint{parts: []string{"/bin/sh", "-d"}}
|
||||
entrypoint3 := &Entrypoint{parts: []string{"/bin/sh", "-c", "echo"}}
|
||||
cmd1 := &Command{parts: []string{"/bin/sh", "-c"}}
|
||||
cmd2 := &Command{parts: []string{"/bin/sh", "-d"}}
|
||||
cmd3 := &Command{parts: []string{"/bin/sh", "-c", "echo"}}
|
||||
entrypoint1 := stringutils.NewStrSlice("/bin/sh", "-c")
|
||||
entrypoint2 := stringutils.NewStrSlice("/bin/sh", "-d")
|
||||
entrypoint3 := stringutils.NewStrSlice("/bin/sh", "-c", "echo")
|
||||
cmd1 := stringutils.NewStrSlice("/bin/sh", "-c")
|
||||
cmd2 := stringutils.NewStrSlice("/bin/sh", "-d")
|
||||
cmd3 := stringutils.NewStrSlice("/bin/sh", "-c", "echo")
|
||||
labels1 := map[string]string{"LABEL1": "value1", "LABEL2": "value2"}
|
||||
labels2 := map[string]string{"LABEL1": "value1", "LABEL2": "value3"}
|
||||
labels3 := map[string]string{"LABEL1": "value1", "LABEL2": "value2", "LABEL3": "value3"}
|
||||
|
|
|
@ -3,132 +3,11 @@ package runconfig
|
|||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/pkg/nat"
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
)
|
||||
|
||||
// Entrypoint encapsulates the container entrypoint.
|
||||
// It might be represented as a string or an array of strings.
|
||||
// We need to override the json decoder to accept both options.
|
||||
// The JSON decoder will fail if the api sends an string and
|
||||
// we try to decode it into an array of string.
|
||||
type Entrypoint struct {
|
||||
parts []string
|
||||
}
|
||||
|
||||
// MarshalJSON Marshals (or serializes) the Entrypoint into the json format.
|
||||
// This method is needed to implement json.Marshaller.
|
||||
func (e *Entrypoint) MarshalJSON() ([]byte, error) {
|
||||
if e == nil {
|
||||
return []byte{}, nil
|
||||
}
|
||||
return json.Marshal(e.Slice())
|
||||
}
|
||||
|
||||
// UnmarshalJSON decodes the entrypoint whether it's a string or an array of strings.
|
||||
// This method is needed to implement json.Unmarshaler.
|
||||
func (e *Entrypoint) UnmarshalJSON(b []byte) error {
|
||||
if len(b) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
p := make([]string, 0, 1)
|
||||
if err := json.Unmarshal(b, &p); err != nil {
|
||||
var s string
|
||||
if err := json.Unmarshal(b, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
p = append(p, s)
|
||||
}
|
||||
e.parts = p
|
||||
return nil
|
||||
}
|
||||
|
||||
// Len returns the number of parts of the Entrypoint.
|
||||
func (e *Entrypoint) Len() int {
|
||||
if e == nil {
|
||||
return 0
|
||||
}
|
||||
return len(e.parts)
|
||||
}
|
||||
|
||||
// Slice gets the parts of the Entrypoint as a Slice of string.
|
||||
func (e *Entrypoint) Slice() []string {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
return e.parts
|
||||
}
|
||||
|
||||
// NewEntrypoint creates an Entrypoint based on the specified parts (as strings).
|
||||
func NewEntrypoint(parts ...string) *Entrypoint {
|
||||
return &Entrypoint{parts}
|
||||
}
|
||||
|
||||
// Command encapsulates the container command.
|
||||
// It might be represented as a string or an array of strings.
|
||||
// We need to override the json decoder to accept both options.
|
||||
// The JSON decoder will fail if the api sends an string and
|
||||
// we try to decode it into an array of string.
|
||||
type Command struct {
|
||||
parts []string
|
||||
}
|
||||
|
||||
// ToString gets a string representing a Command.
|
||||
func (e *Command) ToString() string {
|
||||
return strings.Join(e.parts, " ")
|
||||
}
|
||||
|
||||
// MarshalJSON Marshals (or serializes) the Command into the json format.
|
||||
// This method is needed to implement json.Marshaller.
|
||||
func (e *Command) MarshalJSON() ([]byte, error) {
|
||||
if e == nil {
|
||||
return []byte{}, nil
|
||||
}
|
||||
return json.Marshal(e.Slice())
|
||||
}
|
||||
|
||||
// UnmarshalJSON decodes the entrypoint whether it's a string or an array of strings.
|
||||
// This method is needed to implement json.Unmarshaler.
|
||||
func (e *Command) UnmarshalJSON(b []byte) error {
|
||||
if len(b) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
p := make([]string, 0, 1)
|
||||
if err := json.Unmarshal(b, &p); err != nil {
|
||||
var s string
|
||||
if err := json.Unmarshal(b, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
p = append(p, s)
|
||||
}
|
||||
e.parts = p
|
||||
return nil
|
||||
}
|
||||
|
||||
// Len returns the number of parts of the Entrypoint.
|
||||
func (e *Command) Len() int {
|
||||
if e == nil {
|
||||
return 0
|
||||
}
|
||||
return len(e.parts)
|
||||
}
|
||||
|
||||
// Slice gets the parts of the Entrypoint as a Slice of string.
|
||||
func (e *Command) Slice() []string {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
return e.parts
|
||||
}
|
||||
|
||||
// NewCommand creates a Command based on the specified parts (as strings).
|
||||
func NewCommand(parts ...string) *Command {
|
||||
return &Command{parts}
|
||||
}
|
||||
|
||||
// Config contains the configuration data about a container.
|
||||
// It should hold only portable information about the container.
|
||||
// Here, "portable" means "independent from the host we are running on".
|
||||
|
@ -146,12 +25,12 @@ type Config struct {
|
|||
OpenStdin bool // Open stdin
|
||||
StdinOnce bool // If true, close stdin after the 1 attached client disconnects.
|
||||
Env []string // List of environment variable to set in the container
|
||||
Cmd *Command // Command to run when starting the container
|
||||
Cmd *stringutils.StrSlice // Command to run when starting the container
|
||||
Image string // Name of the image as it was passed by the operator (eg. could be symbolic)
|
||||
Volumes map[string]struct{} // List of volumes (mounts) used for the container
|
||||
VolumeDriver string // Name of the volume driver used to mount volumes
|
||||
WorkingDir string // Current directory (PWD) in the command will be launched
|
||||
Entrypoint *Entrypoint // Entrypoint to run when starting the container
|
||||
Entrypoint *stringutils.StrSlice // Entrypoint to run when starting the container
|
||||
NetworkDisabled bool // Is network disabled
|
||||
MacAddress string // Mac Address of the container
|
||||
OnBuild []string // ONBUILD metadata that were defined on the image Dockerfile
|
||||
|
|
|
@ -2,124 +2,21 @@ package runconfig
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
)
|
||||
|
||||
func TestEntrypointMarshalJSON(t *testing.T) {
|
||||
entrypoints := map[*Entrypoint]string{
|
||||
nil: "",
|
||||
&Entrypoint{}: "null",
|
||||
&Entrypoint{[]string{"/bin/sh", "-c", "echo"}}: `["/bin/sh","-c","echo"]`,
|
||||
}
|
||||
|
||||
for entrypoint, expected := range entrypoints {
|
||||
data, err := entrypoint.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(data) != expected {
|
||||
t.Fatalf("Expected %v, got %v", expected, string(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEntrypointUnmarshalJSON(t *testing.T) {
|
||||
parts := map[string][]string{
|
||||
"": {"default", "values"},
|
||||
"[]": {},
|
||||
`["/bin/sh","-c","echo"]`: {"/bin/sh", "-c", "echo"},
|
||||
}
|
||||
for json, expectedParts := range parts {
|
||||
entrypoint := &Entrypoint{
|
||||
[]string{"default", "values"},
|
||||
}
|
||||
if err := entrypoint.UnmarshalJSON([]byte(json)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
actualParts := entrypoint.Slice()
|
||||
if len(actualParts) != len(expectedParts) {
|
||||
t.Fatalf("Expected %v parts, got %v (%v)", len(expectedParts), len(actualParts), expectedParts)
|
||||
}
|
||||
for index, part := range actualParts {
|
||||
if part != expectedParts[index] {
|
||||
t.Fatalf("Expected %v, got %v", expectedParts, actualParts)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommandToString(t *testing.T) {
|
||||
commands := map[*Command]string{
|
||||
&Command{[]string{""}}: "",
|
||||
&Command{[]string{"one"}}: "one",
|
||||
&Command{[]string{"one", "two"}}: "one two",
|
||||
}
|
||||
for command, expected := range commands {
|
||||
toString := command.ToString()
|
||||
if toString != expected {
|
||||
t.Fatalf("Expected %v, got %v", expected, toString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommandMarshalJSON(t *testing.T) {
|
||||
commands := map[*Command]string{
|
||||
nil: "",
|
||||
&Command{}: "null",
|
||||
&Command{[]string{"/bin/sh", "-c", "echo"}}: `["/bin/sh","-c","echo"]`,
|
||||
}
|
||||
|
||||
for command, expected := range commands {
|
||||
data, err := command.MarshalJSON()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(data) != expected {
|
||||
t.Fatalf("Expected %v, got %v", expected, string(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommandUnmarshalJSON(t *testing.T) {
|
||||
parts := map[string][]string{
|
||||
"": {"default", "values"},
|
||||
"[]": {},
|
||||
`["/bin/sh","-c","echo"]`: {"/bin/sh", "-c", "echo"},
|
||||
}
|
||||
for json, expectedParts := range parts {
|
||||
command := &Command{
|
||||
[]string{"default", "values"},
|
||||
}
|
||||
if err := command.UnmarshalJSON([]byte(json)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
actualParts := command.Slice()
|
||||
if len(actualParts) != len(expectedParts) {
|
||||
t.Fatalf("Expected %v parts, got %v (%v)", len(expectedParts), len(actualParts), expectedParts)
|
||||
}
|
||||
for index, part := range actualParts {
|
||||
if part != expectedParts[index] {
|
||||
t.Fatalf("Expected %v, got %v", expectedParts, actualParts)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeContainerConfig(t *testing.T) {
|
||||
fixtures := []struct {
|
||||
file string
|
||||
entrypoint *Entrypoint
|
||||
entrypoint *stringutils.StrSlice
|
||||
}{
|
||||
{"fixtures/container_config_1_14.json", NewEntrypoint()},
|
||||
{"fixtures/container_config_1_17.json", NewEntrypoint("bash")},
|
||||
{"fixtures/container_config_1_19.json", NewEntrypoint("bash")},
|
||||
{"fixtures/container_config_1_14.json", stringutils.NewStrSlice()},
|
||||
{"fixtures/container_config_1_17.json", stringutils.NewStrSlice("bash")},
|
||||
{"fixtures/container_config_1_19.json", stringutils.NewStrSlice("bash")},
|
||||
}
|
||||
|
||||
for _, f := range fixtures {
|
||||
|
@ -146,83 +43,3 @@ func TestDecodeContainerConfig(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEntrypointUnmarshalString(t *testing.T) {
|
||||
var e *Entrypoint
|
||||
echo, err := json.Marshal("echo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := json.Unmarshal(echo, &e); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
slice := e.Slice()
|
||||
if len(slice) != 1 {
|
||||
t.Fatalf("expected 1 element after unmarshal: %q", slice)
|
||||
}
|
||||
|
||||
if slice[0] != "echo" {
|
||||
t.Fatalf("expected `echo`, got: %q", slice[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestEntrypointUnmarshalSlice(t *testing.T) {
|
||||
var e *Entrypoint
|
||||
echo, err := json.Marshal([]string{"echo"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := json.Unmarshal(echo, &e); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
slice := e.Slice()
|
||||
if len(slice) != 1 {
|
||||
t.Fatalf("expected 1 element after unmarshal: %q", slice)
|
||||
}
|
||||
|
||||
if slice[0] != "echo" {
|
||||
t.Fatalf("expected `echo`, got: %q", slice[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommandUnmarshalSlice(t *testing.T) {
|
||||
var e *Command
|
||||
echo, err := json.Marshal([]string{"echo"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := json.Unmarshal(echo, &e); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
slice := e.Slice()
|
||||
if len(slice) != 1 {
|
||||
t.Fatalf("expected 1 element after unmarshal: %q", slice)
|
||||
}
|
||||
|
||||
if slice[0] != "echo" {
|
||||
t.Fatalf("expected `echo`, got: %q", slice[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommandUnmarshalString(t *testing.T) {
|
||||
var e *Command
|
||||
echo, err := json.Marshal("echo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := json.Unmarshal(echo, &e); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
slice := e.Slice()
|
||||
if len(slice) != 1 {
|
||||
t.Fatalf("expected 1 element after unmarshal: %q", slice)
|
||||
}
|
||||
|
||||
if slice[0] != "echo" {
|
||||
t.Fatalf("expected `echo`, got: %q", slice[0])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
flag "github.com/docker/docker/pkg/mflag"
|
||||
"github.com/docker/docker/pkg/nat"
|
||||
"github.com/docker/docker/pkg/parsers"
|
||||
"github.com/docker/docker/pkg/stringutils"
|
||||
"github.com/docker/docker/pkg/units"
|
||||
)
|
||||
|
||||
|
@ -199,15 +200,15 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe
|
|||
|
||||
var (
|
||||
parsedArgs = cmd.Args()
|
||||
runCmd *Command
|
||||
entrypoint *Entrypoint
|
||||
runCmd *stringutils.StrSlice
|
||||
entrypoint *stringutils.StrSlice
|
||||
image = cmd.Arg(0)
|
||||
)
|
||||
if len(parsedArgs) > 1 {
|
||||
runCmd = NewCommand(parsedArgs[1:]...)
|
||||
runCmd = stringutils.NewStrSlice(parsedArgs[1:]...)
|
||||
}
|
||||
if *flEntrypoint != "" {
|
||||
entrypoint = NewEntrypoint(*flEntrypoint)
|
||||
entrypoint = stringutils.NewStrSlice(*flEntrypoint)
|
||||
}
|
||||
|
||||
lc, err := parseKeyValueOpts(flLxcOpts)
|
||||
|
|
|
@ -486,7 +486,7 @@ func TestParseEntryPoint(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if config.Entrypoint.Len() != 1 && config.Entrypoint.parts[0] != "anything" {
|
||||
if config.Entrypoint.Len() != 1 && config.Entrypoint.Slice()[0] != "anything" {
|
||||
t.Fatalf("Expected entrypoint 'anything', got %v", config.Entrypoint)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue