From 2f23577c7a7b6dba9d6bbc148aa6a4cbbc89ba26 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Sat, 2 Jun 2018 09:46:53 -0700 Subject: [PATCH 1/2] vendor: use dockerfile parser from buildkit Signed-off-by: Tonis Tiigi Upstream-commit: c9ebd2f13b3aab49c2d90cc38dcf2cd0d059697f Component: engine --- .../engine/builder/dockerfile/builder.go | 6 +- .../engine/builder/dockerfile/dispatchers.go | 6 +- .../builder/dockerfile/dispatchers_test.go | 4 +- .../engine/builder/dockerfile/evaluator.go | 4 +- .../builder/dockerfile/evaluator_test.go | 2 +- .../dockerfile/instructions/bflag_test.go | 187 -------------- .../dockerfile/instructions/parse_test.go | 198 --------------- .../dockerfile/instructions/support_test.go | 65 ----- .../builder/dockerfile/parser/dumper/main.go | 32 --- .../builder/dockerfile/parser/json_test.go | 59 ----- .../dockerfile/parser/line_parsers_test.go | 51 ---- .../builder/dockerfile/parser/parser_test.go | 174 ------------- .../parser/testfile-line/Dockerfile | 35 --- .../env_no_value/Dockerfile | 3 - .../shykes-nested-json/Dockerfile | 1 - .../testfiles/ADD-COPY-with-JSON/Dockerfile | 11 - .../testfiles/ADD-COPY-with-JSON/result | 10 - .../testfiles/brimstone-consuldock/Dockerfile | 26 -- .../testfiles/brimstone-consuldock/result | 5 - .../brimstone-docker-consul/Dockerfile | 52 ---- .../testfiles/brimstone-docker-consul/result | 9 - .../testfiles/continue-at-eof/Dockerfile | 3 - .../parser/testfiles/continue-at-eof/result | 2 - .../testfiles/continueIndent/Dockerfile | 36 --- .../parser/testfiles/continueIndent/result | 10 - .../testfiles/cpuguy83-nagios/Dockerfile | 54 ---- .../parser/testfiles/cpuguy83-nagios/result | 40 --- .../parser/testfiles/docker/Dockerfile | 94 ------- .../dockerfile/parser/testfiles/docker/result | 24 -- .../parser/testfiles/env/Dockerfile | 23 -- .../dockerfile/parser/testfiles/env/result | 16 -- .../testfiles/escape-after-comment/Dockerfile | 9 - .../testfiles/escape-after-comment/result | 3 - .../testfiles/escape-nonewline/Dockerfile | 7 - .../parser/testfiles/escape-nonewline/result | 3 - .../parser/testfiles/escape/Dockerfile | 6 - .../dockerfile/parser/testfiles/escape/result | 3 - .../parser/testfiles/escapes/Dockerfile | 14 -- .../parser/testfiles/escapes/result | 6 - .../parser/testfiles/flags/Dockerfile | 10 - .../dockerfile/parser/testfiles/flags/result | 10 - .../parser/testfiles/health/Dockerfile | 10 - .../dockerfile/parser/testfiles/health/result | 9 - .../parser/testfiles/influxdb/Dockerfile | 15 -- .../parser/testfiles/influxdb/result | 11 - .../Dockerfile | 1 - .../result | 1 - .../Dockerfile | 1 - .../result | 1 - .../Dockerfile | 1 - .../jeztah-invalid-json-single-quotes/result | 1 - .../Dockerfile | 1 - .../result | 1 - .../Dockerfile | 1 - .../result | 1 - .../parser/testfiles/json/Dockerfile | 8 - .../dockerfile/parser/testfiles/json/result | 8 - .../kartar-entrypoint-oddities/Dockerfile | 7 - .../kartar-entrypoint-oddities/result | 7 - .../lk4d4-the-edge-case-generator/Dockerfile | 48 ---- .../lk4d4-the-edge-case-generator/result | 29 --- .../parser/testfiles/mail/Dockerfile | 16 -- .../dockerfile/parser/testfiles/mail/result | 14 -- .../testfiles/multiple-volumes/Dockerfile | 3 - .../parser/testfiles/multiple-volumes/result | 2 - .../parser/testfiles/mumble/Dockerfile | 7 - .../dockerfile/parser/testfiles/mumble/result | 4 - .../parser/testfiles/nginx/Dockerfile | 14 -- .../dockerfile/parser/testfiles/nginx/result | 11 - .../parser/testfiles/tf2/Dockerfile | 23 -- .../dockerfile/parser/testfiles/tf2/result | 20 -- .../parser/testfiles/weechat/Dockerfile | 9 - .../parser/testfiles/weechat/result | 6 - .../parser/testfiles/znc/Dockerfile | 7 - .../dockerfile/parser/testfiles/znc/result | 5 - .../builder/dockerfile/shell/envVarTest | 232 ------------------ .../builder/dockerfile/shell/lex_test.go | 150 ----------- .../engine/builder/dockerfile/shell/wordsTest | 30 --- .../engine/builder/remotecontext/detect.go | 2 +- .../integration-cli/docker_cli_build_test.go | 2 +- .../integration/build/build_session_test.go | 3 +- components/engine/vendor.conf | 4 +- .../vendor/github.com/moby/buildkit/README.md | 179 ++++++++++++-- .../frontend}/dockerfile/command/command.go | 2 +- .../dockerfile/instructions/bflag.go | 2 +- .../dockerfile/instructions/commands.go | 2 +- .../dockerfile/instructions/errors_unix.go | 2 +- .../dockerfile/instructions/errors_windows.go | 2 +- .../dockerfile/instructions/parse.go | 6 +- .../dockerfile/instructions/support.go | 2 +- .../dockerfile/parser/line_parsers.go | 2 +- .../frontend}/dockerfile/parser/parser.go | 4 +- .../dockerfile/parser/split_command.go | 2 +- .../dockerfile/shell/equal_env_unix.go | 2 +- .../dockerfile/shell/equal_env_windows.go | 2 +- .../frontend}/dockerfile/shell/lex.go | 2 +- .../moby/buildkit/identity/randomid.go | 53 ++++ .../buildkit/session/filesync/diffcopy.go | 58 +++++ .../buildkit/session/filesync/filesync.go | 70 ++++-- .../buildkit/session/filesync/filesync.pb.go | 39 +-- .../github.com/moby/buildkit/session/grpc.go | 31 ++- .../moby/buildkit/session/manager.go | 8 +- .../moby/buildkit/session/session.go | 37 ++- .../github.com/moby/buildkit/vendor.conf | 74 ++++-- .../{diskwriter_linux.go => chtimes_linux.go} | 0 .../tonistiigi/fsutil/chtimes_nolinux.go | 13 + .../tonistiigi/fsutil/diskwriter.go | 1 + .../tonistiigi/fsutil/diskwriter_darwin.go | 7 - .../tonistiigi/fsutil/diskwriter_windows.go | 8 - .../github.com/tonistiigi/fsutil/receive.go | 44 +++- .../github.com/tonistiigi/fsutil/send.go | 9 +- .../github.com/tonistiigi/fsutil/walker.go | 65 ++++- .../github.com/tonistiigi/fsutil/wire.pb.go | 20 +- .../github.com/tonistiigi/fsutil/wire.proto | 1 + 114 files changed, 601 insertions(+), 2187 deletions(-) delete mode 100644 components/engine/builder/dockerfile/instructions/bflag_test.go delete mode 100644 components/engine/builder/dockerfile/instructions/parse_test.go delete mode 100644 components/engine/builder/dockerfile/instructions/support_test.go delete mode 100644 components/engine/builder/dockerfile/parser/dumper/main.go delete mode 100644 components/engine/builder/dockerfile/parser/json_test.go delete mode 100644 components/engine/builder/dockerfile/parser/line_parsers_test.go delete mode 100644 components/engine/builder/dockerfile/parser/parser_test.go delete mode 100644 components/engine/builder/dockerfile/parser/testfile-line/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles-negative/env_no_value/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles-negative/shykes-nested-json/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/ADD-COPY-with-JSON/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/ADD-COPY-with-JSON/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/brimstone-consuldock/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/brimstone-consuldock/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/brimstone-docker-consul/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/brimstone-docker-consul/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/continue-at-eof/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/continue-at-eof/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/continueIndent/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/continueIndent/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/cpuguy83-nagios/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/cpuguy83-nagios/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/docker/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/docker/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/env/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/env/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/escape-after-comment/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/escape-after-comment/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/escape-nonewline/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/escape-nonewline/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/escape/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/escape/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/escapes/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/escapes/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/flags/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/flags/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/health/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/health/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/influxdb/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/influxdb/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string-double/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string-double/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-single-quotes/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-single-quotes/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-bracket/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-bracket/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-string/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-string/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/json/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/json/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/kartar-entrypoint-oddities/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/kartar-entrypoint-oddities/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/lk4d4-the-edge-case-generator/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/lk4d4-the-edge-case-generator/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/mail/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/mail/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/multiple-volumes/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/multiple-volumes/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/mumble/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/mumble/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/nginx/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/nginx/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/tf2/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/tf2/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/weechat/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/weechat/result delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/znc/Dockerfile delete mode 100644 components/engine/builder/dockerfile/parser/testfiles/znc/result delete mode 100644 components/engine/builder/dockerfile/shell/envVarTest delete mode 100644 components/engine/builder/dockerfile/shell/lex_test.go delete mode 100644 components/engine/builder/dockerfile/shell/wordsTest rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/command/command.go (92%) rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/instructions/bflag.go (97%) rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/instructions/commands.go (99%) rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/instructions/errors_unix.go (63%) rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/instructions/errors_windows.go (92%) rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/instructions/parse.go (98%) rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/instructions/support.go (85%) rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/parser/line_parsers.go (99%) rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/parser/parser.go (98%) rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/parser/split_command.go (96%) rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/shell/equal_env_unix.go (73%) rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/shell/equal_env_windows.go (75%) rename components/engine/{builder => vendor/github.com/moby/buildkit/frontend}/dockerfile/shell/lex.go (99%) create mode 100644 components/engine/vendor/github.com/moby/buildkit/identity/randomid.go rename components/engine/vendor/github.com/tonistiigi/fsutil/{diskwriter_linux.go => chtimes_linux.go} (100%) create mode 100644 components/engine/vendor/github.com/tonistiigi/fsutil/chtimes_nolinux.go delete mode 100644 components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter_darwin.go diff --git a/components/engine/builder/dockerfile/builder.go b/components/engine/builder/dockerfile/builder.go index 890e7b89fd..d5d2de8180 100644 --- a/components/engine/builder/dockerfile/builder.go +++ b/components/engine/builder/dockerfile/builder.go @@ -14,9 +14,6 @@ import ( "github.com/docker/docker/api/types/backend" "github.com/docker/docker/api/types/container" "github.com/docker/docker/builder" - "github.com/docker/docker/builder/dockerfile/instructions" - "github.com/docker/docker/builder/dockerfile/parser" - "github.com/docker/docker/builder/dockerfile/shell" "github.com/docker/docker/builder/fscache" "github.com/docker/docker/builder/remotecontext" "github.com/docker/docker/errdefs" @@ -24,6 +21,9 @@ import ( "github.com/docker/docker/pkg/streamformatter" "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/pkg/system" + "github.com/moby/buildkit/frontend/dockerfile/instructions" + "github.com/moby/buildkit/frontend/dockerfile/parser" + "github.com/moby/buildkit/frontend/dockerfile/shell" "github.com/moby/buildkit/session" "github.com/pkg/errors" "github.com/sirupsen/logrus" diff --git a/components/engine/builder/dockerfile/dispatchers.go b/components/engine/builder/dockerfile/dispatchers.go index 9dd7502453..6ff65292b5 100644 --- a/components/engine/builder/dockerfile/dispatchers.go +++ b/components/engine/builder/dockerfile/dispatchers.go @@ -18,15 +18,15 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/strslice" "github.com/docker/docker/builder" - "github.com/docker/docker/builder/dockerfile/instructions" - "github.com/docker/docker/builder/dockerfile/parser" - "github.com/docker/docker/builder/dockerfile/shell" "github.com/docker/docker/errdefs" "github.com/docker/docker/image" "github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/system" "github.com/docker/go-connections/nat" + "github.com/moby/buildkit/frontend/dockerfile/instructions" + "github.com/moby/buildkit/frontend/dockerfile/parser" + "github.com/moby/buildkit/frontend/dockerfile/shell" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) diff --git a/components/engine/builder/dockerfile/dispatchers_test.go b/components/engine/builder/dockerfile/dispatchers_test.go index 8eed646a70..a5474d6db8 100644 --- a/components/engine/builder/dockerfile/dispatchers_test.go +++ b/components/engine/builder/dockerfile/dispatchers_test.go @@ -11,13 +11,13 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/strslice" "github.com/docker/docker/builder" - "github.com/docker/docker/builder/dockerfile/instructions" - "github.com/docker/docker/builder/dockerfile/shell" "github.com/docker/docker/image" "github.com/docker/docker/pkg/system" "github.com/docker/go-connections/nat" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" + "github.com/moby/buildkit/frontend/dockerfile/instructions" + "github.com/moby/buildkit/frontend/dockerfile/shell" ) func newBuilderWithMockBackend() *Builder { diff --git a/components/engine/builder/dockerfile/evaluator.go b/components/engine/builder/dockerfile/evaluator.go index 75073cec6d..02e1477528 100644 --- a/components/engine/builder/dockerfile/evaluator.go +++ b/components/engine/builder/dockerfile/evaluator.go @@ -27,11 +27,11 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/builder" - "github.com/docker/docker/builder/dockerfile/instructions" - "github.com/docker/docker/builder/dockerfile/shell" "github.com/docker/docker/errdefs" "github.com/docker/docker/pkg/system" "github.com/docker/docker/runconfig/opts" + "github.com/moby/buildkit/frontend/dockerfile/instructions" + "github.com/moby/buildkit/frontend/dockerfile/shell" "github.com/pkg/errors" ) diff --git a/components/engine/builder/dockerfile/evaluator_test.go b/components/engine/builder/dockerfile/evaluator_test.go index 0a64b9fdd6..4657b1c580 100644 --- a/components/engine/builder/dockerfile/evaluator_test.go +++ b/components/engine/builder/dockerfile/evaluator_test.go @@ -4,13 +4,13 @@ import ( "os" "testing" - "github.com/docker/docker/builder/dockerfile/instructions" "github.com/docker/docker/builder/remotecontext" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/reexec" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/skip" + "github.com/moby/buildkit/frontend/dockerfile/instructions" ) type dispatchTestCase struct { diff --git a/components/engine/builder/dockerfile/instructions/bflag_test.go b/components/engine/builder/dockerfile/instructions/bflag_test.go deleted file mode 100644 index d0d203a009..0000000000 --- a/components/engine/builder/dockerfile/instructions/bflag_test.go +++ /dev/null @@ -1,187 +0,0 @@ -package instructions // import "github.com/docker/docker/builder/dockerfile/instructions" - -import ( - "testing" -) - -func TestBuilderFlags(t *testing.T) { - var expected string - var err error - - // --- - - bf := NewBFlags() - bf.Args = []string{} - if err := bf.Parse(); err != nil { - t.Fatalf("Test1 of %q was supposed to work: %s", bf.Args, err) - } - - // --- - - bf = NewBFlags() - bf.Args = []string{"--"} - if err := bf.Parse(); err != nil { - t.Fatalf("Test2 of %q was supposed to work: %s", bf.Args, err) - } - - // --- - - bf = NewBFlags() - flStr1 := bf.AddString("str1", "") - flBool1 := bf.AddBool("bool1", false) - bf.Args = []string{} - if err = bf.Parse(); err != nil { - t.Fatalf("Test3 of %q was supposed to work: %s", bf.Args, err) - } - - if flStr1.IsUsed() { - t.Fatal("Test3 - str1 was not used!") - } - if flBool1.IsUsed() { - t.Fatal("Test3 - bool1 was not used!") - } - - // --- - - bf = NewBFlags() - flStr1 = bf.AddString("str1", "HI") - flBool1 = bf.AddBool("bool1", false) - bf.Args = []string{} - - if err = bf.Parse(); err != nil { - t.Fatalf("Test4 of %q was supposed to work: %s", bf.Args, err) - } - - if flStr1.Value != "HI" { - t.Fatal("Str1 was supposed to default to: HI") - } - if flBool1.IsTrue() { - t.Fatal("Bool1 was supposed to default to: false") - } - if flStr1.IsUsed() { - t.Fatal("Str1 was not used!") - } - if flBool1.IsUsed() { - t.Fatal("Bool1 was not used!") - } - - // --- - - bf = NewBFlags() - flStr1 = bf.AddString("str1", "HI") - bf.Args = []string{"--str1"} - - if err = bf.Parse(); err == nil { - t.Fatalf("Test %q was supposed to fail", bf.Args) - } - - // --- - - bf = NewBFlags() - flStr1 = bf.AddString("str1", "HI") - bf.Args = []string{"--str1="} - - if err = bf.Parse(); err != nil { - t.Fatalf("Test %q was supposed to work: %s", bf.Args, err) - } - - expected = "" - if flStr1.Value != expected { - t.Fatalf("Str1 (%q) should be: %q", flStr1.Value, expected) - } - - // --- - - bf = NewBFlags() - flStr1 = bf.AddString("str1", "HI") - bf.Args = []string{"--str1=BYE"} - - if err = bf.Parse(); err != nil { - t.Fatalf("Test %q was supposed to work: %s", bf.Args, err) - } - - expected = "BYE" - if flStr1.Value != expected { - t.Fatalf("Str1 (%q) should be: %q", flStr1.Value, expected) - } - - // --- - - bf = NewBFlags() - flBool1 = bf.AddBool("bool1", false) - bf.Args = []string{"--bool1"} - - if err = bf.Parse(); err != nil { - t.Fatalf("Test %q was supposed to work: %s", bf.Args, err) - } - - if !flBool1.IsTrue() { - t.Fatal("Test-b1 Bool1 was supposed to be true") - } - - // --- - - bf = NewBFlags() - flBool1 = bf.AddBool("bool1", false) - bf.Args = []string{"--bool1=true"} - - if err = bf.Parse(); err != nil { - t.Fatalf("Test %q was supposed to work: %s", bf.Args, err) - } - - if !flBool1.IsTrue() { - t.Fatal("Test-b2 Bool1 was supposed to be true") - } - - // --- - - bf = NewBFlags() - flBool1 = bf.AddBool("bool1", false) - bf.Args = []string{"--bool1=false"} - - if err = bf.Parse(); err != nil { - t.Fatalf("Test %q was supposed to work: %s", bf.Args, err) - } - - if flBool1.IsTrue() { - t.Fatal("Test-b3 Bool1 was supposed to be false") - } - - // --- - - bf = NewBFlags() - flBool1 = bf.AddBool("bool1", false) - bf.Args = []string{"--bool1=false1"} - - if err = bf.Parse(); err == nil { - t.Fatalf("Test %q was supposed to fail", bf.Args) - } - - // --- - - bf = NewBFlags() - flBool1 = bf.AddBool("bool1", false) - bf.Args = []string{"--bool2"} - - if err = bf.Parse(); err == nil { - t.Fatalf("Test %q was supposed to fail", bf.Args) - } - - // --- - - bf = NewBFlags() - flStr1 = bf.AddString("str1", "HI") - flBool1 = bf.AddBool("bool1", false) - bf.Args = []string{"--bool1", "--str1=BYE"} - - if err = bf.Parse(); err != nil { - t.Fatalf("Test %q was supposed to work: %s", bf.Args, err) - } - - if flStr1.Value != "BYE" { - t.Fatalf("Test %s, str1 should be BYE", bf.Args) - } - if !flBool1.IsTrue() { - t.Fatalf("Test %s, bool1 should be true", bf.Args) - } -} diff --git a/components/engine/builder/dockerfile/instructions/parse_test.go b/components/engine/builder/dockerfile/instructions/parse_test.go deleted file mode 100644 index f5eeea5719..0000000000 --- a/components/engine/builder/dockerfile/instructions/parse_test.go +++ /dev/null @@ -1,198 +0,0 @@ -package instructions // import "github.com/docker/docker/builder/dockerfile/instructions" - -import ( - "strings" - "testing" - - "github.com/docker/docker/builder/dockerfile/command" - "github.com/docker/docker/builder/dockerfile/parser" - "github.com/gotestyourself/gotestyourself/assert" - is "github.com/gotestyourself/gotestyourself/assert/cmp" -) - -func TestCommandsExactlyOneArgument(t *testing.T) { - commands := []string{ - "MAINTAINER", - "WORKDIR", - "USER", - "STOPSIGNAL", - } - - for _, cmd := range commands { - ast, err := parser.Parse(strings.NewReader(cmd)) - assert.NilError(t, err) - _, err = ParseInstruction(ast.AST.Children[0]) - assert.Check(t, is.Error(err, errExactlyOneArgument(cmd).Error())) - } -} - -func TestCommandsAtLeastOneArgument(t *testing.T) { - commands := []string{ - "ENV", - "LABEL", - "ONBUILD", - "HEALTHCHECK", - "EXPOSE", - "VOLUME", - } - - for _, cmd := range commands { - ast, err := parser.Parse(strings.NewReader(cmd)) - assert.NilError(t, err) - _, err = ParseInstruction(ast.AST.Children[0]) - assert.Check(t, is.Error(err, errAtLeastOneArgument(cmd).Error())) - } -} - -func TestCommandsNoDestinationArgument(t *testing.T) { - commands := []string{ - "ADD", - "COPY", - } - - for _, cmd := range commands { - ast, err := parser.Parse(strings.NewReader(cmd + " arg1")) - assert.NilError(t, err) - _, err = ParseInstruction(ast.AST.Children[0]) - assert.Check(t, is.Error(err, errNoDestinationArgument(cmd).Error())) - } -} - -func TestCommandsTooManyArguments(t *testing.T) { - commands := []string{ - "ENV", - "LABEL", - } - - for _, command := range commands { - node := &parser.Node{ - Original: command + "arg1 arg2 arg3", - Value: strings.ToLower(command), - Next: &parser.Node{ - Value: "arg1", - Next: &parser.Node{ - Value: "arg2", - Next: &parser.Node{ - Value: "arg3", - }, - }, - }, - } - _, err := ParseInstruction(node) - assert.Check(t, is.Error(err, errTooManyArguments(command).Error())) - } -} - -func TestCommandsBlankNames(t *testing.T) { - commands := []string{ - "ENV", - "LABEL", - } - - for _, cmd := range commands { - node := &parser.Node{ - Original: cmd + " =arg2", - Value: strings.ToLower(cmd), - Next: &parser.Node{ - Value: "", - Next: &parser.Node{ - Value: "arg2", - }, - }, - } - _, err := ParseInstruction(node) - assert.Check(t, is.Error(err, errBlankCommandNames(cmd).Error())) - } -} - -func TestHealthCheckCmd(t *testing.T) { - node := &parser.Node{ - Value: command.Healthcheck, - Next: &parser.Node{ - Value: "CMD", - Next: &parser.Node{ - Value: "hello", - Next: &parser.Node{ - Value: "world", - }, - }, - }, - } - cmd, err := ParseInstruction(node) - assert.Check(t, err) - hc, ok := cmd.(*HealthCheckCommand) - assert.Check(t, ok) - expected := []string{"CMD-SHELL", "hello world"} - assert.Check(t, is.DeepEqual(expected, hc.Health.Test)) -} - -func TestParseOptInterval(t *testing.T) { - flInterval := &Flag{ - name: "interval", - flagType: stringType, - Value: "50ns", - } - _, err := parseOptInterval(flInterval) - assert.Check(t, is.ErrorContains(err, "cannot be less than 1ms")) - - flInterval.Value = "1ms" - _, err = parseOptInterval(flInterval) - assert.NilError(t, err) -} - -func TestErrorCases(t *testing.T) { - cases := []struct { - name string - dockerfile string - expectedError string - }{ - { - name: "copyEmptyWhitespace", - dockerfile: `COPY - quux \ - bar`, - expectedError: "COPY requires at least two arguments", - }, - { - name: "ONBUILD forbidden FROM", - dockerfile: "ONBUILD FROM scratch", - expectedError: "FROM isn't allowed as an ONBUILD trigger", - }, - { - name: "ONBUILD forbidden MAINTAINER", - dockerfile: "ONBUILD MAINTAINER docker.io", - expectedError: "MAINTAINER isn't allowed as an ONBUILD trigger", - }, - { - name: "ARG two arguments", - dockerfile: "ARG foo bar", - expectedError: "ARG requires exactly one argument", - }, - { - name: "MAINTAINER unknown flag", - dockerfile: "MAINTAINER --boo joe@example.com", - expectedError: "Unknown flag: boo", - }, - { - name: "Chaining ONBUILD", - dockerfile: `ONBUILD ONBUILD RUN touch foobar`, - expectedError: "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed", - }, - { - name: "Invalid instruction", - dockerfile: `foo bar`, - expectedError: "unknown instruction: FOO", - }, - } - for _, c := range cases { - r := strings.NewReader(c.dockerfile) - ast, err := parser.Parse(r) - - if err != nil { - t.Fatalf("Error when parsing Dockerfile: %s", err) - } - n := ast.AST.Children[0] - _, err = ParseInstruction(n) - assert.Check(t, is.ErrorContains(err, c.expectedError)) - } -} diff --git a/components/engine/builder/dockerfile/instructions/support_test.go b/components/engine/builder/dockerfile/instructions/support_test.go deleted file mode 100644 index 0332c524e8..0000000000 --- a/components/engine/builder/dockerfile/instructions/support_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package instructions // import "github.com/docker/docker/builder/dockerfile/instructions" - -import "testing" - -type testCase struct { - name string - args []string - attributes map[string]bool - expected []string -} - -func initTestCases() []testCase { - var testCases []testCase - - testCases = append(testCases, testCase{ - name: "empty args", - args: []string{}, - attributes: make(map[string]bool), - expected: []string{}, - }) - - jsonAttributes := make(map[string]bool) - jsonAttributes["json"] = true - - testCases = append(testCases, testCase{ - name: "json attribute with one element", - args: []string{"foo"}, - attributes: jsonAttributes, - expected: []string{"foo"}, - }) - - testCases = append(testCases, testCase{ - name: "json attribute with two elements", - args: []string{"foo", "bar"}, - attributes: jsonAttributes, - expected: []string{"foo", "bar"}, - }) - - testCases = append(testCases, testCase{ - name: "no attributes", - args: []string{"foo", "bar"}, - attributes: nil, - expected: []string{"foo bar"}, - }) - - return testCases -} - -func TestHandleJSONArgs(t *testing.T) { - testCases := initTestCases() - - for _, test := range testCases { - arguments := handleJSONArgs(test.args, test.attributes) - - if len(arguments) != len(test.expected) { - t.Fatalf("In test \"%s\": length of returned slice is incorrect. Expected: %d, got: %d", test.name, len(test.expected), len(arguments)) - } - - for i := range test.expected { - if arguments[i] != test.expected[i] { - t.Fatalf("In test \"%s\": element as position %d is incorrect. Expected: %s, got: %s", test.name, i, test.expected[i], arguments[i]) - } - } - } -} diff --git a/components/engine/builder/dockerfile/parser/dumper/main.go b/components/engine/builder/dockerfile/parser/dumper/main.go deleted file mode 100644 index ea6205073d..0000000000 --- a/components/engine/builder/dockerfile/parser/dumper/main.go +++ /dev/null @@ -1,32 +0,0 @@ -package main - -import ( - "fmt" - "os" - - "github.com/docker/docker/builder/dockerfile/parser" -) - -func main() { - var f *os.File - var err error - - if len(os.Args) < 2 { - fmt.Println("please supply filename(s)") - os.Exit(1) - } - - for _, fn := range os.Args[1:] { - f, err = os.Open(fn) - if err != nil { - panic(err) - } - defer f.Close() - - result, err := parser.Parse(f) - if err != nil { - panic(err) - } - fmt.Println(result.AST.Dump()) - } -} diff --git a/components/engine/builder/dockerfile/parser/json_test.go b/components/engine/builder/dockerfile/parser/json_test.go deleted file mode 100644 index eddf50bd3f..0000000000 --- a/components/engine/builder/dockerfile/parser/json_test.go +++ /dev/null @@ -1,59 +0,0 @@ -package parser // import "github.com/docker/docker/builder/dockerfile/parser" - -import ( - "testing" -) - -var invalidJSONArraysOfStrings = []string{ - `["a",42,"b"]`, - `["a",123.456,"b"]`, - `["a",{},"b"]`, - `["a",{"c": "d"},"b"]`, - `["a",["c"],"b"]`, - `["a",true,"b"]`, - `["a",false,"b"]`, - `["a",null,"b"]`, -} - -var validJSONArraysOfStrings = map[string][]string{ - `[]`: {}, - `[""]`: {""}, - `["a"]`: {"a"}, - `["a","b"]`: {"a", "b"}, - `[ "a", "b" ]`: {"a", "b"}, - `[ "a", "b" ]`: {"a", "b"}, - ` [ "a", "b" ] `: {"a", "b"}, - `["abc 123", "♥", "☃", "\" \\ \/ \b \f \n \r \t \u0000"]`: {"abc 123", "♥", "☃", "\" \\ / \b \f \n \r \t \u0000"}, -} - -func TestJSONArraysOfStrings(t *testing.T) { - for json, expected := range validJSONArraysOfStrings { - d := NewDefaultDirective() - - if node, _, err := parseJSON(json, d); err != nil { - t.Fatalf("%q should be a valid JSON array of strings, but wasn't! (err: %q)", json, err) - } else { - i := 0 - for node != nil { - if i >= len(expected) { - t.Fatalf("expected result is shorter than parsed result (%d vs %d+) in %q", len(expected), i+1, json) - } - if node.Value != expected[i] { - t.Fatalf("expected %q (not %q) in %q at pos %d", expected[i], node.Value, json, i) - } - node = node.Next - i++ - } - if i != len(expected) { - t.Fatalf("expected result is longer than parsed result (%d vs %d) in %q", len(expected), i+1, json) - } - } - } - for _, json := range invalidJSONArraysOfStrings { - d := NewDefaultDirective() - - if _, _, err := parseJSON(json, d); err != errDockerfileNotStringArray { - t.Fatalf("%q should be an invalid JSON array of strings, but wasn't!", json) - } - } -} diff --git a/components/engine/builder/dockerfile/parser/line_parsers_test.go b/components/engine/builder/dockerfile/parser/line_parsers_test.go deleted file mode 100644 index f7580efa3e..0000000000 --- a/components/engine/builder/dockerfile/parser/line_parsers_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package parser // import "github.com/docker/docker/builder/dockerfile/parser" - -import ( - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/gotestyourself/gotestyourself/assert" - is "github.com/gotestyourself/gotestyourself/assert/cmp" -) - -func TestParseNameValOldFormat(t *testing.T) { - directive := Directive{} - node, err := parseNameVal("foo bar", "LABEL", &directive) - assert.Check(t, err) - - expected := &Node{ - Value: "foo", - Next: &Node{Value: "bar"}, - } - assert.DeepEqual(t, expected, node, cmpNodeOpt) -} - -var cmpNodeOpt = cmp.AllowUnexported(Node{}) - -func TestParseNameValNewFormat(t *testing.T) { - directive := Directive{} - node, err := parseNameVal("foo=bar thing=star", "LABEL", &directive) - assert.Check(t, err) - - expected := &Node{ - Value: "foo", - Next: &Node{ - Value: "bar", - Next: &Node{ - Value: "thing", - Next: &Node{ - Value: "star", - }, - }, - }, - } - assert.DeepEqual(t, expected, node, cmpNodeOpt) -} - -func TestParseNameValWithoutVal(t *testing.T) { - directive := Directive{} - // In Config.Env, a variable without `=` is removed from the environment. (#31634) - // However, in Dockerfile, we don't allow "unsetting" an environment variable. (#11922) - _, err := parseNameVal("foo", "ENV", &directive) - assert.Check(t, is.ErrorContains(err, ""), "ENV must have two arguments") -} diff --git a/components/engine/builder/dockerfile/parser/parser_test.go b/components/engine/builder/dockerfile/parser/parser_test.go deleted file mode 100644 index 10bed1f756..0000000000 --- a/components/engine/builder/dockerfile/parser/parser_test.go +++ /dev/null @@ -1,174 +0,0 @@ -package parser // import "github.com/docker/docker/builder/dockerfile/parser" - -import ( - "bufio" - "bytes" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "runtime" - "strings" - "testing" - - "github.com/gotestyourself/gotestyourself/assert" - is "github.com/gotestyourself/gotestyourself/assert/cmp" -) - -const testDir = "testfiles" -const negativeTestDir = "testfiles-negative" -const testFileLineInfo = "testfile-line/Dockerfile" - -func getDirs(t *testing.T, dir string) []string { - f, err := os.Open(dir) - assert.NilError(t, err) - defer f.Close() - - dirs, err := f.Readdirnames(0) - assert.NilError(t, err) - return dirs -} - -func TestParseErrorCases(t *testing.T) { - for _, dir := range getDirs(t, negativeTestDir) { - dockerfile := filepath.Join(negativeTestDir, dir, "Dockerfile") - - df, err := os.Open(dockerfile) - assert.NilError(t, err, dockerfile) - defer df.Close() - - _, err = Parse(df) - assert.Check(t, is.ErrorContains(err, ""), dockerfile) - } -} - -func TestParseCases(t *testing.T) { - for _, dir := range getDirs(t, testDir) { - dockerfile := filepath.Join(testDir, dir, "Dockerfile") - resultfile := filepath.Join(testDir, dir, "result") - - df, err := os.Open(dockerfile) - assert.NilError(t, err, dockerfile) - defer df.Close() - - result, err := Parse(df) - assert.NilError(t, err, dockerfile) - - content, err := ioutil.ReadFile(resultfile) - assert.NilError(t, err, resultfile) - - if runtime.GOOS == "windows" { - // CRLF --> CR to match Unix behavior - content = bytes.Replace(content, []byte{'\x0d', '\x0a'}, []byte{'\x0a'}, -1) - } - assert.Check(t, is.Equal(result.AST.Dump()+"\n", string(content)), "In "+dockerfile) - } -} - -func TestParseWords(t *testing.T) { - tests := []map[string][]string{ - { - "input": {"foo"}, - "expect": {"foo"}, - }, - { - "input": {"foo bar"}, - "expect": {"foo", "bar"}, - }, - { - "input": {"foo\\ bar"}, - "expect": {"foo\\ bar"}, - }, - { - "input": {"foo=bar"}, - "expect": {"foo=bar"}, - }, - { - "input": {"foo bar 'abc xyz'"}, - "expect": {"foo", "bar", "'abc xyz'"}, - }, - { - "input": {`foo bar "abc xyz"`}, - "expect": {"foo", "bar", `"abc xyz"`}, - }, - { - "input": {"àöû"}, - "expect": {"àöû"}, - }, - { - "input": {`föo bàr "âbc xÿz"`}, - "expect": {"föo", "bàr", `"âbc xÿz"`}, - }, - } - - for _, test := range tests { - words := parseWords(test["input"][0], NewDefaultDirective()) - assert.Check(t, is.DeepEqual(test["expect"], words)) - } -} - -func TestParseIncludesLineNumbers(t *testing.T) { - df, err := os.Open(testFileLineInfo) - assert.NilError(t, err) - defer df.Close() - - result, err := Parse(df) - assert.NilError(t, err) - - ast := result.AST - assert.Check(t, is.Equal(5, ast.StartLine)) - assert.Check(t, is.Equal(31, ast.endLine)) - assert.Check(t, is.Len(ast.Children, 3)) - expected := [][]int{ - {5, 5}, - {11, 12}, - {17, 31}, - } - for i, child := range ast.Children { - msg := fmt.Sprintf("Child %d", i) - assert.Check(t, is.DeepEqual(expected[i], []int{child.StartLine, child.endLine}), msg) - } -} - -func TestParseWarnsOnEmptyContinutationLine(t *testing.T) { - dockerfile := bytes.NewBufferString(` -FROM alpine:3.6 - -RUN something \ - - following \ - - more - -RUN another \ - - thing -RUN non-indented \ -# this is a comment - after-comment - -RUN indented \ - # this is an indented comment - comment - `) - - result, err := Parse(dockerfile) - assert.NilError(t, err) - warnings := result.Warnings - assert.Check(t, is.Len(warnings, 3)) - assert.Check(t, is.Contains(warnings[0], "Empty continuation line found in")) - assert.Check(t, is.Contains(warnings[0], "RUN something following more")) - assert.Check(t, is.Contains(warnings[1], "RUN another thing")) - assert.Check(t, is.Contains(warnings[2], "will become errors in a future release")) -} - -func TestParseReturnsScannerErrors(t *testing.T) { - label := strings.Repeat("a", bufio.MaxScanTokenSize) - - dockerfile := strings.NewReader(fmt.Sprintf(` - FROM image - LABEL test=%s -`, label)) - _, err := Parse(dockerfile) - assert.Check(t, is.Error(err, "dockerfile line greater than max allowed size of 65535")) -} diff --git a/components/engine/builder/dockerfile/parser/testfile-line/Dockerfile b/components/engine/builder/dockerfile/parser/testfile-line/Dockerfile deleted file mode 100644 index c7601c9f69..0000000000 --- a/components/engine/builder/dockerfile/parser/testfile-line/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -# ESCAPE=\ - - - -FROM brimstone/ubuntu:14.04 - - -# TORUN -v /var/run/docker.sock:/var/run/docker.sock - - -ENV GOPATH \ -/go - - - -# Install the packages we need, clean up after them and us -RUN apt-get update \ - && dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.clean \ - - - && apt-get install -y --no-install-recommends git golang ca-certificates \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists \ - - && go get -v github.com/brimstone/consuldock \ - && mv $GOPATH/bin/consuldock /usr/local/bin/consuldock \ - - && dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.dirty \ - && apt-get remove --purge -y $(diff /tmp/dpkg.clean /tmp/dpkg.dirty | awk '/^>/ {print $2}') \ - && rm /tmp/dpkg.* \ - && rm -rf $GOPATH - - - - diff --git a/components/engine/builder/dockerfile/parser/testfiles-negative/env_no_value/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles-negative/env_no_value/Dockerfile deleted file mode 100644 index 1d65578794..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles-negative/env_no_value/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM busybox - -ENV PATH diff --git a/components/engine/builder/dockerfile/parser/testfiles-negative/shykes-nested-json/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles-negative/shykes-nested-json/Dockerfile deleted file mode 100644 index d1be4596c7..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles-negative/shykes-nested-json/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -CMD [ "echo", [ "nested json" ] ] diff --git a/components/engine/builder/dockerfile/parser/testfiles/ADD-COPY-with-JSON/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/ADD-COPY-with-JSON/Dockerfile deleted file mode 100644 index 035b4e8bb5..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/ADD-COPY-with-JSON/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM ubuntu:14.04 -LABEL maintainer Seongyeol Lim - -COPY . /go/src/github.com/docker/docker -ADD . / -ADD null / -COPY nullfile /tmp -ADD [ "vimrc", "/tmp" ] -COPY [ "bashrc", "/tmp" ] -COPY [ "test file", "/tmp" ] -ADD [ "test file", "/tmp/test file" ] diff --git a/components/engine/builder/dockerfile/parser/testfiles/ADD-COPY-with-JSON/result b/components/engine/builder/dockerfile/parser/testfiles/ADD-COPY-with-JSON/result deleted file mode 100644 index d1f71ecc5a..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/ADD-COPY-with-JSON/result +++ /dev/null @@ -1,10 +0,0 @@ -(from "ubuntu:14.04") -(label "maintainer" "Seongyeol Lim ") -(copy "." "/go/src/github.com/docker/docker") -(add "." "/") -(add "null" "/") -(copy "nullfile" "/tmp") -(add "vimrc" "/tmp") -(copy "bashrc" "/tmp") -(copy "test file" "/tmp") -(add "test file" "/tmp/test file") diff --git a/components/engine/builder/dockerfile/parser/testfiles/brimstone-consuldock/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/brimstone-consuldock/Dockerfile deleted file mode 100644 index 9c0952acb0..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/brimstone-consuldock/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -#escape=\ -FROM brimstone/ubuntu:14.04 - -LABEL maintainer brimstone@the.narro.ws - -# TORUN -v /var/run/docker.sock:/var/run/docker.sock - -ENV GOPATH /go - -# Set our command -ENTRYPOINT ["/usr/local/bin/consuldock"] - -# Install the packages we need, clean up after them and us -RUN apt-get update \ - && dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.clean \ - && apt-get install -y --no-install-recommends git golang ca-certificates \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists \ - - && go get -v github.com/brimstone/consuldock \ - && mv $GOPATH/bin/consuldock /usr/local/bin/consuldock \ - - && dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.dirty \ - && apt-get remove --purge -y $(diff /tmp/dpkg.clean /tmp/dpkg.dirty | awk '/^>/ {print $2}') \ - && rm /tmp/dpkg.* \ - && rm -rf $GOPATH diff --git a/components/engine/builder/dockerfile/parser/testfiles/brimstone-consuldock/result b/components/engine/builder/dockerfile/parser/testfiles/brimstone-consuldock/result deleted file mode 100644 index 3b45db62b4..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/brimstone-consuldock/result +++ /dev/null @@ -1,5 +0,0 @@ -(from "brimstone/ubuntu:14.04") -(label "maintainer" "brimstone@the.narro.ws") -(env "GOPATH" "/go") -(entrypoint "/usr/local/bin/consuldock") -(run "apt-get update \t&& dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.clean && apt-get install -y --no-install-recommends git golang ca-certificates && apt-get clean && rm -rf /var/lib/apt/lists \t&& go get -v github.com/brimstone/consuldock && mv $GOPATH/bin/consuldock /usr/local/bin/consuldock \t&& dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.dirty \t&& apt-get remove --purge -y $(diff /tmp/dpkg.clean /tmp/dpkg.dirty | awk '/^>/ {print $2}') \t&& rm /tmp/dpkg.* \t&& rm -rf $GOPATH") diff --git a/components/engine/builder/dockerfile/parser/testfiles/brimstone-docker-consul/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/brimstone-docker-consul/Dockerfile deleted file mode 100644 index 25ae352166..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/brimstone-docker-consul/Dockerfile +++ /dev/null @@ -1,52 +0,0 @@ -FROM brimstone/ubuntu:14.04 - -CMD [] - -ENTRYPOINT ["/usr/bin/consul", "agent", "-server", "-data-dir=/consul", "-client=0.0.0.0", "-ui-dir=/webui"] - -EXPOSE 8500 8600 8400 8301 8302 - -RUN apt-get update \ - && apt-get install -y unzip wget \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists - -RUN cd /tmp \ - && wget https://dl.bintray.com/mitchellh/consul/0.3.1_web_ui.zip \ - -O web_ui.zip \ - && unzip web_ui.zip \ - && mv dist /webui \ - && rm web_ui.zip - -RUN apt-get update \ - && dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.clean \ - && apt-get install -y --no-install-recommends unzip wget \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists \ - - && cd /tmp \ - && wget https://dl.bintray.com/mitchellh/consul/0.3.1_web_ui.zip \ - -O web_ui.zip \ - && unzip web_ui.zip \ - && mv dist /webui \ - && rm web_ui.zip \ - - && dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.dirty \ - && apt-get remove --purge -y $(diff /tmp/dpkg.clean /tmp/dpkg.dirty | awk '/^>/ {print $2}') \ - && rm /tmp/dpkg.* - -ENV GOPATH /go - -RUN apt-get update \ - && dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.clean \ - && apt-get install -y --no-install-recommends git golang ca-certificates build-essential \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists \ - - && go get -v github.com/hashicorp/consul \ - && mv $GOPATH/bin/consul /usr/bin/consul \ - - && dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.dirty \ - && apt-get remove --purge -y $(diff /tmp/dpkg.clean /tmp/dpkg.dirty | awk '/^>/ {print $2}') \ - && rm /tmp/dpkg.* \ - && rm -rf $GOPATH diff --git a/components/engine/builder/dockerfile/parser/testfiles/brimstone-docker-consul/result b/components/engine/builder/dockerfile/parser/testfiles/brimstone-docker-consul/result deleted file mode 100644 index 16492e516a..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/brimstone-docker-consul/result +++ /dev/null @@ -1,9 +0,0 @@ -(from "brimstone/ubuntu:14.04") -(cmd) -(entrypoint "/usr/bin/consul" "agent" "-server" "-data-dir=/consul" "-client=0.0.0.0" "-ui-dir=/webui") -(expose "8500" "8600" "8400" "8301" "8302") -(run "apt-get update && apt-get install -y unzip wget \t&& apt-get clean \t&& rm -rf /var/lib/apt/lists") -(run "cd /tmp && wget https://dl.bintray.com/mitchellh/consul/0.3.1_web_ui.zip -O web_ui.zip && unzip web_ui.zip && mv dist /webui && rm web_ui.zip") -(run "apt-get update \t&& dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.clean && apt-get install -y --no-install-recommends unzip wget && apt-get clean && rm -rf /var/lib/apt/lists && cd /tmp && wget https://dl.bintray.com/mitchellh/consul/0.3.1_web_ui.zip -O web_ui.zip && unzip web_ui.zip && mv dist /webui && rm web_ui.zip \t&& dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.dirty \t&& apt-get remove --purge -y $(diff /tmp/dpkg.clean /tmp/dpkg.dirty | awk '/^>/ {print $2}') \t&& rm /tmp/dpkg.*") -(env "GOPATH" "/go") -(run "apt-get update \t&& dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.clean && apt-get install -y --no-install-recommends git golang ca-certificates build-essential && apt-get clean && rm -rf /var/lib/apt/lists \t&& go get -v github.com/hashicorp/consul \t&& mv $GOPATH/bin/consul /usr/bin/consul \t&& dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.dirty \t&& apt-get remove --purge -y $(diff /tmp/dpkg.clean /tmp/dpkg.dirty | awk '/^>/ {print $2}') \t&& rm /tmp/dpkg.* \t&& rm -rf $GOPATH") diff --git a/components/engine/builder/dockerfile/parser/testfiles/continue-at-eof/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/continue-at-eof/Dockerfile deleted file mode 100644 index a8ec369ad1..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/continue-at-eof/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM alpine:3.5 - -RUN something \ \ No newline at end of file diff --git a/components/engine/builder/dockerfile/parser/testfiles/continue-at-eof/result b/components/engine/builder/dockerfile/parser/testfiles/continue-at-eof/result deleted file mode 100644 index 14e4f09321..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/continue-at-eof/result +++ /dev/null @@ -1,2 +0,0 @@ -(from "alpine:3.5") -(run "something") diff --git a/components/engine/builder/dockerfile/parser/testfiles/continueIndent/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/continueIndent/Dockerfile deleted file mode 100644 index 42b324e77b..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/continueIndent/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -FROM ubuntu:14.04 - -RUN echo hello\ - world\ - goodnight \ - moon\ - light\ -ning -RUN echo hello \ - world -RUN echo hello \ -world -RUN echo hello \ -goodbye\ -frog -RUN echo hello \ -world -RUN echo hi \ - \ - world \ -\ - good\ -\ -night -RUN echo goodbye\ -frog -RUN echo good\ -bye\ -frog - -RUN echo hello \ -# this is a comment - -# this is a comment with a blank line surrounding it - -this is some more useful stuff diff --git a/components/engine/builder/dockerfile/parser/testfiles/continueIndent/result b/components/engine/builder/dockerfile/parser/testfiles/continueIndent/result deleted file mode 100644 index 268ae073c8..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/continueIndent/result +++ /dev/null @@ -1,10 +0,0 @@ -(from "ubuntu:14.04") -(run "echo hello world goodnight moon lightning") -(run "echo hello world") -(run "echo hello world") -(run "echo hello goodbyefrog") -(run "echo hello world") -(run "echo hi world goodnight") -(run "echo goodbyefrog") -(run "echo goodbyefrog") -(run "echo hello this is some more useful stuff") diff --git a/components/engine/builder/dockerfile/parser/testfiles/cpuguy83-nagios/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/cpuguy83-nagios/Dockerfile deleted file mode 100644 index 8ccb71a578..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/cpuguy83-nagios/Dockerfile +++ /dev/null @@ -1,54 +0,0 @@ -FROM cpuguy83/ubuntu -ENV NAGIOS_HOME /opt/nagios -ENV NAGIOS_USER nagios -ENV NAGIOS_GROUP nagios -ENV NAGIOS_CMDUSER nagios -ENV NAGIOS_CMDGROUP nagios -ENV NAGIOSADMIN_USER nagiosadmin -ENV NAGIOSADMIN_PASS nagios -ENV APACHE_RUN_USER nagios -ENV APACHE_RUN_GROUP nagios -ENV NAGIOS_TIMEZONE UTC - -RUN sed -i 's/universe/universe multiverse/' /etc/apt/sources.list -RUN apt-get update && apt-get install -y iputils-ping netcat build-essential snmp snmpd snmp-mibs-downloader php5-cli apache2 libapache2-mod-php5 runit bc postfix bsd-mailx -RUN ( egrep -i "^${NAGIOS_GROUP}" /etc/group || groupadd $NAGIOS_GROUP ) && ( egrep -i "^${NAGIOS_CMDGROUP}" /etc/group || groupadd $NAGIOS_CMDGROUP ) -RUN ( id -u $NAGIOS_USER || useradd --system $NAGIOS_USER -g $NAGIOS_GROUP -d $NAGIOS_HOME ) && ( id -u $NAGIOS_CMDUSER || useradd --system -d $NAGIOS_HOME -g $NAGIOS_CMDGROUP $NAGIOS_CMDUSER ) - -ADD http://downloads.sourceforge.net/project/nagios/nagios-3.x/nagios-3.5.1/nagios-3.5.1.tar.gz?r=http%3A%2F%2Fwww.nagios.org%2Fdownload%2Fcore%2Fthanks%2F%3Ft%3D1398863696&ts=1398863718&use_mirror=superb-dca3 /tmp/nagios.tar.gz -RUN cd /tmp && tar -zxvf nagios.tar.gz && cd nagios && ./configure --prefix=${NAGIOS_HOME} --exec-prefix=${NAGIOS_HOME} --enable-event-broker --with-nagios-command-user=${NAGIOS_CMDUSER} --with-command-group=${NAGIOS_CMDGROUP} --with-nagios-user=${NAGIOS_USER} --with-nagios-group=${NAGIOS_GROUP} && make all && make install && make install-config && make install-commandmode && cp sample-config/httpd.conf /etc/apache2/conf.d/nagios.conf -ADD http://www.nagios-plugins.org/download/nagios-plugins-1.5.tar.gz /tmp/ -RUN cd /tmp && tar -zxvf nagios-plugins-1.5.tar.gz && cd nagios-plugins-1.5 && ./configure --prefix=${NAGIOS_HOME} && make && make install - -RUN sed -i.bak 's/.*\=www\-data//g' /etc/apache2/envvars -RUN export DOC_ROOT="DocumentRoot $(echo $NAGIOS_HOME/share)"; sed -i "s,DocumentRoot.*,$DOC_ROOT," /etc/apache2/sites-enabled/000-default - -RUN ln -s ${NAGIOS_HOME}/bin/nagios /usr/local/bin/nagios && mkdir -p /usr/share/snmp/mibs && chmod 0755 /usr/share/snmp/mibs && touch /usr/share/snmp/mibs/.foo - -RUN echo "use_timezone=$NAGIOS_TIMEZONE" >> ${NAGIOS_HOME}/etc/nagios.cfg && echo "SetEnv TZ \"${NAGIOS_TIMEZONE}\"" >> /etc/apache2/conf.d/nagios.conf - -RUN mkdir -p ${NAGIOS_HOME}/etc/conf.d && mkdir -p ${NAGIOS_HOME}/etc/monitor && ln -s /usr/share/snmp/mibs ${NAGIOS_HOME}/libexec/mibs -RUN echo "cfg_dir=${NAGIOS_HOME}/etc/conf.d" >> ${NAGIOS_HOME}/etc/nagios.cfg -RUN echo "cfg_dir=${NAGIOS_HOME}/etc/monitor" >> ${NAGIOS_HOME}/etc/nagios.cfg -RUN download-mibs && echo "mibs +ALL" > /etc/snmp/snmp.conf - -RUN sed -i 's,/bin/mail,/usr/bin/mail,' /opt/nagios/etc/objects/commands.cfg && \ - sed -i 's,/usr/usr,/usr,' /opt/nagios/etc/objects/commands.cfg -RUN cp /etc/services /var/spool/postfix/etc/ - -RUN mkdir -p /etc/sv/nagios && mkdir -p /etc/sv/apache && rm -rf /etc/sv/getty-5 && mkdir -p /etc/sv/postfix -ADD nagios.init /etc/sv/nagios/run -ADD apache.init /etc/sv/apache/run -ADD postfix.init /etc/sv/postfix/run -ADD postfix.stop /etc/sv/postfix/finish - -ADD start.sh /usr/local/bin/start_nagios - -ENV APACHE_LOCK_DIR /var/run -ENV APACHE_LOG_DIR /var/log/apache2 - -EXPOSE 80 - -VOLUME ["/opt/nagios/var", "/opt/nagios/etc", "/opt/nagios/libexec", "/var/log/apache2", "/usr/share/snmp/mibs"] - -CMD ["/usr/local/bin/start_nagios"] diff --git a/components/engine/builder/dockerfile/parser/testfiles/cpuguy83-nagios/result b/components/engine/builder/dockerfile/parser/testfiles/cpuguy83-nagios/result deleted file mode 100644 index 25dd3ddfe5..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/cpuguy83-nagios/result +++ /dev/null @@ -1,40 +0,0 @@ -(from "cpuguy83/ubuntu") -(env "NAGIOS_HOME" "/opt/nagios") -(env "NAGIOS_USER" "nagios") -(env "NAGIOS_GROUP" "nagios") -(env "NAGIOS_CMDUSER" "nagios") -(env "NAGIOS_CMDGROUP" "nagios") -(env "NAGIOSADMIN_USER" "nagiosadmin") -(env "NAGIOSADMIN_PASS" "nagios") -(env "APACHE_RUN_USER" "nagios") -(env "APACHE_RUN_GROUP" "nagios") -(env "NAGIOS_TIMEZONE" "UTC") -(run "sed -i 's/universe/universe multiverse/' /etc/apt/sources.list") -(run "apt-get update && apt-get install -y iputils-ping netcat build-essential snmp snmpd snmp-mibs-downloader php5-cli apache2 libapache2-mod-php5 runit bc postfix bsd-mailx") -(run "( egrep -i \"^${NAGIOS_GROUP}\" /etc/group || groupadd $NAGIOS_GROUP ) && ( egrep -i \"^${NAGIOS_CMDGROUP}\" /etc/group || groupadd $NAGIOS_CMDGROUP )") -(run "( id -u $NAGIOS_USER || useradd --system $NAGIOS_USER -g $NAGIOS_GROUP -d $NAGIOS_HOME ) && ( id -u $NAGIOS_CMDUSER || useradd --system -d $NAGIOS_HOME -g $NAGIOS_CMDGROUP $NAGIOS_CMDUSER )") -(add "http://downloads.sourceforge.net/project/nagios/nagios-3.x/nagios-3.5.1/nagios-3.5.1.tar.gz?r=http%3A%2F%2Fwww.nagios.org%2Fdownload%2Fcore%2Fthanks%2F%3Ft%3D1398863696&ts=1398863718&use_mirror=superb-dca3" "/tmp/nagios.tar.gz") -(run "cd /tmp && tar -zxvf nagios.tar.gz && cd nagios && ./configure --prefix=${NAGIOS_HOME} --exec-prefix=${NAGIOS_HOME} --enable-event-broker --with-nagios-command-user=${NAGIOS_CMDUSER} --with-command-group=${NAGIOS_CMDGROUP} --with-nagios-user=${NAGIOS_USER} --with-nagios-group=${NAGIOS_GROUP} && make all && make install && make install-config && make install-commandmode && cp sample-config/httpd.conf /etc/apache2/conf.d/nagios.conf") -(add "http://www.nagios-plugins.org/download/nagios-plugins-1.5.tar.gz" "/tmp/") -(run "cd /tmp && tar -zxvf nagios-plugins-1.5.tar.gz && cd nagios-plugins-1.5 && ./configure --prefix=${NAGIOS_HOME} && make && make install") -(run "sed -i.bak 's/.*\\=www\\-data//g' /etc/apache2/envvars") -(run "export DOC_ROOT=\"DocumentRoot $(echo $NAGIOS_HOME/share)\"; sed -i \"s,DocumentRoot.*,$DOC_ROOT,\" /etc/apache2/sites-enabled/000-default") -(run "ln -s ${NAGIOS_HOME}/bin/nagios /usr/local/bin/nagios && mkdir -p /usr/share/snmp/mibs && chmod 0755 /usr/share/snmp/mibs && touch /usr/share/snmp/mibs/.foo") -(run "echo \"use_timezone=$NAGIOS_TIMEZONE\" >> ${NAGIOS_HOME}/etc/nagios.cfg && echo \"SetEnv TZ \\\"${NAGIOS_TIMEZONE}\\\"\" >> /etc/apache2/conf.d/nagios.conf") -(run "mkdir -p ${NAGIOS_HOME}/etc/conf.d && mkdir -p ${NAGIOS_HOME}/etc/monitor && ln -s /usr/share/snmp/mibs ${NAGIOS_HOME}/libexec/mibs") -(run "echo \"cfg_dir=${NAGIOS_HOME}/etc/conf.d\" >> ${NAGIOS_HOME}/etc/nagios.cfg") -(run "echo \"cfg_dir=${NAGIOS_HOME}/etc/monitor\" >> ${NAGIOS_HOME}/etc/nagios.cfg") -(run "download-mibs && echo \"mibs +ALL\" > /etc/snmp/snmp.conf") -(run "sed -i 's,/bin/mail,/usr/bin/mail,' /opt/nagios/etc/objects/commands.cfg && sed -i 's,/usr/usr,/usr,' /opt/nagios/etc/objects/commands.cfg") -(run "cp /etc/services /var/spool/postfix/etc/") -(run "mkdir -p /etc/sv/nagios && mkdir -p /etc/sv/apache && rm -rf /etc/sv/getty-5 && mkdir -p /etc/sv/postfix") -(add "nagios.init" "/etc/sv/nagios/run") -(add "apache.init" "/etc/sv/apache/run") -(add "postfix.init" "/etc/sv/postfix/run") -(add "postfix.stop" "/etc/sv/postfix/finish") -(add "start.sh" "/usr/local/bin/start_nagios") -(env "APACHE_LOCK_DIR" "/var/run") -(env "APACHE_LOG_DIR" "/var/log/apache2") -(expose "80") -(volume "/opt/nagios/var" "/opt/nagios/etc" "/opt/nagios/libexec" "/var/log/apache2" "/usr/share/snmp/mibs") -(cmd "/usr/local/bin/start_nagios") diff --git a/components/engine/builder/dockerfile/parser/testfiles/docker/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/docker/Dockerfile deleted file mode 100644 index cd327aa499..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/docker/Dockerfile +++ /dev/null @@ -1,94 +0,0 @@ -# This file describes the standard way to build Docker, using docker -# -# Usage: -# -# # Assemble the full dev environment. This is slow the first time. -# docker build -t docker . -# -# # Mount your source in an interactive container for quick testing: -# docker run -v `pwd`:/go/src/github.com/docker/docker --privileged -i -t docker bash -# -# # Run the test suite: -# docker run --privileged docker hack/make.sh test-unit test-integration test-docker-py -# -# Note: AppArmor used to mess with privileged mode, but this is no longer -# the case. Therefore, you don't have to disable it anymore. -# - -FROM ubuntu:14.04 -LABEL maintainer Tianon Gravi (@tianon) - -# Packaged dependencies -RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -yq \ - apt-utils \ - aufs-tools \ - automake \ - btrfs-tools \ - build-essential \ - curl \ - dpkg-sig \ - git \ - iptables \ - libapparmor-dev \ - libcap-dev \ - mercurial \ - pandoc \ - parallel \ - reprepro \ - ruby1.9.1 \ - ruby1.9.1-dev \ - s3cmd=1.1.0* \ - --no-install-recommends - -# Get lvm2 source for compiling statically -RUN git clone --no-checkout https://git.fedorahosted.org/git/lvm2.git /usr/local/lvm2 && cd /usr/local/lvm2 && git checkout -q v2_02_103 -# see https://git.fedorahosted.org/cgit/lvm2.git/refs/tags for release tags -# note: we don't use "git clone -b" above because it then spews big nasty warnings about 'detached HEAD' state that we can't silence as easily as we can silence them using "git checkout" directly - -# Compile and install lvm2 -RUN cd /usr/local/lvm2 && ./configure --enable-static_link && make device-mapper && make install_device-mapper -# see https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL - -# Install Go -RUN curl -sSL https://golang.org/dl/go1.3.src.tar.gz | tar -v -C /usr/local -xz -ENV PATH /usr/local/go/bin:$PATH -ENV GOPATH /go:/go/src/github.com/docker/docker/vendor -RUN cd /usr/local/go/src && ./make.bash --no-clean 2>&1 - -# Compile Go for cross compilation -ENV DOCKER_CROSSPLATFORMS \ - linux/386 linux/arm \ - darwin/amd64 darwin/386 \ - freebsd/amd64 freebsd/386 freebsd/arm -# (set an explicit GOARM of 5 for maximum compatibility) -ENV GOARM 5 -RUN cd /usr/local/go/src && bash -xc 'for platform in $DOCKER_CROSSPLATFORMS; do GOOS=${platform%/*} GOARCH=${platform##*/} ./make.bash --no-clean 2>&1; done' - -# Grab Go's cover tool for dead-simple code coverage testing -RUN go get golang.org/x/tools/cmd/cover - -# TODO replace FPM with some very minimal debhelper stuff -RUN gem install --no-rdoc --no-ri fpm --version 1.0.2 - -# Get the "busybox" image source so we can build locally instead of pulling -RUN git clone -b buildroot-2014.02 https://github.com/jpetazzo/docker-busybox.git /docker-busybox - -# Setup s3cmd config -RUN /bin/echo -e '[default]\naccess_key=$AWS_ACCESS_KEY\nsecret_key=$AWS_SECRET_KEY' > /.s3cfg - -# Set user.email so crosbymichael's in-container merge commits go smoothly -RUN git config --global user.email 'docker-dummy@example.com' - -# Add an unprivileged user to be used for tests which need it -RUN groupadd -r docker -RUN useradd --create-home --gid docker unprivilegeduser - -VOLUME /var/lib/docker -WORKDIR /go/src/github.com/docker/docker -ENV DOCKER_BUILDTAGS apparmor selinux - -# Wrap all commands in the "docker-in-docker" script to allow nested containers -ENTRYPOINT ["hack/dind"] - -# Upload docker source -COPY . /go/src/github.com/docker/docker diff --git a/components/engine/builder/dockerfile/parser/testfiles/docker/result b/components/engine/builder/dockerfile/parser/testfiles/docker/result deleted file mode 100644 index 0c2f229916..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/docker/result +++ /dev/null @@ -1,24 +0,0 @@ -(from "ubuntu:14.04") -(label "maintainer" "Tianon Gravi (@tianon)") -(run "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -yq \tapt-utils \taufs-tools \tautomake \tbtrfs-tools \tbuild-essential \tcurl \tdpkg-sig \tgit \tiptables \tlibapparmor-dev \tlibcap-dev \tmercurial \tpandoc \tparallel \treprepro \truby1.9.1 \truby1.9.1-dev \ts3cmd=1.1.0* \t--no-install-recommends") -(run "git clone --no-checkout https://git.fedorahosted.org/git/lvm2.git /usr/local/lvm2 && cd /usr/local/lvm2 && git checkout -q v2_02_103") -(run "cd /usr/local/lvm2 && ./configure --enable-static_link && make device-mapper && make install_device-mapper") -(run "curl -sSL https://golang.org/dl/go1.3.src.tar.gz | tar -v -C /usr/local -xz") -(env "PATH" "/usr/local/go/bin:$PATH") -(env "GOPATH" "/go:/go/src/github.com/docker/docker/vendor") -(run "cd /usr/local/go/src && ./make.bash --no-clean 2>&1") -(env "DOCKER_CROSSPLATFORMS" "linux/386 linux/arm \tdarwin/amd64 darwin/386 \tfreebsd/amd64 freebsd/386 freebsd/arm") -(env "GOARM" "5") -(run "cd /usr/local/go/src && bash -xc 'for platform in $DOCKER_CROSSPLATFORMS; do GOOS=${platform%/*} GOARCH=${platform##*/} ./make.bash --no-clean 2>&1; done'") -(run "go get golang.org/x/tools/cmd/cover") -(run "gem install --no-rdoc --no-ri fpm --version 1.0.2") -(run "git clone -b buildroot-2014.02 https://github.com/jpetazzo/docker-busybox.git /docker-busybox") -(run "/bin/echo -e '[default]\\naccess_key=$AWS_ACCESS_KEY\\nsecret_key=$AWS_SECRET_KEY' > /.s3cfg") -(run "git config --global user.email 'docker-dummy@example.com'") -(run "groupadd -r docker") -(run "useradd --create-home --gid docker unprivilegeduser") -(volume "/var/lib/docker") -(workdir "/go/src/github.com/docker/docker") -(env "DOCKER_BUILDTAGS" "apparmor selinux") -(entrypoint "hack/dind") -(copy "." "/go/src/github.com/docker/docker") diff --git a/components/engine/builder/dockerfile/parser/testfiles/env/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/env/Dockerfile deleted file mode 100644 index 08fa18acec..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/env/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM ubuntu -ENV name value -ENV name=value -ENV name=value name2=value2 -ENV name="value value1" -ENV name=value\ value2 -ENV name="value'quote space'value2" -ENV name='value"double quote"value2' -ENV name=value\ value2 name2=value2\ value3 -ENV name="a\"b" -ENV name="a\'b" -ENV name='a\'b' -ENV name='a\'b'' -ENV name='a\"b' -ENV name="''" -# don't put anything after the next line - it must be the last line of the -# Dockerfile and it must end with \ -ENV name=value \ - name1=value1 \ - name2="value2a \ - value2b" \ - name3="value3a\n\"value3b\"" \ - name4="value4a\\nvalue4b" \ diff --git a/components/engine/builder/dockerfile/parser/testfiles/env/result b/components/engine/builder/dockerfile/parser/testfiles/env/result deleted file mode 100644 index ba0a6dd7cb..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/env/result +++ /dev/null @@ -1,16 +0,0 @@ -(from "ubuntu") -(env "name" "value") -(env "name" "value") -(env "name" "value" "name2" "value2") -(env "name" "\"value value1\"") -(env "name" "value\\ value2") -(env "name" "\"value'quote space'value2\"") -(env "name" "'value\"double quote\"value2'") -(env "name" "value\\ value2" "name2" "value2\\ value3") -(env "name" "\"a\\\"b\"") -(env "name" "\"a\\'b\"") -(env "name" "'a\\'b'") -(env "name" "'a\\'b''") -(env "name" "'a\\\"b'") -(env "name" "\"''\"") -(env "name" "value" "name1" "value1" "name2" "\"value2a value2b\"" "name3" "\"value3a\\n\\\"value3b\\\"\"" "name4" "\"value4a\\\\nvalue4b\"") diff --git a/components/engine/builder/dockerfile/parser/testfiles/escape-after-comment/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/escape-after-comment/Dockerfile deleted file mode 100644 index 18e9a474f2..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/escape-after-comment/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -# Comment here. Should not be looking for the following parser directive. -# Hence the following line will be ignored, and the subsequent backslash -# continuation will be the default. -# escape = ` - -FROM image -LABEL maintainer foo@bar.com -ENV GOPATH \ -\go \ No newline at end of file diff --git a/components/engine/builder/dockerfile/parser/testfiles/escape-after-comment/result b/components/engine/builder/dockerfile/parser/testfiles/escape-after-comment/result deleted file mode 100644 index 9ab119c414..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/escape-after-comment/result +++ /dev/null @@ -1,3 +0,0 @@ -(from "image") -(label "maintainer" "foo@bar.com") -(env "GOPATH" "\\go") diff --git a/components/engine/builder/dockerfile/parser/testfiles/escape-nonewline/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/escape-nonewline/Dockerfile deleted file mode 100644 index 366ee3c36b..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/escape-nonewline/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -# escape = `` -# There is no white space line after the directives. This still succeeds, but goes -# against best practices. -FROM image -LABEL maintainer foo@bar.com -ENV GOPATH ` -\go \ No newline at end of file diff --git a/components/engine/builder/dockerfile/parser/testfiles/escape-nonewline/result b/components/engine/builder/dockerfile/parser/testfiles/escape-nonewline/result deleted file mode 100644 index 9ab119c414..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/escape-nonewline/result +++ /dev/null @@ -1,3 +0,0 @@ -(from "image") -(label "maintainer" "foo@bar.com") -(env "GOPATH" "\\go") diff --git a/components/engine/builder/dockerfile/parser/testfiles/escape/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/escape/Dockerfile deleted file mode 100644 index a515af152d..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/escape/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -#escape = ` - -FROM image -LABEL maintainer foo@bar.com -ENV GOPATH ` -\go \ No newline at end of file diff --git a/components/engine/builder/dockerfile/parser/testfiles/escape/result b/components/engine/builder/dockerfile/parser/testfiles/escape/result deleted file mode 100644 index 9ab119c414..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/escape/result +++ /dev/null @@ -1,3 +0,0 @@ -(from "image") -(label "maintainer" "foo@bar.com") -(env "GOPATH" "\\go") diff --git a/components/engine/builder/dockerfile/parser/testfiles/escapes/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/escapes/Dockerfile deleted file mode 100644 index 03062394ae..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/escapes/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM ubuntu:14.04 -LABEL maintainer Erik \\Hollensbe \" - -RUN apt-get \update && \ - apt-get \"install znc -y -ADD \conf\\" /.znc - -RUN foo \ - -bar \ - -baz - -CMD [ "\/usr\\\"/bin/znc", "-f", "-r" ] diff --git a/components/engine/builder/dockerfile/parser/testfiles/escapes/result b/components/engine/builder/dockerfile/parser/testfiles/escapes/result deleted file mode 100644 index 98e3e3b737..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/escapes/result +++ /dev/null @@ -1,6 +0,0 @@ -(from "ubuntu:14.04") -(label "maintainer" "Erik \\\\Hollensbe \\\"") -(run "apt-get \\update && apt-get \\\"install znc -y") -(add "\\conf\\\\\"" "/.znc") -(run "foo bar baz") -(cmd "/usr\\\"/bin/znc" "-f" "-r") diff --git a/components/engine/builder/dockerfile/parser/testfiles/flags/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/flags/Dockerfile deleted file mode 100644 index 2418e0f069..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/flags/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM scratch -COPY foo /tmp/ -COPY --user=me foo /tmp/ -COPY --doit=true foo /tmp/ -COPY --user=me --doit=true foo /tmp/ -COPY --doit=true -- foo /tmp/ -COPY -- foo /tmp/ -CMD --doit [ "a", "b" ] -CMD --doit=true -- [ "a", "b" ] -CMD --doit -- [ ] diff --git a/components/engine/builder/dockerfile/parser/testfiles/flags/result b/components/engine/builder/dockerfile/parser/testfiles/flags/result deleted file mode 100644 index 4578f4cba4..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/flags/result +++ /dev/null @@ -1,10 +0,0 @@ -(from "scratch") -(copy "foo" "/tmp/") -(copy ["--user=me"] "foo" "/tmp/") -(copy ["--doit=true"] "foo" "/tmp/") -(copy ["--user=me" "--doit=true"] "foo" "/tmp/") -(copy ["--doit=true"] "foo" "/tmp/") -(copy "foo" "/tmp/") -(cmd ["--doit"] "a" "b") -(cmd ["--doit=true"] "a" "b") -(cmd ["--doit"]) diff --git a/components/engine/builder/dockerfile/parser/testfiles/health/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/health/Dockerfile deleted file mode 100644 index 081e442882..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/health/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM debian -ADD check.sh main.sh /app/ -CMD /app/main.sh -HEALTHCHECK -HEALTHCHECK --interval=5s --timeout=3s --retries=3 \ - CMD /app/check.sh --quiet -HEALTHCHECK CMD -HEALTHCHECK CMD a b -HEALTHCHECK --timeout=3s CMD ["foo"] -HEALTHCHECK CONNECT TCP 7000 diff --git a/components/engine/builder/dockerfile/parser/testfiles/health/result b/components/engine/builder/dockerfile/parser/testfiles/health/result deleted file mode 100644 index 092924f88c..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/health/result +++ /dev/null @@ -1,9 +0,0 @@ -(from "debian") -(add "check.sh" "main.sh" "/app/") -(cmd "/app/main.sh") -(healthcheck) -(healthcheck ["--interval=5s" "--timeout=3s" "--retries=3"] "CMD" "/app/check.sh --quiet") -(healthcheck "CMD") -(healthcheck "CMD" "a b") -(healthcheck ["--timeout=3s"] "CMD" "foo") -(healthcheck "CONNECT" "TCP 7000") diff --git a/components/engine/builder/dockerfile/parser/testfiles/influxdb/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/influxdb/Dockerfile deleted file mode 100644 index 587fb9b54b..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/influxdb/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM ubuntu:14.04 - -RUN apt-get update && apt-get install wget -y -RUN wget http://s3.amazonaws.com/influxdb/influxdb_latest_amd64.deb -RUN dpkg -i influxdb_latest_amd64.deb -RUN rm -r /opt/influxdb/shared - -VOLUME /opt/influxdb/shared - -CMD /usr/bin/influxdb --pidfile /var/run/influxdb.pid -config /opt/influxdb/shared/config.toml - -EXPOSE 8083 -EXPOSE 8086 -EXPOSE 8090 -EXPOSE 8099 diff --git a/components/engine/builder/dockerfile/parser/testfiles/influxdb/result b/components/engine/builder/dockerfile/parser/testfiles/influxdb/result deleted file mode 100644 index 0998e87e63..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/influxdb/result +++ /dev/null @@ -1,11 +0,0 @@ -(from "ubuntu:14.04") -(run "apt-get update && apt-get install wget -y") -(run "wget http://s3.amazonaws.com/influxdb/influxdb_latest_amd64.deb") -(run "dpkg -i influxdb_latest_amd64.deb") -(run "rm -r /opt/influxdb/shared") -(volume "/opt/influxdb/shared") -(cmd "/usr/bin/influxdb --pidfile /var/run/influxdb.pid -config /opt/influxdb/shared/config.toml") -(expose "8083") -(expose "8086") -(expose "8090") -(expose "8099") diff --git a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string-double/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string-double/Dockerfile deleted file mode 100644 index 39fe27d99c..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string-double/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -CMD "[\"echo\", \"Phew, I just managed to escaped those double quotes\"]" diff --git a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string-double/result b/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string-double/result deleted file mode 100644 index afc220c2a7..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string-double/result +++ /dev/null @@ -1 +0,0 @@ -(cmd "\"[\\\"echo\\\", \\\"Phew, I just managed to escaped those double quotes\\\"]\"") diff --git a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string/Dockerfile deleted file mode 100644 index eaae081a06..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -CMD '["echo", "Well, JSON in a string is JSON too?"]' diff --git a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string/result b/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string/result deleted file mode 100644 index 484804e2b2..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-json-inside-string/result +++ /dev/null @@ -1 +0,0 @@ -(cmd "'[\"echo\", \"Well, JSON in a string is JSON too?\"]'") diff --git a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-single-quotes/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-single-quotes/Dockerfile deleted file mode 100644 index c3ac63c07a..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-single-quotes/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -CMD ['echo','single quotes are invalid JSON'] diff --git a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-single-quotes/result b/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-single-quotes/result deleted file mode 100644 index 6147891207..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-single-quotes/result +++ /dev/null @@ -1 +0,0 @@ -(cmd "['echo','single quotes are invalid JSON']") diff --git a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-bracket/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-bracket/Dockerfile deleted file mode 100644 index 5fd4afa522..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-bracket/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -CMD ["echo", "Please, close the brackets when you're done" diff --git a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-bracket/result b/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-bracket/result deleted file mode 100644 index 1ffbb8ff85..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-bracket/result +++ /dev/null @@ -1 +0,0 @@ -(cmd "[\"echo\", \"Please, close the brackets when you're done\"") diff --git a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-string/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-string/Dockerfile deleted file mode 100644 index 30cc4bb48f..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-string/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -CMD ["echo", "look ma, no quote!] diff --git a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-string/result b/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-string/result deleted file mode 100644 index 32048147b5..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/jeztah-invalid-json-unterminated-string/result +++ /dev/null @@ -1 +0,0 @@ -(cmd "[\"echo\", \"look ma, no quote!]") diff --git a/components/engine/builder/dockerfile/parser/testfiles/json/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/json/Dockerfile deleted file mode 100644 index a586917110..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/json/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -CMD [] -CMD [""] -CMD ["a"] -CMD ["a","b"] -CMD [ "a", "b" ] -CMD [ "a", "b" ] -CMD [ "a", "b" ] -CMD ["abc 123", "♥", "☃", "\" \\ \/ \b \f \n \r \t \u0000"] diff --git a/components/engine/builder/dockerfile/parser/testfiles/json/result b/components/engine/builder/dockerfile/parser/testfiles/json/result deleted file mode 100644 index c6553e6e1a..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/json/result +++ /dev/null @@ -1,8 +0,0 @@ -(cmd) -(cmd "") -(cmd "a") -(cmd "a" "b") -(cmd "a" "b") -(cmd "a" "b") -(cmd "a" "b") -(cmd "abc 123" "♥" "☃" "\" \\ / \b \f \n \r \t \x00") diff --git a/components/engine/builder/dockerfile/parser/testfiles/kartar-entrypoint-oddities/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/kartar-entrypoint-oddities/Dockerfile deleted file mode 100644 index 728ec9a787..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/kartar-entrypoint-oddities/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM ubuntu:14.04 -LABEL maintainer James Turnbull "james@example.com" -ENV REFRESHED_AT 2014-06-01 -RUN apt-get update -RUN apt-get -y install redis-server redis-tools -EXPOSE 6379 -ENTRYPOINT [ "/usr/bin/redis-server" ] diff --git a/components/engine/builder/dockerfile/parser/testfiles/kartar-entrypoint-oddities/result b/components/engine/builder/dockerfile/parser/testfiles/kartar-entrypoint-oddities/result deleted file mode 100644 index e774bc4f97..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/kartar-entrypoint-oddities/result +++ /dev/null @@ -1,7 +0,0 @@ -(from "ubuntu:14.04") -(label "maintainer" "James Turnbull \"james@example.com\"") -(env "REFRESHED_AT" "2014-06-01") -(run "apt-get update") -(run "apt-get -y install redis-server redis-tools") -(expose "6379") -(entrypoint "/usr/bin/redis-server") diff --git a/components/engine/builder/dockerfile/parser/testfiles/lk4d4-the-edge-case-generator/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/lk4d4-the-edge-case-generator/Dockerfile deleted file mode 100644 index 27f28cb921..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/lk4d4-the-edge-case-generator/Dockerfile +++ /dev/null @@ -1,48 +0,0 @@ -FROM busybox:buildroot-2014.02 - -LABEL maintainer docker - -ONBUILD RUN ["echo", "test"] -ONBUILD RUN echo test -ONBUILD COPY . / - - -# RUN Commands \ -# linebreak in comment \ -RUN ["ls", "-la"] -RUN ["echo", "'1234'"] -RUN echo "1234" -RUN echo 1234 -RUN echo '1234' && \ - echo "456" && \ - echo 789 -RUN sh -c 'echo root:testpass \ - > /tmp/passwd' -RUN mkdir -p /test /test2 /test3/test - -# ENV \ -ENV SCUBA 1 DUBA 3 -ENV SCUBA "1 DUBA 3" - -# CMD \ -CMD ["echo", "test"] -CMD echo test -CMD echo "test" -CMD echo 'test' -CMD echo 'test' | wc - - -#EXPOSE\ -EXPOSE 3000 -EXPOSE 9000 5000 6000 - -USER docker -USER docker:root - -VOLUME ["/test"] -VOLUME ["/test", "/test2"] -VOLUME /test3 - -WORKDIR /test - -ADD . / -COPY . copy diff --git a/components/engine/builder/dockerfile/parser/testfiles/lk4d4-the-edge-case-generator/result b/components/engine/builder/dockerfile/parser/testfiles/lk4d4-the-edge-case-generator/result deleted file mode 100644 index 8a499ff948..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/lk4d4-the-edge-case-generator/result +++ /dev/null @@ -1,29 +0,0 @@ -(from "busybox:buildroot-2014.02") -(label "maintainer" "docker ") -(onbuild (run "echo" "test")) -(onbuild (run "echo test")) -(onbuild (copy "." "/")) -(run "ls" "-la") -(run "echo" "'1234'") -(run "echo \"1234\"") -(run "echo 1234") -(run "echo '1234' && echo \"456\" && echo 789") -(run "sh -c 'echo root:testpass > /tmp/passwd'") -(run "mkdir -p /test /test2 /test3/test") -(env "SCUBA" "1 DUBA 3") -(env "SCUBA" "\"1 DUBA 3\"") -(cmd "echo" "test") -(cmd "echo test") -(cmd "echo \"test\"") -(cmd "echo 'test'") -(cmd "echo 'test' | wc -") -(expose "3000") -(expose "9000" "5000" "6000") -(user "docker") -(user "docker:root") -(volume "/test") -(volume "/test" "/test2") -(volume "/test3") -(workdir "/test") -(add "." "/") -(copy "." "copy") diff --git a/components/engine/builder/dockerfile/parser/testfiles/mail/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/mail/Dockerfile deleted file mode 100644 index f64c1168c1..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/mail/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM ubuntu:14.04 - -RUN apt-get update -qy && apt-get install mutt offlineimap vim-nox abook elinks curl tmux cron zsh -y -ADD .muttrc / -ADD .offlineimaprc / -ADD .tmux.conf / -ADD mutt /.mutt -ADD vim /.vim -ADD vimrc /.vimrc -ADD crontab /etc/crontab -RUN chmod 644 /etc/crontab -RUN mkdir /Mail -RUN mkdir /.offlineimap -RUN echo "export TERM=screen-256color" >/.zshenv - -CMD setsid cron; tmux -2 diff --git a/components/engine/builder/dockerfile/parser/testfiles/mail/result b/components/engine/builder/dockerfile/parser/testfiles/mail/result deleted file mode 100644 index a0efcf04b6..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/mail/result +++ /dev/null @@ -1,14 +0,0 @@ -(from "ubuntu:14.04") -(run "apt-get update -qy && apt-get install mutt offlineimap vim-nox abook elinks curl tmux cron zsh -y") -(add ".muttrc" "/") -(add ".offlineimaprc" "/") -(add ".tmux.conf" "/") -(add "mutt" "/.mutt") -(add "vim" "/.vim") -(add "vimrc" "/.vimrc") -(add "crontab" "/etc/crontab") -(run "chmod 644 /etc/crontab") -(run "mkdir /Mail") -(run "mkdir /.offlineimap") -(run "echo \"export TERM=screen-256color\" >/.zshenv") -(cmd "setsid cron; tmux -2") diff --git a/components/engine/builder/dockerfile/parser/testfiles/multiple-volumes/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/multiple-volumes/Dockerfile deleted file mode 100644 index 57bb5976a3..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/multiple-volumes/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM foo - -VOLUME /opt/nagios/var /opt/nagios/etc /opt/nagios/libexec /var/log/apache2 /usr/share/snmp/mibs diff --git a/components/engine/builder/dockerfile/parser/testfiles/multiple-volumes/result b/components/engine/builder/dockerfile/parser/testfiles/multiple-volumes/result deleted file mode 100644 index 18dbdeeaa0..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/multiple-volumes/result +++ /dev/null @@ -1,2 +0,0 @@ -(from "foo") -(volume "/opt/nagios/var" "/opt/nagios/etc" "/opt/nagios/libexec" "/var/log/apache2" "/usr/share/snmp/mibs") diff --git a/components/engine/builder/dockerfile/parser/testfiles/mumble/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/mumble/Dockerfile deleted file mode 100644 index 5b9ec06a6c..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/mumble/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM ubuntu:14.04 - -RUN apt-get update && apt-get install libcap2-bin mumble-server -y - -ADD ./mumble-server.ini /etc/mumble-server.ini - -CMD /usr/sbin/murmurd diff --git a/components/engine/builder/dockerfile/parser/testfiles/mumble/result b/components/engine/builder/dockerfile/parser/testfiles/mumble/result deleted file mode 100644 index a0036a943e..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/mumble/result +++ /dev/null @@ -1,4 +0,0 @@ -(from "ubuntu:14.04") -(run "apt-get update && apt-get install libcap2-bin mumble-server -y") -(add "./mumble-server.ini" "/etc/mumble-server.ini") -(cmd "/usr/sbin/murmurd") diff --git a/components/engine/builder/dockerfile/parser/testfiles/nginx/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/nginx/Dockerfile deleted file mode 100644 index 0a35e2c6b2..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/nginx/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM ubuntu:14.04 -LABEL maintainer Erik Hollensbe - -RUN apt-get update && apt-get install nginx-full -y -RUN rm -rf /etc/nginx -ADD etc /etc/nginx -RUN chown -R root:root /etc/nginx -RUN /usr/sbin/nginx -qt -RUN mkdir /www - -CMD ["/usr/sbin/nginx"] - -VOLUME /www -EXPOSE 80 diff --git a/components/engine/builder/dockerfile/parser/testfiles/nginx/result b/components/engine/builder/dockerfile/parser/testfiles/nginx/result deleted file mode 100644 index a895fadbbe..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/nginx/result +++ /dev/null @@ -1,11 +0,0 @@ -(from "ubuntu:14.04") -(label "maintainer" "Erik Hollensbe ") -(run "apt-get update && apt-get install nginx-full -y") -(run "rm -rf /etc/nginx") -(add "etc" "/etc/nginx") -(run "chown -R root:root /etc/nginx") -(run "/usr/sbin/nginx -qt") -(run "mkdir /www") -(cmd "/usr/sbin/nginx") -(volume "/www") -(expose "80") diff --git a/components/engine/builder/dockerfile/parser/testfiles/tf2/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/tf2/Dockerfile deleted file mode 100644 index 72b79bdd7d..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/tf2/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM ubuntu:12.04 - -EXPOSE 27015 -EXPOSE 27005 -EXPOSE 26901 -EXPOSE 27020 - -RUN apt-get update && apt-get install libc6-dev-i386 curl unzip -y -RUN mkdir -p /steam -RUN curl http://media.steampowered.com/client/steamcmd_linux.tar.gz | tar vxz -C /steam -ADD ./script /steam/script -RUN /steam/steamcmd.sh +runscript /steam/script -RUN curl http://mirror.pointysoftware.net/alliedmodders/mmsource-1.10.0-linux.tar.gz | tar vxz -C /steam/tf2/tf -RUN curl http://mirror.pointysoftware.net/alliedmodders/sourcemod-1.5.3-linux.tar.gz | tar vxz -C /steam/tf2/tf -ADD ./server.cfg /steam/tf2/tf/cfg/server.cfg -ADD ./ctf_2fort.cfg /steam/tf2/tf/cfg/ctf_2fort.cfg -ADD ./sourcemod.cfg /steam/tf2/tf/cfg/sourcemod/sourcemod.cfg -RUN rm -r /steam/tf2/tf/addons/sourcemod/configs -ADD ./configs /steam/tf2/tf/addons/sourcemod/configs -RUN mkdir -p /steam/tf2/tf/addons/sourcemod/translations/en -RUN cp /steam/tf2/tf/addons/sourcemod/translations/*.txt /steam/tf2/tf/addons/sourcemod/translations/en - -CMD cd /steam/tf2 && ./srcds_run -port 27015 +ip 0.0.0.0 +map ctf_2fort -autoupdate -steam_dir /steam -steamcmd_script /steam/script +tf_bot_quota 12 +tf_bot_quota_mode fill diff --git a/components/engine/builder/dockerfile/parser/testfiles/tf2/result b/components/engine/builder/dockerfile/parser/testfiles/tf2/result deleted file mode 100644 index d4f94cd8be..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/tf2/result +++ /dev/null @@ -1,20 +0,0 @@ -(from "ubuntu:12.04") -(expose "27015") -(expose "27005") -(expose "26901") -(expose "27020") -(run "apt-get update && apt-get install libc6-dev-i386 curl unzip -y") -(run "mkdir -p /steam") -(run "curl http://media.steampowered.com/client/steamcmd_linux.tar.gz | tar vxz -C /steam") -(add "./script" "/steam/script") -(run "/steam/steamcmd.sh +runscript /steam/script") -(run "curl http://mirror.pointysoftware.net/alliedmodders/mmsource-1.10.0-linux.tar.gz | tar vxz -C /steam/tf2/tf") -(run "curl http://mirror.pointysoftware.net/alliedmodders/sourcemod-1.5.3-linux.tar.gz | tar vxz -C /steam/tf2/tf") -(add "./server.cfg" "/steam/tf2/tf/cfg/server.cfg") -(add "./ctf_2fort.cfg" "/steam/tf2/tf/cfg/ctf_2fort.cfg") -(add "./sourcemod.cfg" "/steam/tf2/tf/cfg/sourcemod/sourcemod.cfg") -(run "rm -r /steam/tf2/tf/addons/sourcemod/configs") -(add "./configs" "/steam/tf2/tf/addons/sourcemod/configs") -(run "mkdir -p /steam/tf2/tf/addons/sourcemod/translations/en") -(run "cp /steam/tf2/tf/addons/sourcemod/translations/*.txt /steam/tf2/tf/addons/sourcemod/translations/en") -(cmd "cd /steam/tf2 && ./srcds_run -port 27015 +ip 0.0.0.0 +map ctf_2fort -autoupdate -steam_dir /steam -steamcmd_script /steam/script +tf_bot_quota 12 +tf_bot_quota_mode fill") diff --git a/components/engine/builder/dockerfile/parser/testfiles/weechat/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/weechat/Dockerfile deleted file mode 100644 index 4842088166..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/weechat/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM ubuntu:14.04 - -RUN apt-get update -qy && apt-get install tmux zsh weechat-curses -y - -ADD .weechat /.weechat -ADD .tmux.conf / -RUN echo "export TERM=screen-256color" >/.zshenv - -CMD zsh -c weechat diff --git a/components/engine/builder/dockerfile/parser/testfiles/weechat/result b/components/engine/builder/dockerfile/parser/testfiles/weechat/result deleted file mode 100644 index c3abb4c54f..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/weechat/result +++ /dev/null @@ -1,6 +0,0 @@ -(from "ubuntu:14.04") -(run "apt-get update -qy && apt-get install tmux zsh weechat-curses -y") -(add ".weechat" "/.weechat") -(add ".tmux.conf" "/") -(run "echo \"export TERM=screen-256color\" >/.zshenv") -(cmd "zsh -c weechat") diff --git a/components/engine/builder/dockerfile/parser/testfiles/znc/Dockerfile b/components/engine/builder/dockerfile/parser/testfiles/znc/Dockerfile deleted file mode 100644 index 626b126d8a..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/znc/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM ubuntu:14.04 -LABEL maintainer Erik Hollensbe - -RUN apt-get update && apt-get install znc -y -ADD conf /.znc - -CMD [ "/usr/bin/znc", "-f", "-r" ] diff --git a/components/engine/builder/dockerfile/parser/testfiles/znc/result b/components/engine/builder/dockerfile/parser/testfiles/znc/result deleted file mode 100644 index bfc7f65135..0000000000 --- a/components/engine/builder/dockerfile/parser/testfiles/znc/result +++ /dev/null @@ -1,5 +0,0 @@ -(from "ubuntu:14.04") -(label "maintainer" "Erik Hollensbe ") -(run "apt-get update && apt-get install znc -y") -(add "conf" "/.znc") -(cmd "/usr/bin/znc" "-f" "-r") diff --git a/components/engine/builder/dockerfile/shell/envVarTest b/components/engine/builder/dockerfile/shell/envVarTest deleted file mode 100644 index 08011801c5..0000000000 --- a/components/engine/builder/dockerfile/shell/envVarTest +++ /dev/null @@ -1,232 +0,0 @@ -A|hello | hello -A|he'll'o | hello -A|he'llo | error -A|he\'llo | he'llo -A|he\\'llo | error -A|abc\tdef | abctdef -A|"abc\tdef" | abc\tdef -A|"abc\\tdef" | abc\tdef -A|'abc\tdef' | abc\tdef -A|hello\ | hello -A|hello\\ | hello\ -A|"hello | error -A|"hello\" | error -A|"hel'lo" | hel'lo -A|'hello | error -A|'hello\' | hello\ -A|'hello\there' | hello\there -A|'hello\\there' | hello\\there -A|"''" | '' -A|$. | $. -A|he$1x | hex -A|he$.x | he$.x -# Next one is different on Windows as $pwd==$PWD -U|he$pwd. | he. -W|he$pwd. | he/home. -A|he$PWD | he/home -A|he\$PWD | he$PWD -A|he\\$PWD | he\/home -A|"he\$PWD" | he$PWD -A|"he\\$PWD" | he\/home -A|\${} | ${} -A|\${}aaa | ${}aaa -A|he\${} | he${} -A|he\${}xx | he${}xx -A|${} | error -A|${}aaa | error -A|he${} | error -A|he${}xx | error -A|he${hi} | he -A|he${hi}xx | hexx -A|he${PWD} | he/home -A|he${.} | error -A|he${XXX:-000}xx | he000xx -A|he${PWD:-000}xx | he/homexx -A|he${XXX:-$PWD}xx | he/homexx -A|he${XXX:-${PWD:-yyy}}xx | he/homexx -A|he${XXX:-${YYY:-yyy}}xx | heyyyxx -A|he${XXX:YYY} | error -A|he${XXX:+${PWD}}xx | hexx -A|he${PWD:+${XXX}}xx | hexx -A|he${PWD:+${SHELL}}xx | hebashxx -A|he${XXX:+000}xx | hexx -A|he${PWD:+000}xx | he000xx -A|'he${XX}' | he${XX} -A|"he${PWD}" | he/home -A|"he'$PWD'" | he'/home' -A|"$PWD" | /home -A|'$PWD' | $PWD -A|'\$PWD' | \$PWD -A|'"hello"' | "hello" -A|he\$PWD | he$PWD -A|"he\$PWD" | he$PWD -A|'he\$PWD' | he\$PWD -A|he${PWD | error -A|he${PWD:=000}xx | error -A|he${PWD:+${PWD}:}xx | he/home:xx -A|he${XXX:-\$PWD:}xx | he$PWD:xx -A|he${XXX:-\${PWD}z}xx | he${PWDz}xx -A|안녕하세요 | 안녕하세요 -A|안'녕'하세요 | 안녕하세요 -A|안'녕하세요 | error -A|안녕\'하세요 | 안녕'하세요 -A|안\\'녕하세요 | error -A|안녕\t하세요 | 안녕t하세요 -A|"안녕\t하세요" | 안녕\t하세요 -A|'안녕\t하세요 | error -A|안녕하세요\ | 안녕하세요 -A|안녕하세요\\ | 안녕하세요\ -A|"안녕하세요 | error -A|"안녕하세요\" | error -A|"안녕'하세요" | 안녕'하세요 -A|'안녕하세요 | error -A|'안녕하세요\' | 안녕하세요\ -A|안녕$1x | 안녕x -A|안녕$.x | 안녕$.x -# Next one is different on Windows as $pwd==$PWD -U|안녕$pwd. | 안녕. -W|안녕$pwd. | 안녕/home. -A|안녕$PWD | 안녕/home -A|안녕\$PWD | 안녕$PWD -A|안녕\\$PWD | 안녕\/home -A|안녕\${} | 안녕${} -A|안녕\${}xx | 안녕${}xx -A|안녕${} | error -A|안녕${}xx | error -A|안녕${hi} | 안녕 -A|안녕${hi}xx | 안녕xx -A|안녕${PWD} | 안녕/home -A|안녕${.} | error -A|안녕${XXX:-000}xx | 안녕000xx -A|안녕${PWD:-000}xx | 안녕/homexx -A|안녕${XXX:-$PWD}xx | 안녕/homexx -A|안녕${XXX:-${PWD:-yyy}}xx | 안녕/homexx -A|안녕${XXX:-${YYY:-yyy}}xx | 안녕yyyxx -A|안녕${XXX:YYY} | error -A|안녕${XXX:+${PWD}}xx | 안녕xx -A|안녕${PWD:+${XXX}}xx | 안녕xx -A|안녕${PWD:+${SHELL}}xx | 안녕bashxx -A|안녕${XXX:+000}xx | 안녕xx -A|안녕${PWD:+000}xx | 안녕000xx -A|'안녕${XX}' | 안녕${XX} -A|"안녕${PWD}" | 안녕/home -A|"안녕'$PWD'" | 안녕'/home' -A|'"안녕"' | "안녕" -A|안녕\$PWD | 안녕$PWD -A|"안녕\$PWD" | 안녕$PWD -A|'안녕\$PWD' | 안녕\$PWD -A|안녕${PWD | error -A|안녕${PWD:=000}xx | error -A|안녕${PWD:+${PWD}:}xx | 안녕/home:xx -A|안녕${XXX:-\$PWD:}xx | 안녕$PWD:xx -A|안녕${XXX:-\${PWD}z}xx | 안녕${PWDz}xx -A|$KOREAN | 한국어 -A|안녕$KOREAN | 안녕한국어 -A|${{aaa} | error -A|${aaa}} | } -A|${aaa | error -A|${{aaa:-bbb} | error -A|${aaa:-bbb}} | bbb} -A|${aaa:-bbb | error -A|${aaa:-bbb} | bbb -A|${aaa:-${bbb:-ccc}} | ccc -A|${aaa:-bbb ${foo} | error -A|${aaa:-bbb {foo} | bbb {foo -A|${:} | error -A|${:-bbb} | error -A|${:+bbb} | error - -# Positional parameters won't be set: -# http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_05_01 -A|$1 | -A|${1} | -A|${1:+bbb} | -A|${1:-bbb} | bbb -A|$2 | -A|${2} | -A|${2:+bbb} | -A|${2:-bbb} | bbb -A|$3 | -A|${3} | -A|${3:+bbb} | -A|${3:-bbb} | bbb -A|$4 | -A|${4} | -A|${4:+bbb} | -A|${4:-bbb} | bbb -A|$5 | -A|${5} | -A|${5:+bbb} | -A|${5:-bbb} | bbb -A|$6 | -A|${6} | -A|${6:+bbb} | -A|${6:-bbb} | bbb -A|$7 | -A|${7} | -A|${7:+bbb} | -A|${7:-bbb} | bbb -A|$8 | -A|${8} | -A|${8:+bbb} | -A|${8:-bbb} | bbb -A|$9 | -A|${9} | -A|${9:+bbb} | -A|${9:-bbb} | bbb -A|$999 | -A|${999} | -A|${999:+bbb} | -A|${999:-bbb} | bbb -A|$999aaa | aaa -A|${999}aaa | aaa -A|${999:+bbb}aaa | aaa -A|${999:-bbb}aaa | bbbaaa -A|$001 | -A|${001} | -A|${001:+bbb} | -A|${001:-bbb} | bbb -A|$001aaa | aaa -A|${001}aaa | aaa -A|${001:+bbb}aaa | aaa -A|${001:-bbb}aaa | bbbaaa - -# Special parameters won't be set in the Dockerfile: -# http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_05_02 -A|$@ | -A|${@} | -A|${@:+bbb} | -A|${@:-bbb} | bbb -A|$@@@ | @@ -A|$@aaa | aaa -A|${@}aaa | aaa -A|${@:+bbb}aaa | aaa -A|${@:-bbb}aaa | bbbaaa -A|$* | -A|${*} | -A|${*:+bbb} | -A|${*:-bbb} | bbb -A|$# | -A|${#} | -A|${#:+bbb} | -A|${#:-bbb} | bbb -A|$? | -A|${?} | -A|${?:+bbb} | -A|${?:-bbb} | bbb -A|$- | -A|${-} | -A|${-:+bbb} | -A|${-:-bbb} | bbb -A|$$ | -A|${$} | -A|${$:+bbb} | -A|${$:-bbb} | bbb -A|$! | -A|${!} | -A|${!:+bbb} | -A|${!:-bbb} | bbb -A|$0 | -A|${0} | -A|${0:+bbb} | -A|${0:-bbb} | bbb diff --git a/components/engine/builder/dockerfile/shell/lex_test.go b/components/engine/builder/dockerfile/shell/lex_test.go deleted file mode 100644 index 4b30c32f2b..0000000000 --- a/components/engine/builder/dockerfile/shell/lex_test.go +++ /dev/null @@ -1,150 +0,0 @@ -package shell // import "github.com/docker/docker/builder/dockerfile/shell" - -import ( - "bufio" - "os" - "runtime" - "strings" - "testing" - - "github.com/gotestyourself/gotestyourself/assert" - is "github.com/gotestyourself/gotestyourself/assert/cmp" -) - -func TestShellParser4EnvVars(t *testing.T) { - fn := "envVarTest" - lineCount := 0 - - file, err := os.Open(fn) - assert.Check(t, err) - defer file.Close() - - shlex := NewLex('\\') - scanner := bufio.NewScanner(file) - envs := []string{"PWD=/home", "SHELL=bash", "KOREAN=한국어"} - for scanner.Scan() { - line := scanner.Text() - lineCount++ - - // Skip comments and blank lines - if strings.HasPrefix(line, "#") { - continue - } - line = strings.TrimSpace(line) - if line == "" { - continue - } - - words := strings.Split(line, "|") - assert.Check(t, is.Len(words, 3)) - - platform := strings.TrimSpace(words[0]) - source := strings.TrimSpace(words[1]) - expected := strings.TrimSpace(words[2]) - - // Key W=Windows; A=All; U=Unix - if platform != "W" && platform != "A" && platform != "U" { - t.Fatalf("Invalid tag %s at line %d of %s. Must be W, A or U", platform, lineCount, fn) - } - - if ((platform == "W" || platform == "A") && runtime.GOOS == "windows") || - ((platform == "U" || platform == "A") && runtime.GOOS != "windows") { - newWord, err := shlex.ProcessWord(source, envs) - if expected == "error" { - assert.Check(t, is.ErrorContains(err, ""), "input: %q, result: %q", source, newWord) - } else { - assert.Check(t, err, "at line %d of %s", lineCount, fn) - assert.Check(t, is.Equal(newWord, expected), "at line %d of %s", lineCount, fn) - } - } - } -} - -func TestShellParser4Words(t *testing.T) { - fn := "wordsTest" - - file, err := os.Open(fn) - if err != nil { - t.Fatalf("Can't open '%s': %s", err, fn) - } - defer file.Close() - - var envs []string - shlex := NewLex('\\') - scanner := bufio.NewScanner(file) - lineNum := 0 - for scanner.Scan() { - line := scanner.Text() - lineNum = lineNum + 1 - - if strings.HasPrefix(line, "#") { - continue - } - - if strings.HasPrefix(line, "ENV ") { - line = strings.TrimLeft(line[3:], " ") - envs = append(envs, line) - continue - } - - words := strings.Split(line, "|") - if len(words) != 2 { - t.Fatalf("Error in '%s'(line %d) - should be exactly one | in: %q", fn, lineNum, line) - } - test := strings.TrimSpace(words[0]) - expected := strings.Split(strings.TrimLeft(words[1], " "), ",") - - result, err := shlex.ProcessWords(test, envs) - - if err != nil { - result = []string{"error"} - } - - if len(result) != len(expected) { - t.Fatalf("Error on line %d. %q was suppose to result in %q, but got %q instead", lineNum, test, expected, result) - } - for i, w := range expected { - if w != result[i] { - t.Fatalf("Error on line %d. %q was suppose to result in %q, but got %q instead", lineNum, test, expected, result) - } - } - } -} - -func TestGetEnv(t *testing.T) { - sw := &shellWord{envs: nil} - - sw.envs = []string{} - if sw.getEnv("foo") != "" { - t.Fatal("2 - 'foo' should map to ''") - } - - sw.envs = []string{"foo"} - if sw.getEnv("foo") != "" { - t.Fatal("3 - 'foo' should map to ''") - } - - sw.envs = []string{"foo="} - if sw.getEnv("foo") != "" { - t.Fatal("4 - 'foo' should map to ''") - } - - sw.envs = []string{"foo=bar"} - if sw.getEnv("foo") != "bar" { - t.Fatal("5 - 'foo' should map to 'bar'") - } - - sw.envs = []string{"foo=bar", "car=hat"} - if sw.getEnv("foo") != "bar" { - t.Fatal("6 - 'foo' should map to 'bar'") - } - if sw.getEnv("car") != "hat" { - t.Fatal("7 - 'car' should map to 'hat'") - } - - // Make sure we grab the first 'car' in the list - sw.envs = []string{"foo=bar", "car=hat", "car=bike"} - if sw.getEnv("car") != "hat" { - t.Fatal("8 - 'car' should map to 'hat'") - } -} diff --git a/components/engine/builder/dockerfile/shell/wordsTest b/components/engine/builder/dockerfile/shell/wordsTest deleted file mode 100644 index 1fd9f19433..0000000000 --- a/components/engine/builder/dockerfile/shell/wordsTest +++ /dev/null @@ -1,30 +0,0 @@ -hello | hello -hello${hi}bye | hellobye -ENV hi=hi -hello${hi}bye | hellohibye -ENV space=abc def -hello${space}bye | helloabc,defbye -hello"${space}"bye | helloabc defbye -hello "${space}"bye | hello,abc defbye -ENV leading= ab c -hello${leading}def | hello,ab,cdef -hello"${leading}" def | hello ab c,def -hello"${leading}" | hello ab c -hello${leading} | hello,ab,c -# next line MUST have 3 trailing spaces, don't erase them! -ENV trailing=ab c -hello${trailing} | helloab,c -hello${trailing}d | helloab,c,d -hello"${trailing}"d | helloab c d -# next line MUST have 3 trailing spaces, don't erase them! -hel"lo${trailing}" | helloab c -hello" there " | hello there -hello there | hello,there -hello\ there | hello there -hello" there | error -hello\" there | hello",there -hello"\\there" | hello\there -hello"\there" | hello\there -hello'\\there' | hello\\there -hello'\there' | hello\there -hello'$there' | hello$there diff --git a/components/engine/builder/remotecontext/detect.go b/components/engine/builder/remotecontext/detect.go index af4e20f886..aaace269e9 100644 --- a/components/engine/builder/remotecontext/detect.go +++ b/components/engine/builder/remotecontext/detect.go @@ -10,10 +10,10 @@ import ( "github.com/containerd/continuity/driver" "github.com/docker/docker/api/types/backend" "github.com/docker/docker/builder" - "github.com/docker/docker/builder/dockerfile/parser" "github.com/docker/docker/builder/dockerignore" "github.com/docker/docker/pkg/fileutils" "github.com/docker/docker/pkg/urlutil" + "github.com/moby/buildkit/frontend/dockerfile/parser" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) diff --git a/components/engine/integration-cli/docker_cli_build_test.go b/components/engine/integration-cli/docker_cli_build_test.go index a87e4aaaf1..0aae7c4575 100644 --- a/components/engine/integration-cli/docker_cli_build_test.go +++ b/components/engine/integration-cli/docker_cli_build_test.go @@ -16,7 +16,7 @@ import ( "text/template" "time" - "github.com/docker/docker/builder/dockerfile/command" + "github.com/moby/buildkit/frontend/dockerfile/command" "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli/build" diff --git a/components/engine/integration/build/build_session_test.go b/components/engine/integration/build/build_session_test.go index 3abac981e5..d822f4523e 100644 --- a/components/engine/integration/build/build_session_test.go +++ b/components/engine/integration/build/build_session_test.go @@ -85,7 +85,8 @@ func TestBuildWithSession(t *testing.T) { } func testBuildWithSession(t *testing.T, client dclient.APIClient, daemonHost string, dir, dockerfile string) (outStr string) { - sess, err := session.NewSession("foo1", "foo") + ctx := context.Background() + sess, err := session.NewSession(ctx, "foo1", "foo") assert.Check(t, err) fsProvider := filesync.NewFSSyncProvider([]filesync.SyncedDir{ diff --git a/components/engine/vendor.conf b/components/engine/vendor.conf index 5918cba298..0e7fa7557c 100644 --- a/components/engine/vendor.conf +++ b/components/engine/vendor.conf @@ -26,8 +26,8 @@ github.com/RackSec/srslog 456df3a81436d29ba874f3590eeeee25d666f8a5 github.com/imdario/mergo 0.2.1 golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5 -github.com/moby/buildkit aaff9d591ef128560018433fe61beb802e149de8 -github.com/tonistiigi/fsutil dea3a0da73aee887fc02142d995be764106ac5e2 +github.com/moby/buildkit b14fd548fe80c0399b105aeec5dbd96ccd2f7720 +github.com/tonistiigi/fsutil dc68c74458923f357474a9178bd198aa3ed11a5f #get libnetwork packages diff --git a/components/engine/vendor/github.com/moby/buildkit/README.md b/components/engine/vendor/github.com/moby/buildkit/README.md index 4101bf43b5..841752abee 100644 --- a/components/engine/vendor/github.com/moby/buildkit/README.md +++ b/components/engine/vendor/github.com/moby/buildkit/README.md @@ -5,7 +5,6 @@ ## BuildKit - [![GoDoc](https://godoc.org/github.com/moby/buildkit?status.svg)](https://godoc.org/github.com/moby/buildkit/client/llb) [![Build Status](https://travis-ci.org/moby/buildkit.svg?branch=master)](https://travis-ci.org/moby/buildkit) [![Go Report Card](https://goreportcard.com/badge/github.com/moby/buildkit)](https://goreportcard.com/report/github.com/moby/buildkit) @@ -23,26 +22,58 @@ Key features: - Distributable workers - Multiple output formats - Pluggable architecture +- Execution without root privileges Read the proposal from https://github.com/moby/moby/issues/32925 -#### Quick start +Introductory blog post https://blog.mobyproject.org/introducing-buildkit-17e056cc5317 -BuildKit daemon can be built in two different versions: one that uses [containerd](https://github.com/containerd/containerd) for execution and distribution, and a standalone version that doesn't have other dependencies apart from [runc](https://github.com/opencontainers/runc). We are open for adding more backends. `buildd` is a CLI utility for serving the gRPC API. +### Quick start + +Dependencies: +- [runc](https://github.com/opencontainers/runc) +- [containerd](https://github.com/containerd/containerd) (if you want to use containerd worker) + + +The following command installs `buildkitd` and `buildctl` to `/usr/local/bin`: ```bash -# buildd daemon (choose one) -go build -o buildd-containerd -tags containerd ./cmd/buildd -go build -o buildd-standalone -tags standalone ./cmd/buildd - -# buildctl utility -go build -o buildctl ./cmd/buildctl +$ make && sudo make install ``` -You can also use `make binaries` that prepares all binaries into the `bin/` directory. +You can also use `make binaries-all` to prepare `buildkitd.containerd_only` and `buildkitd.oci_only`. -`examples/buildkit*` directory contains scripts that define how to build different configurations of BuildKit and its dependencies using the `client` package. Running one of these script generates a protobuf definition of a build graph. Note that the script itself does not execute any steps of the build. +#### Starting the buildkitd daemon: + +``` +buildkitd --debug --root /var/lib/buildkit +``` + +The buildkitd daemon suppports two worker backends: OCI (runc) and containerd. + +By default, the OCI (runc) worker is used. +You can set `--oci-worker=false --containerd-worker=true` to use the containerd worker. + +We are open to adding more backends. + +#### Exploring LLB + +BuildKit builds are based on a binary intermediate format called LLB that is used for defining the dependency graph for processes running part of your build. tl;dr: LLB is to Dockerfile what LLVM IR is to C. + +- Marshaled as Protobuf messages +- Concurrently executable +- Efficiently cacheable +- Vendor-neutral (i.e. non-Dockerfile languages can be easily implemented) + +See [`solver/pb/ops.proto`](./solver/pb/ops.proto) for the format definition. + +Currently, following high-level languages has been implemented for LLB: + +- Dockerfile (See [Exploring Dockerfiles](#exploring-dockerfiles)) +- (open a PR to add your own language) + +For understanding the basics of LLB, `examples/buildkit*` directory contains scripts that define how to build different configurations of BuildKit itself and its dependencies using the `client` package. Running one of these scripts generates a protobuf definition of a build graph. Note that the script itself does not execute any steps of the build. You can use `buildctl debug dump-llb` to see what data is in this definition. Add `--dot` to generate dot layout. @@ -50,7 +81,7 @@ You can use `buildctl debug dump-llb` to see what data is in this definition. Ad go run examples/buildkit0/buildkit.go | buildctl debug dump-llb | jq . ``` -To start building use `buildctl build` command. The example script accepts `--target` flag to choose between `containerd` and `standalone` configurations. In standalone mode BuildKit binaries are built together with `runc`. In containerd mode, the `containerd` binary is built as well from the upstream repo. +To start building use `buildctl build` command. The example script accepts `--with-containerd` flag to choose if containerd binaries and support should be included in the end result as well. ```bash go run examples/buildkit0/buildkit.go | buildctl build @@ -68,50 +99,138 @@ Different versions of the example scripts show different ways of describing the - `./examples/gobuild` - shows how to use nested invocation to generate LLB for Go package internal dependencies -#### Examples +#### Exploring Dockerfiles -##### Starting the buildd daemon: +Frontends are components that run inside BuildKit and convert any build definition to LLB. There is a special frontend called gateway (gateway.v0) that allows using any image as a frontend. -``` -buildd-standalone --debug --root /var/lib/buildkit -``` +During development, Dockerfile frontend (dockerfile.v0) is also part of the BuildKit repo. In the future, this will be moved out, and Dockerfiles can be built using an external image. -##### Building a Dockerfile: +##### Building a Dockerfile with `buildctl` ``` buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. +buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --frontend-opt target=foo --frontend-opt build-arg:foo=bar ``` -`context` and `dockerfile` should point to local directories for build context and Dockerfile location. +`--local` exposes local source files from client to the builder. `context` and `dockerfile` are the names Dockerfile frontend looks for build context and Dockerfile location. +##### build-using-dockerfile utility + +For people familiar with `docker build` command, there is an example wrapper utility in `./examples/build-using-dockerfile` that allows building Dockerfiles with BuildKit using a syntax similar to `docker build`. + +``` +go build ./examples/build-using-dockerfile && sudo install build-using-dockerfile /usr/local/bin + +build-using-dockerfile -t myimage . +build-using-dockerfile -t mybuildkit -f ./hack/dockerfiles/test.Dockerfile . + +# build-using-dockerfile will automatically load the resulting image to Docker +docker inspect myimage +``` + +##### Building a Dockerfile using [external frontend](https://hub.docker.com/r/tonistiigi/dockerfile/tags/): + +During development, an external version of the Dockerfile frontend is pushed to https://hub.docker.com/r/tonistiigi/dockerfile that can be used with the gateway frontend. The source for the external frontend is currently located in `./frontend/dockerfile/cmd/dockerfile-frontend` but will move out of this repository in the future ([#163](https://github.com/moby/buildkit/issues/163)). + +``` +buildctl build --frontend=gateway.v0 --frontend-opt=source=tonistiigi/dockerfile:v0 --local context=. --local dockerfile=. +buildctl build --frontend gateway.v0 --frontend-opt=source=tonistiigi/dockerfile:v0 --frontend-opt=context=git://github.com/moby/moby --frontend-opt build-arg:APT_MIRROR=cdn-fastly.deb.debian.org +```` + +### Exporters + +By default, the build result and intermediate cache will only remain internally in BuildKit. Exporter needs to be specified to retrieve the result. ##### Exporting resulting image to containerd -Containerd version of buildd needs to be used +The containerd worker needs to be used ``` buildctl build ... --exporter=image --exporter-opt name=docker.io/username/image ctr --namespace=buildkit images ls ``` +##### Push resulting image to registry + +``` +buildctl build ... --exporter=image --exporter-opt name=docker.io/username/image --exporter-opt push=true +``` + +If credentials are required, `buildctl` will attempt to read Docker configuration file. + + ##### Exporting build result back to client +The local client will copy the files directly to the client. This is useful if BuildKit is being used for building something else than container images. + ``` buildctl build ... --exporter=local --exporter-opt output=path/to/output-dir ``` +##### Exporting built image to Docker + +``` +# exported tarball is also compatible with OCI spec +buildctl build ... --exporter=docker --exporter-opt name=myimage | docker load +``` + +##### Exporting [OCI Image Format](https://github.com/opencontainers/image-spec) tarball to client + +``` +buildctl build ... --exporter=oci --exporter-opt output=path/to/output.tar +buildctl build ... --exporter=oci > output.tar +``` + +### Other + #### View build cache ``` buildctl du -v ``` -#### Supported runc version +#### Show enabled workers -During development buildkit is tested with the version of runc that is being used by the containerd repository. Please refer to [runc.md](https://github.com/containerd/containerd/blob/d1e11f17ec7b325f89608dd46c128300b8727d50/RUNC.md) for more information. +``` +buildctl debug workers -v +``` + +### Running containerized buildkit + +BuildKit can also be used by running the `buildkitd` daemon inside a Docker container and accessing it remotely. The client tool `buildctl` is also available for Mac and Windows. + +To run daemon in a container: + +``` +docker run -d --privileged -p 1234:1234 tonistiigi/buildkit --addr tcp://0.0.0.0:1234 +export BUILDKIT_HOST=tcp://0.0.0.0:1234 +buildctl build --help +``` + +The `tonistiigi/buildkit` image can be built locally using the Dockerfile in `./hack/dockerfiles/test.Dockerfile`. + +### Opentracing support + +BuildKit supports opentracing for buildkitd gRPC API and buildctl commands. To capture the trace to [Jaeger](https://github.com/jaegertracing/jaeger), set `JAEGER_TRACE` environment variable to the collection address. -#### Contributing +``` +docker run -d -p6831:6831/udp -p16686:16686 jaegertracing/all-in-one:latest +export JAEGER_TRACE=0.0.0.0:6831 +# restart buildkitd and buildctl so they know JAEGER_TRACE +# any buildctl command should be traced to http://127.0.0.1:16686/ +``` + + +### Supported runc version + +During development, BuildKit is tested with the version of runc that is being used by the containerd repository. Please refer to [runc.md](https://github.com/containerd/containerd/blob/v1.1.0/RUNC.md) for more information. + +### Running BuildKit without root privileges + +Please refer to [`docs/rootless.md`](docs/rootless.md). + +### Contributing Running tests: @@ -119,6 +238,20 @@ Running tests: make test ``` +This runs all unit and integration tests in a containerized environment. Locally, every package can be tested separately with standard Go tools, but integration tests are skipped if local user doesn't have enough permissions or worker binaries are not installed. + +``` +# test a specific package only +make test TESTPKGS=./client + +# run a specific test with all worker combinations +make test TESTPKGS=./client TESTFLAGS="--run /TestCallDiskUsage -v" + +# run all integration tests with a specific worker +# supported workers are oci and containerd +make test TESTPKGS=./client TESTFLAGS="--run //worker=containerd -v" +``` + Updating vendored dependencies: ```bash diff --git a/components/engine/builder/dockerfile/command/command.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/command/command.go similarity index 92% rename from components/engine/builder/dockerfile/command/command.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/command/command.go index 303b59096b..f23c6874b5 100644 --- a/components/engine/builder/dockerfile/command/command.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/command/command.go @@ -1,5 +1,5 @@ // Package command contains the set of Dockerfile commands. -package command // import "github.com/docker/docker/builder/dockerfile/command" +package command // Define constants for the command strings const ( diff --git a/components/engine/builder/dockerfile/instructions/bflag.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/bflag.go similarity index 97% rename from components/engine/builder/dockerfile/instructions/bflag.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/bflag.go index 00b9610b38..7a81e3c136 100644 --- a/components/engine/builder/dockerfile/instructions/bflag.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/bflag.go @@ -1,4 +1,4 @@ -package instructions // import "github.com/docker/docker/builder/dockerfile/instructions" +package instructions import ( "fmt" diff --git a/components/engine/builder/dockerfile/instructions/commands.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands.go similarity index 99% rename from components/engine/builder/dockerfile/instructions/commands.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands.go index 96d33016b5..12478463cd 100644 --- a/components/engine/builder/dockerfile/instructions/commands.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands.go @@ -1,4 +1,4 @@ -package instructions // import "github.com/docker/docker/builder/dockerfile/instructions" +package instructions import ( "errors" diff --git a/components/engine/builder/dockerfile/instructions/errors_unix.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/errors_unix.go similarity index 63% rename from components/engine/builder/dockerfile/instructions/errors_unix.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/errors_unix.go index 2bd11659e4..0b03b34cd1 100644 --- a/components/engine/builder/dockerfile/instructions/errors_unix.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/errors_unix.go @@ -1,6 +1,6 @@ // +build !windows -package instructions // import "github.com/docker/docker/builder/dockerfile/instructions" +package instructions import "fmt" diff --git a/components/engine/builder/dockerfile/instructions/errors_windows.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/errors_windows.go similarity index 92% rename from components/engine/builder/dockerfile/instructions/errors_windows.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/errors_windows.go index be8dbee065..a4843c5b6a 100644 --- a/components/engine/builder/dockerfile/instructions/errors_windows.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/errors_windows.go @@ -1,4 +1,4 @@ -package instructions // import "github.com/docker/docker/builder/dockerfile/instructions" +package instructions import ( "fmt" diff --git a/components/engine/builder/dockerfile/instructions/parse.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go similarity index 98% rename from components/engine/builder/dockerfile/instructions/parse.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go index e2d69a4887..1285ac3306 100644 --- a/components/engine/builder/dockerfile/instructions/parse.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/parse.go @@ -1,4 +1,4 @@ -package instructions // import "github.com/docker/docker/builder/dockerfile/instructions" +package instructions import ( "fmt" @@ -10,9 +10,9 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/strslice" - "github.com/docker/docker/builder/dockerfile/command" - "github.com/docker/docker/builder/dockerfile/parser" "github.com/docker/docker/pkg/system" + "github.com/moby/buildkit/frontend/dockerfile/command" + "github.com/moby/buildkit/frontend/dockerfile/parser" "github.com/pkg/errors" ) diff --git a/components/engine/builder/dockerfile/instructions/support.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/support.go similarity index 85% rename from components/engine/builder/dockerfile/instructions/support.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/support.go index 1d649a77af..beefe775ce 100644 --- a/components/engine/builder/dockerfile/instructions/support.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/support.go @@ -1,4 +1,4 @@ -package instructions // import "github.com/docker/docker/builder/dockerfile/instructions" +package instructions import "strings" diff --git a/components/engine/builder/dockerfile/parser/line_parsers.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/line_parsers.go similarity index 99% rename from components/engine/builder/dockerfile/parser/line_parsers.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/line_parsers.go index c454835373..15f00ce792 100644 --- a/components/engine/builder/dockerfile/parser/line_parsers.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/line_parsers.go @@ -1,4 +1,4 @@ -package parser // import "github.com/docker/docker/builder/dockerfile/parser" +package parser // line parsers are dispatch calls that parse a single unit of text into a // Node object which contains the whole statement. Dockerfiles have varied diff --git a/components/engine/builder/dockerfile/parser/parser.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/parser.go similarity index 98% rename from components/engine/builder/dockerfile/parser/parser.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/parser.go index f938b808b6..0453f3a9a2 100644 --- a/components/engine/builder/dockerfile/parser/parser.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/parser.go @@ -1,5 +1,5 @@ // Package parser implements a parser and parse tree dumper for Dockerfiles. -package parser // import "github.com/docker/docker/builder/dockerfile/parser" +package parser import ( "bufio" @@ -11,7 +11,7 @@ import ( "strings" "unicode" - "github.com/docker/docker/builder/dockerfile/command" + "github.com/moby/buildkit/frontend/dockerfile/command" "github.com/pkg/errors" ) diff --git a/components/engine/builder/dockerfile/parser/split_command.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/split_command.go similarity index 96% rename from components/engine/builder/dockerfile/parser/split_command.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/split_command.go index 6f4fbf5884..171f454f6d 100644 --- a/components/engine/builder/dockerfile/parser/split_command.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/parser/split_command.go @@ -1,4 +1,4 @@ -package parser // import "github.com/docker/docker/builder/dockerfile/parser" +package parser import ( "strings" diff --git a/components/engine/builder/dockerfile/shell/equal_env_unix.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_unix.go similarity index 73% rename from components/engine/builder/dockerfile/shell/equal_env_unix.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_unix.go index ac97a1e16e..6e3f6b890e 100644 --- a/components/engine/builder/dockerfile/shell/equal_env_unix.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_unix.go @@ -1,6 +1,6 @@ // +build !windows -package shell // import "github.com/docker/docker/builder/dockerfile/shell" +package shell // EqualEnvKeys compare two strings and returns true if they are equal. On // Windows this comparison is case insensitive. diff --git a/components/engine/builder/dockerfile/shell/equal_env_windows.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_windows.go similarity index 75% rename from components/engine/builder/dockerfile/shell/equal_env_windows.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_windows.go index 4baa771bdf..7780fb67e8 100644 --- a/components/engine/builder/dockerfile/shell/equal_env_windows.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/equal_env_windows.go @@ -1,4 +1,4 @@ -package shell // import "github.com/docker/docker/builder/dockerfile/shell" +package shell import "strings" diff --git a/components/engine/builder/dockerfile/shell/lex.go b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/lex.go similarity index 99% rename from components/engine/builder/dockerfile/shell/lex.go rename to components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/lex.go index 0c80900ade..c264459bc8 100644 --- a/components/engine/builder/dockerfile/shell/lex.go +++ b/components/engine/vendor/github.com/moby/buildkit/frontend/dockerfile/shell/lex.go @@ -1,4 +1,4 @@ -package shell // import "github.com/docker/docker/builder/dockerfile/shell" +package shell import ( "bytes" diff --git a/components/engine/vendor/github.com/moby/buildkit/identity/randomid.go b/components/engine/vendor/github.com/moby/buildkit/identity/randomid.go new file mode 100644 index 0000000000..0eb13527aa --- /dev/null +++ b/components/engine/vendor/github.com/moby/buildkit/identity/randomid.go @@ -0,0 +1,53 @@ +package identity + +import ( + cryptorand "crypto/rand" + "fmt" + "io" + "math/big" +) + +var ( + // idReader is used for random id generation. This declaration allows us to + // replace it for testing. + idReader = cryptorand.Reader +) + +// parameters for random identifier generation. We can tweak this when there is +// time for further analysis. +const ( + randomIDEntropyBytes = 17 + randomIDBase = 36 + + // To ensure that all identifiers are fixed length, we make sure they + // get padded out or truncated to 25 characters. + // + // For academics, f5lxx1zz5pnorynqglhzmsp33 == 2^128 - 1. This value + // was calculated from floor(log(2^128-1, 36)) + 1. + // + // While 128 bits is the largest whole-byte size that fits into 25 + // base-36 characters, we generate an extra byte of entropy to fill + // in the high bits, which would otherwise be 0. This gives us a more + // even distribution of the first character. + // + // See http://mathworld.wolfram.com/NumberLength.html for more information. + maxRandomIDLength = 25 +) + +// NewID generates a new identifier for use where random identifiers with low +// collision probability are required. +// +// With the parameters in this package, the generated identifier will provide +// ~129 bits of entropy encoded with base36. Leading padding is added if the +// string is less 25 bytes. We do not intend to maintain this interface, so +// identifiers should be treated opaquely. +func NewID() string { + var p [randomIDEntropyBytes]byte + + if _, err := io.ReadFull(idReader, p[:]); err != nil { + panic(fmt.Errorf("failed to read random bytes: %v", err)) + } + + p[0] |= 0x80 // set high bit to avoid the need for padding + return (&big.Int{}).SetBytes(p[:]).Text(randomIDBase)[1 : maxRandomIDLength+1] +} diff --git a/components/engine/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go b/components/engine/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go index c5a3b5bd6e..7f8bf3c0df 100644 --- a/components/engine/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go +++ b/components/engine/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go @@ -1,9 +1,12 @@ package filesync import ( + "bufio" + io "io" "os" "time" + "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/tonistiigi/fsutil" "google.golang.org/grpc" @@ -17,6 +20,46 @@ func sendDiffCopy(stream grpc.Stream, dir string, includes, excludes []string, p }, progress) } +func newStreamWriter(stream grpc.ClientStream) io.WriteCloser { + wc := &streamWriterCloser{ClientStream: stream} + return &bufferedWriteCloser{Writer: bufio.NewWriter(wc), Closer: wc} +} + +type bufferedWriteCloser struct { + *bufio.Writer + io.Closer +} + +func (bwc *bufferedWriteCloser) Close() error { + if err := bwc.Writer.Flush(); err != nil { + return err + } + return bwc.Closer.Close() +} + +type streamWriterCloser struct { + grpc.ClientStream +} + +func (wc *streamWriterCloser) Write(dt []byte) (int, error) { + if err := wc.ClientStream.SendMsg(&BytesMessage{Data: dt}); err != nil { + return 0, err + } + return len(dt), nil +} + +func (wc *streamWriterCloser) Close() error { + if err := wc.ClientStream.CloseSend(); err != nil { + return err + } + // block until receiver is done + var bm BytesMessage + if err := wc.ClientStream.RecvMsg(&bm); err != io.EOF { + return err + } + return nil +} + func recvDiffCopy(ds grpc.Stream, dest string, cu CacheUpdater, progress progressCb) error { st := time.Now() defer func() { @@ -53,3 +96,18 @@ func syncTargetDiffCopy(ds grpc.Stream, dest string) error { }(), }) } + +func writeTargetFile(ds grpc.Stream, wc io.WriteCloser) error { + for { + bm := BytesMessage{} + if err := ds.RecvMsg(&bm); err != nil { + if errors.Cause(err) == io.EOF { + return nil + } + return err + } + if _, err := wc.Write(bm.Data); err != nil { + return err + } + } +} diff --git a/components/engine/vendor/github.com/moby/buildkit/session/filesync/filesync.go b/components/engine/vendor/github.com/moby/buildkit/session/filesync/filesync.go index 5642f07ac4..232a696d73 100644 --- a/components/engine/vendor/github.com/moby/buildkit/session/filesync/filesync.go +++ b/components/engine/vendor/github.com/moby/buildkit/session/filesync/filesync.go @@ -1,14 +1,15 @@ package filesync import ( + "context" "fmt" + io "io" "os" "strings" "github.com/moby/buildkit/session" "github.com/pkg/errors" "github.com/tonistiigi/fsutil" - "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/metadata" ) @@ -16,6 +17,7 @@ import ( const ( keyOverrideExcludes = "override-excludes" keyIncludePatterns = "include-patterns" + keyExcludePatterns = "exclude-patterns" keyDirName = "dir-name" ) @@ -54,7 +56,7 @@ func (sp *fsSyncProvider) TarStream(stream FileSync_TarStreamServer) error { return sp.handle("tarstream", stream) } -func (sp *fsSyncProvider) handle(method string, stream grpc.ServerStream) error { +func (sp *fsSyncProvider) handle(method string, stream grpc.ServerStream) (retErr error) { var pr *protocol for _, p := range supportedProtocols { if method == p.name && isProtoSupported(p.name) { @@ -66,20 +68,21 @@ func (sp *fsSyncProvider) handle(method string, stream grpc.ServerStream) error return errors.New("failed to negotiate protocol") } - opts, _ := metadata.FromContext(stream.Context()) // if no metadata continue with empty object + opts, _ := metadata.FromIncomingContext(stream.Context()) // if no metadata continue with empty object + dirName := "" name, ok := opts[keyDirName] - if !ok || len(name) != 1 { - return errors.New("no dir name in request") + if ok && len(name) > 0 { + dirName = name[0] } - dir, ok := sp.dirs[name[0]] + dir, ok := sp.dirs[dirName] if !ok { - return errors.Errorf("no access allowed to dir %q", name[0]) + return errors.Errorf("no access allowed to dir %q", dirName) } - var excludes []string - if len(opts[keyOverrideExcludes]) == 0 || opts[keyOverrideExcludes][0] != "true" { + excludes := opts[keyExcludePatterns] + if len(dir.Excludes) != 0 && (len(opts[keyOverrideExcludes]) == 0 || opts[keyOverrideExcludes][0] != "true") { excludes = dir.Excludes } includes := opts[keyIncludePatterns] @@ -138,7 +141,8 @@ var supportedProtocols = []protocol{ type FSSendRequestOpt struct { Name string IncludePatterns []string - OverrideExcludes bool + ExcludePatterns []string + OverrideExcludes bool // deprecated: this is used by docker/cli for automatically loading .dockerignore from the directory DestDir string CacheUpdater CacheUpdater ProgressCb func(int, bool) @@ -173,6 +177,10 @@ func FSSync(ctx context.Context, c session.Caller, opt FSSendRequestOpt) error { opts[keyIncludePatterns] = opt.IncludePatterns } + if opt.ExcludePatterns != nil { + opts[keyExcludePatterns] = opt.ExcludePatterns + } + opts[keyDirName] = []string{opt.Name} ctx, cancel := context.WithCancel(ctx) @@ -182,7 +190,7 @@ func FSSync(ctx context.Context, c session.Caller, opt FSSendRequestOpt) error { var stream grpc.ClientStream - ctx = metadata.NewContext(ctx, opts) + ctx = metadata.NewOutgoingContext(ctx, opts) switch pr.name { case "tarstream": @@ -204,16 +212,25 @@ func FSSync(ctx context.Context, c session.Caller, opt FSSendRequestOpt) error { return pr.recvFn(stream, opt.DestDir, opt.CacheUpdater, opt.ProgressCb) } -// NewFSSyncTarget allows writing into a directory -func NewFSSyncTarget(outdir string) session.Attachable { +// NewFSSyncTargetDir allows writing into a directory +func NewFSSyncTargetDir(outdir string) session.Attachable { p := &fsSyncTarget{ outdir: outdir, } return p } +// NewFSSyncTarget allows writing into an io.WriteCloser +func NewFSSyncTarget(w io.WriteCloser) session.Attachable { + p := &fsSyncTarget{ + outfile: w, + } + return p +} + type fsSyncTarget struct { - outdir string + outdir string + outfile io.WriteCloser } func (sp *fsSyncTarget) Register(server *grpc.Server) { @@ -221,7 +238,14 @@ func (sp *fsSyncTarget) Register(server *grpc.Server) { } func (sp *fsSyncTarget) DiffCopy(stream FileSend_DiffCopyServer) error { - return syncTargetDiffCopy(stream, sp.outdir) + if sp.outdir != "" { + return syncTargetDiffCopy(stream, sp.outdir) + } + if sp.outfile == nil { + return errors.New("empty outfile and outdir") + } + defer sp.outfile.Close() + return writeTargetFile(stream, sp.outfile) } func CopyToCaller(ctx context.Context, srcPath string, c session.Caller, progress func(int, bool)) error { @@ -239,3 +263,19 @@ func CopyToCaller(ctx context.Context, srcPath string, c session.Caller, progres return sendDiffCopy(cc, srcPath, nil, nil, progress, nil) } + +func CopyFileWriter(ctx context.Context, c session.Caller) (io.WriteCloser, error) { + method := session.MethodURL(_FileSend_serviceDesc.ServiceName, "diffcopy") + if !c.Supports(method) { + return nil, errors.Errorf("method %s not supported by the client", method) + } + + client := NewFileSendClient(c.Conn()) + + cc, err := client.DiffCopy(ctx) + if err != nil { + return nil, err + } + + return newStreamWriter(cc), nil +} diff --git a/components/engine/vendor/github.com/moby/buildkit/session/filesync/filesync.pb.go b/components/engine/vendor/github.com/moby/buildkit/session/filesync/filesync.pb.go index 69c78886f2..4a9697e342 100644 --- a/components/engine/vendor/github.com/moby/buildkit/session/filesync/filesync.pb.go +++ b/components/engine/vendor/github.com/moby/buildkit/session/filesync/filesync.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-gogo. +// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: filesync.proto -// DO NOT EDIT! /* Package filesync is a generated protocol buffer package. @@ -22,10 +21,8 @@ import bytes "bytes" import strings "strings" import reflect "reflect" -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) +import context "golang.org/x/net/context" +import grpc "google.golang.org/grpc" import io "io" @@ -61,10 +58,7 @@ func init() { } func (this *BytesMessage) Equal(that interface{}) bool { if that == nil { - if this == nil { - return true - } - return false + return this == nil } that1, ok := that.(*BytesMessage) @@ -77,10 +71,7 @@ func (this *BytesMessage) Equal(that interface{}) bool { } } if that1 == nil { - if this == nil { - return true - } - return false + return this == nil } else if this == nil { return false } @@ -397,24 +388,6 @@ func (m *BytesMessage) MarshalTo(dAtA []byte) (int, error) { return i, nil } -func encodeFixed64Filesync(dAtA []byte, offset int, v uint64) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - dAtA[offset+4] = uint8(v >> 32) - dAtA[offset+5] = uint8(v >> 40) - dAtA[offset+6] = uint8(v >> 48) - dAtA[offset+7] = uint8(v >> 56) - return offset + 8 -} -func encodeFixed32Filesync(dAtA []byte, offset int, v uint32) int { - dAtA[offset] = uint8(v) - dAtA[offset+1] = uint8(v >> 8) - dAtA[offset+2] = uint8(v >> 16) - dAtA[offset+3] = uint8(v >> 24) - return offset + 4 -} func encodeVarintFilesync(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) @@ -655,7 +628,7 @@ func init() { proto.RegisterFile("filesync.proto", fileDescriptorFilesync) } var fileDescriptorFilesync = []byte{ // 208 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0xcb, 0xcc, 0x49, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0xcb, 0xcc, 0x49, 0x2d, 0xae, 0xcc, 0x4b, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0xc8, 0xcd, 0x4f, 0xaa, 0xd4, 0x83, 0x0b, 0x96, 0x19, 0x2a, 0x29, 0x71, 0xf1, 0x38, 0x55, 0x96, 0xa4, 0x16, 0xfb, 0xa6, 0x16, 0x17, 0x27, 0xa6, 0xa7, 0x0a, 0x09, 0x71, 0xb1, 0xa4, 0x24, 0x96, 0x24, 0x4a, 0x30, 0x2a, diff --git a/components/engine/vendor/github.com/moby/buildkit/session/grpc.go b/components/engine/vendor/github.com/moby/buildkit/session/grpc.go index 71d77bf448..2798b6abba 100644 --- a/components/engine/vendor/github.com/moby/buildkit/session/grpc.go +++ b/components/engine/vendor/github.com/moby/buildkit/session/grpc.go @@ -1,12 +1,15 @@ package session import ( + "context" "net" + "sync/atomic" "time" + "github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc" + opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "golang.org/x/net/context" "golang.org/x/net/http2" "google.golang.org/grpc" "google.golang.org/grpc/health/grpc_health_v1" @@ -22,11 +25,28 @@ func serve(ctx context.Context, grpcServer *grpc.Server, conn net.Conn) { } func grpcClientConn(ctx context.Context, conn net.Conn) (context.Context, *grpc.ClientConn, error) { - dialOpt := grpc.WithDialer(func(addr string, d time.Duration) (net.Conn, error) { + var dialCount int64 + dialer := grpc.WithDialer(func(addr string, d time.Duration) (net.Conn, error) { + if c := atomic.AddInt64(&dialCount, 1); c > 1 { + return nil, errors.Errorf("only one connection allowed") + } return conn, nil }) - cc, err := grpc.DialContext(ctx, "", dialOpt, grpc.WithInsecure()) + dialOpts := []grpc.DialOption{ + dialer, + grpc.WithInsecure(), + } + + if span := opentracing.SpanFromContext(ctx); span != nil { + tracer := span.Tracer() + dialOpts = append(dialOpts, + grpc.WithUnaryInterceptor(otgrpc.OpenTracingClientInterceptor(tracer, traceFilter())), + grpc.WithStreamInterceptor(otgrpc.OpenTracingStreamClientInterceptor(tracer, traceFilter())), + ) + } + + cc, err := grpc.DialContext(ctx, "", dialOpts...) if err != nil { return nil, nil, errors.Wrap(err, "failed to create grpc client") } @@ -41,7 +61,7 @@ func monitorHealth(ctx context.Context, cc *grpc.ClientConn, cancelConn func()) defer cancelConn() defer cc.Close() - ticker := time.NewTicker(500 * time.Millisecond) + ticker := time.NewTicker(1 * time.Second) defer ticker.Stop() healthClient := grpc_health_v1.NewHealthClient(cc) @@ -50,8 +70,7 @@ func monitorHealth(ctx context.Context, cc *grpc.ClientConn, cancelConn func()) case <-ctx.Done(): return case <-ticker.C: - <-ticker.C - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) _, err := healthClient.Check(ctx, &grpc_health_v1.HealthCheckRequest{}) cancel() if err != nil { diff --git a/components/engine/vendor/github.com/moby/buildkit/session/manager.go b/components/engine/vendor/github.com/moby/buildkit/session/manager.go index b3e5955652..f401c7fb33 100644 --- a/components/engine/vendor/github.com/moby/buildkit/session/manager.go +++ b/components/engine/vendor/github.com/moby/buildkit/session/manager.go @@ -1,13 +1,13 @@ package session import ( + "context" "net" "net/http" "strings" "sync" "github.com/pkg/errors" - "golang.org/x/net/context" "google.golang.org/grpc" ) @@ -150,6 +150,12 @@ func (sm *Manager) handleConn(ctx context.Context, conn net.Conn, opts map[strin // Get returns a session by ID func (sm *Manager) Get(ctx context.Context, id string) (Caller, error) { + // session prefix is used to identify vertexes with different contexts so + // they would not collide, but for lookup we don't need the prefix + if p := strings.SplitN(id, ":", 2); len(p) == 2 && len(p[1]) > 0 { + id = p[1] + } + ctx, cancel := context.WithCancel(ctx) defer cancel() diff --git a/components/engine/vendor/github.com/moby/buildkit/session/session.go b/components/engine/vendor/github.com/moby/buildkit/session/session.go index 454c3d7f3f..47c9579633 100644 --- a/components/engine/vendor/github.com/moby/buildkit/session/session.go +++ b/components/engine/vendor/github.com/moby/buildkit/session/session.go @@ -1,11 +1,14 @@ package session import ( + "context" "net" + "strings" - "github.com/docker/docker/pkg/stringid" + "github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc" + "github.com/moby/buildkit/identity" + opentracing "github.com/opentracing/opentracing-go" "github.com/pkg/errors" - "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/health" "google.golang.org/grpc/health/grpc_health_v1" @@ -35,16 +38,27 @@ type Session struct { cancelCtx func() done chan struct{} grpcServer *grpc.Server + conn net.Conn } // NewSession returns a new long running session -func NewSession(name, sharedKey string) (*Session, error) { - id := stringid.GenerateRandomID() +func NewSession(ctx context.Context, name, sharedKey string) (*Session, error) { + id := identity.NewID() + + serverOpts := []grpc.ServerOption{} + if span := opentracing.SpanFromContext(ctx); span != nil { + tracer := span.Tracer() + serverOpts = []grpc.ServerOption{ + grpc.StreamInterceptor(otgrpc.OpenTracingStreamServerInterceptor(span.Tracer(), traceFilter())), + grpc.UnaryInterceptor(otgrpc.OpenTracingServerInterceptor(tracer, traceFilter())), + } + } + s := &Session{ id: id, name: name, sharedKey: sharedKey, - grpcServer: grpc.NewServer(), + grpcServer: grpc.NewServer(serverOpts...), } grpc_health_v1.RegisterHealthServer(s.grpcServer, health.NewServer()) @@ -85,6 +99,7 @@ func (s *Session) Run(ctx context.Context, dialer Dialer) error { if err != nil { return errors.Wrap(err, "failed to dial gRPC") } + s.conn = conn serve(ctx, s.grpcServer, conn) return nil } @@ -92,8 +107,10 @@ func (s *Session) Run(ctx context.Context, dialer Dialer) error { // Close closes the session func (s *Session) Close() error { if s.cancelCtx != nil && s.done != nil { + if s.conn != nil { + s.conn.Close() + } s.grpcServer.Stop() - s.cancelCtx() <-s.done } return nil @@ -116,3 +133,11 @@ func (s *Session) closed() bool { func MethodURL(s, m string) string { return "/" + s + "/" + m } + +func traceFilter() otgrpc.Option { + return otgrpc.IncludingSpans(func(parentSpanCtx opentracing.SpanContext, + method string, + req, resp interface{}) bool { + return !strings.HasSuffix(method, "Health/Check") + }) +} diff --git a/components/engine/vendor/github.com/moby/buildkit/vendor.conf b/components/engine/vendor/github.com/moby/buildkit/vendor.conf index f3760bd0f7..7ded9c2d90 100644 --- a/components/engine/vendor/github.com/moby/buildkit/vendor.conf +++ b/components/engine/vendor/github.com/moby/buildkit/vendor.conf @@ -1,46 +1,68 @@ github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd -github.com/pkg/errors c605e284fe17294bda444b34710735b29d1a9d90 +github.com/pkg/errors v0.8.0 github.com/stretchr/testify v1.1.4 github.com/davecgh/go-spew v1.1.0 github.com/pmezard/go-difflib v1.0.0 -golang.org/x/sys 739734461d1c916b6c72a63d7efda2b27edb369f +golang.org/x/sys 314a259e304ff91bd6985da2a7149bbf91237993 -github.com/containerd/containerd d1e11f17ec7b325f89608dd46c128300b8727d50 -golang.org/x/sync f52d1811a62927559de87708c8913c1650ce4f26 +github.com/containerd/containerd 7f800e0a7bb1e2547baca4d5bbf317ceeb341c14 +github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788 +golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c github.com/sirupsen/logrus v1.0.0 -google.golang.org/grpc v1.3.0 -github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448 -golang.org/x/net 1f9224279e98554b6a6432d4dd998a739f8b2b7c -github.com/gogo/protobuf d2e1ade2d719b78fe5b061b4c18a9f7111b5bdc8 -github.com/golang/protobuf 5a0f697c9ed9d68fef0116532c6e05cfeae00e55 -github.com/containerd/continuity 86cec1535a968310e7532819f699ff2830ed7463 -github.com/opencontainers/image-spec v1.0.0 -github.com/opencontainers/runc e775f0fba3ea329b8b766451c892c41a3d49594d -github.com/Microsoft/go-winio v0.4.1 -github.com/containerd/fifo 69b99525e472735860a5269b75af1970142b3062 -github.com/opencontainers/runtime-spec 96de01bbb42c7af89bff100e10a9f0fb62e75bfb -github.com/containerd/go-runc 2774a2ea124a5c2d0aba13b5c2dd8a5a9a48775d -github.com/containerd/console 7fed77e673ca4abcd0cbd6d4d0e0e22137cbd778 -github.com/Azure/go-ansiterm 19f72df4d05d31cbe1c56bfc8045c96babff6c7e +google.golang.org/grpc v1.10.1 +github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7 +golang.org/x/net 0ed95abb35c445290478a5348a7b38bb154135fd +github.com/gogo/protobuf v1.0.0 +github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef +github.com/golang/protobuf 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9 +github.com/containerd/continuity d3c23511c1bf5851696cba83143d9cbcd666869b +github.com/opencontainers/image-spec v1.0.1 +github.com/opencontainers/runc 0e561642f81e84ebd0b3afd6ec510c75a2ccb71b +github.com/Microsoft/go-winio v0.4.5 +github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c +github.com/opencontainers/runtime-spec v1.0.1 +github.com/containerd/go-runc f271fa2021de855d4d918dbef83c5fe19db1bdd5 +github.com/containerd/console cb7008ab3d8359b78c5f464cb7cf160107ad5925 google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944 golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 +github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16 +github.com/Microsoft/hcsshim v0.6.10 -github.com/urfave/cli d70f47eeca3afd795160003bc6e28b001d60c67c -github.com/docker/go-units 0dadbb0345b35ec7ef35e228dabb8de89a65bf52 +github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c +github.com/morikuni/aec 39771216ff4c63d11f5e604076f9c45e8be1067b +github.com/docker/go-units v0.3.1 github.com/google/shlex 6f45313302b9c56850fc17f99e40caebce98c716 -golang.org/x/time 8be79e1e0910c292df4e79c241bb7e8f7e725959 +golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631 -github.com/BurntSushi/locker 392720b78f44e9d0249fcac6c43b111b47a370b8 -github.com/docker/docker 6f723db8c6f0c7f0b252674a9673a25b5978db04 https://github.com/tonistiigi/docker.git +github.com/BurntSushi/locker a6e239ea1c69bff1cfdb20c4b73dadf52f784b6a +github.com/docker/docker 71cd53e4a197b303c6ba086bd584ffd67a884281 github.com/pkg/profile 5b67d428864e92711fcbd2f8629456121a56d91f -github.com/tonistiigi/fsutil 1dedf6e90084bd88c4c518a15e68a37ed1370203 -github.com/stevvooe/continuity 86cec1535a968310e7532819f699ff2830ed7463 -github.com/dmcgowan/go-tar 2e2c51242e8993c50445dab7c03c8e7febddd0cf +github.com/tonistiigi/fsutil dc68c74458923f357474a9178bd198aa3ed11a5f github.com/hashicorp/go-immutable-radix 826af9ccf0feeee615d546d69b11f8e98da8c8f1 git://github.com/tonistiigi/go-immutable-radix.git github.com/hashicorp/golang-lru a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4 github.com/mitchellh/hashstructure 2bca23e0e452137f789efbc8610126fd8b94f73b github.com/docker/go-connections 3ede32e2033de7505e6500d6c868c2b9ed9f169d github.com/docker/distribution 30578ca32960a4d368bf6db67b0a33c2a1f3dc6f + +github.com/tonistiigi/units 29de085e9400559bd68aea2e7bc21566e7b8281d +github.com/docker/cli 99576756eb3303b7af8102c502f21a912e3c1af6 https://github.com/tonistiigi/docker-cli.git +github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1 +github.com/docker/libnetwork 822e5b59d346b7ad0735df2c8e445e9787320e67 + + +github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746 +github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7 +github.com/uber/jaeger-client-go e02c85f9069ea625a96fc4e1afb5e9ac6c569a6d +github.com/apache/thrift b2a4d4ae21c789b689dd162deb819665567f481c +github.com/uber/jaeger-lib c48167d9cae5887393dd5e61efd06a4a48b7fbb3 +github.com/codahale/hdrhistogram f8ad88b59a584afeee9d334eff879b104439117b + +github.com/opentracing-contrib/go-stdlib b1a47cfbdd7543e70e9ef3e73d0802ad306cc1cc +github.com/opencontainers/selinux 74a747aeaf2d66097b6908f572794f49f07dda2c + +# used by dockerfile tests +github.com/gotestyourself/gotestyourself cf3a5ab914a2efa8bc838d09f5918c1d44d029 +github.com/google/go-cmp v0.2.0 diff --git a/components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter_linux.go b/components/engine/vendor/github.com/tonistiigi/fsutil/chtimes_linux.go similarity index 100% rename from components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter_linux.go rename to components/engine/vendor/github.com/tonistiigi/fsutil/chtimes_linux.go diff --git a/components/engine/vendor/github.com/tonistiigi/fsutil/chtimes_nolinux.go b/components/engine/vendor/github.com/tonistiigi/fsutil/chtimes_nolinux.go new file mode 100644 index 0000000000..39bfdfee5b --- /dev/null +++ b/components/engine/vendor/github.com/tonistiigi/fsutil/chtimes_nolinux.go @@ -0,0 +1,13 @@ +// +build !linux + +package fsutil + +import ( + "os" + "time" +) + +func chtimes(path string, un int64) error { + mtime := time.Unix(0, un) + return os.Chtimes(path, mtime, mtime) +} diff --git a/components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter.go b/components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter.go index a465615c3b..e2d034c75e 100644 --- a/components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter.go +++ b/components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter.go @@ -55,6 +55,7 @@ func NewDiskWriter(ctx context.Context, dest string, opt DiskWriterOpt) (*DiskWr eg: eg, ctx: ctx, cancel: cancel, + filter: opt.Filter, }, nil } diff --git a/components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter_darwin.go b/components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter_darwin.go deleted file mode 100644 index 94d3324acf..0000000000 --- a/components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter_darwin.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build darwin - -package fsutil - -func chtimes(path string, un int64) error { - return nil -} diff --git a/components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter_windows.go b/components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter_windows.go index 16a26f01c5..c6d0d7bec7 100644 --- a/components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter_windows.go +++ b/components/engine/vendor/github.com/tonistiigi/fsutil/diskwriter_windows.go @@ -3,9 +3,6 @@ package fsutil import ( - "os" - "time" - "github.com/pkg/errors" ) @@ -13,11 +10,6 @@ func rewriteMetadata(p string, stat *Stat) error { return chtimes(p, stat.ModTime) } -func chtimes(path string, un int64) error { - mtime := time.Unix(0, un) - return os.Chtimes(path, mtime, mtime) -} - // handleTarTypeBlockCharFifo is an OS-specific helper function used by // createTarFile to handle the following types of header: Block; Char; Fifo func handleTarTypeBlockCharFifo(path string, stat *Stat) error { diff --git a/components/engine/vendor/github.com/tonistiigi/fsutil/receive.go b/components/engine/vendor/github.com/tonistiigi/fsutil/receive.go index 233c28b70e..5867c984ee 100644 --- a/components/engine/vendor/github.com/tonistiigi/fsutil/receive.go +++ b/components/engine/vendor/github.com/tonistiigi/fsutil/receive.go @@ -55,25 +55,33 @@ type receiver struct { type dynamicWalker struct { walkChan chan *currentPath - closed bool + err error + closeCh chan struct{} } func newDynamicWalker() *dynamicWalker { return &dynamicWalker{ walkChan: make(chan *currentPath, 128), + closeCh: make(chan struct{}), } } func (w *dynamicWalker) update(p *currentPath) error { - if w.closed { - return errors.New("walker is closed") + select { + case <-w.closeCh: + return errors.Wrap(w.err, "walker is closed") + default: } if p == nil { close(w.walkChan) return nil } - w.walkChan <- p - return nil + select { + case w.walkChan <- p: + return nil + case <-w.closeCh: + return errors.Wrap(w.err, "walker is closed") + } } func (w *dynamicWalker) fill(ctx context.Context, pathC chan<- *currentPath) error { @@ -85,6 +93,8 @@ func (w *dynamicWalker) fill(ctx context.Context, pathC chan<- *currentPath) err } pathC <- p case <-ctx.Done(): + w.err = ctx.Err() + close(w.closeCh) return ctx.Err() } } @@ -106,7 +116,12 @@ func (r *receiver) run(ctx context.Context) error { w := newDynamicWalker() - g.Go(func() error { + g.Go(func() (retErr error) { + defer func() { + if retErr != nil { + r.conn.SendMsg(&Packet{Type: PACKET_ERR, Data: []byte(retErr.Error())}) + } + }() destWalker := emptyWalker if !r.merge { destWalker = GetWalkerFn(r.dest) @@ -143,6 +158,8 @@ func (r *receiver) run(ctx context.Context) error { } switch p.Type { + case PACKET_ERR: + return errors.Errorf("error from sender: %s", p.Data) case PACKET_STAT: if p.Stat == nil { if err := w.update(nil); err != nil { @@ -183,7 +200,15 @@ func (r *receiver) run(ctx context.Context) error { } } case PACKET_FIN: - return nil + for { + var p Packet + if err := r.conn.RecvMsg(&p); err != nil { + if err == io.EOF { + return nil + } + return err + } + } } } }) @@ -208,10 +233,13 @@ func (r *receiver) asyncDataFunc(ctx context.Context, p string, wc io.WriteClose return err } err := wwc.Wait(ctx) + if err != nil { + return err + } r.muPipes.Lock() delete(r.pipes, id) r.muPipes.Unlock() - return err + return nil } type wrappedWriteCloser struct { diff --git a/components/engine/vendor/github.com/tonistiigi/fsutil/send.go b/components/engine/vendor/github.com/tonistiigi/fsutil/send.go index c7b6382c6c..d3cda0bb64 100644 --- a/components/engine/vendor/github.com/tonistiigi/fsutil/send.go +++ b/components/engine/vendor/github.com/tonistiigi/fsutil/send.go @@ -57,7 +57,11 @@ func (s *sender) run(ctx context.Context) error { defer s.updateProgress(0, true) g.Go(func() error { - return s.walk(ctx) + err := s.walk(ctx) + if err != nil { + s.conn.SendMsg(&Packet{Type: PACKET_ERR, Data: []byte(err.Error())}) + } + return err }) for i := 0; i < 4; i++ { @@ -90,6 +94,8 @@ func (s *sender) run(ctx context.Context) error { return err } switch p.Type { + case PACKET_ERR: + return errors.Errorf("error from receiver: %s", p.Data) case PACKET_REQ: if err := s.queue(p.ID); err != nil { return err @@ -126,6 +132,7 @@ func (s *sender) queue(id uint32) error { func (s *sender) sendFile(h *sendHandle) error { f, err := os.Open(filepath.Join(s.root, h.path)) if err == nil { + defer f.Close() buf := bufPool.Get().([]byte) defer bufPool.Put(buf) if _, err := io.CopyBuffer(&fileSender{sender: s, id: h.id}, f, buf); err != nil { diff --git a/components/engine/vendor/github.com/tonistiigi/fsutil/walker.go b/components/engine/vendor/github.com/tonistiigi/fsutil/walker.go index db1af56b49..d05a42dbed 100644 --- a/components/engine/vendor/github.com/tonistiigi/fsutil/walker.go +++ b/components/engine/vendor/github.com/tonistiigi/fsutil/walker.go @@ -39,14 +39,22 @@ func Walk(ctx context.Context, p string, opt *WalkOpt, fn filepath.WalkFunc) err } } + var lastIncludedDir string + var includePatternPrefixes []string + seenFiles := make(map[uint64]string) - return filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { + return filepath.Walk(root, func(path string, fi os.FileInfo, err error) (retErr error) { if err != nil { if os.IsNotExist(err) { return filepath.SkipDir } return err } + defer func() { + if retErr != nil && os.IsNotExist(errors.Cause(retErr)) { + retErr = filepath.SkipDir + } + }() origpath := path path, err = filepath.Rel(root, path) if err != nil { @@ -59,18 +67,34 @@ func Walk(ctx context.Context, p string, opt *WalkOpt, fn filepath.WalkFunc) err if opt != nil { if opt.IncludePatterns != nil { + if includePatternPrefixes == nil { + includePatternPrefixes = patternPrefixes(opt.IncludePatterns) + } matched := false - for _, p := range opt.IncludePatterns { - if m, _ := filepath.Match(p, path); m { + if lastIncludedDir != "" { + if strings.HasPrefix(path, lastIncludedDir+string(filepath.Separator)) { matched = true - break } } if !matched { - if fi.IsDir() { - return filepath.SkipDir + for _, p := range opt.IncludePatterns { + if m, _ := filepath.Match(p, path); m { + matched = true + break + } + } + if matched && fi.IsDir() { + lastIncludedDir = path + } + } + if !matched { + if !fi.IsDir() { + return nil + } else { + if noPossiblePrefixMatch(path, includePatternPrefixes) { + return filepath.SkipDir + } } - return nil } } if pm != nil { @@ -174,3 +198,30 @@ func (s *StatInfo) IsDir() bool { func (s *StatInfo) Sys() interface{} { return s.Stat } + +func patternPrefixes(patterns []string) []string { + pfxs := make([]string, 0, len(patterns)) + for _, ptrn := range patterns { + idx := strings.IndexFunc(ptrn, func(ch rune) bool { + return ch == '*' || ch == '?' || ch == '[' || ch == '\\' + }) + if idx == -1 { + idx = len(ptrn) + } + pfxs = append(pfxs, ptrn[:idx]) + } + return pfxs +} + +func noPossiblePrefixMatch(p string, pfxs []string) bool { + for _, pfx := range pfxs { + chk := p + if len(pfx) < len(p) { + chk = p[:len(pfx)] + } + if strings.HasPrefix(pfx, chk) { + return false + } + } + return true +} diff --git a/components/engine/vendor/github.com/tonistiigi/fsutil/wire.pb.go b/components/engine/vendor/github.com/tonistiigi/fsutil/wire.pb.go index 263fb126be..9d334bbdba 100644 --- a/components/engine/vendor/github.com/tonistiigi/fsutil/wire.pb.go +++ b/components/engine/vendor/github.com/tonistiigi/fsutil/wire.pb.go @@ -29,6 +29,7 @@ const ( PACKET_REQ Packet_PacketType = 1 PACKET_DATA Packet_PacketType = 2 PACKET_FIN Packet_PacketType = 3 + PACKET_ERR Packet_PacketType = 4 ) var Packet_PacketType_name = map[int32]string{ @@ -36,12 +37,14 @@ var Packet_PacketType_name = map[int32]string{ 1: "PACKET_REQ", 2: "PACKET_DATA", 3: "PACKET_FIN", + 4: "PACKET_ERR", } var Packet_PacketType_value = map[string]int32{ "PACKET_STAT": 0, "PACKET_REQ": 1, "PACKET_DATA": 2, "PACKET_FIN": 3, + "PACKET_ERR": 4, } func (Packet_PacketType) EnumDescriptor() ([]byte, []int) { return fileDescriptorWire, []int{0, 0} } @@ -543,21 +546,22 @@ var ( func init() { proto.RegisterFile("wire.proto", fileDescriptorWire) } var fileDescriptorWire = []byte{ - // 253 bytes of a gzipped FileDescriptorProto + // 259 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0xcf, 0x2c, 0x4a, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x4b, 0x2b, 0x2e, 0x2d, 0xc9, 0xcc, 0x91, 0xe2, - 0x2a, 0x2e, 0x49, 0x2c, 0x81, 0x88, 0x29, 0x9d, 0x65, 0xe4, 0x62, 0x0b, 0x48, 0x4c, 0xce, 0x4e, + 0x2a, 0x2e, 0x49, 0x2c, 0x81, 0x88, 0x29, 0xdd, 0x65, 0xe4, 0x62, 0x0b, 0x48, 0x4c, 0xce, 0x4e, 0x2d, 0x11, 0xd2, 0xe5, 0x62, 0x29, 0xa9, 0x2c, 0x48, 0x95, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x33, 0x92, 0xd4, 0x83, 0xa8, 0xd6, 0x83, 0xc8, 0x42, 0xa9, 0x90, 0xca, 0x82, 0xd4, 0x20, 0xb0, 0x32, 0x21, 0x05, 0x2e, 0x16, 0x90, 0x39, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xdc, 0x46, 0x3c, 0x30, 0xe5, 0xc1, 0x25, 0x89, 0x25, 0x41, 0x60, 0x19, 0x21, 0x3e, 0x2e, 0x26, 0x4f, 0x17, 0x09, 0x66, 0x05, 0x46, 0x0d, 0xde, 0x20, 0x26, 0x4f, 0x17, 0x21, 0x21, 0x2e, 0x96, 0x94, 0xc4, 0x92, 0x44, 0x09, - 0x16, 0x05, 0x46, 0x0d, 0x9e, 0x20, 0x30, 0x5b, 0xc9, 0x8f, 0x8b, 0x0b, 0x61, 0xb2, 0x10, 0x3f, + 0x16, 0x05, 0x46, 0x0d, 0x9e, 0x20, 0x30, 0x5b, 0x29, 0x8e, 0x8b, 0x0b, 0x61, 0xb2, 0x10, 0x3f, 0x17, 0x77, 0x80, 0xa3, 0xb3, 0xb7, 0x6b, 0x48, 0x7c, 0x70, 0x88, 0x63, 0x88, 0x00, 0x83, 0x10, 0x1f, 0x17, 0x17, 0x54, 0x20, 0xc8, 0x35, 0x50, 0x80, 0x11, 0x49, 0x81, 0x8b, 0x63, 0x88, 0xa3, - 0x00, 0x13, 0x92, 0x02, 0x37, 0x4f, 0x3f, 0x01, 0x66, 0x27, 0x9d, 0x0b, 0x0f, 0xe5, 0x18, 0x6e, - 0x3c, 0x94, 0x63, 0xf8, 0xf0, 0x50, 0x8e, 0xb1, 0xe1, 0x91, 0x1c, 0xe3, 0x8a, 0x47, 0x72, 0x8c, - 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x8b, 0x47, 0x72, - 0x0c, 0x1f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x90, 0xc4, 0x06, 0x0e, 0x04, 0x63, 0x40, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xda, 0x30, 0x43, 0x22, 0x26, 0x01, 0x00, 0x00, + 0x00, 0x13, 0x92, 0x02, 0x37, 0x4f, 0x3f, 0x01, 0x66, 0x24, 0xbe, 0x6b, 0x50, 0x90, 0x00, 0x8b, + 0x93, 0xce, 0x85, 0x87, 0x72, 0x0c, 0x37, 0x1e, 0xca, 0x31, 0x7c, 0x78, 0x28, 0xc7, 0xd8, 0xf0, + 0x48, 0x8e, 0x71, 0xc5, 0x23, 0x39, 0xc6, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, + 0xf0, 0x48, 0x8e, 0xf1, 0xc5, 0x23, 0x39, 0x86, 0x0f, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, + 0x48, 0x62, 0x03, 0x07, 0x8a, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x8b, 0xce, 0x55, 0x3b, 0x36, + 0x01, 0x00, 0x00, } diff --git a/components/engine/vendor/github.com/tonistiigi/fsutil/wire.proto b/components/engine/vendor/github.com/tonistiigi/fsutil/wire.proto index d19432093f..f9b33f312c 100644 --- a/components/engine/vendor/github.com/tonistiigi/fsutil/wire.proto +++ b/components/engine/vendor/github.com/tonistiigi/fsutil/wire.proto @@ -10,6 +10,7 @@ message Packet { PACKET_REQ = 1; PACKET_DATA = 2; PACKET_FIN = 3; + PACKET_ERR = 4; } PacketType type = 1; Stat stat = 2; From f01f23683f23fd2b615cb1212b5f9a76b12b1229 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Sat, 2 Jun 2018 10:18:25 -0700 Subject: [PATCH 2/2] vendor: add new opentracing deps for session tracing Signed-off-by: Tonis Tiigi Upstream-commit: ad77dee8baafc478baa18f65a4972ba19b6e973f Component: engine --- components/engine/vendor.conf | 3 + .../grpc-ecosystem/grpc-opentracing/LICENSE | 27 ++ .../grpc-ecosystem/grpc-opentracing/PATENTS | 23 ++ .../grpc-opentracing/README.rst | 25 ++ .../grpc-opentracing/go/otgrpc/README.md | 57 ++++ .../grpc-opentracing/go/otgrpc/client.go | 239 ++++++++++++++ .../grpc-opentracing/go/otgrpc/errors.go | 69 ++++ .../grpc-opentracing/go/otgrpc/options.go | 76 +++++ .../grpc-opentracing/go/otgrpc/package.go | 5 + .../grpc-opentracing/go/otgrpc/server.go | 141 ++++++++ .../grpc-opentracing/go/otgrpc/shared.go | 42 +++ .../grpc-opentracing/python/README.md | 4 + .../python/examples/protos/command_line.proto | 15 + .../python/examples/protos/store.proto | 37 +++ .../opentracing/opentracing-go/LICENSE | 21 ++ .../opentracing/opentracing-go/README.md | 163 ++++++++++ .../opentracing/opentracing-go/ext/tags.go | 210 ++++++++++++ .../opentracing-go/globaltracer.go | 32 ++ .../opentracing/opentracing-go/gocontext.go | 57 ++++ .../opentracing/opentracing-go/log/field.go | 269 +++++++++++++++ .../opentracing/opentracing-go/log/util.go | 54 ++++ .../opentracing/opentracing-go/noop.go | 64 ++++ .../opentracing/opentracing-go/propagation.go | 176 ++++++++++ .../opentracing/opentracing-go/span.go | 185 +++++++++++ .../opentracing/opentracing-go/tracer.go | 305 ++++++++++++++++++ 25 files changed, 2299 insertions(+) create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/LICENSE create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/PATENTS create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/README.rst create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/README.md create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/client.go create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/errors.go create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/options.go create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/package.go create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/server.go create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/shared.go create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/python/README.md create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/python/examples/protos/command_line.proto create mode 100644 components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/python/examples/protos/store.proto create mode 100644 components/engine/vendor/github.com/opentracing/opentracing-go/LICENSE create mode 100644 components/engine/vendor/github.com/opentracing/opentracing-go/README.md create mode 100644 components/engine/vendor/github.com/opentracing/opentracing-go/ext/tags.go create mode 100644 components/engine/vendor/github.com/opentracing/opentracing-go/globaltracer.go create mode 100644 components/engine/vendor/github.com/opentracing/opentracing-go/gocontext.go create mode 100644 components/engine/vendor/github.com/opentracing/opentracing-go/log/field.go create mode 100644 components/engine/vendor/github.com/opentracing/opentracing-go/log/util.go create mode 100644 components/engine/vendor/github.com/opentracing/opentracing-go/noop.go create mode 100644 components/engine/vendor/github.com/opentracing/opentracing-go/propagation.go create mode 100644 components/engine/vendor/github.com/opentracing/opentracing-go/span.go create mode 100644 components/engine/vendor/github.com/opentracing/opentracing-go/tracer.go diff --git a/components/engine/vendor.conf b/components/engine/vendor.conf index 0e7fa7557c..df91f13c7d 100644 --- a/components/engine/vendor.conf +++ b/components/engine/vendor.conf @@ -26,8 +26,11 @@ github.com/RackSec/srslog 456df3a81436d29ba874f3590eeeee25d666f8a5 github.com/imdario/mergo 0.2.1 golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5 +# buildkit github.com/moby/buildkit b14fd548fe80c0399b105aeec5dbd96ccd2f7720 github.com/tonistiigi/fsutil dc68c74458923f357474a9178bd198aa3ed11a5f +github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746 +github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7 #get libnetwork packages diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/LICENSE b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/LICENSE new file mode 100644 index 0000000000..abe5fe170b --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2016, gRPC Ecosystem +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of grpc-opentracing nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/PATENTS b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/PATENTS new file mode 100644 index 0000000000..5cfe0175ee --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/PATENTS @@ -0,0 +1,23 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the GRPC project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of GRPC, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of GRPC. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of GRPC or any code incorporated within this +implementation of GRPC constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of GRPC +shall terminate as of the date such litigation is filed. +Status API Training Shop Blog About diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/README.rst b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/README.rst new file mode 100644 index 0000000000..1d44e691a8 --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/README.rst @@ -0,0 +1,25 @@ +################ +GRPC-OpenTracing +################ + +This package enables distributed tracing in GRPC clients and servers via `The OpenTracing Project`_: a set of consistent, expressive, vendor-neutral APIs for distributed tracing and context propagation. + +Once a production system contends with real concurrency or splits into many services, crucial (and formerly easy) tasks become difficult: user-facing latency optimization, root-cause analysis of backend errors, communication about distinct pieces of a now-distributed system, etc. Distributed tracing follows a request on its journey from inception to completion from mobile/browser all the way to the microservices. + +As core services and libraries adopt OpenTracing, the application builder is no longer burdened with the task of adding basic tracing instrumentation to their own code. In this way, developers can build their applications with the tools they prefer and benefit from built-in tracing instrumentation. OpenTracing implementations exist for major distributed tracing systems and can be bound or swapped with a one-line configuration change. + +******************* +Further Information +******************* + +If you’re interested in learning more about the OpenTracing standard, join the conversation on our `mailing list`_ or `Gitter`_. + +If you want to learn more about the underlying API for your platform, visit the `source code`_. + +If you would like to implement OpenTracing in your project and need help, feel free to send us a note at `community@opentracing.io`_. + +.. _The OpenTracing Project: http://opentracing.io/ +.. _source code: https://github.com/opentracing/ +.. _mailing list: http://opentracing.us13.list-manage.com/subscribe?u=180afe03860541dae59e84153&id=19117aa6cd +.. _Gitter: https://gitter.im/opentracing/public +.. _community@opentracing.io: community@opentracing.io diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/README.md b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/README.md new file mode 100644 index 0000000000..78c49dbbea --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/README.md @@ -0,0 +1,57 @@ +# OpenTracing support for gRPC in Go + +The `otgrpc` package makes it easy to add OpenTracing support to gRPC-based +systems in Go. + +## Installation + +``` +go get github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc +``` + +## Documentation + +See the basic usage examples below and the [package documentation on +godoc.org](https://godoc.org/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc). + +## Client-side usage example + +Wherever you call `grpc.Dial`: + +```go +// You must have some sort of OpenTracing Tracer instance on hand. +var tracer opentracing.Tracer = ... +... + +// Set up a connection to the server peer. +conn, err := grpc.Dial( + address, + ... // other options + grpc.WithUnaryInterceptor( + otgrpc.OpenTracingClientInterceptor(tracer)), + grpc.WithStreamInterceptor( + otgrpc.OpenTracingStreamClientInterceptor(tracer))) + +// All future RPC activity involving `conn` will be automatically traced. +``` + +## Server-side usage example + +Wherever you call `grpc.NewServer`: + +```go +// You must have some sort of OpenTracing Tracer instance on hand. +var tracer opentracing.Tracer = ... +... + +// Initialize the gRPC server. +s := grpc.NewServer( + ... // other options + grpc.UnaryInterceptor( + otgrpc.OpenTracingServerInterceptor(tracer)), + grpc.StreamInterceptor( + otgrpc.OpenTracingStreamServerInterceptor(tracer))) + +// All future RPC activity involving `s` will be automatically traced. +``` + diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/client.go b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/client.go new file mode 100644 index 0000000000..3414e55cb1 --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/client.go @@ -0,0 +1,239 @@ +package otgrpc + +import ( + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + "github.com/opentracing/opentracing-go/log" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" + "io" + "runtime" + "sync/atomic" +) + +// OpenTracingClientInterceptor returns a grpc.UnaryClientInterceptor suitable +// for use in a grpc.Dial call. +// +// For example: +// +// conn, err := grpc.Dial( +// address, +// ..., // (existing DialOptions) +// grpc.WithUnaryInterceptor(otgrpc.OpenTracingClientInterceptor(tracer))) +// +// All gRPC client spans will inject the OpenTracing SpanContext into the gRPC +// metadata; they will also look in the context.Context for an active +// in-process parent Span and establish a ChildOf reference if such a parent +// Span could be found. +func OpenTracingClientInterceptor(tracer opentracing.Tracer, optFuncs ...Option) grpc.UnaryClientInterceptor { + otgrpcOpts := newOptions() + otgrpcOpts.apply(optFuncs...) + return func( + ctx context.Context, + method string, + req, resp interface{}, + cc *grpc.ClientConn, + invoker grpc.UnaryInvoker, + opts ...grpc.CallOption, + ) error { + var err error + var parentCtx opentracing.SpanContext + if parent := opentracing.SpanFromContext(ctx); parent != nil { + parentCtx = parent.Context() + } + if otgrpcOpts.inclusionFunc != nil && + !otgrpcOpts.inclusionFunc(parentCtx, method, req, resp) { + return invoker(ctx, method, req, resp, cc, opts...) + } + clientSpan := tracer.StartSpan( + method, + opentracing.ChildOf(parentCtx), + ext.SpanKindRPCClient, + gRPCComponentTag, + ) + defer clientSpan.Finish() + ctx = injectSpanContext(ctx, tracer, clientSpan) + if otgrpcOpts.logPayloads { + clientSpan.LogFields(log.Object("gRPC request", req)) + } + err = invoker(ctx, method, req, resp, cc, opts...) + if err == nil { + if otgrpcOpts.logPayloads { + clientSpan.LogFields(log.Object("gRPC response", resp)) + } + } else { + SetSpanTags(clientSpan, err, true) + clientSpan.LogFields(log.String("event", "error"), log.String("message", err.Error())) + } + if otgrpcOpts.decorator != nil { + otgrpcOpts.decorator(clientSpan, method, req, resp, err) + } + return err + } +} + +// OpenTracingStreamClientInterceptor returns a grpc.StreamClientInterceptor suitable +// for use in a grpc.Dial call. The interceptor instruments streaming RPCs by creating +// a single span to correspond to the lifetime of the RPC's stream. +// +// For example: +// +// conn, err := grpc.Dial( +// address, +// ..., // (existing DialOptions) +// grpc.WithStreamInterceptor(otgrpc.OpenTracingStreamClientInterceptor(tracer))) +// +// All gRPC client spans will inject the OpenTracing SpanContext into the gRPC +// metadata; they will also look in the context.Context for an active +// in-process parent Span and establish a ChildOf reference if such a parent +// Span could be found. +func OpenTracingStreamClientInterceptor(tracer opentracing.Tracer, optFuncs ...Option) grpc.StreamClientInterceptor { + otgrpcOpts := newOptions() + otgrpcOpts.apply(optFuncs...) + return func( + ctx context.Context, + desc *grpc.StreamDesc, + cc *grpc.ClientConn, + method string, + streamer grpc.Streamer, + opts ...grpc.CallOption, + ) (grpc.ClientStream, error) { + var err error + var parentCtx opentracing.SpanContext + if parent := opentracing.SpanFromContext(ctx); parent != nil { + parentCtx = parent.Context() + } + if otgrpcOpts.inclusionFunc != nil && + !otgrpcOpts.inclusionFunc(parentCtx, method, nil, nil) { + return streamer(ctx, desc, cc, method, opts...) + } + + clientSpan := tracer.StartSpan( + method, + opentracing.ChildOf(parentCtx), + ext.SpanKindRPCClient, + gRPCComponentTag, + ) + ctx = injectSpanContext(ctx, tracer, clientSpan) + cs, err := streamer(ctx, desc, cc, method, opts...) + if err != nil { + clientSpan.LogFields(log.String("event", "error"), log.String("message", err.Error())) + SetSpanTags(clientSpan, err, true) + clientSpan.Finish() + return cs, err + } + return newOpenTracingClientStream(cs, method, desc, clientSpan, otgrpcOpts), nil + } +} + +func newOpenTracingClientStream(cs grpc.ClientStream, method string, desc *grpc.StreamDesc, clientSpan opentracing.Span, otgrpcOpts *options) grpc.ClientStream { + finishChan := make(chan struct{}) + + isFinished := new(int32) + *isFinished = 0 + finishFunc := func(err error) { + // The current OpenTracing specification forbids finishing a span more than + // once. Since we have multiple code paths that could concurrently call + // `finishFunc`, we need to add some sort of synchronization to guard against + // multiple finishing. + if !atomic.CompareAndSwapInt32(isFinished, 0, 1) { + return + } + close(finishChan) + defer clientSpan.Finish() + if err != nil { + clientSpan.LogFields(log.String("event", "error"), log.String("message", err.Error())) + SetSpanTags(clientSpan, err, true) + } + if otgrpcOpts.decorator != nil { + otgrpcOpts.decorator(clientSpan, method, nil, nil, err) + } + } + go func() { + select { + case <-finishChan: + // The client span is being finished by another code path; hence, no + // action is necessary. + case <-cs.Context().Done(): + finishFunc(cs.Context().Err()) + } + }() + otcs := &openTracingClientStream{ + ClientStream: cs, + desc: desc, + finishFunc: finishFunc, + } + + // The `ClientStream` interface allows one to omit calling `Recv` if it's + // known that the result will be `io.EOF`. See + // http://stackoverflow.com/q/42915337 + // In such cases, there's nothing that triggers the span to finish. We, + // therefore, set a finalizer so that the span and the context goroutine will + // at least be cleaned up when the garbage collector is run. + runtime.SetFinalizer(otcs, func(otcs *openTracingClientStream) { + otcs.finishFunc(nil) + }) + return otcs +} + +type openTracingClientStream struct { + grpc.ClientStream + desc *grpc.StreamDesc + finishFunc func(error) +} + +func (cs *openTracingClientStream) Header() (metadata.MD, error) { + md, err := cs.ClientStream.Header() + if err != nil { + cs.finishFunc(err) + } + return md, err +} + +func (cs *openTracingClientStream) SendMsg(m interface{}) error { + err := cs.ClientStream.SendMsg(m) + if err != nil { + cs.finishFunc(err) + } + return err +} + +func (cs *openTracingClientStream) RecvMsg(m interface{}) error { + err := cs.ClientStream.RecvMsg(m) + if err == io.EOF { + cs.finishFunc(nil) + return err + } else if err != nil { + cs.finishFunc(err) + return err + } + if !cs.desc.ServerStreams { + cs.finishFunc(nil) + } + return err +} + +func (cs *openTracingClientStream) CloseSend() error { + err := cs.ClientStream.CloseSend() + if err != nil { + cs.finishFunc(err) + } + return err +} + +func injectSpanContext(ctx context.Context, tracer opentracing.Tracer, clientSpan opentracing.Span) context.Context { + md, ok := metadata.FromOutgoingContext(ctx) + if !ok { + md = metadata.New(nil) + } else { + md = md.Copy() + } + mdWriter := metadataReaderWriter{md} + err := tracer.Inject(clientSpan.Context(), opentracing.HTTPHeaders, mdWriter) + // We have no better place to record an error than the Span itself :-/ + if err != nil { + clientSpan.LogFields(log.String("event", "Tracer.Inject() failed"), log.Error(err)) + } + return metadata.NewOutgoingContext(ctx, md) +} diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/errors.go b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/errors.go new file mode 100644 index 0000000000..41a6346f25 --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/errors.go @@ -0,0 +1,69 @@ +package otgrpc + +import ( + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// A Class is a set of types of outcomes (including errors) that will often +// be handled in the same way. +type Class string + +const ( + Unknown Class = "0xx" + // Success represents outcomes that achieved the desired results. + Success Class = "2xx" + // ClientError represents errors that were the client's fault. + ClientError Class = "4xx" + // ServerError represents errors that were the server's fault. + ServerError Class = "5xx" +) + +// ErrorClass returns the class of the given error +func ErrorClass(err error) Class { + if s, ok := status.FromError(err); ok { + switch s.Code() { + // Success or "success" + case codes.OK, codes.Canceled: + return Success + + // Client errors + case codes.InvalidArgument, codes.NotFound, codes.AlreadyExists, + codes.PermissionDenied, codes.Unauthenticated, codes.FailedPrecondition, + codes.OutOfRange: + return ClientError + + // Server errors + case codes.DeadlineExceeded, codes.ResourceExhausted, codes.Aborted, + codes.Unimplemented, codes.Internal, codes.Unavailable, codes.DataLoss: + return ServerError + + // Not sure + case codes.Unknown: + fallthrough + default: + return Unknown + } + } + return Unknown +} + +// SetSpanTags sets one or more tags on the given span according to the +// error. +func SetSpanTags(span opentracing.Span, err error, client bool) { + c := ErrorClass(err) + code := codes.Unknown + if s, ok := status.FromError(err); ok { + code = s.Code() + } + span.SetTag("response_code", code) + span.SetTag("response_class", c) + if err == nil { + return + } + if client || c == ServerError { + ext.Error.Set(span, true) + } +} diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/options.go b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/options.go new file mode 100644 index 0000000000..903e8382e3 --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/options.go @@ -0,0 +1,76 @@ +package otgrpc + +import "github.com/opentracing/opentracing-go" + +// Option instances may be used in OpenTracing(Server|Client)Interceptor +// initialization. +// +// See this post about the "functional options" pattern: +// http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis +type Option func(o *options) + +// LogPayloads returns an Option that tells the OpenTracing instrumentation to +// try to log application payloads in both directions. +func LogPayloads() Option { + return func(o *options) { + o.logPayloads = true + } +} + +// SpanInclusionFunc provides an optional mechanism to decide whether or not +// to trace a given gRPC call. Return true to create a Span and initiate +// tracing, false to not create a Span and not trace. +// +// parentSpanCtx may be nil if no parent could be extraction from either the Go +// context.Context (on the client) or the RPC (on the server). +type SpanInclusionFunc func( + parentSpanCtx opentracing.SpanContext, + method string, + req, resp interface{}) bool + +// IncludingSpans binds a IncludeSpanFunc to the options +func IncludingSpans(inclusionFunc SpanInclusionFunc) Option { + return func(o *options) { + o.inclusionFunc = inclusionFunc + } +} + +// SpanDecoratorFunc provides an (optional) mechanism for otgrpc users to add +// arbitrary tags/logs/etc to the opentracing.Span associated with client +// and/or server RPCs. +type SpanDecoratorFunc func( + span opentracing.Span, + method string, + req, resp interface{}, + grpcError error) + +// SpanDecorator binds a function that decorates gRPC Spans. +func SpanDecorator(decorator SpanDecoratorFunc) Option { + return func(o *options) { + o.decorator = decorator + } +} + +// The internal-only options struct. Obviously overkill at the moment; but will +// scale well as production use dictates other configuration and tuning +// parameters. +type options struct { + logPayloads bool + decorator SpanDecoratorFunc + // May be nil. + inclusionFunc SpanInclusionFunc +} + +// newOptions returns the default options. +func newOptions() *options { + return &options{ + logPayloads: false, + inclusionFunc: nil, + } +} + +func (o *options) apply(opts ...Option) { + for _, opt := range opts { + opt(o) + } +} diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/package.go b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/package.go new file mode 100644 index 0000000000..4ff3d19978 --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/package.go @@ -0,0 +1,5 @@ +// Package otgrpc provides OpenTracing support for any gRPC client or server. +// +// See the README for simple usage examples: +// https://github.com/grpc-ecosystem/grpc-opentracing/blob/master/go/otgrpc/README.md +package otgrpc diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/server.go b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/server.go new file mode 100644 index 0000000000..62cf54d221 --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/server.go @@ -0,0 +1,141 @@ +package otgrpc + +import ( + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + "github.com/opentracing/opentracing-go/log" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" +) + +// OpenTracingServerInterceptor returns a grpc.UnaryServerInterceptor suitable +// for use in a grpc.NewServer call. +// +// For example: +// +// s := grpc.NewServer( +// ..., // (existing ServerOptions) +// grpc.UnaryInterceptor(otgrpc.OpenTracingServerInterceptor(tracer))) +// +// All gRPC server spans will look for an OpenTracing SpanContext in the gRPC +// metadata; if found, the server span will act as the ChildOf that RPC +// SpanContext. +// +// Root or not, the server Span will be embedded in the context.Context for the +// application-specific gRPC handler(s) to access. +func OpenTracingServerInterceptor(tracer opentracing.Tracer, optFuncs ...Option) grpc.UnaryServerInterceptor { + otgrpcOpts := newOptions() + otgrpcOpts.apply(optFuncs...) + return func( + ctx context.Context, + req interface{}, + info *grpc.UnaryServerInfo, + handler grpc.UnaryHandler, + ) (resp interface{}, err error) { + spanContext, err := extractSpanContext(ctx, tracer) + if err != nil && err != opentracing.ErrSpanContextNotFound { + // TODO: establish some sort of error reporting mechanism here. We + // don't know where to put such an error and must rely on Tracer + // implementations to do something appropriate for the time being. + } + if otgrpcOpts.inclusionFunc != nil && + !otgrpcOpts.inclusionFunc(spanContext, info.FullMethod, req, nil) { + return handler(ctx, req) + } + serverSpan := tracer.StartSpan( + info.FullMethod, + ext.RPCServerOption(spanContext), + gRPCComponentTag, + ) + defer serverSpan.Finish() + + ctx = opentracing.ContextWithSpan(ctx, serverSpan) + if otgrpcOpts.logPayloads { + serverSpan.LogFields(log.Object("gRPC request", req)) + } + resp, err = handler(ctx, req) + if err == nil { + if otgrpcOpts.logPayloads { + serverSpan.LogFields(log.Object("gRPC response", resp)) + } + } else { + SetSpanTags(serverSpan, err, false) + serverSpan.LogFields(log.String("event", "error"), log.String("message", err.Error())) + } + if otgrpcOpts.decorator != nil { + otgrpcOpts.decorator(serverSpan, info.FullMethod, req, resp, err) + } + return resp, err + } +} + +// OpenTracingStreamServerInterceptor returns a grpc.StreamServerInterceptor suitable +// for use in a grpc.NewServer call. The interceptor instruments streaming RPCs by +// creating a single span to correspond to the lifetime of the RPC's stream. +// +// For example: +// +// s := grpc.NewServer( +// ..., // (existing ServerOptions) +// grpc.StreamInterceptor(otgrpc.OpenTracingStreamServerInterceptor(tracer))) +// +// All gRPC server spans will look for an OpenTracing SpanContext in the gRPC +// metadata; if found, the server span will act as the ChildOf that RPC +// SpanContext. +// +// Root or not, the server Span will be embedded in the context.Context for the +// application-specific gRPC handler(s) to access. +func OpenTracingStreamServerInterceptor(tracer opentracing.Tracer, optFuncs ...Option) grpc.StreamServerInterceptor { + otgrpcOpts := newOptions() + otgrpcOpts.apply(optFuncs...) + return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + spanContext, err := extractSpanContext(ss.Context(), tracer) + if err != nil && err != opentracing.ErrSpanContextNotFound { + // TODO: establish some sort of error reporting mechanism here. We + // don't know where to put such an error and must rely on Tracer + // implementations to do something appropriate for the time being. + } + if otgrpcOpts.inclusionFunc != nil && + !otgrpcOpts.inclusionFunc(spanContext, info.FullMethod, nil, nil) { + return handler(srv, ss) + } + + serverSpan := tracer.StartSpan( + info.FullMethod, + ext.RPCServerOption(spanContext), + gRPCComponentTag, + ) + defer serverSpan.Finish() + ss = &openTracingServerStream{ + ServerStream: ss, + ctx: opentracing.ContextWithSpan(ss.Context(), serverSpan), + } + err = handler(srv, ss) + if err != nil { + SetSpanTags(serverSpan, err, false) + serverSpan.LogFields(log.String("event", "error"), log.String("message", err.Error())) + } + if otgrpcOpts.decorator != nil { + otgrpcOpts.decorator(serverSpan, info.FullMethod, nil, nil, err) + } + return err + } +} + +type openTracingServerStream struct { + grpc.ServerStream + ctx context.Context +} + +func (ss *openTracingServerStream) Context() context.Context { + return ss.ctx +} + +func extractSpanContext(ctx context.Context, tracer opentracing.Tracer) (opentracing.SpanContext, error) { + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + md = metadata.New(nil) + } + return tracer.Extract(opentracing.HTTPHeaders, metadataReaderWriter{md}) +} diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/shared.go b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/shared.go new file mode 100644 index 0000000000..9abd5eaa62 --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/shared.go @@ -0,0 +1,42 @@ +package otgrpc + +import ( + "strings" + + opentracing "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + "google.golang.org/grpc/metadata" +) + +var ( + // Morally a const: + gRPCComponentTag = opentracing.Tag{string(ext.Component), "gRPC"} +) + +// metadataReaderWriter satisfies both the opentracing.TextMapReader and +// opentracing.TextMapWriter interfaces. +type metadataReaderWriter struct { + metadata.MD +} + +func (w metadataReaderWriter) Set(key, val string) { + // The GRPC HPACK implementation rejects any uppercase keys here. + // + // As such, since the HTTP_HEADERS format is case-insensitive anyway, we + // blindly lowercase the key (which is guaranteed to work in the + // Inject/Extract sense per the OpenTracing spec). + key = strings.ToLower(key) + w.MD[key] = append(w.MD[key], val) +} + +func (w metadataReaderWriter) ForeachKey(handler func(key, val string) error) error { + for k, vals := range w.MD { + for _, v := range vals { + if err := handler(k, v); err != nil { + return err + } + } + } + + return nil +} diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/python/README.md b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/python/README.md new file mode 100644 index 0000000000..843acd9a20 --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/python/README.md @@ -0,0 +1,4 @@ +The repo has moved. +------------------- + +https://github.com/opentracing-contrib/python-grpc diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/python/examples/protos/command_line.proto b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/python/examples/protos/command_line.proto new file mode 100644 index 0000000000..b2367a72e7 --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/python/examples/protos/command_line.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package command_line; + +service CommandLine { + rpc Echo(CommandRequest) returns (CommandResponse) {} +} + +message CommandRequest { + string text = 1; +} + +message CommandResponse { + string text = 1; +} diff --git a/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/python/examples/protos/store.proto b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/python/examples/protos/store.proto new file mode 100644 index 0000000000..6822d985d3 --- /dev/null +++ b/components/engine/vendor/github.com/grpc-ecosystem/grpc-opentracing/python/examples/protos/store.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; + +package store; + +service Store { + rpc AddItem(AddItemRequest) returns (Empty) {} + rpc AddItems(stream AddItemRequest) returns (Empty) {} + rpc RemoveItem(RemoveItemRequest) returns (RemoveItemResponse) {} + rpc RemoveItems(stream RemoveItemRequest) returns (RemoveItemResponse) {} + rpc ListInventory(Empty) returns (stream QuantityResponse) {} + rpc QueryQuantity(QueryItemRequest) returns (QuantityResponse) {} + rpc QueryQuantities(stream QueryItemRequest) + returns (stream QuantityResponse) {} +} + +message Empty {} + +message AddItemRequest { + string name = 1; +} + +message RemoveItemRequest { + string name = 1; +} + +message RemoveItemResponse { + bool was_successful = 1; +} + +message QueryItemRequest { + string name = 1; +} + +message QuantityResponse { + string name = 1; + int32 count = 2; +} diff --git a/components/engine/vendor/github.com/opentracing/opentracing-go/LICENSE b/components/engine/vendor/github.com/opentracing/opentracing-go/LICENSE new file mode 100644 index 0000000000..148509a403 --- /dev/null +++ b/components/engine/vendor/github.com/opentracing/opentracing-go/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 The OpenTracing Authors + +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. diff --git a/components/engine/vendor/github.com/opentracing/opentracing-go/README.md b/components/engine/vendor/github.com/opentracing/opentracing-go/README.md new file mode 100644 index 0000000000..19a541c2c5 --- /dev/null +++ b/components/engine/vendor/github.com/opentracing/opentracing-go/README.md @@ -0,0 +1,163 @@ +[![Gitter chat](http://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg)](https://gitter.im/opentracing/public) [![Build Status](https://travis-ci.org/opentracing/opentracing-go.svg?branch=master)](https://travis-ci.org/opentracing/opentracing-go) [![GoDoc](https://godoc.org/github.com/opentracing/opentracing-go?status.svg)](http://godoc.org/github.com/opentracing/opentracing-go) +[![Sourcegraph Badge](https://sourcegraph.com/github.com/opentracing/opentracing-go/-/badge.svg)](https://sourcegraph.com/github.com/opentracing/opentracing-go?badge) + +# OpenTracing API for Go + +This package is a Go platform API for OpenTracing. + +## Required Reading + +In order to understand the Go platform API, one must first be familiar with the +[OpenTracing project](http://opentracing.io) and +[terminology](http://opentracing.io/documentation/pages/spec.html) more specifically. + +## API overview for those adding instrumentation + +Everyday consumers of this `opentracing` package really only need to worry +about a couple of key abstractions: the `StartSpan` function, the `Span` +interface, and binding a `Tracer` at `main()`-time. Here are code snippets +demonstrating some important use cases. + +#### Singleton initialization + +The simplest starting point is `./default_tracer.go`. As early as possible, call + +```go + import "github.com/opentracing/opentracing-go" + import ".../some_tracing_impl" + + func main() { + opentracing.InitGlobalTracer( + // tracing impl specific: + some_tracing_impl.New(...), + ) + ... + } +``` + +##### Non-Singleton initialization + +If you prefer direct control to singletons, manage ownership of the +`opentracing.Tracer` implementation explicitly. + +#### Creating a Span given an existing Go `context.Context` + +If you use `context.Context` in your application, OpenTracing's Go library will +happily rely on it for `Span` propagation. To start a new (blocking child) +`Span`, you can use `StartSpanFromContext`. + +```go + func xyz(ctx context.Context, ...) { + ... + span, ctx := opentracing.StartSpanFromContext(ctx, "operation_name") + defer span.Finish() + span.LogFields( + log.String("event", "soft error"), + log.String("type", "cache timeout"), + log.Int("waited.millis", 1500)) + ... + } +``` + +#### Starting an empty trace by creating a "root span" + +It's always possible to create a "root" `Span` with no parent or other causal +reference. + +```go + func xyz() { + ... + sp := opentracing.StartSpan("operation_name") + defer sp.Finish() + ... + } +``` + +#### Creating a (child) Span given an existing (parent) Span + +```go + func xyz(parentSpan opentracing.Span, ...) { + ... + sp := opentracing.StartSpan( + "operation_name", + opentracing.ChildOf(parentSpan.Context())) + defer sp.Finish() + ... + } +``` + +#### Serializing to the wire + +```go + func makeSomeRequest(ctx context.Context) ... { + if span := opentracing.SpanFromContext(ctx); span != nil { + httpClient := &http.Client{} + httpReq, _ := http.NewRequest("GET", "http://myservice/", nil) + + // Transmit the span's TraceContext as HTTP headers on our + // outbound request. + opentracing.GlobalTracer().Inject( + span.Context(), + opentracing.HTTPHeaders, + opentracing.HTTPHeadersCarrier(httpReq.Header)) + + resp, err := httpClient.Do(httpReq) + ... + } + ... + } +``` + +#### Deserializing from the wire + +```go + http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { + var serverSpan opentracing.Span + appSpecificOperationName := ... + wireContext, err := opentracing.GlobalTracer().Extract( + opentracing.HTTPHeaders, + opentracing.HTTPHeadersCarrier(req.Header)) + if err != nil { + // Optionally record something about err here + } + + // Create the span referring to the RPC client if available. + // If wireContext == nil, a root span will be created. + serverSpan = opentracing.StartSpan( + appSpecificOperationName, + ext.RPCServerOption(wireContext)) + + defer serverSpan.Finish() + + ctx := opentracing.ContextWithSpan(context.Background(), serverSpan) + ... + } +``` + +#### Conditionally capture a field using `log.Noop` + +In some situations, you may want to dynamically decide whether or not +to log a field. For example, you may want to capture additional data, +such as a customer ID, in non-production environments: + +```go + func Customer(order *Order) log.Field { + if os.Getenv("ENVIRONMENT") == "dev" { + return log.String("customer", order.Customer.ID) + } + return log.Noop() + } +``` + +#### Goroutine-safety + +The entire public API is goroutine-safe and does not require external +synchronization. + +## API pointers for those implementing a tracing system + +Tracing system implementors may be able to reuse or copy-paste-modify the `basictracer` package, found [here](https://github.com/opentracing/basictracer-go). In particular, see `basictracer.New(...)`. + +## API compatibility + +For the time being, "mild" backwards-incompatible changes may be made without changing the major version number. As OpenTracing and `opentracing-go` mature, backwards compatibility will become more of a priority. diff --git a/components/engine/vendor/github.com/opentracing/opentracing-go/ext/tags.go b/components/engine/vendor/github.com/opentracing/opentracing-go/ext/tags.go new file mode 100644 index 0000000000..8800129a23 --- /dev/null +++ b/components/engine/vendor/github.com/opentracing/opentracing-go/ext/tags.go @@ -0,0 +1,210 @@ +package ext + +import opentracing "github.com/opentracing/opentracing-go" + +// These constants define common tag names recommended for better portability across +// tracing systems and languages/platforms. +// +// The tag names are defined as typed strings, so that in addition to the usual use +// +// span.setTag(TagName, value) +// +// they also support value type validation via this additional syntax: +// +// TagName.Set(span, value) +// +var ( + ////////////////////////////////////////////////////////////////////// + // SpanKind (client/server or producer/consumer) + ////////////////////////////////////////////////////////////////////// + + // SpanKind hints at relationship between spans, e.g. client/server + SpanKind = spanKindTagName("span.kind") + + // SpanKindRPCClient marks a span representing the client-side of an RPC + // or other remote call + SpanKindRPCClientEnum = SpanKindEnum("client") + SpanKindRPCClient = opentracing.Tag{Key: string(SpanKind), Value: SpanKindRPCClientEnum} + + // SpanKindRPCServer marks a span representing the server-side of an RPC + // or other remote call + SpanKindRPCServerEnum = SpanKindEnum("server") + SpanKindRPCServer = opentracing.Tag{Key: string(SpanKind), Value: SpanKindRPCServerEnum} + + // SpanKindProducer marks a span representing the producer-side of a + // message bus + SpanKindProducerEnum = SpanKindEnum("producer") + SpanKindProducer = opentracing.Tag{Key: string(SpanKind), Value: SpanKindProducerEnum} + + // SpanKindConsumer marks a span representing the consumer-side of a + // message bus + SpanKindConsumerEnum = SpanKindEnum("consumer") + SpanKindConsumer = opentracing.Tag{Key: string(SpanKind), Value: SpanKindConsumerEnum} + + ////////////////////////////////////////////////////////////////////// + // Component name + ////////////////////////////////////////////////////////////////////// + + // Component is a low-cardinality identifier of the module, library, + // or package that is generating a span. + Component = stringTagName("component") + + ////////////////////////////////////////////////////////////////////// + // Sampling hint + ////////////////////////////////////////////////////////////////////// + + // SamplingPriority determines the priority of sampling this Span. + SamplingPriority = uint16TagName("sampling.priority") + + ////////////////////////////////////////////////////////////////////// + // Peer tags. These tags can be emitted by either client-side of + // server-side to describe the other side/service in a peer-to-peer + // communications, like an RPC call. + ////////////////////////////////////////////////////////////////////// + + // PeerService records the service name of the peer. + PeerService = stringTagName("peer.service") + + // PeerAddress records the address name of the peer. This may be a "ip:port", + // a bare "hostname", a FQDN or even a database DSN substring + // like "mysql://username@127.0.0.1:3306/dbname" + PeerAddress = stringTagName("peer.address") + + // PeerHostname records the host name of the peer + PeerHostname = stringTagName("peer.hostname") + + // PeerHostIPv4 records IP v4 host address of the peer + PeerHostIPv4 = ipv4Tag("peer.ipv4") + + // PeerHostIPv6 records IP v6 host address of the peer + PeerHostIPv6 = stringTagName("peer.ipv6") + + // PeerPort records port number of the peer + PeerPort = uint16TagName("peer.port") + + ////////////////////////////////////////////////////////////////////// + // HTTP Tags + ////////////////////////////////////////////////////////////////////// + + // HTTPUrl should be the URL of the request being handled in this segment + // of the trace, in standard URI format. The protocol is optional. + HTTPUrl = stringTagName("http.url") + + // HTTPMethod is the HTTP method of the request, and is case-insensitive. + HTTPMethod = stringTagName("http.method") + + // HTTPStatusCode is the numeric HTTP status code (200, 404, etc) of the + // HTTP response. + HTTPStatusCode = uint16TagName("http.status_code") + + ////////////////////////////////////////////////////////////////////// + // DB Tags + ////////////////////////////////////////////////////////////////////// + + // DBInstance is database instance name. + DBInstance = stringTagName("db.instance") + + // DBStatement is a database statement for the given database type. + // It can be a query or a prepared statement (i.e., before substitution). + DBStatement = stringTagName("db.statement") + + // DBType is a database type. For any SQL database, "sql". + // For others, the lower-case database category, e.g. "redis" + DBType = stringTagName("db.type") + + // DBUser is a username for accessing database. + DBUser = stringTagName("db.user") + + ////////////////////////////////////////////////////////////////////// + // Message Bus Tag + ////////////////////////////////////////////////////////////////////// + + // MessageBusDestination is an address at which messages can be exchanged + MessageBusDestination = stringTagName("message_bus.destination") + + ////////////////////////////////////////////////////////////////////// + // Error Tag + ////////////////////////////////////////////////////////////////////// + + // Error indicates that operation represented by the span resulted in an error. + Error = boolTagName("error") +) + +// --- + +// SpanKindEnum represents common span types +type SpanKindEnum string + +type spanKindTagName string + +// Set adds a string tag to the `span` +func (tag spanKindTagName) Set(span opentracing.Span, value SpanKindEnum) { + span.SetTag(string(tag), value) +} + +type rpcServerOption struct { + clientContext opentracing.SpanContext +} + +func (r rpcServerOption) Apply(o *opentracing.StartSpanOptions) { + if r.clientContext != nil { + opentracing.ChildOf(r.clientContext).Apply(o) + } + SpanKindRPCServer.Apply(o) +} + +// RPCServerOption returns a StartSpanOption appropriate for an RPC server span +// with `client` representing the metadata for the remote peer Span if available. +// In case client == nil, due to the client not being instrumented, this RPC +// server span will be a root span. +func RPCServerOption(client opentracing.SpanContext) opentracing.StartSpanOption { + return rpcServerOption{client} +} + +// --- + +type stringTagName string + +// Set adds a string tag to the `span` +func (tag stringTagName) Set(span opentracing.Span, value string) { + span.SetTag(string(tag), value) +} + +// --- + +type uint32TagName string + +// Set adds a uint32 tag to the `span` +func (tag uint32TagName) Set(span opentracing.Span, value uint32) { + span.SetTag(string(tag), value) +} + +// --- + +type uint16TagName string + +// Set adds a uint16 tag to the `span` +func (tag uint16TagName) Set(span opentracing.Span, value uint16) { + span.SetTag(string(tag), value) +} + +// --- + +type boolTagName string + +// Add adds a bool tag to the `span` +func (tag boolTagName) Set(span opentracing.Span, value bool) { + span.SetTag(string(tag), value) +} + +type ipv4Tag string + +// Set adds IP v4 host address of the peer as an uint32 value to the `span`, keep this for backward and zipkin compatibility +func (tag ipv4Tag) Set(span opentracing.Span, value uint32) { + span.SetTag(string(tag), value) +} + +// SetString records IP v4 host address of the peer as a .-separated tuple to the `span`. E.g., "127.0.0.1" +func (tag ipv4Tag) SetString(span opentracing.Span, value string) { + span.SetTag(string(tag), value) +} diff --git a/components/engine/vendor/github.com/opentracing/opentracing-go/globaltracer.go b/components/engine/vendor/github.com/opentracing/opentracing-go/globaltracer.go new file mode 100644 index 0000000000..8c8e793ff2 --- /dev/null +++ b/components/engine/vendor/github.com/opentracing/opentracing-go/globaltracer.go @@ -0,0 +1,32 @@ +package opentracing + +var ( + globalTracer Tracer = NoopTracer{} +) + +// SetGlobalTracer sets the [singleton] opentracing.Tracer returned by +// GlobalTracer(). Those who use GlobalTracer (rather than directly manage an +// opentracing.Tracer instance) should call SetGlobalTracer as early as +// possible in main(), prior to calling the `StartSpan` global func below. +// Prior to calling `SetGlobalTracer`, any Spans started via the `StartSpan` +// (etc) globals are noops. +func SetGlobalTracer(tracer Tracer) { + globalTracer = tracer +} + +// GlobalTracer returns the global singleton `Tracer` implementation. +// Before `SetGlobalTracer()` is called, the `GlobalTracer()` is a noop +// implementation that drops all data handed to it. +func GlobalTracer() Tracer { + return globalTracer +} + +// StartSpan defers to `Tracer.StartSpan`. See `GlobalTracer()`. +func StartSpan(operationName string, opts ...StartSpanOption) Span { + return globalTracer.StartSpan(operationName, opts...) +} + +// InitGlobalTracer is deprecated. Please use SetGlobalTracer. +func InitGlobalTracer(tracer Tracer) { + SetGlobalTracer(tracer) +} diff --git a/components/engine/vendor/github.com/opentracing/opentracing-go/gocontext.go b/components/engine/vendor/github.com/opentracing/opentracing-go/gocontext.go new file mode 100644 index 0000000000..222a65202f --- /dev/null +++ b/components/engine/vendor/github.com/opentracing/opentracing-go/gocontext.go @@ -0,0 +1,57 @@ +package opentracing + +import "golang.org/x/net/context" + +type contextKey struct{} + +var activeSpanKey = contextKey{} + +// ContextWithSpan returns a new `context.Context` that holds a reference to +// `span`'s SpanContext. +func ContextWithSpan(ctx context.Context, span Span) context.Context { + return context.WithValue(ctx, activeSpanKey, span) +} + +// SpanFromContext returns the `Span` previously associated with `ctx`, or +// `nil` if no such `Span` could be found. +// +// NOTE: context.Context != SpanContext: the former is Go's intra-process +// context propagation mechanism, and the latter houses OpenTracing's per-Span +// identity and baggage information. +func SpanFromContext(ctx context.Context) Span { + val := ctx.Value(activeSpanKey) + if sp, ok := val.(Span); ok { + return sp + } + return nil +} + +// StartSpanFromContext starts and returns a Span with `operationName`, using +// any Span found within `ctx` as a ChildOfRef. If no such parent could be +// found, StartSpanFromContext creates a root (parentless) Span. +// +// The second return value is a context.Context object built around the +// returned Span. +// +// Example usage: +// +// SomeFunction(ctx context.Context, ...) { +// sp, ctx := opentracing.StartSpanFromContext(ctx, "SomeFunction") +// defer sp.Finish() +// ... +// } +func StartSpanFromContext(ctx context.Context, operationName string, opts ...StartSpanOption) (Span, context.Context) { + return startSpanFromContextWithTracer(ctx, GlobalTracer(), operationName, opts...) +} + +// startSpanFromContextWithTracer is factored out for testing purposes. +func startSpanFromContextWithTracer(ctx context.Context, tracer Tracer, operationName string, opts ...StartSpanOption) (Span, context.Context) { + var span Span + if parentSpan := SpanFromContext(ctx); parentSpan != nil { + opts = append(opts, ChildOf(parentSpan.Context())) + span = tracer.StartSpan(operationName, opts...) + } else { + span = tracer.StartSpan(operationName, opts...) + } + return span, ContextWithSpan(ctx, span) +} diff --git a/components/engine/vendor/github.com/opentracing/opentracing-go/log/field.go b/components/engine/vendor/github.com/opentracing/opentracing-go/log/field.go new file mode 100644 index 0000000000..50feea341a --- /dev/null +++ b/components/engine/vendor/github.com/opentracing/opentracing-go/log/field.go @@ -0,0 +1,269 @@ +package log + +import ( + "fmt" + "math" +) + +type fieldType int + +const ( + stringType fieldType = iota + boolType + intType + int32Type + uint32Type + int64Type + uint64Type + float32Type + float64Type + errorType + objectType + lazyLoggerType + noopType +) + +// Field instances are constructed via LogBool, LogString, and so on. +// Tracing implementations may then handle them via the Field.Marshal +// method. +// +// "heavily influenced by" (i.e., partially stolen from) +// https://github.com/uber-go/zap +type Field struct { + key string + fieldType fieldType + numericVal int64 + stringVal string + interfaceVal interface{} +} + +// String adds a string-valued key:value pair to a Span.LogFields() record +func String(key, val string) Field { + return Field{ + key: key, + fieldType: stringType, + stringVal: val, + } +} + +// Bool adds a bool-valued key:value pair to a Span.LogFields() record +func Bool(key string, val bool) Field { + var numericVal int64 + if val { + numericVal = 1 + } + return Field{ + key: key, + fieldType: boolType, + numericVal: numericVal, + } +} + +// Int adds an int-valued key:value pair to a Span.LogFields() record +func Int(key string, val int) Field { + return Field{ + key: key, + fieldType: intType, + numericVal: int64(val), + } +} + +// Int32 adds an int32-valued key:value pair to a Span.LogFields() record +func Int32(key string, val int32) Field { + return Field{ + key: key, + fieldType: int32Type, + numericVal: int64(val), + } +} + +// Int64 adds an int64-valued key:value pair to a Span.LogFields() record +func Int64(key string, val int64) Field { + return Field{ + key: key, + fieldType: int64Type, + numericVal: val, + } +} + +// Uint32 adds a uint32-valued key:value pair to a Span.LogFields() record +func Uint32(key string, val uint32) Field { + return Field{ + key: key, + fieldType: uint32Type, + numericVal: int64(val), + } +} + +// Uint64 adds a uint64-valued key:value pair to a Span.LogFields() record +func Uint64(key string, val uint64) Field { + return Field{ + key: key, + fieldType: uint64Type, + numericVal: int64(val), + } +} + +// Float32 adds a float32-valued key:value pair to a Span.LogFields() record +func Float32(key string, val float32) Field { + return Field{ + key: key, + fieldType: float32Type, + numericVal: int64(math.Float32bits(val)), + } +} + +// Float64 adds a float64-valued key:value pair to a Span.LogFields() record +func Float64(key string, val float64) Field { + return Field{ + key: key, + fieldType: float64Type, + numericVal: int64(math.Float64bits(val)), + } +} + +// Error adds an error with the key "error" to a Span.LogFields() record +func Error(err error) Field { + return Field{ + key: "error", + fieldType: errorType, + interfaceVal: err, + } +} + +// Object adds an object-valued key:value pair to a Span.LogFields() record +func Object(key string, obj interface{}) Field { + return Field{ + key: key, + fieldType: objectType, + interfaceVal: obj, + } +} + +// LazyLogger allows for user-defined, late-bound logging of arbitrary data +type LazyLogger func(fv Encoder) + +// Lazy adds a LazyLogger to a Span.LogFields() record; the tracing +// implementation will call the LazyLogger function at an indefinite time in +// the future (after Lazy() returns). +func Lazy(ll LazyLogger) Field { + return Field{ + fieldType: lazyLoggerType, + interfaceVal: ll, + } +} + +// Noop creates a no-op log field that should be ignored by the tracer. +// It can be used to capture optional fields, for example those that should +// only be logged in non-production environment: +// +// func customerField(order *Order) log.Field { +// if os.Getenv("ENVIRONMENT") == "dev" { +// return log.String("customer", order.Customer.ID) +// } +// return log.Noop() +// } +// +// span.LogFields(log.String("event", "purchase"), customerField(order)) +// +func Noop() Field { + return Field{ + fieldType: noopType, + } +} + +// Encoder allows access to the contents of a Field (via a call to +// Field.Marshal). +// +// Tracer implementations typically provide an implementation of Encoder; +// OpenTracing callers typically do not need to concern themselves with it. +type Encoder interface { + EmitString(key, value string) + EmitBool(key string, value bool) + EmitInt(key string, value int) + EmitInt32(key string, value int32) + EmitInt64(key string, value int64) + EmitUint32(key string, value uint32) + EmitUint64(key string, value uint64) + EmitFloat32(key string, value float32) + EmitFloat64(key string, value float64) + EmitObject(key string, value interface{}) + EmitLazyLogger(value LazyLogger) +} + +// Marshal passes a Field instance through to the appropriate +// field-type-specific method of an Encoder. +func (lf Field) Marshal(visitor Encoder) { + switch lf.fieldType { + case stringType: + visitor.EmitString(lf.key, lf.stringVal) + case boolType: + visitor.EmitBool(lf.key, lf.numericVal != 0) + case intType: + visitor.EmitInt(lf.key, int(lf.numericVal)) + case int32Type: + visitor.EmitInt32(lf.key, int32(lf.numericVal)) + case int64Type: + visitor.EmitInt64(lf.key, int64(lf.numericVal)) + case uint32Type: + visitor.EmitUint32(lf.key, uint32(lf.numericVal)) + case uint64Type: + visitor.EmitUint64(lf.key, uint64(lf.numericVal)) + case float32Type: + visitor.EmitFloat32(lf.key, math.Float32frombits(uint32(lf.numericVal))) + case float64Type: + visitor.EmitFloat64(lf.key, math.Float64frombits(uint64(lf.numericVal))) + case errorType: + if err, ok := lf.interfaceVal.(error); ok { + visitor.EmitString(lf.key, err.Error()) + } else { + visitor.EmitString(lf.key, "") + } + case objectType: + visitor.EmitObject(lf.key, lf.interfaceVal) + case lazyLoggerType: + visitor.EmitLazyLogger(lf.interfaceVal.(LazyLogger)) + case noopType: + // intentionally left blank + } +} + +// Key returns the field's key. +func (lf Field) Key() string { + return lf.key +} + +// Value returns the field's value as interface{}. +func (lf Field) Value() interface{} { + switch lf.fieldType { + case stringType: + return lf.stringVal + case boolType: + return lf.numericVal != 0 + case intType: + return int(lf.numericVal) + case int32Type: + return int32(lf.numericVal) + case int64Type: + return int64(lf.numericVal) + case uint32Type: + return uint32(lf.numericVal) + case uint64Type: + return uint64(lf.numericVal) + case float32Type: + return math.Float32frombits(uint32(lf.numericVal)) + case float64Type: + return math.Float64frombits(uint64(lf.numericVal)) + case errorType, objectType, lazyLoggerType: + return lf.interfaceVal + case noopType: + return nil + default: + return nil + } +} + +// String returns a string representation of the key and value. +func (lf Field) String() string { + return fmt.Sprint(lf.key, ":", lf.Value()) +} diff --git a/components/engine/vendor/github.com/opentracing/opentracing-go/log/util.go b/components/engine/vendor/github.com/opentracing/opentracing-go/log/util.go new file mode 100644 index 0000000000..3832feb5ce --- /dev/null +++ b/components/engine/vendor/github.com/opentracing/opentracing-go/log/util.go @@ -0,0 +1,54 @@ +package log + +import "fmt" + +// InterleavedKVToFields converts keyValues a la Span.LogKV() to a Field slice +// a la Span.LogFields(). +func InterleavedKVToFields(keyValues ...interface{}) ([]Field, error) { + if len(keyValues)%2 != 0 { + return nil, fmt.Errorf("non-even keyValues len: %d", len(keyValues)) + } + fields := make([]Field, len(keyValues)/2) + for i := 0; i*2 < len(keyValues); i++ { + key, ok := keyValues[i*2].(string) + if !ok { + return nil, fmt.Errorf( + "non-string key (pair #%d): %T", + i, keyValues[i*2]) + } + switch typedVal := keyValues[i*2+1].(type) { + case bool: + fields[i] = Bool(key, typedVal) + case string: + fields[i] = String(key, typedVal) + case int: + fields[i] = Int(key, typedVal) + case int8: + fields[i] = Int32(key, int32(typedVal)) + case int16: + fields[i] = Int32(key, int32(typedVal)) + case int32: + fields[i] = Int32(key, typedVal) + case int64: + fields[i] = Int64(key, typedVal) + case uint: + fields[i] = Uint64(key, uint64(typedVal)) + case uint64: + fields[i] = Uint64(key, typedVal) + case uint8: + fields[i] = Uint32(key, uint32(typedVal)) + case uint16: + fields[i] = Uint32(key, uint32(typedVal)) + case uint32: + fields[i] = Uint32(key, typedVal) + case float32: + fields[i] = Float32(key, typedVal) + case float64: + fields[i] = Float64(key, typedVal) + default: + // When in doubt, coerce to a string + fields[i] = String(key, fmt.Sprint(typedVal)) + } + } + return fields, nil +} diff --git a/components/engine/vendor/github.com/opentracing/opentracing-go/noop.go b/components/engine/vendor/github.com/opentracing/opentracing-go/noop.go new file mode 100644 index 0000000000..0d32f692c4 --- /dev/null +++ b/components/engine/vendor/github.com/opentracing/opentracing-go/noop.go @@ -0,0 +1,64 @@ +package opentracing + +import "github.com/opentracing/opentracing-go/log" + +// A NoopTracer is a trivial, minimum overhead implementation of Tracer +// for which all operations are no-ops. +// +// The primary use of this implementation is in libraries, such as RPC +// frameworks, that make tracing an optional feature controlled by the +// end user. A no-op implementation allows said libraries to use it +// as the default Tracer and to write instrumentation that does +// not need to keep checking if the tracer instance is nil. +// +// For the same reason, the NoopTracer is the default "global" tracer +// (see GlobalTracer and SetGlobalTracer functions). +// +// WARNING: NoopTracer does not support baggage propagation. +type NoopTracer struct{} + +type noopSpan struct{} +type noopSpanContext struct{} + +var ( + defaultNoopSpanContext = noopSpanContext{} + defaultNoopSpan = noopSpan{} + defaultNoopTracer = NoopTracer{} +) + +const ( + emptyString = "" +) + +// noopSpanContext: +func (n noopSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {} + +// noopSpan: +func (n noopSpan) Context() SpanContext { return defaultNoopSpanContext } +func (n noopSpan) SetBaggageItem(key, val string) Span { return defaultNoopSpan } +func (n noopSpan) BaggageItem(key string) string { return emptyString } +func (n noopSpan) SetTag(key string, value interface{}) Span { return n } +func (n noopSpan) LogFields(fields ...log.Field) {} +func (n noopSpan) LogKV(keyVals ...interface{}) {} +func (n noopSpan) Finish() {} +func (n noopSpan) FinishWithOptions(opts FinishOptions) {} +func (n noopSpan) SetOperationName(operationName string) Span { return n } +func (n noopSpan) Tracer() Tracer { return defaultNoopTracer } +func (n noopSpan) LogEvent(event string) {} +func (n noopSpan) LogEventWithPayload(event string, payload interface{}) {} +func (n noopSpan) Log(data LogData) {} + +// StartSpan belongs to the Tracer interface. +func (n NoopTracer) StartSpan(operationName string, opts ...StartSpanOption) Span { + return defaultNoopSpan +} + +// Inject belongs to the Tracer interface. +func (n NoopTracer) Inject(sp SpanContext, format interface{}, carrier interface{}) error { + return nil +} + +// Extract belongs to the Tracer interface. +func (n NoopTracer) Extract(format interface{}, carrier interface{}) (SpanContext, error) { + return nil, ErrSpanContextNotFound +} diff --git a/components/engine/vendor/github.com/opentracing/opentracing-go/propagation.go b/components/engine/vendor/github.com/opentracing/opentracing-go/propagation.go new file mode 100644 index 0000000000..0dd466a373 --- /dev/null +++ b/components/engine/vendor/github.com/opentracing/opentracing-go/propagation.go @@ -0,0 +1,176 @@ +package opentracing + +import ( + "errors" + "net/http" +) + +/////////////////////////////////////////////////////////////////////////////// +// CORE PROPAGATION INTERFACES: +/////////////////////////////////////////////////////////////////////////////// + +var ( + // ErrUnsupportedFormat occurs when the `format` passed to Tracer.Inject() or + // Tracer.Extract() is not recognized by the Tracer implementation. + ErrUnsupportedFormat = errors.New("opentracing: Unknown or unsupported Inject/Extract format") + + // ErrSpanContextNotFound occurs when the `carrier` passed to + // Tracer.Extract() is valid and uncorrupted but has insufficient + // information to extract a SpanContext. + ErrSpanContextNotFound = errors.New("opentracing: SpanContext not found in Extract carrier") + + // ErrInvalidSpanContext errors occur when Tracer.Inject() is asked to + // operate on a SpanContext which it is not prepared to handle (for + // example, since it was created by a different tracer implementation). + ErrInvalidSpanContext = errors.New("opentracing: SpanContext type incompatible with tracer") + + // ErrInvalidCarrier errors occur when Tracer.Inject() or Tracer.Extract() + // implementations expect a different type of `carrier` than they are + // given. + ErrInvalidCarrier = errors.New("opentracing: Invalid Inject/Extract carrier") + + // ErrSpanContextCorrupted occurs when the `carrier` passed to + // Tracer.Extract() is of the expected type but is corrupted. + ErrSpanContextCorrupted = errors.New("opentracing: SpanContext data corrupted in Extract carrier") +) + +/////////////////////////////////////////////////////////////////////////////// +// BUILTIN PROPAGATION FORMATS: +/////////////////////////////////////////////////////////////////////////////// + +// BuiltinFormat is used to demarcate the values within package `opentracing` +// that are intended for use with the Tracer.Inject() and Tracer.Extract() +// methods. +type BuiltinFormat byte + +const ( + // Binary represents SpanContexts as opaque binary data. + // + // For Tracer.Inject(): the carrier must be an `io.Writer`. + // + // For Tracer.Extract(): the carrier must be an `io.Reader`. + Binary BuiltinFormat = iota + + // TextMap represents SpanContexts as key:value string pairs. + // + // Unlike HTTPHeaders, the TextMap format does not restrict the key or + // value character sets in any way. + // + // For Tracer.Inject(): the carrier must be a `TextMapWriter`. + // + // For Tracer.Extract(): the carrier must be a `TextMapReader`. + TextMap + + // HTTPHeaders represents SpanContexts as HTTP header string pairs. + // + // Unlike TextMap, the HTTPHeaders format requires that the keys and values + // be valid as HTTP headers as-is (i.e., character casing may be unstable + // and special characters are disallowed in keys, values should be + // URL-escaped, etc). + // + // For Tracer.Inject(): the carrier must be a `TextMapWriter`. + // + // For Tracer.Extract(): the carrier must be a `TextMapReader`. + // + // See HTTPHeadersCarrier for an implementation of both TextMapWriter + // and TextMapReader that defers to an http.Header instance for storage. + // For example, Inject(): + // + // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) + // err := span.Tracer().Inject( + // span.Context(), opentracing.HTTPHeaders, carrier) + // + // Or Extract(): + // + // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) + // clientContext, err := tracer.Extract( + // opentracing.HTTPHeaders, carrier) + // + HTTPHeaders +) + +// TextMapWriter is the Inject() carrier for the TextMap builtin format. With +// it, the caller can encode a SpanContext for propagation as entries in a map +// of unicode strings. +type TextMapWriter interface { + // Set a key:value pair to the carrier. Multiple calls to Set() for the + // same key leads to undefined behavior. + // + // NOTE: The backing store for the TextMapWriter may contain data unrelated + // to SpanContext. As such, Inject() and Extract() implementations that + // call the TextMapWriter and TextMapReader interfaces must agree on a + // prefix or other convention to distinguish their own key:value pairs. + Set(key, val string) +} + +// TextMapReader is the Extract() carrier for the TextMap builtin format. With it, +// the caller can decode a propagated SpanContext as entries in a map of +// unicode strings. +type TextMapReader interface { + // ForeachKey returns TextMap contents via repeated calls to the `handler` + // function. If any call to `handler` returns a non-nil error, ForeachKey + // terminates and returns that error. + // + // NOTE: The backing store for the TextMapReader may contain data unrelated + // to SpanContext. As such, Inject() and Extract() implementations that + // call the TextMapWriter and TextMapReader interfaces must agree on a + // prefix or other convention to distinguish their own key:value pairs. + // + // The "foreach" callback pattern reduces unnecessary copying in some cases + // and also allows implementations to hold locks while the map is read. + ForeachKey(handler func(key, val string) error) error +} + +// TextMapCarrier allows the use of regular map[string]string +// as both TextMapWriter and TextMapReader. +type TextMapCarrier map[string]string + +// ForeachKey conforms to the TextMapReader interface. +func (c TextMapCarrier) ForeachKey(handler func(key, val string) error) error { + for k, v := range c { + if err := handler(k, v); err != nil { + return err + } + } + return nil +} + +// Set implements Set() of opentracing.TextMapWriter +func (c TextMapCarrier) Set(key, val string) { + c[key] = val +} + +// HTTPHeadersCarrier satisfies both TextMapWriter and TextMapReader. +// +// Example usage for server side: +// +// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) +// clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier) +// +// Example usage for client side: +// +// carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) +// err := tracer.Inject( +// span.Context(), +// opentracing.HTTPHeaders, +// carrier) +// +type HTTPHeadersCarrier http.Header + +// Set conforms to the TextMapWriter interface. +func (c HTTPHeadersCarrier) Set(key, val string) { + h := http.Header(c) + h.Add(key, val) +} + +// ForeachKey conforms to the TextMapReader interface. +func (c HTTPHeadersCarrier) ForeachKey(handler func(key, val string) error) error { + for k, vals := range c { + for _, v := range vals { + if err := handler(k, v); err != nil { + return err + } + } + } + return nil +} diff --git a/components/engine/vendor/github.com/opentracing/opentracing-go/span.go b/components/engine/vendor/github.com/opentracing/opentracing-go/span.go new file mode 100644 index 0000000000..f6c3234acc --- /dev/null +++ b/components/engine/vendor/github.com/opentracing/opentracing-go/span.go @@ -0,0 +1,185 @@ +package opentracing + +import ( + "time" + + "github.com/opentracing/opentracing-go/log" +) + +// SpanContext represents Span state that must propagate to descendant Spans and across process +// boundaries (e.g., a tuple). +type SpanContext interface { + // ForeachBaggageItem grants access to all baggage items stored in the + // SpanContext. + // The handler function will be called for each baggage key/value pair. + // The ordering of items is not guaranteed. + // + // The bool return value indicates if the handler wants to continue iterating + // through the rest of the baggage items; for example if the handler is trying to + // find some baggage item by pattern matching the name, it can return false + // as soon as the item is found to stop further iterations. + ForeachBaggageItem(handler func(k, v string) bool) +} + +// Span represents an active, un-finished span in the OpenTracing system. +// +// Spans are created by the Tracer interface. +type Span interface { + // Sets the end timestamp and finalizes Span state. + // + // With the exception of calls to Context() (which are always allowed), + // Finish() must be the last call made to any span instance, and to do + // otherwise leads to undefined behavior. + Finish() + // FinishWithOptions is like Finish() but with explicit control over + // timestamps and log data. + FinishWithOptions(opts FinishOptions) + + // Context() yields the SpanContext for this Span. Note that the return + // value of Context() is still valid after a call to Span.Finish(), as is + // a call to Span.Context() after a call to Span.Finish(). + Context() SpanContext + + // Sets or changes the operation name. + SetOperationName(operationName string) Span + + // Adds a tag to the span. + // + // If there is a pre-existing tag set for `key`, it is overwritten. + // + // Tag values can be numeric types, strings, or bools. The behavior of + // other tag value types is undefined at the OpenTracing level. If a + // tracing system does not know how to handle a particular value type, it + // may ignore the tag, but shall not panic. + SetTag(key string, value interface{}) Span + + // LogFields is an efficient and type-checked way to record key:value + // logging data about a Span, though the programming interface is a little + // more verbose than LogKV(). Here's an example: + // + // span.LogFields( + // log.String("event", "soft error"), + // log.String("type", "cache timeout"), + // log.Int("waited.millis", 1500)) + // + // Also see Span.FinishWithOptions() and FinishOptions.BulkLogData. + LogFields(fields ...log.Field) + + // LogKV is a concise, readable way to record key:value logging data about + // a Span, though unfortunately this also makes it less efficient and less + // type-safe than LogFields(). Here's an example: + // + // span.LogKV( + // "event", "soft error", + // "type", "cache timeout", + // "waited.millis", 1500) + // + // For LogKV (as opposed to LogFields()), the parameters must appear as + // key-value pairs, like + // + // span.LogKV(key1, val1, key2, val2, key3, val3, ...) + // + // The keys must all be strings. The values may be strings, numeric types, + // bools, Go error instances, or arbitrary structs. + // + // (Note to implementors: consider the log.InterleavedKVToFields() helper) + LogKV(alternatingKeyValues ...interface{}) + + // SetBaggageItem sets a key:value pair on this Span and its SpanContext + // that also propagates to descendants of this Span. + // + // SetBaggageItem() enables powerful functionality given a full-stack + // opentracing integration (e.g., arbitrary application data from a mobile + // app can make it, transparently, all the way into the depths of a storage + // system), and with it some powerful costs: use this feature with care. + // + // IMPORTANT NOTE #1: SetBaggageItem() will only propagate baggage items to + // *future* causal descendants of the associated Span. + // + // IMPORTANT NOTE #2: Use this thoughtfully and with care. Every key and + // value is copied into every local *and remote* child of the associated + // Span, and that can add up to a lot of network and cpu overhead. + // + // Returns a reference to this Span for chaining. + SetBaggageItem(restrictedKey, value string) Span + + // Gets the value for a baggage item given its key. Returns the empty string + // if the value isn't found in this Span. + BaggageItem(restrictedKey string) string + + // Provides access to the Tracer that created this Span. + Tracer() Tracer + + // Deprecated: use LogFields or LogKV + LogEvent(event string) + // Deprecated: use LogFields or LogKV + LogEventWithPayload(event string, payload interface{}) + // Deprecated: use LogFields or LogKV + Log(data LogData) +} + +// LogRecord is data associated with a single Span log. Every LogRecord +// instance must specify at least one Field. +type LogRecord struct { + Timestamp time.Time + Fields []log.Field +} + +// FinishOptions allows Span.FinishWithOptions callers to override the finish +// timestamp and provide log data via a bulk interface. +type FinishOptions struct { + // FinishTime overrides the Span's finish time, or implicitly becomes + // time.Now() if FinishTime.IsZero(). + // + // FinishTime must resolve to a timestamp that's >= the Span's StartTime + // (per StartSpanOptions). + FinishTime time.Time + + // LogRecords allows the caller to specify the contents of many LogFields() + // calls with a single slice. May be nil. + // + // None of the LogRecord.Timestamp values may be .IsZero() (i.e., they must + // be set explicitly). Also, they must be >= the Span's start timestamp and + // <= the FinishTime (or time.Now() if FinishTime.IsZero()). Otherwise the + // behavior of FinishWithOptions() is undefined. + // + // If specified, the caller hands off ownership of LogRecords at + // FinishWithOptions() invocation time. + // + // If specified, the (deprecated) BulkLogData must be nil or empty. + LogRecords []LogRecord + + // BulkLogData is DEPRECATED. + BulkLogData []LogData +} + +// LogData is DEPRECATED +type LogData struct { + Timestamp time.Time + Event string + Payload interface{} +} + +// ToLogRecord converts a deprecated LogData to a non-deprecated LogRecord +func (ld *LogData) ToLogRecord() LogRecord { + var literalTimestamp time.Time + if ld.Timestamp.IsZero() { + literalTimestamp = time.Now() + } else { + literalTimestamp = ld.Timestamp + } + rval := LogRecord{ + Timestamp: literalTimestamp, + } + if ld.Payload == nil { + rval.Fields = []log.Field{ + log.String("event", ld.Event), + } + } else { + rval.Fields = []log.Field{ + log.String("event", ld.Event), + log.Object("payload", ld.Payload), + } + } + return rval +} diff --git a/components/engine/vendor/github.com/opentracing/opentracing-go/tracer.go b/components/engine/vendor/github.com/opentracing/opentracing-go/tracer.go new file mode 100644 index 0000000000..7bca1f7367 --- /dev/null +++ b/components/engine/vendor/github.com/opentracing/opentracing-go/tracer.go @@ -0,0 +1,305 @@ +package opentracing + +import "time" + +// Tracer is a simple, thin interface for Span creation and SpanContext +// propagation. +type Tracer interface { + + // Create, start, and return a new Span with the given `operationName` and + // incorporate the given StartSpanOption `opts`. (Note that `opts` borrows + // from the "functional options" pattern, per + // http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis) + // + // A Span with no SpanReference options (e.g., opentracing.ChildOf() or + // opentracing.FollowsFrom()) becomes the root of its own trace. + // + // Examples: + // + // var tracer opentracing.Tracer = ... + // + // // The root-span case: + // sp := tracer.StartSpan("GetFeed") + // + // // The vanilla child span case: + // sp := tracer.StartSpan( + // "GetFeed", + // opentracing.ChildOf(parentSpan.Context())) + // + // // All the bells and whistles: + // sp := tracer.StartSpan( + // "GetFeed", + // opentracing.ChildOf(parentSpan.Context()), + // opentracing.Tag{"user_agent", loggedReq.UserAgent}, + // opentracing.StartTime(loggedReq.Timestamp), + // ) + // + StartSpan(operationName string, opts ...StartSpanOption) Span + + // Inject() takes the `sm` SpanContext instance and injects it for + // propagation within `carrier`. The actual type of `carrier` depends on + // the value of `format`. + // + // OpenTracing defines a common set of `format` values (see BuiltinFormat), + // and each has an expected carrier type. + // + // Other packages may declare their own `format` values, much like the keys + // used by `context.Context` (see + // https://godoc.org/golang.org/x/net/context#WithValue). + // + // Example usage (sans error handling): + // + // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) + // err := tracer.Inject( + // span.Context(), + // opentracing.HTTPHeaders, + // carrier) + // + // NOTE: All opentracing.Tracer implementations MUST support all + // BuiltinFormats. + // + // Implementations may return opentracing.ErrUnsupportedFormat if `format` + // is not supported by (or not known by) the implementation. + // + // Implementations may return opentracing.ErrInvalidCarrier or any other + // implementation-specific error if the format is supported but injection + // fails anyway. + // + // See Tracer.Extract(). + Inject(sm SpanContext, format interface{}, carrier interface{}) error + + // Extract() returns a SpanContext instance given `format` and `carrier`. + // + // OpenTracing defines a common set of `format` values (see BuiltinFormat), + // and each has an expected carrier type. + // + // Other packages may declare their own `format` values, much like the keys + // used by `context.Context` (see + // https://godoc.org/golang.org/x/net/context#WithValue). + // + // Example usage (with StartSpan): + // + // + // carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) + // clientContext, err := tracer.Extract(opentracing.HTTPHeaders, carrier) + // + // // ... assuming the ultimate goal here is to resume the trace with a + // // server-side Span: + // var serverSpan opentracing.Span + // if err == nil { + // span = tracer.StartSpan( + // rpcMethodName, ext.RPCServerOption(clientContext)) + // } else { + // span = tracer.StartSpan(rpcMethodName) + // } + // + // + // NOTE: All opentracing.Tracer implementations MUST support all + // BuiltinFormats. + // + // Return values: + // - A successful Extract returns a SpanContext instance and a nil error + // - If there was simply no SpanContext to extract in `carrier`, Extract() + // returns (nil, opentracing.ErrSpanContextNotFound) + // - If `format` is unsupported or unrecognized, Extract() returns (nil, + // opentracing.ErrUnsupportedFormat) + // - If there are more fundamental problems with the `carrier` object, + // Extract() may return opentracing.ErrInvalidCarrier, + // opentracing.ErrSpanContextCorrupted, or implementation-specific + // errors. + // + // See Tracer.Inject(). + Extract(format interface{}, carrier interface{}) (SpanContext, error) +} + +// StartSpanOptions allows Tracer.StartSpan() callers and implementors a +// mechanism to override the start timestamp, specify Span References, and make +// a single Tag or multiple Tags available at Span start time. +// +// StartSpan() callers should look at the StartSpanOption interface and +// implementations available in this package. +// +// Tracer implementations can convert a slice of `StartSpanOption` instances +// into a `StartSpanOptions` struct like so: +// +// func StartSpan(opName string, opts ...opentracing.StartSpanOption) { +// sso := opentracing.StartSpanOptions{} +// for _, o := range opts { +// o.Apply(&sso) +// } +// ... +// } +// +type StartSpanOptions struct { + // Zero or more causal references to other Spans (via their SpanContext). + // If empty, start a "root" Span (i.e., start a new trace). + References []SpanReference + + // StartTime overrides the Span's start time, or implicitly becomes + // time.Now() if StartTime.IsZero(). + StartTime time.Time + + // Tags may have zero or more entries; the restrictions on map values are + // identical to those for Span.SetTag(). May be nil. + // + // If specified, the caller hands off ownership of Tags at + // StartSpan() invocation time. + Tags map[string]interface{} +} + +// StartSpanOption instances (zero or more) may be passed to Tracer.StartSpan. +// +// StartSpanOption borrows from the "functional options" pattern, per +// http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis +type StartSpanOption interface { + Apply(*StartSpanOptions) +} + +// SpanReferenceType is an enum type describing different categories of +// relationships between two Spans. If Span-2 refers to Span-1, the +// SpanReferenceType describes Span-1 from Span-2's perspective. For example, +// ChildOfRef means that Span-1 created Span-2. +// +// NOTE: Span-1 and Span-2 do *not* necessarily depend on each other for +// completion; e.g., Span-2 may be part of a background job enqueued by Span-1, +// or Span-2 may be sitting in a distributed queue behind Span-1. +type SpanReferenceType int + +const ( + // ChildOfRef refers to a parent Span that caused *and* somehow depends + // upon the new child Span. Often (but not always), the parent Span cannot + // finish until the child Span does. + // + // An timing diagram for a ChildOfRef that's blocked on the new Span: + // + // [-Parent Span---------] + // [-Child Span----] + // + // See http://opentracing.io/spec/ + // + // See opentracing.ChildOf() + ChildOfRef SpanReferenceType = iota + + // FollowsFromRef refers to a parent Span that does not depend in any way + // on the result of the new child Span. For instance, one might use + // FollowsFromRefs to describe pipeline stages separated by queues, + // or a fire-and-forget cache insert at the tail end of a web request. + // + // A FollowsFromRef Span is part of the same logical trace as the new Span: + // i.e., the new Span is somehow caused by the work of its FollowsFromRef. + // + // All of the following could be valid timing diagrams for children that + // "FollowFrom" a parent. + // + // [-Parent Span-] [-Child Span-] + // + // + // [-Parent Span--] + // [-Child Span-] + // + // + // [-Parent Span-] + // [-Child Span-] + // + // See http://opentracing.io/spec/ + // + // See opentracing.FollowsFrom() + FollowsFromRef +) + +// SpanReference is a StartSpanOption that pairs a SpanReferenceType and a +// referenced SpanContext. See the SpanReferenceType documentation for +// supported relationships. If SpanReference is created with +// ReferencedContext==nil, it has no effect. Thus it allows for a more concise +// syntax for starting spans: +// +// sc, _ := tracer.Extract(someFormat, someCarrier) +// span := tracer.StartSpan("operation", opentracing.ChildOf(sc)) +// +// The `ChildOf(sc)` option above will not panic if sc == nil, it will just +// not add the parent span reference to the options. +type SpanReference struct { + Type SpanReferenceType + ReferencedContext SpanContext +} + +// Apply satisfies the StartSpanOption interface. +func (r SpanReference) Apply(o *StartSpanOptions) { + if r.ReferencedContext != nil { + o.References = append(o.References, r) + } +} + +// ChildOf returns a StartSpanOption pointing to a dependent parent span. +// If sc == nil, the option has no effect. +// +// See ChildOfRef, SpanReference +func ChildOf(sc SpanContext) SpanReference { + return SpanReference{ + Type: ChildOfRef, + ReferencedContext: sc, + } +} + +// FollowsFrom returns a StartSpanOption pointing to a parent Span that caused +// the child Span but does not directly depend on its result in any way. +// If sc == nil, the option has no effect. +// +// See FollowsFromRef, SpanReference +func FollowsFrom(sc SpanContext) SpanReference { + return SpanReference{ + Type: FollowsFromRef, + ReferencedContext: sc, + } +} + +// StartTime is a StartSpanOption that sets an explicit start timestamp for the +// new Span. +type StartTime time.Time + +// Apply satisfies the StartSpanOption interface. +func (t StartTime) Apply(o *StartSpanOptions) { + o.StartTime = time.Time(t) +} + +// Tags are a generic map from an arbitrary string key to an opaque value type. +// The underlying tracing system is responsible for interpreting and +// serializing the values. +type Tags map[string]interface{} + +// Apply satisfies the StartSpanOption interface. +func (t Tags) Apply(o *StartSpanOptions) { + if o.Tags == nil { + o.Tags = make(map[string]interface{}) + } + for k, v := range t { + o.Tags[k] = v + } +} + +// Tag may be passed as a StartSpanOption to add a tag to new spans, +// or its Set method may be used to apply the tag to an existing Span, +// for example: +// +// tracer.StartSpan("opName", Tag{"Key", value}) +// +// or +// +// Tag{"key", value}.Set(span) +type Tag struct { + Key string + Value interface{} +} + +// Apply satisfies the StartSpanOption interface. +func (t Tag) Apply(o *StartSpanOptions) { + if o.Tags == nil { + o.Tags = make(map[string]interface{}) + } + o.Tags[t.Key] = t.Value +} + +// Set applies the tag to an existing Span. +func (t Tag) Set(s Span) { + s.SetTag(t.Key, t.Value) +}