This is a very docker concept that nobody elses need.
We only maintain it to keep the API backwards compatible.
Signed-off-by: David Calavera <david.calavera@gmail.com>
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,71 @@ |
| 0 |
+package strslice |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "encoding/json" |
|
| 4 |
+ "strings" |
|
| 5 |
+) |
|
| 6 |
+ |
|
| 7 |
+// StrSlice represents a string or an array of strings. |
|
| 8 |
+// We need to override the json decoder to accept both options. |
|
| 9 |
+type StrSlice struct {
|
|
| 10 |
+ parts []string |
|
| 11 |
+} |
|
| 12 |
+ |
|
| 13 |
+// MarshalJSON Marshals (or serializes) the StrSlice into the json format. |
|
| 14 |
+// This method is needed to implement json.Marshaller. |
|
| 15 |
+func (e *StrSlice) MarshalJSON() ([]byte, error) {
|
|
| 16 |
+ if e == nil {
|
|
| 17 |
+ return []byte{}, nil
|
|
| 18 |
+ } |
|
| 19 |
+ return json.Marshal(e.Slice()) |
|
| 20 |
+} |
|
| 21 |
+ |
|
| 22 |
+// UnmarshalJSON decodes the byte slice whether it's a string or an array of strings. |
|
| 23 |
+// This method is needed to implement json.Unmarshaler. |
|
| 24 |
+func (e *StrSlice) UnmarshalJSON(b []byte) error {
|
|
| 25 |
+ if len(b) == 0 {
|
|
| 26 |
+ return nil |
|
| 27 |
+ } |
|
| 28 |
+ |
|
| 29 |
+ p := make([]string, 0, 1) |
|
| 30 |
+ if err := json.Unmarshal(b, &p); err != nil {
|
|
| 31 |
+ var s string |
|
| 32 |
+ if err := json.Unmarshal(b, &s); err != nil {
|
|
| 33 |
+ return err |
|
| 34 |
+ } |
|
| 35 |
+ p = append(p, s) |
|
| 36 |
+ } |
|
| 37 |
+ |
|
| 38 |
+ e.parts = p |
|
| 39 |
+ return nil |
|
| 40 |
+} |
|
| 41 |
+ |
|
| 42 |
+// Len returns the number of parts of the StrSlice. |
|
| 43 |
+func (e *StrSlice) Len() int {
|
|
| 44 |
+ if e == nil {
|
|
| 45 |
+ return 0 |
|
| 46 |
+ } |
|
| 47 |
+ return len(e.parts) |
|
| 48 |
+} |
|
| 49 |
+ |
|
| 50 |
+// Slice gets the parts of the StrSlice as a Slice of string. |
|
| 51 |
+func (e *StrSlice) Slice() []string {
|
|
| 52 |
+ if e == nil {
|
|
| 53 |
+ return nil |
|
| 54 |
+ } |
|
| 55 |
+ return e.parts |
|
| 56 |
+} |
|
| 57 |
+ |
|
| 58 |
+// ToString gets space separated string of all the parts. |
|
| 59 |
+func (e *StrSlice) ToString() string {
|
|
| 60 |
+ s := e.Slice() |
|
| 61 |
+ if s == nil {
|
|
| 62 |
+ return "" |
|
| 63 |
+ } |
|
| 64 |
+ return strings.Join(s, " ") |
|
| 65 |
+} |
|
| 66 |
+ |
|
| 67 |
+// New creates an StrSlice based on the specified parts (as strings). |
|
| 68 |
+func New(parts ...string) *StrSlice {
|
|
| 69 |
+ return &StrSlice{parts}
|
|
| 70 |
+} |
| 0 | 71 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,135 @@ |
| 0 |
+package strslice |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "encoding/json" |
|
| 4 |
+ "reflect" |
|
| 5 |
+ "testing" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+func TestStrSliceMarshalJSON(t *testing.T) {
|
|
| 9 |
+ strss := map[*StrSlice]string{
|
|
| 10 |
+ nil: "", |
|
| 11 |
+ &StrSlice{}: "null",
|
|
| 12 |
+ &StrSlice{[]string{"/bin/sh", "-c", "echo"}}: `["/bin/sh","-c","echo"]`,
|
|
| 13 |
+ } |
|
| 14 |
+ |
|
| 15 |
+ for strs, expected := range strss {
|
|
| 16 |
+ data, err := strs.MarshalJSON() |
|
| 17 |
+ if err != nil {
|
|
| 18 |
+ t.Fatal(err) |
|
| 19 |
+ } |
|
| 20 |
+ if string(data) != expected {
|
|
| 21 |
+ t.Fatalf("Expected %v, got %v", expected, string(data))
|
|
| 22 |
+ } |
|
| 23 |
+ } |
|
| 24 |
+} |
|
| 25 |
+ |
|
| 26 |
+func TestStrSliceUnmarshalJSON(t *testing.T) {
|
|
| 27 |
+ parts := map[string][]string{
|
|
| 28 |
+ "": {"default", "values"},
|
|
| 29 |
+ "[]": {},
|
|
| 30 |
+ `["/bin/sh","-c","echo"]`: {"/bin/sh", "-c", "echo"},
|
|
| 31 |
+ } |
|
| 32 |
+ for json, expectedParts := range parts {
|
|
| 33 |
+ strs := &StrSlice{
|
|
| 34 |
+ []string{"default", "values"},
|
|
| 35 |
+ } |
|
| 36 |
+ if err := strs.UnmarshalJSON([]byte(json)); err != nil {
|
|
| 37 |
+ t.Fatal(err) |
|
| 38 |
+ } |
|
| 39 |
+ |
|
| 40 |
+ actualParts := strs.Slice() |
|
| 41 |
+ if len(actualParts) != len(expectedParts) {
|
|
| 42 |
+ t.Fatalf("Expected %v parts, got %v (%v)", len(expectedParts), len(actualParts), expectedParts)
|
|
| 43 |
+ } |
|
| 44 |
+ for index, part := range actualParts {
|
|
| 45 |
+ if part != expectedParts[index] {
|
|
| 46 |
+ t.Fatalf("Expected %v, got %v", expectedParts, actualParts)
|
|
| 47 |
+ break |
|
| 48 |
+ } |
|
| 49 |
+ } |
|
| 50 |
+ } |
|
| 51 |
+} |
|
| 52 |
+ |
|
| 53 |
+func TestStrSliceUnmarshalString(t *testing.T) {
|
|
| 54 |
+ var e *StrSlice |
|
| 55 |
+ echo, err := json.Marshal("echo")
|
|
| 56 |
+ if err != nil {
|
|
| 57 |
+ t.Fatal(err) |
|
| 58 |
+ } |
|
| 59 |
+ if err := json.Unmarshal(echo, &e); err != nil {
|
|
| 60 |
+ t.Fatal(err) |
|
| 61 |
+ } |
|
| 62 |
+ |
|
| 63 |
+ slice := e.Slice() |
|
| 64 |
+ if len(slice) != 1 {
|
|
| 65 |
+ t.Fatalf("expected 1 element after unmarshal: %q", slice)
|
|
| 66 |
+ } |
|
| 67 |
+ |
|
| 68 |
+ if slice[0] != "echo" {
|
|
| 69 |
+ t.Fatalf("expected `echo`, got: %q", slice[0])
|
|
| 70 |
+ } |
|
| 71 |
+} |
|
| 72 |
+ |
|
| 73 |
+func TestStrSliceUnmarshalSlice(t *testing.T) {
|
|
| 74 |
+ var e *StrSlice |
|
| 75 |
+ echo, err := json.Marshal([]string{"echo"})
|
|
| 76 |
+ if err != nil {
|
|
| 77 |
+ t.Fatal(err) |
|
| 78 |
+ } |
|
| 79 |
+ if err := json.Unmarshal(echo, &e); err != nil {
|
|
| 80 |
+ t.Fatal(err) |
|
| 81 |
+ } |
|
| 82 |
+ |
|
| 83 |
+ slice := e.Slice() |
|
| 84 |
+ if len(slice) != 1 {
|
|
| 85 |
+ t.Fatalf("expected 1 element after unmarshal: %q", slice)
|
|
| 86 |
+ } |
|
| 87 |
+ |
|
| 88 |
+ if slice[0] != "echo" {
|
|
| 89 |
+ t.Fatalf("expected `echo`, got: %q", slice[0])
|
|
| 90 |
+ } |
|
| 91 |
+} |
|
| 92 |
+ |
|
| 93 |
+func TestStrSliceToString(t *testing.T) {
|
|
| 94 |
+ slices := map[*StrSlice]string{
|
|
| 95 |
+ New(""): "",
|
|
| 96 |
+ New("one"): "one",
|
|
| 97 |
+ New("one", "two"): "one two",
|
|
| 98 |
+ } |
|
| 99 |
+ for s, expected := range slices {
|
|
| 100 |
+ toString := s.ToString() |
|
| 101 |
+ if toString != expected {
|
|
| 102 |
+ t.Fatalf("Expected %v, got %v", expected, toString)
|
|
| 103 |
+ } |
|
| 104 |
+ } |
|
| 105 |
+} |
|
| 106 |
+ |
|
| 107 |
+func TestStrSliceLen(t *testing.T) {
|
|
| 108 |
+ var emptyStrSlice *StrSlice |
|
| 109 |
+ slices := map[*StrSlice]int{
|
|
| 110 |
+ New(""): 1,
|
|
| 111 |
+ New("one"): 1,
|
|
| 112 |
+ New("one", "two"): 2,
|
|
| 113 |
+ emptyStrSlice: 0, |
|
| 114 |
+ } |
|
| 115 |
+ for s, expected := range slices {
|
|
| 116 |
+ if s.Len() != expected {
|
|
| 117 |
+ t.Fatalf("Expected %d, got %d", s.Len(), expected)
|
|
| 118 |
+ } |
|
| 119 |
+ } |
|
| 120 |
+} |
|
| 121 |
+ |
|
| 122 |
+func TestStrSliceSlice(t *testing.T) {
|
|
| 123 |
+ var emptyStrSlice *StrSlice |
|
| 124 |
+ slices := map[*StrSlice][]string{
|
|
| 125 |
+ New("one"): {"one"},
|
|
| 126 |
+ New("one", "two"): {"one", "two"},
|
|
| 127 |
+ emptyStrSlice: nil, |
|
| 128 |
+ } |
|
| 129 |
+ for s, expected := range slices {
|
|
| 130 |
+ if !reflect.DeepEqual(s.Slice(), expected) {
|
|
| 131 |
+ t.Fatalf("Expected %v, got %v", s.Slice(), expected)
|
|
| 132 |
+ } |
|
| 133 |
+ } |
|
| 134 |
+} |
| ... | ... |
@@ -18,12 +18,12 @@ import ( |
| 18 | 18 |
"strings" |
| 19 | 19 |
|
| 20 | 20 |
"github.com/Sirupsen/logrus" |
| 21 |
+ "github.com/docker/docker/api/types/strslice" |
|
| 21 | 22 |
"github.com/docker/docker/builder" |
| 22 | 23 |
derr "github.com/docker/docker/errors" |
| 23 | 24 |
flag "github.com/docker/docker/pkg/mflag" |
| 24 | 25 |
"github.com/docker/docker/pkg/nat" |
| 25 | 26 |
"github.com/docker/docker/pkg/signal" |
| 26 |
- "github.com/docker/docker/pkg/stringutils" |
|
| 27 | 27 |
"github.com/docker/docker/pkg/system" |
| 28 | 28 |
"github.com/docker/docker/runconfig" |
| 29 | 29 |
) |
| ... | ... |
@@ -330,7 +330,7 @@ func run(b *Builder, args []string, attributes map[string]bool, original string) |
| 330 | 330 |
// stash the config environment |
| 331 | 331 |
env := b.runConfig.Env |
| 332 | 332 |
|
| 333 |
- defer func(cmd *stringutils.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
|
|
| 333 |
+ defer func(cmd *strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
|
|
| 334 | 334 |
defer func(env []string) { b.runConfig.Env = env }(env)
|
| 335 | 335 |
|
| 336 | 336 |
// derive the net build-time environment for this run. We let config |
| ... | ... |
@@ -373,7 +373,7 @@ func run(b *Builder, args []string, attributes map[string]bool, original string) |
| 373 | 373 |
if len(cmdBuildEnv) > 0 {
|
| 374 | 374 |
sort.Strings(cmdBuildEnv) |
| 375 | 375 |
tmpEnv := append([]string{fmt.Sprintf("|%d", len(cmdBuildEnv))}, cmdBuildEnv...)
|
| 376 |
- saveCmd = stringutils.NewStrSlice(append(tmpEnv, saveCmd.Slice()...)...) |
|
| 376 |
+ saveCmd = strslice.New(append(tmpEnv, saveCmd.Slice()...)...) |
|
| 377 | 377 |
} |
| 378 | 378 |
|
| 379 | 379 |
b.runConfig.Cmd = saveCmd |
| ... | ... |
@@ -431,7 +431,7 @@ func cmd(b *Builder, args []string, attributes map[string]bool, original string) |
| 431 | 431 |
} |
| 432 | 432 |
} |
| 433 | 433 |
|
| 434 |
- b.runConfig.Cmd = stringutils.NewStrSlice(cmdSlice...) |
|
| 434 |
+ b.runConfig.Cmd = strslice.New(cmdSlice...) |
|
| 435 | 435 |
|
| 436 | 436 |
if err := b.commit("", b.runConfig.Cmd, fmt.Sprintf("CMD %q", cmdSlice)); err != nil {
|
| 437 | 437 |
return err |
| ... | ... |
@@ -462,16 +462,16 @@ func entrypoint(b *Builder, args []string, attributes map[string]bool, original |
| 462 | 462 |
switch {
|
| 463 | 463 |
case attributes["json"]: |
| 464 | 464 |
// ENTRYPOINT ["echo", "hi"] |
| 465 |
- b.runConfig.Entrypoint = stringutils.NewStrSlice(parsed...) |
|
| 465 |
+ b.runConfig.Entrypoint = strslice.New(parsed...) |
|
| 466 | 466 |
case len(parsed) == 0: |
| 467 | 467 |
// ENTRYPOINT [] |
| 468 | 468 |
b.runConfig.Entrypoint = nil |
| 469 | 469 |
default: |
| 470 | 470 |
// ENTRYPOINT echo hi |
| 471 | 471 |
if runtime.GOOS != "windows" {
|
| 472 |
- b.runConfig.Entrypoint = stringutils.NewStrSlice("/bin/sh", "-c", parsed[0])
|
|
| 472 |
+ b.runConfig.Entrypoint = strslice.New("/bin/sh", "-c", parsed[0])
|
|
| 473 | 473 |
} else {
|
| 474 |
- b.runConfig.Entrypoint = stringutils.NewStrSlice("cmd", "/S", "/C", parsed[0])
|
|
| 474 |
+ b.runConfig.Entrypoint = strslice.New("cmd", "/S", "/C", parsed[0])
|
|
| 475 | 475 |
} |
| 476 | 476 |
} |
| 477 | 477 |
|
| ... | ... |
@@ -21,6 +21,7 @@ import ( |
| 21 | 21 |
"github.com/Sirupsen/logrus" |
| 22 | 22 |
"github.com/docker/docker/api" |
| 23 | 23 |
"github.com/docker/docker/api/types" |
| 24 |
+ "github.com/docker/docker/api/types/strslice" |
|
| 24 | 25 |
"github.com/docker/docker/builder" |
| 25 | 26 |
"github.com/docker/docker/builder/dockerfile/parser" |
| 26 | 27 |
"github.com/docker/docker/pkg/archive" |
| ... | ... |
@@ -30,14 +31,13 @@ import ( |
| 30 | 30 |
"github.com/docker/docker/pkg/progress" |
| 31 | 31 |
"github.com/docker/docker/pkg/streamformatter" |
| 32 | 32 |
"github.com/docker/docker/pkg/stringid" |
| 33 |
- "github.com/docker/docker/pkg/stringutils" |
|
| 34 | 33 |
"github.com/docker/docker/pkg/system" |
| 35 | 34 |
"github.com/docker/docker/pkg/tarsum" |
| 36 | 35 |
"github.com/docker/docker/pkg/urlutil" |
| 37 | 36 |
"github.com/docker/docker/runconfig" |
| 38 | 37 |
) |
| 39 | 38 |
|
| 40 |
-func (b *Builder) commit(id string, autoCmd *stringutils.StrSlice, comment string) error {
|
|
| 39 |
+func (b *Builder) commit(id string, autoCmd *strslice.StrSlice, comment string) error {
|
|
| 41 | 40 |
if b.disableCommit {
|
| 42 | 41 |
return nil |
| 43 | 42 |
} |
| ... | ... |
@@ -48,11 +48,11 @@ func (b *Builder) commit(id string, autoCmd *stringutils.StrSlice, comment strin |
| 48 | 48 |
if id == "" {
|
| 49 | 49 |
cmd := b.runConfig.Cmd |
| 50 | 50 |
if runtime.GOOS != "windows" {
|
| 51 |
- b.runConfig.Cmd = stringutils.NewStrSlice("/bin/sh", "-c", "#(nop) "+comment)
|
|
| 51 |
+ b.runConfig.Cmd = strslice.New("/bin/sh", "-c", "#(nop) "+comment)
|
|
| 52 | 52 |
} else {
|
| 53 |
- b.runConfig.Cmd = stringutils.NewStrSlice("cmd", "/S /C", "REM (nop) "+comment)
|
|
| 53 |
+ b.runConfig.Cmd = strslice.New("cmd", "/S /C", "REM (nop) "+comment)
|
|
| 54 | 54 |
} |
| 55 |
- defer func(cmd *stringutils.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
|
|
| 55 |
+ defer func(cmd *strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
|
|
| 56 | 56 |
|
| 57 | 57 |
hit, err := b.probeCache() |
| 58 | 58 |
if err != nil {
|
| ... | ... |
@@ -171,11 +171,11 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowLocalD |
| 171 | 171 |
|
| 172 | 172 |
cmd := b.runConfig.Cmd |
| 173 | 173 |
if runtime.GOOS != "windows" {
|
| 174 |
- b.runConfig.Cmd = stringutils.NewStrSlice("/bin/sh", "-c", fmt.Sprintf("#(nop) %s %s in %s", cmdName, srcHash, dest))
|
|
| 174 |
+ b.runConfig.Cmd = strslice.New("/bin/sh", "-c", fmt.Sprintf("#(nop) %s %s in %s", cmdName, srcHash, dest))
|
|
| 175 | 175 |
} else {
|
| 176 |
- b.runConfig.Cmd = stringutils.NewStrSlice("cmd", "/S", "/C", fmt.Sprintf("REM (nop) %s %s in %s", cmdName, srcHash, dest))
|
|
| 176 |
+ b.runConfig.Cmd = strslice.New("cmd", "/S", "/C", fmt.Sprintf("REM (nop) %s %s in %s", cmdName, srcHash, dest))
|
|
| 177 | 177 |
} |
| 178 |
- defer func(cmd *stringutils.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
|
|
| 178 |
+ defer func(cmd *strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
|
|
| 179 | 179 |
|
| 180 | 180 |
if hit, err := b.probeCache(); err != nil {
|
| 181 | 181 |
return err |
| ... | ... |
@@ -23,6 +23,7 @@ import ( |
| 23 | 23 |
"github.com/docker/docker/api/types" |
| 24 | 24 |
"github.com/docker/docker/api/types/filters" |
| 25 | 25 |
registrytypes "github.com/docker/docker/api/types/registry" |
| 26 |
+ "github.com/docker/docker/api/types/strslice" |
|
| 26 | 27 |
"github.com/docker/docker/container" |
| 27 | 28 |
"github.com/docker/docker/daemon/events" |
| 28 | 29 |
"github.com/docker/docker/daemon/exec" |
| ... | ... |
@@ -53,7 +54,6 @@ import ( |
| 53 | 53 |
"github.com/docker/docker/pkg/signal" |
| 54 | 54 |
"github.com/docker/docker/pkg/streamformatter" |
| 55 | 55 |
"github.com/docker/docker/pkg/stringid" |
| 56 |
- "github.com/docker/docker/pkg/stringutils" |
|
| 57 | 56 |
"github.com/docker/docker/pkg/sysinfo" |
| 58 | 57 |
"github.com/docker/docker/pkg/system" |
| 59 | 58 |
"github.com/docker/docker/pkg/truncindex" |
| ... | ... |
@@ -479,7 +479,7 @@ func (daemon *Daemon) generateHostname(id string, config *runconfig.Config) {
|
| 479 | 479 |
} |
| 480 | 480 |
} |
| 481 | 481 |
|
| 482 |
-func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint *stringutils.StrSlice, configCmd *stringutils.StrSlice) (string, []string) {
|
|
| 482 |
+func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint *strslice.StrSlice, configCmd *strslice.StrSlice) (string, []string) {
|
|
| 483 | 483 |
cmdSlice := configCmd.Slice() |
| 484 | 484 |
if configEntrypoint.Len() != 0 {
|
| 485 | 485 |
eSlice := configEntrypoint.Slice() |
| ... | ... |
@@ -6,13 +6,13 @@ import ( |
| 6 | 6 |
"time" |
| 7 | 7 |
|
| 8 | 8 |
"github.com/Sirupsen/logrus" |
| 9 |
+ "github.com/docker/docker/api/types/strslice" |
|
| 9 | 10 |
"github.com/docker/docker/container" |
| 10 | 11 |
"github.com/docker/docker/daemon/exec" |
| 11 | 12 |
"github.com/docker/docker/daemon/execdriver" |
| 12 | 13 |
derr "github.com/docker/docker/errors" |
| 13 | 14 |
"github.com/docker/docker/pkg/pools" |
| 14 | 15 |
"github.com/docker/docker/pkg/promise" |
| 15 |
- "github.com/docker/docker/pkg/stringutils" |
|
| 16 | 16 |
"github.com/docker/docker/runconfig" |
| 17 | 17 |
) |
| 18 | 18 |
|
| ... | ... |
@@ -85,8 +85,8 @@ func (d *Daemon) ContainerExecCreate(config *runconfig.ExecConfig) (string, erro |
| 85 | 85 |
return "", err |
| 86 | 86 |
} |
| 87 | 87 |
|
| 88 |
- cmd := stringutils.NewStrSlice(config.Cmd...) |
|
| 89 |
- entrypoint, args := d.getEntrypointAndArgs(stringutils.NewStrSlice(), cmd) |
|
| 88 |
+ cmd := strslice.New(config.Cmd...) |
|
| 89 |
+ entrypoint, args := d.getEntrypointAndArgs(strslice.New(), cmd) |
|
| 90 | 90 |
|
| 91 | 91 |
processConfig := &execdriver.ProcessConfig{
|
| 92 | 92 |
CommonProcessConfig: execdriver.CommonProcessConfig{
|
| 93 | 93 |
deleted file mode 100644 |
| ... | ... |
@@ -1,71 +0,0 @@ |
| 1 |
-package stringutils |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "encoding/json" |
|
| 5 |
- "strings" |
|
| 6 |
-) |
|
| 7 |
- |
|
| 8 |
-// StrSlice represents a string or an array of strings. |
|
| 9 |
-// We need to override the json decoder to accept both options. |
|
| 10 |
-type StrSlice struct {
|
|
| 11 |
- parts []string |
|
| 12 |
-} |
|
| 13 |
- |
|
| 14 |
-// MarshalJSON Marshals (or serializes) the StrSlice into the json format. |
|
| 15 |
-// This method is needed to implement json.Marshaller. |
|
| 16 |
-func (e *StrSlice) MarshalJSON() ([]byte, error) {
|
|
| 17 |
- if e == nil {
|
|
| 18 |
- return []byte{}, nil
|
|
| 19 |
- } |
|
| 20 |
- return json.Marshal(e.Slice()) |
|
| 21 |
-} |
|
| 22 |
- |
|
| 23 |
-// UnmarshalJSON decodes the byte slice whether it's a string or an array of strings. |
|
| 24 |
-// This method is needed to implement json.Unmarshaler. |
|
| 25 |
-func (e *StrSlice) UnmarshalJSON(b []byte) error {
|
|
| 26 |
- if len(b) == 0 {
|
|
| 27 |
- return nil |
|
| 28 |
- } |
|
| 29 |
- |
|
| 30 |
- p := make([]string, 0, 1) |
|
| 31 |
- if err := json.Unmarshal(b, &p); err != nil {
|
|
| 32 |
- var s string |
|
| 33 |
- if err := json.Unmarshal(b, &s); err != nil {
|
|
| 34 |
- return err |
|
| 35 |
- } |
|
| 36 |
- p = append(p, s) |
|
| 37 |
- } |
|
| 38 |
- |
|
| 39 |
- e.parts = p |
|
| 40 |
- return nil |
|
| 41 |
-} |
|
| 42 |
- |
|
| 43 |
-// Len returns the number of parts of the StrSlice. |
|
| 44 |
-func (e *StrSlice) Len() int {
|
|
| 45 |
- if e == nil {
|
|
| 46 |
- return 0 |
|
| 47 |
- } |
|
| 48 |
- return len(e.parts) |
|
| 49 |
-} |
|
| 50 |
- |
|
| 51 |
-// Slice gets the parts of the StrSlice as a Slice of string. |
|
| 52 |
-func (e *StrSlice) Slice() []string {
|
|
| 53 |
- if e == nil {
|
|
| 54 |
- return nil |
|
| 55 |
- } |
|
| 56 |
- return e.parts |
|
| 57 |
-} |
|
| 58 |
- |
|
| 59 |
-// ToString gets space separated string of all the parts. |
|
| 60 |
-func (e *StrSlice) ToString() string {
|
|
| 61 |
- s := e.Slice() |
|
| 62 |
- if s == nil {
|
|
| 63 |
- return "" |
|
| 64 |
- } |
|
| 65 |
- return strings.Join(s, " ") |
|
| 66 |
-} |
|
| 67 |
- |
|
| 68 |
-// NewStrSlice creates an StrSlice based on the specified parts (as strings). |
|
| 69 |
-func NewStrSlice(parts ...string) *StrSlice {
|
|
| 70 |
- return &StrSlice{parts}
|
|
| 71 |
-} |
| 72 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,135 +0,0 @@ |
| 1 |
-package stringutils |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "encoding/json" |
|
| 5 |
- "reflect" |
|
| 6 |
- "testing" |
|
| 7 |
-) |
|
| 8 |
- |
|
| 9 |
-func TestStrSliceMarshalJSON(t *testing.T) {
|
|
| 10 |
- strss := map[*StrSlice]string{
|
|
| 11 |
- nil: "", |
|
| 12 |
- &StrSlice{}: "null",
|
|
| 13 |
- &StrSlice{[]string{"/bin/sh", "-c", "echo"}}: `["/bin/sh","-c","echo"]`,
|
|
| 14 |
- } |
|
| 15 |
- |
|
| 16 |
- for strs, expected := range strss {
|
|
| 17 |
- data, err := strs.MarshalJSON() |
|
| 18 |
- if err != nil {
|
|
| 19 |
- t.Fatal(err) |
|
| 20 |
- } |
|
| 21 |
- if string(data) != expected {
|
|
| 22 |
- t.Fatalf("Expected %v, got %v", expected, string(data))
|
|
| 23 |
- } |
|
| 24 |
- } |
|
| 25 |
-} |
|
| 26 |
- |
|
| 27 |
-func TestStrSliceUnmarshalJSON(t *testing.T) {
|
|
| 28 |
- parts := map[string][]string{
|
|
| 29 |
- "": {"default", "values"},
|
|
| 30 |
- "[]": {},
|
|
| 31 |
- `["/bin/sh","-c","echo"]`: {"/bin/sh", "-c", "echo"},
|
|
| 32 |
- } |
|
| 33 |
- for json, expectedParts := range parts {
|
|
| 34 |
- strs := &StrSlice{
|
|
| 35 |
- []string{"default", "values"},
|
|
| 36 |
- } |
|
| 37 |
- if err := strs.UnmarshalJSON([]byte(json)); err != nil {
|
|
| 38 |
- t.Fatal(err) |
|
| 39 |
- } |
|
| 40 |
- |
|
| 41 |
- actualParts := strs.Slice() |
|
| 42 |
- if len(actualParts) != len(expectedParts) {
|
|
| 43 |
- t.Fatalf("Expected %v parts, got %v (%v)", len(expectedParts), len(actualParts), expectedParts)
|
|
| 44 |
- } |
|
| 45 |
- for index, part := range actualParts {
|
|
| 46 |
- if part != expectedParts[index] {
|
|
| 47 |
- t.Fatalf("Expected %v, got %v", expectedParts, actualParts)
|
|
| 48 |
- break |
|
| 49 |
- } |
|
| 50 |
- } |
|
| 51 |
- } |
|
| 52 |
-} |
|
| 53 |
- |
|
| 54 |
-func TestStrSliceUnmarshalString(t *testing.T) {
|
|
| 55 |
- var e *StrSlice |
|
| 56 |
- echo, err := json.Marshal("echo")
|
|
| 57 |
- if err != nil {
|
|
| 58 |
- t.Fatal(err) |
|
| 59 |
- } |
|
| 60 |
- if err := json.Unmarshal(echo, &e); err != nil {
|
|
| 61 |
- t.Fatal(err) |
|
| 62 |
- } |
|
| 63 |
- |
|
| 64 |
- slice := e.Slice() |
|
| 65 |
- if len(slice) != 1 {
|
|
| 66 |
- t.Fatalf("expected 1 element after unmarshal: %q", slice)
|
|
| 67 |
- } |
|
| 68 |
- |
|
| 69 |
- if slice[0] != "echo" {
|
|
| 70 |
- t.Fatalf("expected `echo`, got: %q", slice[0])
|
|
| 71 |
- } |
|
| 72 |
-} |
|
| 73 |
- |
|
| 74 |
-func TestStrSliceUnmarshalSlice(t *testing.T) {
|
|
| 75 |
- var e *StrSlice |
|
| 76 |
- echo, err := json.Marshal([]string{"echo"})
|
|
| 77 |
- if err != nil {
|
|
| 78 |
- t.Fatal(err) |
|
| 79 |
- } |
|
| 80 |
- if err := json.Unmarshal(echo, &e); err != nil {
|
|
| 81 |
- t.Fatal(err) |
|
| 82 |
- } |
|
| 83 |
- |
|
| 84 |
- slice := e.Slice() |
|
| 85 |
- if len(slice) != 1 {
|
|
| 86 |
- t.Fatalf("expected 1 element after unmarshal: %q", slice)
|
|
| 87 |
- } |
|
| 88 |
- |
|
| 89 |
- if slice[0] != "echo" {
|
|
| 90 |
- t.Fatalf("expected `echo`, got: %q", slice[0])
|
|
| 91 |
- } |
|
| 92 |
-} |
|
| 93 |
- |
|
| 94 |
-func TestStrSliceToString(t *testing.T) {
|
|
| 95 |
- slices := map[*StrSlice]string{
|
|
| 96 |
- NewStrSlice(""): "",
|
|
| 97 |
- NewStrSlice("one"): "one",
|
|
| 98 |
- NewStrSlice("one", "two"): "one two",
|
|
| 99 |
- } |
|
| 100 |
- for s, expected := range slices {
|
|
| 101 |
- toString := s.ToString() |
|
| 102 |
- if toString != expected {
|
|
| 103 |
- t.Fatalf("Expected %v, got %v", expected, toString)
|
|
| 104 |
- } |
|
| 105 |
- } |
|
| 106 |
-} |
|
| 107 |
- |
|
| 108 |
-func TestStrSliceLen(t *testing.T) {
|
|
| 109 |
- var emptyStrSlice *StrSlice |
|
| 110 |
- slices := map[*StrSlice]int{
|
|
| 111 |
- NewStrSlice(""): 1,
|
|
| 112 |
- NewStrSlice("one"): 1,
|
|
| 113 |
- NewStrSlice("one", "two"): 2,
|
|
| 114 |
- emptyStrSlice: 0, |
|
| 115 |
- } |
|
| 116 |
- for s, expected := range slices {
|
|
| 117 |
- if s.Len() != expected {
|
|
| 118 |
- t.Fatalf("Expected %d, got %d", s.Len(), expected)
|
|
| 119 |
- } |
|
| 120 |
- } |
|
| 121 |
-} |
|
| 122 |
- |
|
| 123 |
-func TestStrSliceSlice(t *testing.T) {
|
|
| 124 |
- var emptyStrSlice *StrSlice |
|
| 125 |
- slices := map[*StrSlice][]string{
|
|
| 126 |
- NewStrSlice("one"): {"one"},
|
|
| 127 |
- NewStrSlice("one", "two"): {"one", "two"},
|
|
| 128 |
- emptyStrSlice: nil, |
|
| 129 |
- } |
|
| 130 |
- for s, expected := range slices {
|
|
| 131 |
- if !reflect.DeepEqual(s.Slice(), expected) {
|
|
| 132 |
- t.Fatalf("Expected %v, got %v", s.Slice(), expected)
|
|
| 133 |
- } |
|
| 134 |
- } |
|
| 135 |
-} |
| ... | ... |
@@ -3,8 +3,8 @@ package runconfig |
| 3 | 3 |
import ( |
| 4 | 4 |
"testing" |
| 5 | 5 |
|
| 6 |
+ "github.com/docker/docker/api/types/strslice" |
|
| 6 | 7 |
"github.com/docker/docker/pkg/nat" |
| 7 |
- "github.com/docker/docker/pkg/stringutils" |
|
| 8 | 8 |
) |
| 9 | 9 |
|
| 10 | 10 |
// Just to make life easier |
| ... | ... |
@@ -33,12 +33,12 @@ func TestCompare(t *testing.T) {
|
| 33 | 33 |
volumes3["/test3"] = struct{}{}
|
| 34 | 34 |
envs1 := []string{"ENV1=value1", "ENV2=value2"}
|
| 35 | 35 |
envs2 := []string{"ENV1=value1", "ENV3=value3"}
|
| 36 |
- entrypoint1 := stringutils.NewStrSlice("/bin/sh", "-c")
|
|
| 37 |
- entrypoint2 := stringutils.NewStrSlice("/bin/sh", "-d")
|
|
| 38 |
- entrypoint3 := stringutils.NewStrSlice("/bin/sh", "-c", "echo")
|
|
| 39 |
- cmd1 := stringutils.NewStrSlice("/bin/sh", "-c")
|
|
| 40 |
- cmd2 := stringutils.NewStrSlice("/bin/sh", "-d")
|
|
| 41 |
- cmd3 := stringutils.NewStrSlice("/bin/sh", "-c", "echo")
|
|
| 36 |
+ entrypoint1 := strslice.New("/bin/sh", "-c")
|
|
| 37 |
+ entrypoint2 := strslice.New("/bin/sh", "-d")
|
|
| 38 |
+ entrypoint3 := strslice.New("/bin/sh", "-c", "echo")
|
|
| 39 |
+ cmd1 := strslice.New("/bin/sh", "-c")
|
|
| 40 |
+ cmd2 := strslice.New("/bin/sh", "-d")
|
|
| 41 |
+ cmd3 := strslice.New("/bin/sh", "-c", "echo")
|
|
| 42 | 42 |
labels1 := map[string]string{"LABEL1": "value1", "LABEL2": "value2"}
|
| 43 | 43 |
labels2 := map[string]string{"LABEL1": "value1", "LABEL2": "value3"}
|
| 44 | 44 |
labels3 := map[string]string{"LABEL1": "value1", "LABEL2": "value2", "LABEL3": "value3"}
|
| ... | ... |
@@ -5,8 +5,8 @@ import ( |
| 5 | 5 |
"fmt" |
| 6 | 6 |
"io" |
| 7 | 7 |
|
| 8 |
+ "github.com/docker/docker/api/types/strslice" |
|
| 8 | 9 |
"github.com/docker/docker/pkg/nat" |
| 9 |
- "github.com/docker/docker/pkg/stringutils" |
|
| 10 | 10 |
"github.com/docker/docker/volume" |
| 11 | 11 |
) |
| 12 | 12 |
|
| ... | ... |
@@ -29,12 +29,12 @@ type Config struct {
|
| 29 | 29 |
OpenStdin bool // Open stdin |
| 30 | 30 |
StdinOnce bool // If true, close stdin after the 1 attached client disconnects. |
| 31 | 31 |
Env []string // List of environment variable to set in the container |
| 32 |
- Cmd *stringutils.StrSlice // Command to run when starting the container |
|
| 32 |
+ Cmd *strslice.StrSlice // Command to run when starting the container |
|
| 33 | 33 |
ArgsEscaped bool `json:",omitempty"` // True if command is already escaped (Windows specific) |
| 34 | 34 |
Image string // Name of the image as it was passed by the operator (eg. could be symbolic) |
| 35 | 35 |
Volumes map[string]struct{} // List of volumes (mounts) used for the container
|
| 36 | 36 |
WorkingDir string // Current directory (PWD) in the command will be launched |
| 37 |
- Entrypoint *stringutils.StrSlice // Entrypoint to run when starting the container |
|
| 37 |
+ Entrypoint *strslice.StrSlice // Entrypoint to run when starting the container |
|
| 38 | 38 |
NetworkDisabled bool `json:",omitempty"` // Is network disabled |
| 39 | 39 |
MacAddress string `json:",omitempty"` // Mac Address of the container |
| 40 | 40 |
OnBuild []string // ONBUILD metadata that were defined on the image Dockerfile |
| ... | ... |
@@ -9,12 +9,12 @@ import ( |
| 9 | 9 |
"strings" |
| 10 | 10 |
"testing" |
| 11 | 11 |
|
| 12 |
- "github.com/docker/docker/pkg/stringutils" |
|
| 12 |
+ "github.com/docker/docker/api/types/strslice" |
|
| 13 | 13 |
) |
| 14 | 14 |
|
| 15 | 15 |
type f struct {
|
| 16 | 16 |
file string |
| 17 |
- entrypoint *stringutils.StrSlice |
|
| 17 |
+ entrypoint *strslice.StrSlice |
|
| 18 | 18 |
} |
| 19 | 19 |
|
| 20 | 20 |
func TestDecodeContainerConfig(t *testing.T) {
|
| ... | ... |
@@ -27,14 +27,14 @@ func TestDecodeContainerConfig(t *testing.T) {
|
| 27 | 27 |
if runtime.GOOS != "windows" {
|
| 28 | 28 |
image = "ubuntu" |
| 29 | 29 |
fixtures = []f{
|
| 30 |
- {"fixtures/unix/container_config_1_14.json", stringutils.NewStrSlice()},
|
|
| 31 |
- {"fixtures/unix/container_config_1_17.json", stringutils.NewStrSlice("bash")},
|
|
| 32 |
- {"fixtures/unix/container_config_1_19.json", stringutils.NewStrSlice("bash")},
|
|
| 30 |
+ {"fixtures/unix/container_config_1_14.json", strslice.New()},
|
|
| 31 |
+ {"fixtures/unix/container_config_1_17.json", strslice.New("bash")},
|
|
| 32 |
+ {"fixtures/unix/container_config_1_19.json", strslice.New("bash")},
|
|
| 33 | 33 |
} |
| 34 | 34 |
} else {
|
| 35 | 35 |
image = "windows" |
| 36 | 36 |
fixtures = []f{
|
| 37 |
- {"fixtures/windows/container_config_1_19.json", stringutils.NewStrSlice("cmd")},
|
|
| 37 |
+ {"fixtures/windows/container_config_1_19.json", strslice.New("cmd")},
|
|
| 38 | 38 |
} |
| 39 | 39 |
} |
| 40 | 40 |
|
| ... | ... |
@@ -5,9 +5,9 @@ import ( |
| 5 | 5 |
"io" |
| 6 | 6 |
"strings" |
| 7 | 7 |
|
| 8 |
+ "github.com/docker/docker/api/types/strslice" |
|
| 8 | 9 |
"github.com/docker/docker/pkg/blkiodev" |
| 9 | 10 |
"github.com/docker/docker/pkg/nat" |
| 10 |
- "github.com/docker/docker/pkg/stringutils" |
|
| 11 | 11 |
"github.com/docker/docker/pkg/ulimit" |
| 12 | 12 |
) |
| 13 | 13 |
|
| ... | ... |
@@ -207,24 +207,24 @@ type HostConfig struct {
|
| 207 | 207 |
VolumesFrom []string // List of volumes to take from other container |
| 208 | 208 |
|
| 209 | 209 |
// Applicable to UNIX platforms |
| 210 |
- CapAdd *stringutils.StrSlice // List of kernel capabilities to add to the container |
|
| 211 |
- CapDrop *stringutils.StrSlice // List of kernel capabilities to remove from the container |
|
| 212 |
- DNS []string `json:"Dns"` // List of DNS server to lookup |
|
| 213 |
- DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for |
|
| 214 |
- DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for |
|
| 215 |
- ExtraHosts []string // List of extra hosts |
|
| 216 |
- GroupAdd []string // List of additional groups that the container process will run as |
|
| 217 |
- IpcMode IpcMode // IPC namespace to use for the container |
|
| 218 |
- Links []string // List of links (in the name:alias form) |
|
| 219 |
- OomScoreAdj int // Container preference for OOM-killing |
|
| 220 |
- PidMode PidMode // PID namespace to use for the container |
|
| 221 |
- Privileged bool // Is the container in privileged mode |
|
| 222 |
- PublishAllPorts bool // Should docker publish all exposed port for the container |
|
| 223 |
- ReadonlyRootfs bool // Is the container root filesystem in read-only |
|
| 224 |
- SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux. |
|
| 225 |
- Tmpfs map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container |
|
| 226 |
- UTSMode UTSMode // UTS namespace to use for the container |
|
| 227 |
- ShmSize *int64 // Total shm memory usage |
|
| 210 |
+ CapAdd *strslice.StrSlice // List of kernel capabilities to add to the container |
|
| 211 |
+ CapDrop *strslice.StrSlice // List of kernel capabilities to remove from the container |
|
| 212 |
+ DNS []string `json:"Dns"` // List of DNS server to lookup |
|
| 213 |
+ DNSOptions []string `json:"DnsOptions"` // List of DNSOption to look for |
|
| 214 |
+ DNSSearch []string `json:"DnsSearch"` // List of DNSSearch to look for |
|
| 215 |
+ ExtraHosts []string // List of extra hosts |
|
| 216 |
+ GroupAdd []string // List of additional groups that the container process will run as |
|
| 217 |
+ IpcMode IpcMode // IPC namespace to use for the container |
|
| 218 |
+ Links []string // List of links (in the name:alias form) |
|
| 219 |
+ OomScoreAdj int // Container preference for OOM-killing |
|
| 220 |
+ PidMode PidMode // PID namespace to use for the container |
|
| 221 |
+ Privileged bool // Is the container in privileged mode |
|
| 222 |
+ PublishAllPorts bool // Should docker publish all exposed port for the container |
|
| 223 |
+ ReadonlyRootfs bool // Is the container root filesystem in read-only |
|
| 224 |
+ SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux. |
|
| 225 |
+ Tmpfs map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container |
|
| 226 |
+ UTSMode UTSMode // UTS namespace to use for the container |
|
| 227 |
+ ShmSize *int64 // Total shm memory usage |
|
| 228 | 228 |
|
| 229 | 229 |
// Applicable to Windows |
| 230 | 230 |
ConsoleSize [2]int // Initial console size |
| ... | ... |
@@ -6,13 +6,13 @@ import ( |
| 6 | 6 |
"strconv" |
| 7 | 7 |
"strings" |
| 8 | 8 |
|
| 9 |
+ "github.com/docker/docker/api/types/strslice" |
|
| 9 | 10 |
"github.com/docker/docker/opts" |
| 10 | 11 |
flag "github.com/docker/docker/pkg/mflag" |
| 11 | 12 |
"github.com/docker/docker/pkg/mount" |
| 12 | 13 |
"github.com/docker/docker/pkg/nat" |
| 13 | 14 |
"github.com/docker/docker/pkg/parsers" |
| 14 | 15 |
"github.com/docker/docker/pkg/signal" |
| 15 |
- "github.com/docker/docker/pkg/stringutils" |
|
| 16 | 16 |
"github.com/docker/docker/volume" |
| 17 | 17 |
"github.com/docker/go-units" |
| 18 | 18 |
) |
| ... | ... |
@@ -249,15 +249,15 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 249 | 249 |
|
| 250 | 250 |
var ( |
| 251 | 251 |
parsedArgs = cmd.Args() |
| 252 |
- runCmd *stringutils.StrSlice |
|
| 253 |
- entrypoint *stringutils.StrSlice |
|
| 252 |
+ runCmd *strslice.StrSlice |
|
| 253 |
+ entrypoint *strslice.StrSlice |
|
| 254 | 254 |
image = cmd.Arg(0) |
| 255 | 255 |
) |
| 256 | 256 |
if len(parsedArgs) > 1 {
|
| 257 |
- runCmd = stringutils.NewStrSlice(parsedArgs[1:]...) |
|
| 257 |
+ runCmd = strslice.New(parsedArgs[1:]...) |
|
| 258 | 258 |
} |
| 259 | 259 |
if *flEntrypoint != "" {
|
| 260 |
- entrypoint = stringutils.NewStrSlice(*flEntrypoint) |
|
| 260 |
+ entrypoint = strslice.New(*flEntrypoint) |
|
| 261 | 261 |
} |
| 262 | 262 |
|
| 263 | 263 |
var ( |
| ... | ... |
@@ -416,8 +416,8 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 416 | 416 |
IpcMode: ipcMode, |
| 417 | 417 |
PidMode: pidMode, |
| 418 | 418 |
UTSMode: utsMode, |
| 419 |
- CapAdd: stringutils.NewStrSlice(flCapAdd.GetAll()...), |
|
| 420 |
- CapDrop: stringutils.NewStrSlice(flCapDrop.GetAll()...), |
|
| 419 |
+ CapAdd: strslice.New(flCapAdd.GetAll()...), |
|
| 420 |
+ CapDrop: strslice.New(flCapDrop.GetAll()...), |
|
| 421 | 421 |
GroupAdd: flGroupAdd.GetAll(), |
| 422 | 422 |
RestartPolicy: restartPolicy, |
| 423 | 423 |
SecurityOpt: flSecurityOpt.GetAll(), |