diff --git a/Dockerfile b/Dockerfile
index b5d31dbe..b14dafe9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1.0-experimental
-ARG DOCKERD_VERSION=18.09
+ARG DOCKERD_VERSION=19.03-rc
ARG CLI_VERSION=19.03
FROM docker:$DOCKERD_VERSION AS dockerd-release
@@ -54,11 +54,13 @@ FROM binaries-$TARGETOS AS binaries
FROM alpine AS demo-env
RUN apk add --no-cache iptables tmux git
+RUN apt-get update && apt-get install -y iptables tmux git curl vim file
+RUN curl https://get.docker.com/ | CHANNEL=test sh
RUN mkdir -p /usr/local/lib/docker/cli-plugins && ln -s /usr/local/bin/buildx /usr/local/lib/docker/cli-plugins/docker-buildx
COPY ./hack/demo-env/entrypoint.sh /usr/local/bin
COPY ./hack/demo-env/tmux.conf /root/.tmux.conf
COPY --from=dockerd-release /usr/local/bin /usr/local/bin
-COPY --from=docker-cli-build /go/src/github.com/docker/cli/build/docker /usr/local/bin
+#COPY --from=docker-cli-build /go/src/github.com/docker/cli/build/docker /usr/local/bin
WORKDIR /work
COPY ./hack/demo-env/examples .
diff --git a/go.mod b/go.mod
index a1120fbb..12869bb6 100644
--- a/go.mod
+++ b/go.mod
@@ -53,7 +53,7 @@ require (
github.com/mattn/go-sqlite3 v1.10.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/miekg/pkcs11 v0.0.0-20190322140431-074fd7a1ed19 // indirect
- github.com/moby/buildkit v0.4.1-0.20190326070013-325bd96b6b62
+ github.com/moby/buildkit v0.4.1-0.20190405144722-cbfb5c476a09
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/opencontainers/go-digest v1.0.0-rc1
@@ -84,3 +84,5 @@ require (
k8s.io/client-go v2.0.0-alpha.0.0.20180806134042-1f13a808da65+incompatible // indirect
vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787 // indirect
)
+
+replace github.com/jaguilar/vt100 => github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305
diff --git a/go.sum b/go.sum
index 7077fffc..ce07f86c 100644
--- a/go.sum
+++ b/go.sum
@@ -183,8 +183,8 @@ github.com/miekg/pkcs11 v0.0.0-20190322140431-074fd7a1ed19/go.mod h1:WCBAbTOdfhH
github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/moby/buildkit v0.4.1-0.20190326070013-325bd96b6b62 h1:GulTASjmiroM1LFiX4HX1zo7nQ7vRm3BbzdUou7UMaw=
-github.com/moby/buildkit v0.4.1-0.20190326070013-325bd96b6b62/go.mod h1:CGtUCEvQ3mcP73SmixGWRxEOECm+hCUJsdfNVKPNzVA=
+github.com/moby/buildkit v0.4.1-0.20190405144722-cbfb5c476a09 h1:OHOk/ObJ9P40As+zA6PNN8w1ZulvpVQyYtSzkWjDEyQ=
+github.com/moby/buildkit v0.4.1-0.20190405144722-cbfb5c476a09/go.mod h1:ivyIn0/bTW+YAXWeOqMWJ9aHLeac6SKIB4QeGlxzu/Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
@@ -251,10 +251,12 @@ github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/theupdateframework/notary v0.6.1 h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0=
github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY=
-github.com/tonistiigi/fsutil v0.0.0-20190319020005-1bdbf124ad49 h1:UFQ7uDVXIH4fFfOb+fISgTl8Ukk0CkGQudHQh980l+0=
-github.com/tonistiigi/fsutil v0.0.0-20190319020005-1bdbf124ad49/go.mod h1:pzh7kdwkDRh+Bx8J30uqaKJ1M4QrSH/um8fcIXeM8rc=
+github.com/tonistiigi/fsutil v0.0.0-20190327153851-3bbb99cdbd76 h1:eGfgYrNUSD448sa4mxH6nQpyZfN39QH0mLB7QaKIjus=
+github.com/tonistiigi/fsutil v0.0.0-20190327153851-3bbb99cdbd76/go.mod h1:pzh7kdwkDRh+Bx8J30uqaKJ1M4QrSH/um8fcIXeM8rc=
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0=
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk=
+github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305 h1:y/1cL5AL2oRcfzz8CAHHhR6kDDfIOT0WEyH5k40sccM=
+github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305/go.mod h1:gXOLibKqQTRAVuVZ9gX7G9Ykky8ll8yb4slxsEMoY0c=
github.com/uber/jaeger-client-go v0.0.0-20180103221425-e02c85f9069e/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v1.2.1/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
diff --git a/vendor/github.com/jaguilar/vt100/.travis.yml b/vendor/github.com/jaguilar/vt100/.travis.yml
new file mode 100644
index 00000000..eb93f278
--- /dev/null
+++ b/vendor/github.com/jaguilar/vt100/.travis.yml
@@ -0,0 +1 @@
+language: go
\ No newline at end of file
diff --git a/vendor/github.com/jaguilar/vt100/LICENSE b/vendor/github.com/jaguilar/vt100/LICENSE
new file mode 100644
index 00000000..50d8a71f
--- /dev/null
+++ b/vendor/github.com/jaguilar/vt100/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 James Aguilar
+
+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/vendor/github.com/jaguilar/vt100/README.md b/vendor/github.com/jaguilar/vt100/README.md
new file mode 100644
index 00000000..4df69852
--- /dev/null
+++ b/vendor/github.com/jaguilar/vt100/README.md
@@ -0,0 +1,54 @@
+#VT100
+
+[![Build Status](https://travis-ci.org/jaguilar/vt100.svg?branch=master)](https://travis-ci.org/jaguilar/vt100)
+
+[![GoDoc](https://godoc.org/github.com/jaguilar/vt100?status.svg)](https://godoc.org/github.com/jaguilar/vt100)
+
+This is a vt100 screen reader. It seems to do a pretty
+decent job of parsing the nethack input stream, which
+is all I want it for anyway.
+
+Here is a screenshot of the HTML-formatted screen data:
+
+![](_readme/screencap.png)
+
+The features we currently support:
+
+* Cursor movement
+* Erasing
+* Many of the text properties -- underline, inverse, blink, etc.
+* Sixteen colors
+* Cursor saving and unsaving
+* UTF-8
+
+Not currently supported (and no plans to support):
+
+* Scrolling
+* Prompts
+* Other cooked mode features
+
+The API is not stable! This is a v0 package.
+
+## Demo
+
+Try running the demo! Install nethack:
+
+ sudo apt-get install nethack
+
+Get this code:
+
+ go get github.com/jaguilar/vt100
+ cd $GOPATH/src/githib.com/jaguilar/vt100
+
+Run this code:
+
+ go run demo/demo.go -port=8080 2>/tmp/error.txt
+
+Play some nethack and check out the resulting VT100 terminal status:
+
+ # From another terminal . . .
+ xdg-open http://localhost:8080/debug/vt100
+
+The demo probably assumes Linux (it uses pty-related syscalls). I'll happily
+accept pull requests that replicate the pty-spawning functions on OSX and
+Windows.
\ No newline at end of file
diff --git a/vendor/github.com/jaguilar/vt100/command.go b/vendor/github.com/jaguilar/vt100/command.go
new file mode 100644
index 00000000..c2386544
--- /dev/null
+++ b/vendor/github.com/jaguilar/vt100/command.go
@@ -0,0 +1,288 @@
+package vt100
+
+import (
+ "errors"
+ "expvar"
+ "fmt"
+ "image/color"
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+// UnsupportedError indicates that we parsed an operation that this
+// terminal does not implement. Such errors indicate that the client
+// program asked us to perform an action that we don't know how to.
+// It MAY be safe to continue trying to do additional operations.
+// This is a distinct category of errors from things we do know how
+// to do, but are badly encoded, or errors from the underlying io.RuneScanner
+// that we're reading commands from.
+type UnsupportedError struct {
+ error
+}
+
+var (
+ supportErrors = expvar.NewMap("vt100-unsupported-operations")
+)
+
+func supportError(e error) error {
+ supportErrors.Add(e.Error(), 1)
+ return UnsupportedError{e}
+}
+
+// Command is a type of object that the terminal can process to perform
+// an update.
+type Command interface {
+ display(v *VT100) error
+}
+
+// runeCommand is a simple command that just writes a rune
+// to the current cell and advances the cursor.
+type runeCommand rune
+
+func (r runeCommand) display(v *VT100) error {
+ v.put(rune(r))
+ return nil
+}
+
+// escapeCommand is a control sequence command. It includes a variety
+// of control and escape sequences that move and modify the cursor
+// or the terminal.
+type escapeCommand struct {
+ cmd rune
+ args string
+}
+
+func (c escapeCommand) String() string {
+ return fmt.Sprintf("[%q %U](%v)", c.cmd, c.cmd, c.args)
+}
+
+type intHandler func(*VT100, []int) error
+
+var (
+ // intHandlers are handlers for which all arguments are numbers.
+ // This is most of them -- all the ones that we process. Eventually,
+ // we may add handlers that support non-int args. Those handlers
+ // will instead receive []string, and they'll have to choose on their
+ // own how they might be parsed.
+ intHandlers = map[rune]intHandler{
+ 's': save,
+ '7': save,
+ 'u': unsave,
+ '8': unsave,
+ 'A': relativeMove(-1, 0),
+ 'B': relativeMove(1, 0),
+ 'C': relativeMove(0, 1),
+ 'D': relativeMove(0, -1),
+ 'K': eraseColumns,
+ 'J': eraseLines,
+ 'H': home,
+ 'f': home,
+ 'm': updateAttributes,
+ }
+)
+
+func save(v *VT100, _ []int) error {
+ v.save()
+ return nil
+}
+
+func unsave(v *VT100, _ []int) error {
+ v.unsave()
+ return nil
+}
+
+var (
+ codeColors = []color.RGBA{
+ Black,
+ Red,
+ Green,
+ Yellow,
+ Blue,
+ Magenta,
+ Cyan,
+ White,
+ {}, // Not used.
+ DefaultColor,
+ }
+)
+
+// A command to update the attributes of the cursor based on the arg list.
+func updateAttributes(v *VT100, args []int) error {
+ f := &v.Cursor.F
+
+ var unsupported []int
+ for _, x := range args {
+ switch x {
+ case 0:
+ *f = Format{}
+ case 1:
+ f.Intensity = Bright
+ case 2:
+ f.Intensity = Dim
+ case 22:
+ f.Intensity = Normal
+ case 4:
+ f.Underscore = true
+ case 24:
+ f.Underscore = false
+ case 5, 6:
+ f.Blink = true // We don't distinguish between blink speeds.
+ case 25:
+ f.Blink = false
+ case 7:
+ f.Inverse = true
+ case 27:
+ f.Inverse = false
+ case 8:
+ f.Conceal = true
+ case 28:
+ f.Conceal = false
+ case 30, 31, 32, 33, 34, 35, 36, 37, 39:
+ f.Fg = codeColors[x-30]
+ case 40, 41, 42, 43, 44, 45, 46, 47, 49:
+ f.Bg = codeColors[x-40]
+ // 38 and 48 not supported. Maybe someday.
+ default:
+ unsupported = append(unsupported, x)
+ }
+ }
+
+ if unsupported != nil {
+ return supportError(fmt.Errorf("unknown attributes: %v", unsupported))
+ }
+ return nil
+}
+
+func relativeMove(y, x int) func(*VT100, []int) error {
+ return func(v *VT100, args []int) error {
+ c := 1
+ if len(args) >= 1 {
+ c = args[0]
+ }
+ // home is 1-indexed, because that's what the terminal sends us. We want to
+ // reuse its sanitization scheme, so we'll just modify our args by that amount.
+ return home(v, []int{v.Cursor.Y + y*c + 1, v.Cursor.X + x*c + 1})
+ }
+}
+
+func eraseColumns(v *VT100, args []int) error {
+ d := eraseForward
+ if len(args) > 0 {
+ d = eraseDirection(args[0])
+ }
+ if d > eraseAll {
+ return fmt.Errorf("unknown erase direction: %d", d)
+ }
+ v.eraseColumns(d)
+ return nil
+}
+
+func eraseLines(v *VT100, args []int) error {
+ d := eraseForward
+ if len(args) > 0 {
+ d = eraseDirection(args[0])
+ }
+ if d > eraseAll {
+ return fmt.Errorf("unknown erase direction: %d", d)
+ }
+ v.eraseLines(d)
+ return nil
+}
+
+func sanitize(v *VT100, y, x int) (int, int, error) {
+ var err error
+ if y < 0 || y >= v.Height || x < 0 || x >= v.Width {
+ err = fmt.Errorf("out of bounds (%d, %d)", y, x)
+ } else {
+ return y, x, nil
+ }
+
+ if y < 0 {
+ y = 0
+ }
+ if y >= v.Height {
+ y = v.Height - 1
+ }
+ if x < 0 {
+ x = 0
+ }
+ if x >= v.Width {
+ x = v.Width - 1
+ }
+ return y, x, err
+}
+
+func home(v *VT100, args []int) error {
+ var y, x int
+ if len(args) >= 2 {
+ y, x = args[0]-1, args[1]-1 // home args are 1-indexed.
+ }
+ y, x, err := sanitize(v, y, x) // Clamp y and x to the bounds of the terminal.
+ v.home(y, x) // Try to do something like what the client asked.
+ return err
+}
+
+func (c escapeCommand) display(v *VT100) error {
+ f, ok := intHandlers[c.cmd]
+ if !ok {
+ return supportError(c.err(errors.New("unsupported command")))
+ }
+
+ args, err := c.argInts()
+ if err != nil {
+ return c.err(fmt.Errorf("while parsing int args: %v", err))
+ }
+
+ return f(v, args)
+}
+
+// err enhances e with information about the current escape command
+func (c escapeCommand) err(e error) error {
+ return fmt.Errorf("%s: %s", c, e)
+}
+
+var csArgsRe = regexp.MustCompile("^([^0-9]*)(.*)$")
+
+// argInts parses c.args as a slice of at least arity ints. If the number
+// of ; separated arguments is less than arity, the remaining elements of
+// the result will be zero. errors only on integer parsing failure.
+func (c escapeCommand) argInts() ([]int, error) {
+ if len(c.args) == 0 {
+ return make([]int, 0), nil
+ }
+ args := strings.Split(c.args, ";")
+ out := make([]int, len(args))
+ for i, s := range args {
+ x, err := strconv.ParseInt(s, 10, 0)
+ if err != nil {
+ return nil, err
+ }
+ out[i] = int(x)
+ }
+ return out, nil
+}
+
+type controlCommand rune
+
+const (
+ backspace controlCommand = '\b'
+ _horizontalTab = '\t'
+ linefeed = '\n'
+ _verticalTab = '\v'
+ _formfeed = '\f'
+ carriageReturn = '\r'
+)
+
+func (c controlCommand) display(v *VT100) error {
+ switch c {
+ case backspace:
+ v.backspace()
+ case linefeed:
+ v.Cursor.Y++
+ v.Cursor.X = 0
+ case carriageReturn:
+ v.Cursor.X = 0
+ }
+ return nil
+}
diff --git a/vendor/github.com/jaguilar/vt100/go.mod b/vendor/github.com/jaguilar/vt100/go.mod
new file mode 100644
index 00000000..938cab63
--- /dev/null
+++ b/vendor/github.com/jaguilar/vt100/go.mod
@@ -0,0 +1,5 @@
+module github.com/jaguilar/vt100
+
+go 1.12
+
+require github.com/stretchr/testify v1.3.0
diff --git a/vendor/github.com/jaguilar/vt100/go.sum b/vendor/github.com/jaguilar/vt100/go.sum
new file mode 100644
index 00000000..4347755a
--- /dev/null
+++ b/vendor/github.com/jaguilar/vt100/go.sum
@@ -0,0 +1,7 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
diff --git a/vendor/github.com/jaguilar/vt100/scanner.go b/vendor/github.com/jaguilar/vt100/scanner.go
new file mode 100644
index 00000000..19a4b97f
--- /dev/null
+++ b/vendor/github.com/jaguilar/vt100/scanner.go
@@ -0,0 +1,97 @@
+package vt100
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "unicode"
+)
+
+// Decode decodes one ANSI terminal command from s.
+//
+// s should be connected to a client program that expects an
+// ANSI terminal on the other end. It will push bytes to us that we are meant
+// to intepret as terminal control codes, or text to place onto the terminal.
+//
+// This Command alone does not actually update the terminal. You need to pass
+// it to VT100.Process().
+//
+// You should not share s with any other reader, because it could leave
+// the stream in an invalid state.
+func Decode(s io.RuneScanner) (Command, error) {
+ r, size, err := s.ReadRune()
+ if err != nil {
+ return nil, err
+ }
+
+ if r == unicode.ReplacementChar && size == 1 {
+ return nil, fmt.Errorf("non-utf8 data from reader")
+ }
+
+ if r == escape || r == monogramCsi { // At beginning of escape sequence.
+ s.UnreadRune()
+ return scanEscapeCommand(s)
+ }
+
+ if unicode.IsControl(r) {
+ return controlCommand(r), nil
+ }
+
+ return runeCommand(r), nil
+}
+
+const (
+ // There are two ways to begin an escape sequence. One is to put the escape byte.
+ // The other is to put the single-rune control sequence indicator, which is equivalent
+ // to putting "\u001b[".
+ escape = '\u001b'
+ monogramCsi = '\u009b'
+)
+
+var (
+ csEnd = &unicode.RangeTable{R16: []unicode.Range16{{Lo: 64, Hi: 126, Stride: 1}}}
+)
+
+// scanEscapeCommand scans to the end of the current escape sequence. The scanner
+// must be positioned at an escape rune (esc or the unicode CSI).
+func scanEscapeCommand(s io.RuneScanner) (Command, error) {
+ csi := false
+ esc, _, err := s.ReadRune()
+ if err != nil {
+ return nil, err
+ }
+ if esc != escape && esc != monogramCsi {
+ return nil, fmt.Errorf("invalid content")
+ }
+ if esc == monogramCsi {
+ csi = true
+ }
+
+ var args bytes.Buffer
+ quote := false
+ for i := 0; ; i++ {
+ r, _, err := s.ReadRune()
+ if err != nil {
+ return nil, err
+ }
+ if i == 0 && r == '[' {
+ csi = true
+ continue
+ }
+
+ if !csi {
+ return escapeCommand{r, ""}, nil
+ } else if quote == false && unicode.Is(csEnd, r) {
+ return escapeCommand{r, args.String()}, nil
+ }
+
+ if r == '"' {
+ quote = !quote
+ }
+
+ // Otherwise, we're still in the args, and this rune is one of those args.
+ if _, err := args.WriteRune(r); err != nil {
+ panic(err) // WriteRune cannot return an error from bytes.Buffer.
+ }
+ }
+}
diff --git a/vendor/github.com/jaguilar/vt100/vt100.go b/vendor/github.com/jaguilar/vt100/vt100.go
new file mode 100644
index 00000000..5bf7df96
--- /dev/null
+++ b/vendor/github.com/jaguilar/vt100/vt100.go
@@ -0,0 +1,435 @@
+// package vt100 implements a quick-and-dirty programmable ANSI terminal emulator.
+//
+// You could, for example, use it to run a program like nethack that expects
+// a terminal as a subprocess. It tracks the position of the cursor,
+// colors, and various other aspects of the terminal's state, and
+// allows you to inspect them.
+//
+// We do very much mean the dirty part. It's not that we think it might have
+// bugs. It's that we're SURE it does. Currently, we only handle raw mode, with no
+// cooked mode features like scrolling. We also misinterpret some of the control
+// codes, which may or may not matter for your purpose.
+package vt100
+
+import (
+ "bytes"
+ "fmt"
+ "image/color"
+ "sort"
+ "strings"
+)
+
+type Intensity int
+
+const (
+ Normal Intensity = 0
+ Bright = 1
+ Dim = 2
+ // TODO(jaguilar): Should this be in a subpackage, since the names are pretty collide-y?
+)
+
+var (
+ // Technically RGBAs are supposed to be premultiplied. But CSS doesn't expect them
+ // that way, so we won't do it in this file.
+ DefaultColor = color.RGBA{0, 0, 0, 0}
+ // Our black has 255 alpha, so it will compare negatively with DefaultColor.
+ Black = color.RGBA{0, 0, 0, 255}
+ Red = color.RGBA{255, 0, 0, 255}
+ Green = color.RGBA{0, 255, 0, 255}
+ Yellow = color.RGBA{255, 255, 0, 255}
+ Blue = color.RGBA{0, 0, 255, 255}
+ Magenta = color.RGBA{255, 0, 255, 255}
+ Cyan = color.RGBA{0, 255, 255, 255}
+ White = color.RGBA{255, 255, 255, 255}
+)
+
+func (i Intensity) alpha() uint8 {
+ switch i {
+ case Bright:
+ return 255
+ case Normal:
+ return 170
+ case Dim:
+ return 85
+ default:
+ return 170
+ }
+}
+
+// Format represents the display format of text on a terminal.
+type Format struct {
+ // Fg is the foreground color.
+ Fg color.RGBA
+ // Bg is the background color.
+ Bg color.RGBA
+ // Intensity is the text intensity (bright, normal, dim).
+ Intensity Intensity
+ // Various text properties.
+ Underscore, Conceal, Negative, Blink, Inverse bool
+}
+
+func toCss(c color.RGBA) string {
+ return fmt.Sprintf("rgba(%d, %d, %d, %f)", c.R, c.G, c.B, float32(c.A)/255)
+}
+
+func (f Format) css() string {
+ parts := make([]string, 0)
+ fg, bg := f.Fg, f.Bg
+ if f.Inverse {
+ bg, fg = fg, bg
+ }
+
+ if f.Intensity != Normal {
+ // Intensity only applies to the text -- i.e., the foreground.
+ fg.A = f.Intensity.alpha()
+ }
+
+ if fg != DefaultColor {
+ parts = append(parts, "color:"+toCss(fg))
+ }
+ if bg != DefaultColor {
+ parts = append(parts, "background-color:"+toCss(bg))
+ }
+ if f.Underscore {
+ parts = append(parts, "text-decoration:underline")
+ }
+ if f.Conceal {
+ parts = append(parts, "display:none")
+ }
+ if f.Blink {
+ parts = append(parts, "text-decoration:blink")
+ }
+
+ // We're not in performance sensitive code. Although this sort
+ // isn't strictly necessary, it gives us the nice property that
+ // the style of a particular set of attributes will always be
+ // generated the same way. As a result, we can use the html
+ // output in tests.
+ sort.StringSlice(parts).Sort()
+
+ return strings.Join(parts, ";")
+}
+
+// Cursor represents both the position and text type of the cursor.
+type Cursor struct {
+ // Y and X are the coordinates.
+ Y, X int
+
+ // F is the format that will be displayed.
+ F Format
+}
+
+// VT100 represents a simplified, raw VT100 terminal.
+type VT100 struct {
+ // Height and Width are the dimensions of the terminal.
+ Height, Width int
+
+ // Content is the text in the terminal.
+ Content [][]rune
+
+ // Format is the display properties of each cell.
+ Format [][]Format
+
+ // Cursor is the current state of the cursor.
+ Cursor Cursor
+
+ // savedCursor is the state of the cursor last time save() was called.
+ savedCursor Cursor
+
+ unparsed []byte
+}
+
+// NewVT100 creates a new VT100 object with the specified dimensions. y and x
+// must both be greater than zero.
+//
+// Each cell is set to contain a ' ' rune, and all formats are left as the
+// default.
+func NewVT100(y, x int) *VT100 {
+ if y == 0 || x == 0 {
+ panic(fmt.Errorf("invalid dim (%d, %d)", y, x))
+ }
+
+ v := &VT100{
+ Height: y,
+ Width: x,
+ Content: make([][]rune, y),
+ Format: make([][]Format, y),
+ }
+
+ for row := 0; row < y; row++ {
+ v.Content[row] = make([]rune, x)
+ v.Format[row] = make([]Format, x)
+
+ for col := 0; col < x; col++ {
+ v.clear(row, col)
+ }
+ }
+ return v
+}
+
+func (v *VT100) UsedHeight() int {
+ count := 0
+ for _, l := range v.Content {
+ for _, r := range l {
+ if r != ' ' {
+ count++
+ break
+ }
+ }
+ }
+ return count
+}
+
+func (v *VT100) Resize(y, x int) {
+ if y > v.Height {
+ n := y - v.Height
+ for row := 0; row < n; row++ {
+ v.Content = append(v.Content, make([]rune, v.Width))
+ v.Format = append(v.Format, make([]Format, v.Width))
+ for col := 0; col < v.Width; col++ {
+ v.clear(v.Height+row, col)
+ }
+ }
+ v.Height = y
+ } else if y < v.Height {
+ v.Content = v.Content[:y]
+ v.Height = y
+ }
+
+ if x > v.Width {
+ for i := range v.Content {
+ row := make([]rune, x)
+ copy(row, v.Content[i])
+ v.Content[i] = row
+ format := make([]Format, x)
+ copy(format, v.Format[i])
+ v.Format[i] = format
+ for j := v.Width; j < x; j++ {
+ v.clear(i, j)
+ }
+ }
+ v.Width = x
+ } else if x < v.Width {
+ for i := range v.Content {
+ v.Content[i] = v.Content[i][:x]
+ v.Format[i] = v.Format[i][:x]
+ }
+ v.Width = x
+ }
+}
+
+func (v *VT100) Write(dt []byte) (int, error) {
+ n := len(dt)
+ if len(v.unparsed) > 0 {
+ dt = append(v.unparsed, dt...) // this almost never happens
+ v.unparsed = nil
+ }
+ buf := bytes.NewBuffer(dt)
+ for {
+ if buf.Len() == 0 {
+ return n, nil
+ }
+ cmd, err := Decode(buf)
+ if err != nil {
+ if l := buf.Len(); l > 0 && l < 12 { // on small leftover handle unparsed, otherwise skip
+ v.unparsed = buf.Bytes()
+ }
+ return n, nil
+ }
+ v.Process(cmd) // ignore error
+ }
+}
+
+// Process handles a single ANSI terminal command, updating the terminal
+// appropriately.
+//
+// One special kind of error that this can return is an UnsupportedError. It's
+// probably best to check for these and skip, because they are likely recoverable.
+// Support errors are exported as expvars, so it is possibly not necessary to log
+// them. If you want to check what's failed, start a debug http server and examine
+// the vt100-unsupported-commands field in /debug/vars.
+func (v *VT100) Process(c Command) error {
+ return c.display(v)
+}
+
+// HTML renders v as an HTML fragment. One idea for how to use this is to debug
+// the current state of the screen reader.
+func (v *VT100) HTML() string {
+ var buf bytes.Buffer
+ buf.WriteString(`
`)
+
+ // Iterate each row. When the css changes, close the previous span, and open
+ // a new one. No need to close a span when the css is empty, we won't have
+ // opened one in the past.
+ var lastFormat Format
+ for y, row := range v.Content {
+ for x, r := range row {
+ f := v.Format[y][x]
+ if f != lastFormat {
+ if lastFormat != (Format{}) {
+ buf.WriteString("")
+ }
+ if f != (Format{}) {
+ buf.WriteString(``)
+ }
+ lastFormat = f
+ }
+ if s := maybeEscapeRune(r); s != "" {
+ buf.WriteString(s)
+ } else {
+ buf.WriteRune(r)
+ }
+ }
+ buf.WriteRune('\n')
+ }
+ buf.WriteString("
")
+
+ return buf.String()
+}
+
+// maybeEscapeRune potentially escapes a rune for display in an html document.
+// It only escapes the things that html.EscapeString does, but it works without allocating
+// a string to hold r. Returns an empty string if there is no need to escape.
+func maybeEscapeRune(r rune) string {
+ switch r {
+ case '&':
+ return "&"
+ case '\'':
+ return "'"
+ case '<':
+ return "<"
+ case '>':
+ return ">"
+ case '"':
+ return """
+ }
+ return ""
+}
+
+// put puts r onto the current cursor's position, then advances the cursor.
+func (v *VT100) put(r rune) {
+ v.scrollIfNeeded()
+ v.Content[v.Cursor.Y][v.Cursor.X] = r
+ v.Format[v.Cursor.Y][v.Cursor.X] = v.Cursor.F
+ v.advance()
+}
+
+// advance advances the cursor, wrapping to the next line if need be.
+func (v *VT100) advance() {
+ v.Cursor.X++
+ if v.Cursor.X >= v.Width {
+ v.Cursor.X = 0
+ v.Cursor.Y++
+ }
+ // if v.Cursor.Y >= v.Height {
+ // // TODO(jaguilar): if we implement scroll, this should probably scroll.
+ // // v.Cursor.Y = 0
+ // v.scroll()
+ // }
+}
+
+func (v *VT100) scrollIfNeeded() {
+ if v.Cursor.Y >= v.Height {
+ first := v.Content[0]
+ copy(v.Content, v.Content[1:])
+ for i := range first {
+ first[i] = ' '
+ }
+ v.Content[v.Height-1] = first
+ v.Cursor.Y = v.Height - 1
+ }
+}
+
+// home moves the cursor to the coordinates y x. If y x are out of bounds, v.Err
+// is set.
+func (v *VT100) home(y, x int) {
+ v.Cursor.Y, v.Cursor.X = y, x
+}
+
+// eraseDirection is the logical direction in which an erase command happens,
+// from the cursor. For both erase commands, forward is 0, backward is 1,
+// and everything is 2.
+type eraseDirection int
+
+const (
+ // From the cursor to the end, inclusive.
+ eraseForward eraseDirection = iota
+
+ // From the beginning to the cursor, inclusive.
+ eraseBack
+
+ // Everything.
+ eraseAll
+)
+
+// eraseColumns erases columns from the current line.
+func (v *VT100) eraseColumns(d eraseDirection) {
+ y, x := v.Cursor.Y, v.Cursor.X // Aliases for simplicity.
+ switch d {
+ case eraseBack:
+ v.eraseRegion(y, 0, y, x)
+ case eraseForward:
+ v.eraseRegion(y, x, y, v.Width-1)
+ case eraseAll:
+ v.eraseRegion(y, 0, y, v.Width-1)
+ }
+}
+
+// eraseLines erases lines from the current terminal. Note that
+// no matter what is selected, the entire current line is erased.
+func (v *VT100) eraseLines(d eraseDirection) {
+ y := v.Cursor.Y // Alias for simplicity.
+ switch d {
+ case eraseBack:
+ v.eraseRegion(0, 0, y, v.Width-1)
+ case eraseForward:
+ v.eraseRegion(y, 0, v.Height-1, v.Width-1)
+ case eraseAll:
+ v.eraseRegion(0, 0, v.Height-1, v.Width-1)
+ }
+}
+
+func (v *VT100) eraseRegion(y1, x1, y2, x2 int) {
+ // Do not sanitize or bounds-check these coordinates, since they come from the
+ // programmer (me). We should panic if any of them are out of bounds.
+ if y1 > y2 {
+ y1, y2 = y2, y1
+ }
+ if x1 > x2 {
+ x1, x2 = x2, x1
+ }
+
+ for y := y1; y <= y2; y++ {
+ for x := x1; x <= x2; x++ {
+ v.clear(y, x)
+ }
+ }
+}
+
+func (v *VT100) clear(y, x int) {
+ if y >= len(v.Content) || x >= len(v.Content[0]) {
+ return
+ }
+ v.Content[y][x] = ' '
+ v.Format[y][x] = Format{}
+}
+
+func (v *VT100) backspace() {
+ v.Cursor.X--
+ if v.Cursor.X < 0 {
+ if v.Cursor.Y == 0 {
+ v.Cursor.X = 0
+ } else {
+ v.Cursor.Y--
+ v.Cursor.X = v.Width - 1
+ }
+ }
+}
+
+func (v *VT100) save() {
+ v.savedCursor = v.Cursor
+}
+
+func (v *VT100) unsave() {
+ v.Cursor = v.savedCursor
+}
diff --git a/vendor/github.com/moby/buildkit/client/connhelper/connhelper.go b/vendor/github.com/moby/buildkit/client/connhelper/connhelper.go
index 9fa5edcd..e634bb5c 100644
--- a/vendor/github.com/moby/buildkit/client/connhelper/connhelper.go
+++ b/vendor/github.com/moby/buildkit/client/connhelper/connhelper.go
@@ -5,10 +5,10 @@ import (
"context"
"net"
"net/url"
-
- "github.com/docker/cli/cli/connhelper/commandconn"
)
+var helpers = map[string]func(*url.URL) (*ConnectionHelper, error){}
+
// ConnectionHelper allows to connect to a remote host with custom stream provider binary.
type ConnectionHelper struct {
// ContextDialer can be passed to grpc.WithContextDialer
@@ -17,21 +17,21 @@ type ConnectionHelper struct {
// GetConnectionHelper returns BuildKit-specific connection helper for the given URL.
// GetConnectionHelper returns nil without error when no helper is registered for the scheme.
-//
-// docker:// URL requires BuildKit v0.5.0 or later in the container.
func GetConnectionHelper(daemonURL string) (*ConnectionHelper, error) {
u, err := url.Parse(daemonURL)
if err != nil {
return nil, err
}
- switch scheme := u.Scheme; scheme {
- case "docker":
- container := u.Host
- return &ConnectionHelper{
- ContextDialer: func(ctx context.Context, addr string) (net.Conn, error) {
- return commandconn.New(ctx, "docker", "exec", "-i", container, "buildctl", "dial-stdio")
- },
- }, nil
+
+ fn, ok := helpers[u.Scheme]
+ if !ok {
+ return nil, nil
}
- return nil, err
+
+ return fn(u)
+}
+
+// Register registers new connectionhelper for scheme
+func Register(scheme string, fn func(*url.URL) (*ConnectionHelper, error)) {
+ helpers[scheme] = fn
}
diff --git a/vendor/github.com/moby/buildkit/client/exporters.go b/vendor/github.com/moby/buildkit/client/exporters.go
index 4160d92a..0f70d59c 100644
--- a/vendor/github.com/moby/buildkit/client/exporters.go
+++ b/vendor/github.com/moby/buildkit/client/exporters.go
@@ -3,6 +3,7 @@ package client
const (
ExporterImage = "image"
ExporterLocal = "local"
+ ExporterTar = "tar"
ExporterOCI = "oci"
ExporterDocker = "docker"
)
diff --git a/vendor/github.com/moby/buildkit/client/llb/exec.go b/vendor/github.com/moby/buildkit/client/llb/exec.go
index 8233b076..e45a2330 100644
--- a/vendor/github.com/moby/buildkit/client/llb/exec.go
+++ b/vendor/github.com/moby/buildkit/client/llb/exec.go
@@ -20,6 +20,7 @@ type Meta struct {
ProxyEnv *ProxyEnv
ExtraHosts []HostIP
Network pb.NetMode
+ Security pb.SecurityMode
}
func NewExecOp(root Output, meta Meta, readOnly bool, c Constraints) *ExecOp {
@@ -52,7 +53,7 @@ type mount struct {
cacheID string
tmpfs bool
cacheSharing CacheMountSharingMode
- // hasOutput bool
+ noOutput bool
}
type ExecOp struct {
@@ -79,6 +80,8 @@ func (e *ExecOp) AddMount(target string, source Output, opt ...MountOption) Outp
m.output = source
} else if m.tmpfs {
m.output = &output{vertex: e, err: errors.Errorf("tmpfs mount for %s can't be used as a parent", target)}
+ } else if m.noOutput {
+ m.output = &output{vertex: e, err: errors.Errorf("mount marked no-output and %s can't be used as a parent", target)}
} else {
o := &output{vertex: e, getIndex: e.getMountIndexFn(m)}
if p := e.constraints.Platform; p != nil {
@@ -166,13 +169,18 @@ func (e *ExecOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata,
}
peo := &pb.ExecOp{
- Meta: meta,
- Network: e.meta.Network,
+ Meta: meta,
+ Network: e.meta.Network,
+ Security: e.meta.Security,
}
if e.meta.Network != NetModeSandbox {
addCap(&e.constraints, pb.CapExecMetaNetwork)
}
+ if e.meta.Security != SecurityModeInsecure {
+ addCap(&e.constraints, pb.CapExecMetaSecurity)
+ }
+
if p := e.meta.ProxyEnv; p != nil {
peo.Meta.ProxyEnv = &pb.ProxyEnv{
HttpProxy: p.HttpProxy,
@@ -242,7 +250,7 @@ func (e *ExecOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata,
}
outputIndex := pb.OutputIndex(-1)
- if !m.readonly && m.cacheID == "" && !m.tmpfs {
+ if !m.noOutput && !m.readonly && m.cacheID == "" && !m.tmpfs {
outputIndex = pb.OutputIndex(outIndex)
outIndex++
}
@@ -338,7 +346,7 @@ func (e *ExecOp) getMountIndexFn(m *mount) func() (pb.OutputIndex, error) {
i := 0
for _, m2 := range e.mounts {
- if m2.readonly || m2.cacheID != "" {
+ if m2.noOutput || m2.readonly || m2.cacheID != "" {
continue
}
if m == m2 {
@@ -379,6 +387,10 @@ func SourcePath(src string) MountOption {
}
}
+func ForceNoOutput(m *mount) {
+ m.noOutput = true
+}
+
func AsPersistentCacheDir(id string, sharing CacheMountSharingMode) MountOption {
return func(m *mount) {
m.cacheID = id
@@ -408,6 +420,12 @@ func Network(n pb.NetMode) RunOption {
})
}
+func Security(s pb.SecurityMode) RunOption {
+ return runOptionFunc(func(ei *ExecInfo) {
+ ei.State = security(s)(ei.State)
+ })
+}
+
func Shlex(str string) RunOption {
return Shlexf(str)
}
@@ -623,3 +641,8 @@ const (
NetModeHost = pb.NetMode_HOST
NetModeNone = pb.NetMode_NONE
)
+
+const (
+ SecurityModeInsecure = pb.SecurityMode_INSECURE
+ SecurityModeSandbox = pb.SecurityMode_SANDBOX
+)
diff --git a/vendor/github.com/moby/buildkit/client/llb/meta.go b/vendor/github.com/moby/buildkit/client/llb/meta.go
index 702ea145..78a24730 100644
--- a/vendor/github.com/moby/buildkit/client/llb/meta.go
+++ b/vendor/github.com/moby/buildkit/client/llb/meta.go
@@ -21,6 +21,7 @@ var (
keyExtraHost = contextKeyT("llb.exec.extrahost")
keyPlatform = contextKeyT("llb.platform")
keyNetwork = contextKeyT("llb.network")
+ keySecurity = contextKeyT("llb.security")
)
func addEnvf(key, value string, v ...interface{}) StateOption {
@@ -148,7 +149,6 @@ func network(v pb.NetMode) StateOption {
return s.WithValue(keyNetwork, v)
}
}
-
func getNetwork(s State) pb.NetMode {
v := s.Value(keyNetwork)
if v != nil {
@@ -158,6 +158,20 @@ func getNetwork(s State) pb.NetMode {
return NetModeSandbox
}
+func security(v pb.SecurityMode) StateOption {
+ return func(s State) State {
+ return s.WithValue(keySecurity, v)
+ }
+}
+func getSecurity(s State) pb.SecurityMode {
+ v := s.Value(keySecurity)
+ if v != nil {
+ n := v.(pb.SecurityMode)
+ return n
+ }
+ return SecurityModeSandbox
+}
+
type EnvList []KeyValue
type KeyValue struct {
diff --git a/vendor/github.com/moby/buildkit/client/llb/state.go b/vendor/github.com/moby/buildkit/client/llb/state.go
index 0336b7fd..928242af 100644
--- a/vendor/github.com/moby/buildkit/client/llb/state.go
+++ b/vendor/github.com/moby/buildkit/client/llb/state.go
@@ -214,6 +214,7 @@ func (s State) Run(ro ...RunOption) ExecState {
ProxyEnv: ei.ProxyEnv,
ExtraHosts: getExtraHosts(ei.State),
Network: getNetwork(ei.State),
+ Security: getSecurity(ei.State),
}
exec := NewExecOp(s.Output(), meta, ei.ReadonlyRootFS, ei.Constraints)
@@ -292,6 +293,13 @@ func (s State) Network(n pb.NetMode) State {
func (s State) GetNetwork() pb.NetMode {
return getNetwork(s)
}
+func (s State) Security(n pb.SecurityMode) State {
+ return security(n)(s)
+}
+
+func (s State) GetSecurity() pb.SecurityMode {
+ return getSecurity(s)
+}
func (s State) With(so ...StateOption) State {
for _, o := range so {
diff --git a/vendor/github.com/moby/buildkit/client/solve.go b/vendor/github.com/moby/buildkit/client/solve.go
index ce321f92..d772eaa3 100644
--- a/vendor/github.com/moby/buildkit/client/solve.go
+++ b/vendor/github.com/moby/buildkit/client/solve.go
@@ -124,7 +124,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
return nil, errors.New("output directory is required for local exporter")
}
s.Allow(filesync.NewFSSyncTargetDir(ex.OutputDir))
- case ExporterOCI, ExporterDocker:
+ case ExporterOCI, ExporterDocker, ExporterTar:
if ex.OutputDir != "" {
return nil, errors.Errorf("output directory %s is not supported by %s exporter", ex.OutputDir, ex.Type)
}
diff --git a/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go b/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go
index 5148ade7..6934f946 100644
--- a/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go
+++ b/vendor/github.com/moby/buildkit/session/filesync/diffcopy.go
@@ -57,7 +57,7 @@ func (wc *streamWriterCloser) Close() error {
return nil
}
-func recvDiffCopy(ds grpc.Stream, dest string, cu CacheUpdater, progress progressCb) error {
+func recvDiffCopy(ds grpc.Stream, dest string, cu CacheUpdater, progress progressCb, filter func(string, *fstypes.Stat) bool) error {
st := time.Now()
defer func() {
logrus.Debugf("diffcopy took: %v", time.Since(st))
@@ -73,6 +73,7 @@ func recvDiffCopy(ds grpc.Stream, dest string, cu CacheUpdater, progress progres
NotifyHashed: cf,
ContentHasher: ch,
ProgressCb: progress,
+ Filter: fsutil.FilterFunc(filter),
})
}
diff --git a/vendor/github.com/moby/buildkit/session/filesync/filesync.go b/vendor/github.com/moby/buildkit/session/filesync/filesync.go
index d6adee82..de5237b1 100644
--- a/vendor/github.com/moby/buildkit/session/filesync/filesync.go
+++ b/vendor/github.com/moby/buildkit/session/filesync/filesync.go
@@ -129,7 +129,7 @@ type progressCb func(int, bool)
type protocol struct {
name string
sendFn func(stream grpc.Stream, fs fsutil.FS, progress progressCb) error
- recvFn func(stream grpc.Stream, destDir string, cu CacheUpdater, progress progressCb) error
+ recvFn func(stream grpc.Stream, destDir string, cu CacheUpdater, progress progressCb, mapFunc func(string, *fstypes.Stat) bool) error
}
func isProtoSupported(p string) bool {
@@ -158,6 +158,7 @@ type FSSendRequestOpt struct {
DestDir string
CacheUpdater CacheUpdater
ProgressCb func(int, bool)
+ Filter func(string, *fstypes.Stat) bool
}
// CacheUpdater is an object capable of sending notifications for the cache hash changes
@@ -225,7 +226,7 @@ func FSSync(ctx context.Context, c session.Caller, opt FSSendRequestOpt) error {
panic(fmt.Sprintf("invalid protocol: %q", pr.name))
}
- return pr.recvFn(stream, opt.DestDir, opt.CacheUpdater, opt.ProgressCb)
+ return pr.recvFn(stream, opt.DestDir, opt.CacheUpdater, opt.ProgressCb, opt.Filter)
}
// NewFSSyncTargetDir allows writing into a directory
diff --git a/vendor/github.com/moby/buildkit/solver/pb/caps.go b/vendor/github.com/moby/buildkit/solver/pb/caps.go
index b7f80b81..7ff0358e 100644
--- a/vendor/github.com/moby/buildkit/solver/pb/caps.go
+++ b/vendor/github.com/moby/buildkit/solver/pb/caps.go
@@ -33,6 +33,7 @@ const (
CapExecMetaBase apicaps.CapID = "exec.meta.base"
CapExecMetaProxy apicaps.CapID = "exec.meta.proxyenv"
CapExecMetaNetwork apicaps.CapID = "exec.meta.network"
+ CapExecMetaSecurity apicaps.CapID = "exec.meta.security"
CapExecMetaSetsDefaultPath apicaps.CapID = "exec.meta.setsdefaultpath"
CapExecMountBind apicaps.CapID = "exec.mount.bind"
CapExecMountCache apicaps.CapID = "exec.mount.cache"
@@ -180,6 +181,12 @@ func init() {
Status: apicaps.CapStatusExperimental,
})
+ Caps.Init(apicaps.Cap{
+ ID: CapExecMetaSecurity,
+ Enabled: true,
+ Status: apicaps.CapStatusExperimental,
+ })
+
Caps.Init(apicaps.Cap{
ID: CapExecMountBind,
Enabled: true,
diff --git a/vendor/github.com/moby/buildkit/solver/pb/ops.pb.go b/vendor/github.com/moby/buildkit/solver/pb/ops.pb.go
index 394b325a..dbb0f21f 100644
--- a/vendor/github.com/moby/buildkit/solver/pb/ops.pb.go
+++ b/vendor/github.com/moby/buildkit/solver/pb/ops.pb.go
@@ -54,7 +54,30 @@ func (x NetMode) String() string {
return proto.EnumName(NetMode_name, int32(x))
}
func (NetMode) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{0}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{0}
+}
+
+type SecurityMode int32
+
+const (
+ SecurityMode_SANDBOX SecurityMode = 0
+ SecurityMode_INSECURE SecurityMode = 1
+)
+
+var SecurityMode_name = map[int32]string{
+ 0: "SANDBOX",
+ 1: "INSECURE",
+}
+var SecurityMode_value = map[string]int32{
+ "SANDBOX": 0,
+ "INSECURE": 1,
+}
+
+func (x SecurityMode) String() string {
+ return proto.EnumName(SecurityMode_name, int32(x))
+}
+func (SecurityMode) EnumDescriptor() ([]byte, []int) {
+ return fileDescriptor_ops_0b9d2e829935306b, []int{1}
}
// MountType defines a type of a mount from a supported set
@@ -87,7 +110,7 @@ func (x MountType) String() string {
return proto.EnumName(MountType_name, int32(x))
}
func (MountType) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{1}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{2}
}
// CacheSharingOpt defines different sharing modes for cache mount
@@ -117,7 +140,7 @@ func (x CacheSharingOpt) String() string {
return proto.EnumName(CacheSharingOpt_name, int32(x))
}
func (CacheSharingOpt) EnumDescriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{2}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{3}
}
// Op represents a vertex of the LLB DAG.
@@ -138,7 +161,7 @@ func (m *Op) Reset() { *m = Op{} }
func (m *Op) String() string { return proto.CompactTextString(m) }
func (*Op) ProtoMessage() {}
func (*Op) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{0}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{0}
}
func (m *Op) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -368,7 +391,7 @@ func (m *Platform) Reset() { *m = Platform{} }
func (m *Platform) String() string { return proto.CompactTextString(m) }
func (*Platform) ProtoMessage() {}
func (*Platform) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{1}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{1}
}
func (m *Platform) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -440,7 +463,7 @@ func (m *Input) Reset() { *m = Input{} }
func (m *Input) String() string { return proto.CompactTextString(m) }
func (*Input) ProtoMessage() {}
func (*Input) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{2}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{2}
}
func (m *Input) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -467,16 +490,17 @@ var xxx_messageInfo_Input proto.InternalMessageInfo
// ExecOp executes a command in a container.
type ExecOp struct {
- Meta *Meta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"`
- Mounts []*Mount `protobuf:"bytes,2,rep,name=mounts,proto3" json:"mounts,omitempty"`
- Network NetMode `protobuf:"varint,3,opt,name=network,proto3,enum=pb.NetMode" json:"network,omitempty"`
+ Meta *Meta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,omitempty"`
+ Mounts []*Mount `protobuf:"bytes,2,rep,name=mounts,proto3" json:"mounts,omitempty"`
+ Network NetMode `protobuf:"varint,3,opt,name=network,proto3,enum=pb.NetMode" json:"network,omitempty"`
+ Security SecurityMode `protobuf:"varint,4,opt,name=security,proto3,enum=pb.SecurityMode" json:"security,omitempty"`
}
func (m *ExecOp) Reset() { *m = ExecOp{} }
func (m *ExecOp) String() string { return proto.CompactTextString(m) }
func (*ExecOp) ProtoMessage() {}
func (*ExecOp) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{3}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{3}
}
func (m *ExecOp) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -522,6 +546,13 @@ func (m *ExecOp) GetNetwork() NetMode {
return NetMode_UNSET
}
+func (m *ExecOp) GetSecurity() SecurityMode {
+ if m != nil {
+ return m.Security
+ }
+ return SecurityMode_SANDBOX
+}
+
// Meta is a set of arguments for ExecOp.
// Meta is unrelated to LLB metadata.
// FIXME: rename (ExecContext? ExecArgs?)
@@ -538,7 +569,7 @@ func (m *Meta) Reset() { *m = Meta{} }
func (m *Meta) String() string { return proto.CompactTextString(m) }
func (*Meta) ProtoMessage() {}
func (*Meta) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{4}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{4}
}
func (m *Meta) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -622,7 +653,7 @@ func (m *Mount) Reset() { *m = Mount{} }
func (m *Mount) String() string { return proto.CompactTextString(m) }
func (*Mount) ProtoMessage() {}
func (*Mount) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{5}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{5}
}
func (m *Mount) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -708,7 +739,7 @@ func (m *CacheOpt) Reset() { *m = CacheOpt{} }
func (m *CacheOpt) String() string { return proto.CompactTextString(m) }
func (*CacheOpt) ProtoMessage() {}
func (*CacheOpt) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{6}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{6}
}
func (m *CacheOpt) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -766,7 +797,7 @@ func (m *SecretOpt) Reset() { *m = SecretOpt{} }
func (m *SecretOpt) String() string { return proto.CompactTextString(m) }
func (*SecretOpt) ProtoMessage() {}
func (*SecretOpt) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{7}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{7}
}
func (m *SecretOpt) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -845,7 +876,7 @@ func (m *SSHOpt) Reset() { *m = SSHOpt{} }
func (m *SSHOpt) String() string { return proto.CompactTextString(m) }
func (*SSHOpt) ProtoMessage() {}
func (*SSHOpt) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{8}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{8}
}
func (m *SSHOpt) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -918,7 +949,7 @@ func (m *SourceOp) Reset() { *m = SourceOp{} }
func (m *SourceOp) String() string { return proto.CompactTextString(m) }
func (*SourceOp) ProtoMessage() {}
func (*SourceOp) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{9}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{9}
}
func (m *SourceOp) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -970,7 +1001,7 @@ func (m *BuildOp) Reset() { *m = BuildOp{} }
func (m *BuildOp) String() string { return proto.CompactTextString(m) }
func (*BuildOp) ProtoMessage() {}
func (*BuildOp) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{10}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{10}
}
func (m *BuildOp) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1025,7 +1056,7 @@ func (m *BuildInput) Reset() { *m = BuildInput{} }
func (m *BuildInput) String() string { return proto.CompactTextString(m) }
func (*BuildInput) ProtoMessage() {}
func (*BuildInput) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{11}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{11}
}
func (m *BuildInput) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1066,7 +1097,7 @@ func (m *OpMetadata) Reset() { *m = OpMetadata{} }
func (m *OpMetadata) String() string { return proto.CompactTextString(m) }
func (*OpMetadata) ProtoMessage() {}
func (*OpMetadata) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{12}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{12}
}
func (m *OpMetadata) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1127,7 +1158,7 @@ func (m *ExportCache) Reset() { *m = ExportCache{} }
func (m *ExportCache) String() string { return proto.CompactTextString(m) }
func (*ExportCache) ProtoMessage() {}
func (*ExportCache) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{13}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{13}
}
func (m *ExportCache) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1170,7 +1201,7 @@ func (m *ProxyEnv) Reset() { *m = ProxyEnv{} }
func (m *ProxyEnv) String() string { return proto.CompactTextString(m) }
func (*ProxyEnv) ProtoMessage() {}
func (*ProxyEnv) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{14}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{14}
}
func (m *ProxyEnv) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1232,7 +1263,7 @@ func (m *WorkerConstraints) Reset() { *m = WorkerConstraints{} }
func (m *WorkerConstraints) String() string { return proto.CompactTextString(m) }
func (*WorkerConstraints) ProtoMessage() {}
func (*WorkerConstraints) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{15}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{15}
}
func (m *WorkerConstraints) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1277,7 +1308,7 @@ func (m *Definition) Reset() { *m = Definition{} }
func (m *Definition) String() string { return proto.CompactTextString(m) }
func (*Definition) ProtoMessage() {}
func (*Definition) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{16}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{16}
}
func (m *Definition) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1325,7 +1356,7 @@ func (m *HostIP) Reset() { *m = HostIP{} }
func (m *HostIP) String() string { return proto.CompactTextString(m) }
func (*HostIP) ProtoMessage() {}
func (*HostIP) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{17}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{17}
}
func (m *HostIP) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1372,7 +1403,7 @@ func (m *FileOp) Reset() { *m = FileOp{} }
func (m *FileOp) String() string { return proto.CompactTextString(m) }
func (*FileOp) ProtoMessage() {}
func (*FileOp) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{18}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{18}
}
func (m *FileOp) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1420,7 +1451,7 @@ func (m *FileAction) Reset() { *m = FileAction{} }
func (m *FileAction) String() string { return proto.CompactTextString(m) }
func (*FileAction) ProtoMessage() {}
func (*FileAction) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{19}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{19}
}
func (m *FileAction) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1645,7 +1676,7 @@ func (m *FileActionCopy) Reset() { *m = FileActionCopy{} }
func (m *FileActionCopy) String() string { return proto.CompactTextString(m) }
func (*FileActionCopy) ProtoMessage() {}
func (*FileActionCopy) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{20}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{20}
}
func (m *FileActionCopy) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1764,7 +1795,7 @@ func (m *FileActionMkFile) Reset() { *m = FileActionMkFile{} }
func (m *FileActionMkFile) String() string { return proto.CompactTextString(m) }
func (*FileActionMkFile) ProtoMessage() {}
func (*FileActionMkFile) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{21}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{21}
}
func (m *FileActionMkFile) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1841,7 +1872,7 @@ func (m *FileActionMkDir) Reset() { *m = FileActionMkDir{} }
func (m *FileActionMkDir) String() string { return proto.CompactTextString(m) }
func (*FileActionMkDir) ProtoMessage() {}
func (*FileActionMkDir) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{22}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{22}
}
func (m *FileActionMkDir) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1914,7 +1945,7 @@ func (m *FileActionRm) Reset() { *m = FileActionRm{} }
func (m *FileActionRm) String() string { return proto.CompactTextString(m) }
func (*FileActionRm) ProtoMessage() {}
func (*FileActionRm) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{23}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{23}
}
func (m *FileActionRm) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1969,7 +2000,7 @@ func (m *ChownOpt) Reset() { *m = ChownOpt{} }
func (m *ChownOpt) String() string { return proto.CompactTextString(m) }
func (*ChownOpt) ProtoMessage() {}
func (*ChownOpt) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{24}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{24}
}
func (m *ChownOpt) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -2019,7 +2050,7 @@ func (m *UserOpt) Reset() { *m = UserOpt{} }
func (m *UserOpt) String() string { return proto.CompactTextString(m) }
func (*UserOpt) ProtoMessage() {}
func (*UserOpt) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{25}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{25}
}
func (m *UserOpt) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -2159,7 +2190,7 @@ func (m *NamedUserOpt) Reset() { *m = NamedUserOpt{} }
func (m *NamedUserOpt) String() string { return proto.CompactTextString(m) }
func (*NamedUserOpt) ProtoMessage() {}
func (*NamedUserOpt) Descriptor() ([]byte, []int) {
- return fileDescriptor_ops_8d64813b9835ab08, []int{26}
+ return fileDescriptor_ops_0b9d2e829935306b, []int{26}
}
func (m *NamedUserOpt) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -2226,6 +2257,7 @@ func init() {
proto.RegisterType((*UserOpt)(nil), "pb.UserOpt")
proto.RegisterType((*NamedUserOpt)(nil), "pb.NamedUserOpt")
proto.RegisterEnum("pb.NetMode", NetMode_name, NetMode_value)
+ proto.RegisterEnum("pb.SecurityMode", SecurityMode_name, SecurityMode_value)
proto.RegisterEnum("pb.MountType", MountType_name, MountType_value)
proto.RegisterEnum("pb.CacheSharingOpt", CacheSharingOpt_name, CacheSharingOpt_value)
}
@@ -2470,6 +2502,11 @@ func (m *ExecOp) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintOps(dAtA, i, uint64(m.Network))
}
+ if m.Security != 0 {
+ dAtA[i] = 0x20
+ i++
+ i = encodeVarintOps(dAtA, i, uint64(m.Security))
+ }
return i, nil
}
@@ -3852,6 +3889,9 @@ func (m *ExecOp) Size() (n int) {
if m.Network != 0 {
n += 1 + sovOps(uint64(m.Network))
}
+ if m.Security != 0 {
+ n += 1 + sovOps(uint64(m.Security))
+ }
return n
}
@@ -5156,6 +5196,25 @@ func (m *ExecOp) Unmarshal(dAtA []byte) error {
break
}
}
+ case 4:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Security", wireType)
+ }
+ m.Security = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowOps
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Security |= (SecurityMode(b) & 0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
default:
iNdEx = preIndex
skippy, err := skipOps(dAtA[iNdEx:])
@@ -9171,129 +9230,132 @@ var (
ErrIntOverflowOps = fmt.Errorf("proto: integer overflow")
)
-func init() { proto.RegisterFile("ops.proto", fileDescriptor_ops_8d64813b9835ab08) }
+func init() { proto.RegisterFile("ops.proto", fileDescriptor_ops_0b9d2e829935306b) }
-var fileDescriptor_ops_8d64813b9835ab08 = []byte{
- // 1924 bytes of a gzipped FileDescriptorProto
+var fileDescriptor_ops_0b9d2e829935306b = []byte{
+ // 1978 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x5f, 0x6f, 0x1b, 0xc7,
- 0x11, 0x17, 0x8f, 0x7f, 0x6f, 0x28, 0xc9, 0xec, 0xc6, 0x49, 0x59, 0xd5, 0x95, 0x94, 0x4b, 0x1a,
- 0x30, 0xb2, 0x4d, 0x01, 0x0a, 0x90, 0x04, 0x79, 0x28, 0x2a, 0xfe, 0x31, 0xc4, 0x24, 0x16, 0x85,
- 0xa5, 0xed, 0x3c, 0x1a, 0xc7, 0xbb, 0x25, 0x75, 0x20, 0xef, 0xf6, 0xb0, 0xb7, 0xb4, 0xc4, 0x97,
- 0x3e, 0xf8, 0x13, 0x04, 0x28, 0xd0, 0xb7, 0x3e, 0xf4, 0xa5, 0x40, 0x3f, 0x44, 0xdf, 0xf3, 0x18,
- 0x14, 0x7d, 0x48, 0xfb, 0x90, 0x16, 0xf6, 0x17, 0x29, 0x66, 0x77, 0x8f, 0x77, 0xa4, 0x15, 0xd8,
- 0x46, 0x8b, 0x3e, 0x71, 0x76, 0xe6, 0xb7, 0xb3, 0xb3, 0x33, 0xb3, 0x33, 0x73, 0x04, 0x9b, 0xc7,
- 0x49, 0x3b, 0x16, 0x5c, 0x72, 0x62, 0xc5, 0xe3, 0xbd, 0xfb, 0xd3, 0x40, 0x5e, 0x2e, 0xc6, 0x6d,
- 0x8f, 0x87, 0xc7, 0x53, 0x3e, 0xe5, 0xc7, 0x4a, 0x34, 0x5e, 0x4c, 0xd4, 0x4a, 0x2d, 0x14, 0xa5,
- 0xb7, 0x38, 0x7f, 0xb2, 0xc0, 0x1a, 0xc6, 0xe4, 0x7d, 0xa8, 0x04, 0x51, 0xbc, 0x90, 0x49, 0xb3,
- 0x70, 0x58, 0x6c, 0xd5, 0x4f, 0xec, 0x76, 0x3c, 0x6e, 0x0f, 0x90, 0x43, 0x8d, 0x80, 0x1c, 0x42,
- 0x89, 0x5d, 0x33, 0xaf, 0x69, 0x1d, 0x16, 0x5a, 0xf5, 0x13, 0x40, 0x40, 0xff, 0x9a, 0x79, 0xc3,
- 0xf8, 0x6c, 0x8b, 0x2a, 0x09, 0xf9, 0x08, 0x2a, 0x09, 0x5f, 0x08, 0x8f, 0x35, 0x8b, 0x0a, 0xb3,
- 0x8d, 0x98, 0x91, 0xe2, 0x28, 0x94, 0x91, 0xa2, 0xa6, 0x49, 0x30, 0x67, 0xcd, 0x52, 0xa6, 0xe9,
- 0x41, 0x30, 0xd7, 0x18, 0x25, 0x21, 0x1f, 0x40, 0x79, 0xbc, 0x08, 0xe6, 0x7e, 0xb3, 0xac, 0x20,
- 0x75, 0x84, 0x74, 0x90, 0xa1, 0x30, 0x5a, 0x46, 0x5a, 0x50, 0x8b, 0xe7, 0xae, 0x9c, 0x70, 0x11,
- 0x36, 0x21, 0x3b, 0xf0, 0xc2, 0xf0, 0xe8, 0x4a, 0x4a, 0x3e, 0x83, 0xba, 0xc7, 0xa3, 0x44, 0x0a,
- 0x37, 0x88, 0x64, 0xd2, 0xac, 0x2b, 0xf0, 0xbb, 0x08, 0xfe, 0x86, 0x8b, 0x19, 0x13, 0xdd, 0x4c,
- 0x48, 0xf3, 0xc8, 0x4e, 0x09, 0x2c, 0x1e, 0x3b, 0x7f, 0x28, 0x40, 0x2d, 0xd5, 0x4a, 0x1c, 0xd8,
- 0x3e, 0x15, 0xde, 0x65, 0x20, 0x99, 0x27, 0x17, 0x82, 0x35, 0x0b, 0x87, 0x85, 0x96, 0x4d, 0xd7,
- 0x78, 0x64, 0x17, 0xac, 0xe1, 0x48, 0x39, 0xca, 0xa6, 0xd6, 0x70, 0x44, 0x9a, 0x50, 0x7d, 0xe2,
- 0x8a, 0xc0, 0x8d, 0xa4, 0xf2, 0x8c, 0x4d, 0xd3, 0x25, 0xb9, 0x03, 0xf6, 0x70, 0xf4, 0x84, 0x89,
- 0x24, 0xe0, 0x91, 0xf2, 0x87, 0x4d, 0x33, 0x06, 0xd9, 0x07, 0x18, 0x8e, 0x1e, 0x30, 0x17, 0x95,
- 0x26, 0xcd, 0xf2, 0x61, 0xb1, 0x65, 0xd3, 0x1c, 0xc7, 0xf9, 0x1d, 0x94, 0x55, 0x8c, 0xc8, 0x97,
- 0x50, 0xf1, 0x83, 0x29, 0x4b, 0xa4, 0x36, 0xa7, 0x73, 0xf2, 0xdd, 0x8f, 0x07, 0x5b, 0xff, 0xfc,
- 0xf1, 0xe0, 0x28, 0x97, 0x0c, 0x3c, 0x66, 0x91, 0xc7, 0x23, 0xe9, 0x06, 0x11, 0x13, 0xc9, 0xf1,
- 0x94, 0xdf, 0xd7, 0x5b, 0xda, 0x3d, 0xf5, 0x43, 0x8d, 0x06, 0xf2, 0x31, 0x94, 0x83, 0xc8, 0x67,
- 0xd7, 0xca, 0xfe, 0x62, 0xe7, 0x1d, 0xa3, 0xaa, 0x3e, 0x5c, 0xc8, 0x78, 0x21, 0x07, 0x28, 0xa2,
- 0x1a, 0xe1, 0xc4, 0x50, 0xd1, 0x29, 0x40, 0xee, 0x40, 0x29, 0x64, 0xd2, 0x55, 0xc7, 0xd7, 0x4f,
- 0x6a, 0xe8, 0xda, 0x87, 0x4c, 0xba, 0x54, 0x71, 0x31, 0xbb, 0x42, 0xbe, 0x40, 0xd7, 0x5b, 0x59,
- 0x76, 0x3d, 0x44, 0x0e, 0x35, 0x02, 0xf2, 0x6b, 0xa8, 0x46, 0x4c, 0x5e, 0x71, 0x31, 0x53, 0x2e,
- 0xda, 0xd5, 0x31, 0x3f, 0x67, 0xf2, 0x21, 0xf7, 0x19, 0x4d, 0x65, 0xce, 0x5f, 0x0a, 0x50, 0x42,
- 0xc5, 0x84, 0x40, 0xc9, 0x15, 0x53, 0x9d, 0xae, 0x36, 0x55, 0x34, 0x69, 0x40, 0x91, 0x45, 0xcf,
- 0xd4, 0x19, 0x36, 0x45, 0x12, 0x39, 0xde, 0x95, 0x6f, 0x9c, 0x8e, 0x24, 0xee, 0x5b, 0x24, 0x4c,
- 0x18, 0x5f, 0x2b, 0x9a, 0x7c, 0x0c, 0x76, 0x2c, 0xf8, 0xf5, 0xf2, 0x29, 0xee, 0x2e, 0xe7, 0x32,
- 0x09, 0x99, 0xfd, 0xe8, 0x19, 0xad, 0xc5, 0x86, 0x22, 0x47, 0x00, 0xec, 0x5a, 0x0a, 0xf7, 0x8c,
- 0x27, 0x32, 0x69, 0x56, 0xd4, 0x6d, 0x54, 0x02, 0x23, 0x63, 0x70, 0x41, 0x73, 0x52, 0xe7, 0x6f,
- 0x16, 0x94, 0xd5, 0x25, 0x49, 0x0b, 0x5d, 0x1a, 0x2f, 0x74, 0x74, 0x8a, 0x1d, 0x62, 0x5c, 0x0a,
- 0x2a, 0x78, 0x2b, 0x8f, 0x62, 0x20, 0xf7, 0xa0, 0x96, 0xb0, 0x39, 0xf3, 0x24, 0x17, 0x26, 0x7f,
- 0x56, 0x6b, 0x34, 0xdd, 0xc7, 0x10, 0xeb, 0xdb, 0x28, 0x9a, 0xdc, 0x85, 0x0a, 0x57, 0x71, 0x51,
- 0x17, 0xfa, 0x89, 0x68, 0x19, 0x08, 0x2a, 0x17, 0xcc, 0xf5, 0x79, 0x34, 0x5f, 0xaa, 0x6b, 0xd6,
- 0xe8, 0x6a, 0x4d, 0xee, 0x82, 0xad, 0x22, 0xf1, 0x68, 0x19, 0xb3, 0x66, 0x45, 0x45, 0x60, 0x67,
- 0x15, 0x25, 0x64, 0xd2, 0x4c, 0x8e, 0x2f, 0xcf, 0x73, 0xbd, 0x4b, 0x36, 0x8c, 0x65, 0xf3, 0x76,
- 0xe6, 0xaf, 0xae, 0xe1, 0xd1, 0x95, 0x14, 0xd5, 0x26, 0xcc, 0x13, 0x4c, 0x22, 0xf4, 0x5d, 0x05,
- 0x55, 0x6a, 0x47, 0x29, 0x93, 0x66, 0x72, 0xe2, 0x40, 0x65, 0x34, 0x3a, 0x43, 0xe4, 0x7b, 0x59,
- 0x65, 0xd0, 0x1c, 0x6a, 0x24, 0xce, 0x00, 0x6a, 0xe9, 0x31, 0xf8, 0xcc, 0x06, 0x3d, 0xf3, 0x00,
- 0xad, 0x41, 0x8f, 0xdc, 0x87, 0x6a, 0x72, 0xe9, 0x8a, 0x20, 0x9a, 0x2a, 0xdf, 0xed, 0x9e, 0xbc,
- 0xb3, 0xb2, 0x6a, 0xa4, 0xf9, 0xa8, 0x29, 0xc5, 0x38, 0x1c, 0xec, 0x95, 0x19, 0xaf, 0xe8, 0x6a,
- 0x40, 0x71, 0x11, 0xf8, 0x4a, 0xcf, 0x0e, 0x45, 0x12, 0x39, 0xd3, 0x40, 0xe7, 0xd2, 0x0e, 0x45,
- 0x12, 0x03, 0x12, 0x72, 0x5f, 0xd7, 0xb1, 0x1d, 0xaa, 0x68, 0xf4, 0x31, 0x8f, 0x65, 0xc0, 0x23,
- 0x77, 0x9e, 0xfa, 0x38, 0x5d, 0x3b, 0xf3, 0xf4, 0x7e, 0xff, 0x97, 0xd3, 0x7e, 0x5f, 0x80, 0x5a,
- 0x5a, 0x7c, 0xb1, 0x92, 0x04, 0x3e, 0x8b, 0x64, 0x30, 0x09, 0x98, 0x30, 0x07, 0xe7, 0x38, 0xe4,
- 0x3e, 0x94, 0x5d, 0x29, 0x45, 0xfa, 0x40, 0x7f, 0x9e, 0xaf, 0xdc, 0xed, 0x53, 0x94, 0xf4, 0x23,
- 0x29, 0x96, 0x54, 0xa3, 0xf6, 0x3e, 0x07, 0xc8, 0x98, 0x68, 0xeb, 0x8c, 0x2d, 0x8d, 0x56, 0x24,
- 0xc9, 0x6d, 0x28, 0x3f, 0x73, 0xe7, 0x0b, 0x66, 0x72, 0x58, 0x2f, 0xbe, 0xb0, 0x3e, 0x2f, 0x38,
- 0x7f, 0xb5, 0xa0, 0x6a, 0x2a, 0x39, 0xb9, 0x07, 0x55, 0x55, 0xc9, 0x8d, 0x45, 0x37, 0x3f, 0x8c,
- 0x14, 0x42, 0x8e, 0x57, 0x2d, 0x2a, 0x67, 0xa3, 0x51, 0xa5, 0x5b, 0x95, 0xb1, 0x31, 0x6b, 0x58,
- 0x45, 0x9f, 0x4d, 0x4c, 0x2f, 0xda, 0x45, 0x74, 0x8f, 0x4d, 0x82, 0x28, 0x40, 0xff, 0x50, 0x14,
- 0x91, 0x7b, 0xe9, 0xad, 0x4b, 0x4a, 0xe3, 0x7b, 0x79, 0x8d, 0xaf, 0x5e, 0x7a, 0x00, 0xf5, 0xdc,
- 0x31, 0x37, 0xdc, 0xfa, 0xc3, 0xfc, 0xad, 0xcd, 0x91, 0x4a, 0x9d, 0x6e, 0xa4, 0x99, 0x17, 0xfe,
- 0x0b, 0xff, 0x7d, 0x0a, 0x90, 0xa9, 0x7c, 0xf3, 0xc2, 0xe2, 0x3c, 0x2f, 0x02, 0x0c, 0x63, 0x2c,
- 0x9d, 0xbe, 0xab, 0x2a, 0xf2, 0x76, 0x30, 0x8d, 0xb8, 0x60, 0x4f, 0xd5, 0x53, 0x55, 0xfb, 0x6b,
- 0xb4, 0xae, 0x79, 0xea, 0xc5, 0x90, 0x53, 0xa8, 0xfb, 0x2c, 0xf1, 0x44, 0xa0, 0x12, 0xca, 0x38,
- 0xfd, 0x00, 0xef, 0x94, 0xe9, 0x69, 0xf7, 0x32, 0x84, 0xf6, 0x55, 0x7e, 0x0f, 0x39, 0x81, 0x6d,
- 0x76, 0x1d, 0x73, 0x21, 0xcd, 0x29, 0xba, 0xe1, 0xdf, 0xd2, 0xa3, 0x03, 0xf2, 0xd5, 0x49, 0xb4,
- 0xce, 0xb2, 0x05, 0x71, 0xa1, 0xe4, 0xb9, 0xb1, 0xee, 0x76, 0xf5, 0x93, 0xe6, 0xc6, 0x79, 0x5d,
- 0x37, 0xd6, 0x4e, 0xeb, 0x7c, 0x82, 0x77, 0x7d, 0xfe, 0xaf, 0x83, 0xbb, 0xb9, 0x16, 0x17, 0xf2,
- 0xf1, 0xf2, 0x58, 0xe5, 0xcb, 0x2c, 0x90, 0xc7, 0x0b, 0x19, 0xcc, 0x8f, 0xdd, 0x38, 0x40, 0x75,
- 0xb8, 0x71, 0xd0, 0xa3, 0x4a, 0xf5, 0xde, 0x6f, 0xa0, 0xb1, 0x69, 0xf7, 0xdb, 0xc4, 0x60, 0xef,
- 0x33, 0xb0, 0x57, 0x76, 0xbc, 0x6e, 0x63, 0x2d, 0x1f, 0xbc, 0x0f, 0xa0, 0x9e, 0xbb, 0x37, 0x02,
- 0x9f, 0x28, 0xa0, 0xf6, 0xbe, 0x5e, 0x38, 0xcf, 0x71, 0xda, 0x48, 0xfb, 0xcd, 0xaf, 0x00, 0x2e,
- 0xa5, 0x8c, 0x9f, 0xaa, 0x06, 0x64, 0x0e, 0xb1, 0x91, 0xa3, 0x10, 0xe4, 0x00, 0xea, 0xb8, 0x48,
- 0x8c, 0x5c, 0x5b, 0xaa, 0x76, 0x24, 0x1a, 0xf0, 0x4b, 0xb0, 0x27, 0xab, 0xed, 0xba, 0x71, 0xd4,
- 0x26, 0xe9, 0xee, 0x5f, 0x40, 0x2d, 0xe2, 0x46, 0xa6, 0xfb, 0x61, 0x35, 0xe2, 0x4a, 0xe4, 0xdc,
- 0x85, 0x9f, 0xbd, 0x32, 0x1a, 0x91, 0xf7, 0xa0, 0x32, 0x09, 0xe6, 0x52, 0x3d, 0x57, 0x6c, 0xb1,
- 0x66, 0xe5, 0xfc, 0xa3, 0x00, 0x90, 0x3d, 0x2d, 0xf4, 0x08, 0xbe, 0x3b, 0xc4, 0x6c, 0xeb, 0x77,
- 0x36, 0x87, 0x5a, 0x68, 0x22, 0x68, 0xf2, 0xe8, 0xce, 0xfa, 0x73, 0x6c, 0xa7, 0x01, 0xd6, 0xb1,
- 0x3d, 0x31, 0xb1, 0x7d, 0x9b, 0xf1, 0x65, 0x75, 0xc2, 0xde, 0x57, 0xb0, 0xb3, 0xa6, 0xee, 0x0d,
- 0x5f, 0x6a, 0x96, 0x65, 0xf9, 0x90, 0xdd, 0x83, 0x8a, 0x6e, 0xed, 0x58, 0x7f, 0x91, 0x32, 0x6a,
- 0x14, 0xad, 0xea, 0xf8, 0x45, 0x3a, 0xe8, 0x0d, 0x2e, 0x9c, 0x13, 0xa8, 0xe8, 0x49, 0x96, 0xb4,
- 0xa0, 0xea, 0x7a, 0x78, 0xb5, 0xb4, 0x5c, 0xed, 0xa6, 0x63, 0xee, 0xa9, 0x62, 0xd3, 0x54, 0xec,
- 0xfc, 0xdd, 0x02, 0xc8, 0xf8, 0x6f, 0x31, 0x2b, 0x7c, 0x01, 0xbb, 0x09, 0xf3, 0x78, 0xe4, 0xbb,
- 0x62, 0xa9, 0xa4, 0x66, 0x62, 0xbb, 0x69, 0xcb, 0x06, 0x32, 0x37, 0x37, 0x14, 0x5f, 0x3f, 0x37,
- 0xb4, 0xa0, 0xe4, 0xf1, 0x78, 0x69, 0x9e, 0x2f, 0x59, 0xbf, 0x48, 0x97, 0xc7, 0x4b, 0x9c, 0xdb,
- 0x11, 0x41, 0xda, 0x50, 0x09, 0x67, 0x6a, 0xb6, 0xd7, 0x63, 0xd4, 0xed, 0x75, 0xec, 0xc3, 0x19,
- 0xd2, 0xf8, 0x25, 0xa0, 0x51, 0xe4, 0x2e, 0x94, 0xc3, 0x99, 0x1f, 0x08, 0x35, 0x71, 0xd4, 0x75,
- 0xbf, 0xce, 0xc3, 0x7b, 0x81, 0xc0, 0x79, 0x5f, 0x61, 0x88, 0x03, 0x96, 0x08, 0x9b, 0x55, 0x85,
- 0x6c, 0x6c, 0x78, 0x33, 0x3c, 0xdb, 0xa2, 0x96, 0x08, 0x3b, 0x35, 0xa8, 0x68, 0xbf, 0x3a, 0x7f,
- 0x2e, 0xc2, 0xee, 0xba, 0x95, 0x98, 0x07, 0x89, 0xf0, 0xd2, 0x3c, 0x48, 0x84, 0xb7, 0x1a, 0xa9,
- 0xac, 0xdc, 0x48, 0xe5, 0x40, 0x99, 0x5f, 0x45, 0x4c, 0xe4, 0x3f, 0x62, 0xba, 0x97, 0xfc, 0x2a,
- 0xc2, 0xe1, 0x41, 0x8b, 0xd6, 0x7a, 0x71, 0xd9, 0xf4, 0xe2, 0x0f, 0x61, 0x67, 0xc2, 0xe7, 0x73,
- 0x7e, 0x35, 0x5a, 0x86, 0xf3, 0x20, 0x9a, 0x99, 0x86, 0xbc, 0xce, 0x24, 0x2d, 0xb8, 0xe5, 0x07,
- 0x02, 0xcd, 0xe9, 0xf2, 0x48, 0xb2, 0x48, 0x4d, 0x91, 0x88, 0xdb, 0x64, 0x93, 0x2f, 0xe1, 0xd0,
- 0x95, 0x92, 0x85, 0xb1, 0x7c, 0x1c, 0xc5, 0xae, 0x37, 0xeb, 0x71, 0x4f, 0xbd, 0xc7, 0x30, 0x76,
- 0x65, 0x30, 0x0e, 0xe6, 0x81, 0x5c, 0x2a, 0x67, 0xd4, 0xe8, 0x6b, 0x71, 0xe4, 0x23, 0xd8, 0xf5,
- 0x04, 0x73, 0x25, 0xeb, 0xb1, 0x44, 0x5e, 0xb8, 0xf2, 0xb2, 0x59, 0x53, 0x3b, 0x37, 0xb8, 0x78,
- 0x07, 0x17, 0xad, 0xfd, 0x26, 0x98, 0xfb, 0x9e, 0x2b, 0xfc, 0xa6, 0xad, 0xef, 0xb0, 0xc6, 0x24,
- 0x6d, 0x20, 0x8a, 0xd1, 0x0f, 0x63, 0xb9, 0x5c, 0x41, 0x41, 0x41, 0x6f, 0x90, 0xe0, 0x47, 0x8e,
- 0x0c, 0x42, 0x96, 0x48, 0x37, 0x8c, 0xd5, 0xc7, 0x57, 0x91, 0x66, 0x0c, 0xe7, 0xdb, 0x02, 0x34,
- 0x36, 0x53, 0x04, 0x1d, 0x1c, 0xa3, 0x99, 0xe6, 0xb1, 0x21, 0xbd, 0x72, 0xba, 0x95, 0x73, 0x3a,
- 0x06, 0x10, 0xab, 0x0a, 0xc6, 0x6a, 0x9b, 0x2a, 0x3a, 0x0b, 0x60, 0xe9, 0xa7, 0x03, 0xb8, 0x66,
- 0x52, 0x79, 0xd3, 0xa4, 0x3f, 0x16, 0xe0, 0xd6, 0x46, 0x1a, 0xbe, 0xb1, 0x45, 0x87, 0x50, 0x0f,
- 0xdd, 0x19, 0xbb, 0x70, 0x85, 0x0a, 0x6e, 0x51, 0x37, 0xd6, 0x1c, 0xeb, 0x7f, 0x60, 0x5f, 0x04,
- 0xdb, 0xf9, 0xdc, 0xbf, 0xd1, 0xb6, 0x34, 0x94, 0xe7, 0x5c, 0x3e, 0xe0, 0x8b, 0xc8, 0x37, 0xdd,
- 0x68, 0x9d, 0xf9, 0x6a, 0xc0, 0x8b, 0x37, 0x04, 0xdc, 0x39, 0x87, 0x5a, 0x6a, 0x20, 0x39, 0x30,
- 0x1f, 0x50, 0x85, 0xec, 0xcb, 0xfc, 0x71, 0xc2, 0x04, 0xda, 0xae, 0xbf, 0xa6, 0xde, 0x87, 0xf2,
- 0x54, 0xf0, 0x45, 0x6c, 0x6a, 0xeb, 0x1a, 0x42, 0x4b, 0x9c, 0x11, 0x54, 0x0d, 0x87, 0x1c, 0x41,
- 0x65, 0xbc, 0x3c, 0x77, 0x43, 0x66, 0x14, 0xaa, 0x87, 0x8d, 0x6b, 0xdf, 0x20, 0xb0, 0x5a, 0x68,
- 0x04, 0xb9, 0x0d, 0xa5, 0xf1, 0x72, 0xd0, 0xd3, 0x63, 0x32, 0xd6, 0x1c, 0x5c, 0x75, 0x2a, 0xda,
- 0x20, 0xe7, 0x6b, 0xd8, 0xce, 0xef, 0x43, 0xa7, 0x44, 0xa9, 0x5e, 0x9b, 0x2a, 0x3a, 0x2b, 0xae,
- 0xd6, 0x6b, 0x8a, 0xeb, 0x51, 0x0b, 0xaa, 0xe6, 0xe3, 0x93, 0xd8, 0x50, 0x7e, 0x7c, 0x3e, 0xea,
- 0x3f, 0x6a, 0x6c, 0x91, 0x1a, 0x94, 0xce, 0x86, 0xa3, 0x47, 0x8d, 0x02, 0x52, 0xe7, 0xc3, 0xf3,
- 0x7e, 0xc3, 0x3a, 0xfa, 0x2d, 0xd8, 0xab, 0x8f, 0x24, 0x64, 0x77, 0x06, 0xe7, 0xbd, 0xc6, 0x16,
- 0x01, 0xa8, 0x8c, 0xfa, 0x5d, 0xda, 0x47, 0x70, 0x15, 0x8a, 0xa3, 0xd1, 0x59, 0xc3, 0x42, 0x55,
- 0xdd, 0xd3, 0xee, 0x59, 0xbf, 0x51, 0x44, 0xf2, 0xd1, 0xc3, 0x8b, 0x07, 0xa3, 0x46, 0xe9, 0xe8,
- 0x53, 0xb8, 0xb5, 0xf1, 0x91, 0xa2, 0x76, 0x9f, 0x9d, 0xd2, 0x3e, 0x6a, 0xaa, 0x43, 0xf5, 0x82,
- 0x0e, 0x9e, 0x9c, 0x3e, 0xea, 0x37, 0x0a, 0x28, 0xf8, 0x7a, 0xd8, 0xfd, 0xaa, 0xdf, 0x6b, 0x58,
- 0x9d, 0x3b, 0xdf, 0xbd, 0xd8, 0x2f, 0x7c, 0xff, 0x62, 0xbf, 0xf0, 0xc3, 0x8b, 0xfd, 0xc2, 0xbf,
- 0x5f, 0xec, 0x17, 0xbe, 0x7d, 0xb9, 0xbf, 0xf5, 0xfd, 0xcb, 0xfd, 0xad, 0x1f, 0x5e, 0xee, 0x6f,
- 0x8d, 0x2b, 0xea, 0x0f, 0x9e, 0x4f, 0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, 0x9b, 0x24, 0xd0, 0xaa,
- 0x20, 0x12, 0x00, 0x00,
+ 0x11, 0xd7, 0x1d, 0xff, 0xde, 0x50, 0x92, 0xd9, 0x8d, 0x93, 0xb2, 0xaa, 0x2b, 0x29, 0x97, 0x34,
+ 0x90, 0x65, 0x5b, 0x02, 0x14, 0x20, 0x09, 0xf2, 0x50, 0x54, 0xfc, 0x63, 0x88, 0x49, 0x2c, 0x0a,
+ 0x4b, 0xdb, 0xe9, 0x9b, 0x71, 0xbc, 0x5b, 0x52, 0x07, 0xf2, 0x6e, 0x0f, 0x7b, 0x4b, 0x5b, 0x7c,
+ 0xe9, 0x83, 0x3f, 0x41, 0x80, 0x02, 0x7d, 0x6b, 0x81, 0xbe, 0x14, 0xe8, 0x87, 0xe8, 0x7b, 0x1e,
+ 0x83, 0xa2, 0x0f, 0x69, 0x1f, 0xd2, 0xc2, 0xfe, 0x22, 0xc5, 0xec, 0xee, 0xf1, 0x8e, 0xb4, 0x02,
+ 0xdb, 0x68, 0xd1, 0x27, 0xce, 0xcd, 0xfc, 0x76, 0x76, 0x76, 0x66, 0x76, 0x66, 0x96, 0xe0, 0xf0,
+ 0x24, 0x3d, 0x4a, 0x04, 0x97, 0x9c, 0xd8, 0xc9, 0x68, 0xe7, 0xde, 0x24, 0x94, 0x97, 0xf3, 0xd1,
+ 0x91, 0xcf, 0xa3, 0xe3, 0x09, 0x9f, 0xf0, 0x63, 0x25, 0x1a, 0xcd, 0xc7, 0xea, 0x4b, 0x7d, 0x28,
+ 0x4a, 0x2f, 0x71, 0xff, 0x64, 0x83, 0x3d, 0x48, 0xc8, 0xfb, 0x50, 0x0d, 0xe3, 0x64, 0x2e, 0xd3,
+ 0x96, 0xb5, 0x5f, 0x3a, 0x68, 0x9c, 0x38, 0x47, 0xc9, 0xe8, 0xa8, 0x8f, 0x1c, 0x6a, 0x04, 0x64,
+ 0x1f, 0xca, 0xec, 0x8a, 0xf9, 0x2d, 0x7b, 0xdf, 0x3a, 0x68, 0x9c, 0x00, 0x02, 0x7a, 0x57, 0xcc,
+ 0x1f, 0x24, 0x67, 0x1b, 0x54, 0x49, 0xc8, 0x47, 0x50, 0x4d, 0xf9, 0x5c, 0xf8, 0xac, 0x55, 0x52,
+ 0x98, 0x4d, 0xc4, 0x0c, 0x15, 0x47, 0xa1, 0x8c, 0x14, 0x35, 0x8d, 0xc3, 0x19, 0x6b, 0x95, 0x73,
+ 0x4d, 0xf7, 0xc3, 0x99, 0xc6, 0x28, 0x09, 0xf9, 0x00, 0x2a, 0xa3, 0x79, 0x38, 0x0b, 0x5a, 0x15,
+ 0x05, 0x69, 0x20, 0xa4, 0x8d, 0x0c, 0x85, 0xd1, 0x32, 0x72, 0x00, 0xf5, 0x64, 0xe6, 0xc9, 0x31,
+ 0x17, 0x51, 0x0b, 0xf2, 0x0d, 0x2f, 0x0c, 0x8f, 0x2e, 0xa5, 0xe4, 0x53, 0x68, 0xf8, 0x3c, 0x4e,
+ 0xa5, 0xf0, 0xc2, 0x58, 0xa6, 0xad, 0x86, 0x02, 0xbf, 0x8b, 0xe0, 0xaf, 0xb9, 0x98, 0x32, 0xd1,
+ 0xc9, 0x85, 0xb4, 0x88, 0x6c, 0x97, 0xc1, 0xe6, 0x89, 0xfb, 0x7b, 0x0b, 0xea, 0x99, 0x56, 0xe2,
+ 0xc2, 0xe6, 0xa9, 0xf0, 0x2f, 0x43, 0xc9, 0x7c, 0x39, 0x17, 0xac, 0x65, 0xed, 0x5b, 0x07, 0x0e,
+ 0x5d, 0xe1, 0x91, 0x6d, 0xb0, 0x07, 0x43, 0xe5, 0x28, 0x87, 0xda, 0x83, 0x21, 0x69, 0x41, 0xed,
+ 0xb1, 0x27, 0x42, 0x2f, 0x96, 0xca, 0x33, 0x0e, 0xcd, 0x3e, 0xc9, 0x2d, 0x70, 0x06, 0xc3, 0xc7,
+ 0x4c, 0xa4, 0x21, 0x8f, 0x95, 0x3f, 0x1c, 0x9a, 0x33, 0xc8, 0x2e, 0xc0, 0x60, 0x78, 0x9f, 0x79,
+ 0xa8, 0x34, 0x6d, 0x55, 0xf6, 0x4b, 0x07, 0x0e, 0x2d, 0x70, 0xdc, 0xdf, 0x42, 0x45, 0xc5, 0x88,
+ 0x7c, 0x01, 0xd5, 0x20, 0x9c, 0xb0, 0x54, 0x6a, 0x73, 0xda, 0x27, 0xdf, 0xfe, 0xb0, 0xb7, 0xf1,
+ 0xcf, 0x1f, 0xf6, 0x0e, 0x0b, 0xc9, 0xc0, 0x13, 0x16, 0xfb, 0x3c, 0x96, 0x5e, 0x18, 0x33, 0x91,
+ 0x1e, 0x4f, 0xf8, 0x3d, 0xbd, 0xe4, 0xa8, 0xab, 0x7e, 0xa8, 0xd1, 0x40, 0x6e, 0x43, 0x25, 0x8c,
+ 0x03, 0x76, 0xa5, 0xec, 0x2f, 0xb5, 0xdf, 0x31, 0xaa, 0x1a, 0x83, 0xb9, 0x4c, 0xe6, 0xb2, 0x8f,
+ 0x22, 0xaa, 0x11, 0xee, 0x1f, 0x2d, 0xa8, 0xea, 0x1c, 0x20, 0xb7, 0xa0, 0x1c, 0x31, 0xe9, 0xa9,
+ 0xfd, 0x1b, 0x27, 0x75, 0xf4, 0xed, 0x03, 0x26, 0x3d, 0xaa, 0xb8, 0x98, 0x5e, 0x11, 0x9f, 0xa3,
+ 0xef, 0xed, 0x3c, 0xbd, 0x1e, 0x20, 0x87, 0x1a, 0x01, 0xf9, 0x25, 0xd4, 0x62, 0x26, 0x9f, 0x71,
+ 0x31, 0x55, 0x3e, 0xda, 0xd6, 0x41, 0x3f, 0x67, 0xf2, 0x01, 0x0f, 0x18, 0xcd, 0x64, 0xe4, 0x2e,
+ 0xd4, 0x53, 0xe6, 0xcf, 0x45, 0x28, 0x17, 0xca, 0x5f, 0xdb, 0x27, 0x4d, 0x95, 0x65, 0x86, 0xa7,
+ 0xc0, 0x4b, 0x84, 0xfb, 0x17, 0x0b, 0xca, 0x68, 0x06, 0x21, 0x50, 0xf6, 0xc4, 0x44, 0x67, 0xb7,
+ 0x43, 0x15, 0x4d, 0x9a, 0x50, 0x62, 0xf1, 0x53, 0x65, 0x91, 0x43, 0x91, 0x44, 0x8e, 0xff, 0x2c,
+ 0x30, 0x31, 0x42, 0x12, 0xd7, 0xcd, 0x53, 0x26, 0x4c, 0x68, 0x14, 0x4d, 0x6e, 0x83, 0x93, 0x08,
+ 0x7e, 0xb5, 0x78, 0x82, 0xab, 0x2b, 0x85, 0xc4, 0x43, 0x66, 0x2f, 0x7e, 0x4a, 0xeb, 0x89, 0xa1,
+ 0xc8, 0x21, 0x00, 0xbb, 0x92, 0xc2, 0x3b, 0xe3, 0xa9, 0x4c, 0x5b, 0x55, 0x75, 0x76, 0x95, 0xef,
+ 0xc8, 0xe8, 0x5f, 0xd0, 0x82, 0xd4, 0xfd, 0x9b, 0x0d, 0x15, 0xe5, 0x12, 0x72, 0x80, 0x11, 0x48,
+ 0xe6, 0x3a, 0x98, 0xa5, 0x36, 0x31, 0x11, 0x00, 0x15, 0xeb, 0x65, 0x00, 0x30, 0xee, 0x3b, 0xe8,
+ 0x8d, 0x19, 0xf3, 0x25, 0x17, 0x26, 0xdd, 0x96, 0xdf, 0x68, 0x7a, 0x80, 0x19, 0xa1, 0x4f, 0xa3,
+ 0x68, 0x72, 0x07, 0xaa, 0x5c, 0x85, 0x51, 0x1d, 0xe8, 0x47, 0x82, 0x6b, 0x20, 0xa8, 0x5c, 0x30,
+ 0x2f, 0xe0, 0xf1, 0x6c, 0xa1, 0x8e, 0x59, 0xa7, 0xcb, 0x6f, 0x72, 0x07, 0x1c, 0x15, 0xb7, 0x87,
+ 0x8b, 0x84, 0xb5, 0xaa, 0x2a, 0x0e, 0x5b, 0xcb, 0x98, 0x22, 0x93, 0xe6, 0x72, 0xbc, 0xa8, 0xbe,
+ 0xe7, 0x5f, 0xb2, 0x41, 0x22, 0x5b, 0x37, 0x73, 0x7f, 0x75, 0x0c, 0x8f, 0x2e, 0xa5, 0xa8, 0x36,
+ 0x65, 0xbe, 0x60, 0x12, 0xa1, 0xef, 0x2a, 0xe8, 0x96, 0x09, 0xaf, 0x66, 0xd2, 0x5c, 0x4e, 0x5c,
+ 0xa8, 0x0e, 0x87, 0x67, 0x88, 0x7c, 0x2f, 0x2f, 0x24, 0x9a, 0x43, 0x8d, 0xc4, 0xed, 0x43, 0x3d,
+ 0xdb, 0x06, 0x6f, 0x65, 0xbf, 0x6b, 0xee, 0xab, 0xdd, 0xef, 0x92, 0x7b, 0x50, 0x4b, 0x2f, 0x3d,
+ 0x11, 0xc6, 0x13, 0xe5, 0xbb, 0xed, 0x93, 0x77, 0x96, 0x56, 0x0d, 0x35, 0x1f, 0x35, 0x65, 0x18,
+ 0x97, 0x83, 0xb3, 0x34, 0xe3, 0x15, 0x5d, 0x4d, 0x28, 0xcd, 0xc3, 0x40, 0xe9, 0xd9, 0xa2, 0x48,
+ 0x22, 0x67, 0x12, 0xea, 0x5c, 0xda, 0xa2, 0x48, 0x62, 0x40, 0x22, 0x1e, 0xe8, 0xb2, 0xb7, 0x45,
+ 0x15, 0x8d, 0x3e, 0xe6, 0x89, 0x0c, 0x79, 0xec, 0xcd, 0x32, 0x1f, 0x67, 0xdf, 0xee, 0x2c, 0x3b,
+ 0xdf, 0xff, 0x65, 0xb7, 0xdf, 0x59, 0x50, 0xcf, 0x6a, 0x35, 0x16, 0x9e, 0x30, 0x60, 0xb1, 0x0c,
+ 0xc7, 0x21, 0x13, 0x66, 0xe3, 0x02, 0x87, 0xdc, 0x83, 0x8a, 0x27, 0xa5, 0xc8, 0xae, 0xf3, 0x4f,
+ 0x8b, 0x85, 0xfe, 0xe8, 0x14, 0x25, 0xbd, 0x58, 0x8a, 0x05, 0xd5, 0xa8, 0x9d, 0xcf, 0x00, 0x72,
+ 0x26, 0xda, 0x3a, 0x65, 0x0b, 0xa3, 0x15, 0x49, 0x72, 0x13, 0x2a, 0x4f, 0xbd, 0xd9, 0x9c, 0x99,
+ 0x1c, 0xd6, 0x1f, 0x9f, 0xdb, 0x9f, 0x59, 0xee, 0x5f, 0x6d, 0xa8, 0x99, 0xc2, 0x4f, 0xee, 0x42,
+ 0x4d, 0x15, 0x7e, 0x63, 0xd1, 0xf5, 0x17, 0x23, 0x83, 0x90, 0xe3, 0x65, 0x47, 0x2b, 0xd8, 0x68,
+ 0x54, 0xe9, 0xce, 0x66, 0x6c, 0xcc, 0xfb, 0x5b, 0x29, 0x60, 0x63, 0xd3, 0xba, 0xb6, 0x11, 0xdd,
+ 0x65, 0xe3, 0x30, 0x0e, 0xd1, 0x3f, 0x14, 0x45, 0xe4, 0x6e, 0x76, 0xea, 0xb2, 0xd2, 0xf8, 0x5e,
+ 0x51, 0xe3, 0xab, 0x87, 0xee, 0x43, 0xa3, 0xb0, 0xcd, 0x35, 0xa7, 0xfe, 0xb0, 0x78, 0x6a, 0xb3,
+ 0xa5, 0x52, 0xa7, 0xfb, 0x6e, 0xee, 0x85, 0xff, 0xc2, 0x7f, 0x9f, 0x00, 0xe4, 0x2a, 0xdf, 0xbc,
+ 0xb0, 0xb8, 0xcf, 0x4b, 0x00, 0x83, 0x04, 0x4b, 0x67, 0xe0, 0xa9, 0xfa, 0xbd, 0x19, 0x4e, 0x62,
+ 0x2e, 0xd8, 0x13, 0x75, 0x55, 0xd5, 0xfa, 0x3a, 0x6d, 0x68, 0x9e, 0xba, 0x31, 0xe4, 0x14, 0x1a,
+ 0x01, 0x4b, 0x7d, 0x11, 0xaa, 0x84, 0x32, 0x4e, 0xdf, 0xc3, 0x33, 0xe5, 0x7a, 0x8e, 0xba, 0x39,
+ 0x42, 0xfb, 0xaa, 0xb8, 0x86, 0x9c, 0xc0, 0x26, 0xbb, 0x4a, 0xb8, 0x90, 0x66, 0x17, 0x3d, 0x1f,
+ 0xdc, 0xd0, 0x93, 0x06, 0xf2, 0xd5, 0x4e, 0xb4, 0xc1, 0xf2, 0x0f, 0xe2, 0x41, 0xd9, 0xf7, 0x12,
+ 0xdd, 0x1c, 0x1b, 0x27, 0xad, 0xb5, 0xfd, 0x3a, 0x5e, 0xa2, 0x9d, 0xd6, 0xfe, 0x18, 0xcf, 0xfa,
+ 0xfc, 0x5f, 0x7b, 0x77, 0x0a, 0x1d, 0x31, 0xe2, 0xa3, 0xc5, 0xb1, 0xca, 0x97, 0x69, 0x28, 0x8f,
+ 0xe7, 0x32, 0x9c, 0x1d, 0x7b, 0x49, 0x88, 0xea, 0x70, 0x61, 0xbf, 0x4b, 0x95, 0xea, 0x9d, 0x5f,
+ 0x41, 0x73, 0xdd, 0xee, 0xb7, 0x89, 0xc1, 0xce, 0xa7, 0xe0, 0x2c, 0xed, 0x78, 0xdd, 0xc2, 0x7a,
+ 0x31, 0x78, 0x1f, 0x40, 0xa3, 0x70, 0x6e, 0x04, 0x3e, 0x56, 0x40, 0xed, 0x7d, 0xfd, 0xe1, 0x3e,
+ 0xc7, 0xe1, 0x24, 0xeb, 0x37, 0xbf, 0x00, 0xb8, 0x94, 0x32, 0x79, 0xa2, 0x1a, 0x90, 0xd9, 0xc4,
+ 0x41, 0x8e, 0x42, 0x90, 0x3d, 0x68, 0xe0, 0x47, 0x6a, 0xe4, 0xda, 0x52, 0xb5, 0x22, 0xd5, 0x80,
+ 0x9f, 0x83, 0x33, 0x5e, 0x2e, 0xd7, 0x8d, 0xa3, 0x3e, 0xce, 0x56, 0xff, 0x0c, 0xea, 0x31, 0x37,
+ 0x32, 0xdd, 0x0f, 0x6b, 0x31, 0x57, 0x22, 0xf7, 0x0e, 0xfc, 0xe4, 0x95, 0x49, 0x8a, 0xbc, 0x07,
+ 0xd5, 0x71, 0x38, 0x93, 0xea, 0xba, 0x62, 0x8b, 0x35, 0x5f, 0xee, 0x3f, 0x2c, 0x80, 0xfc, 0x6a,
+ 0xa1, 0x47, 0xf0, 0xde, 0x21, 0x66, 0x53, 0xdf, 0xb3, 0x19, 0xd4, 0x23, 0x13, 0x41, 0x93, 0x47,
+ 0xb7, 0x56, 0xaf, 0xe3, 0x51, 0x16, 0x60, 0x1d, 0xdb, 0x13, 0x13, 0xdb, 0xb7, 0x99, 0x76, 0x96,
+ 0x3b, 0xec, 0x7c, 0x09, 0x5b, 0x2b, 0xea, 0xde, 0xf0, 0xa6, 0xe6, 0x59, 0x56, 0x0c, 0xd9, 0x5d,
+ 0xa8, 0xea, 0xd6, 0x8e, 0xf5, 0x17, 0x29, 0xa3, 0x46, 0xd1, 0xaa, 0x8e, 0x5f, 0x64, 0x73, 0x61,
+ 0xff, 0xc2, 0x3d, 0x81, 0xaa, 0x1e, 0x7c, 0xc9, 0x01, 0xd4, 0x3c, 0x1f, 0x8f, 0x96, 0x95, 0xab,
+ 0xed, 0x6c, 0x2a, 0x3e, 0x55, 0x6c, 0x9a, 0x89, 0xdd, 0xbf, 0xdb, 0x00, 0x39, 0xff, 0x2d, 0x66,
+ 0x85, 0xcf, 0x61, 0x3b, 0x65, 0x3e, 0x8f, 0x03, 0x4f, 0x2c, 0x94, 0xd4, 0x0c, 0x78, 0xd7, 0x2d,
+ 0x59, 0x43, 0x16, 0xe6, 0x86, 0xd2, 0xeb, 0xe7, 0x86, 0x03, 0x28, 0xfb, 0x3c, 0x59, 0x98, 0xeb,
+ 0x4b, 0x56, 0x0f, 0xd2, 0xe1, 0xc9, 0x02, 0xc7, 0x7c, 0x44, 0x90, 0x23, 0xa8, 0x46, 0x53, 0xf5,
+ 0x14, 0xd0, 0x63, 0xd4, 0xcd, 0x55, 0xec, 0x83, 0x29, 0xd2, 0xf8, 0x70, 0xd0, 0x28, 0x72, 0x07,
+ 0x2a, 0xd1, 0x34, 0x08, 0x85, 0x9a, 0x38, 0x1a, 0xba, 0x5f, 0x17, 0xe1, 0xdd, 0x50, 0xe0, 0xf3,
+ 0x40, 0x61, 0x88, 0x0b, 0xb6, 0x88, 0x5a, 0x35, 0x85, 0x6c, 0xae, 0x79, 0x33, 0x3a, 0xdb, 0xa0,
+ 0xb6, 0x88, 0xda, 0x75, 0xa8, 0x6a, 0xbf, 0xba, 0x7f, 0x2e, 0xc1, 0xf6, 0xaa, 0x95, 0x98, 0x07,
+ 0xa9, 0xf0, 0xb3, 0x3c, 0x48, 0x85, 0xbf, 0x1c, 0xa9, 0xec, 0xc2, 0x48, 0xe5, 0x42, 0x85, 0x3f,
+ 0x8b, 0x99, 0x28, 0xbe, 0x79, 0x3a, 0x97, 0xfc, 0x59, 0x8c, 0xc3, 0x83, 0x16, 0xad, 0xf4, 0xe2,
+ 0x8a, 0xe9, 0xc5, 0x1f, 0xc2, 0xd6, 0x98, 0xcf, 0x66, 0xfc, 0xd9, 0x70, 0x11, 0xcd, 0xc2, 0x78,
+ 0x6a, 0x1a, 0xf2, 0x2a, 0x93, 0x1c, 0xc0, 0x8d, 0x20, 0x14, 0x68, 0x4e, 0x87, 0xc7, 0x92, 0xc5,
+ 0x6a, 0x8a, 0x44, 0xdc, 0x3a, 0x9b, 0x7c, 0x01, 0xfb, 0x9e, 0x94, 0x2c, 0x4a, 0xe4, 0xa3, 0x38,
+ 0xf1, 0xfc, 0x69, 0x97, 0xfb, 0xea, 0x3e, 0x46, 0x89, 0x27, 0xc3, 0x51, 0x38, 0xc3, 0x81, 0xb9,
+ 0xa6, 0x96, 0xbe, 0x16, 0x47, 0x3e, 0x82, 0x6d, 0x5f, 0x30, 0x4f, 0xb2, 0x2e, 0x4b, 0xe5, 0x85,
+ 0x27, 0x2f, 0x5b, 0x75, 0xb5, 0x72, 0x8d, 0x8b, 0x67, 0xf0, 0xd0, 0xda, 0xaf, 0xc3, 0x59, 0xe0,
+ 0x7b, 0x22, 0x68, 0x39, 0xfa, 0x0c, 0x2b, 0x4c, 0x72, 0x04, 0x44, 0x31, 0x7a, 0x51, 0x22, 0x17,
+ 0x4b, 0x28, 0x28, 0xe8, 0x35, 0x12, 0x7c, 0x13, 0xc9, 0x30, 0x62, 0xa9, 0xf4, 0xa2, 0x44, 0xbd,
+ 0xd5, 0x4a, 0x34, 0x67, 0xb8, 0xdf, 0x58, 0xd0, 0x5c, 0x4f, 0x11, 0x74, 0x70, 0x82, 0x66, 0x9a,
+ 0xcb, 0x86, 0xf4, 0xd2, 0xe9, 0x76, 0xc1, 0xe9, 0x18, 0x40, 0xac, 0x2a, 0x18, 0xab, 0x4d, 0xaa,
+ 0xe8, 0x3c, 0x80, 0xe5, 0x1f, 0x0f, 0xe0, 0x8a, 0x49, 0x95, 0x75, 0x93, 0xfe, 0x60, 0xc1, 0x8d,
+ 0xb5, 0x34, 0x7c, 0x63, 0x8b, 0xf6, 0xa1, 0x11, 0x79, 0x53, 0x76, 0xe1, 0x09, 0x15, 0xdc, 0x92,
+ 0x6e, 0xac, 0x05, 0xd6, 0xff, 0xc0, 0xbe, 0x18, 0x36, 0x8b, 0xb9, 0x7f, 0xad, 0x6d, 0x59, 0x28,
+ 0xcf, 0xb9, 0xbc, 0xcf, 0xe7, 0x71, 0x60, 0xba, 0xd1, 0x2a, 0xf3, 0xd5, 0x80, 0x97, 0xae, 0x09,
+ 0xb8, 0x7b, 0x0e, 0xf5, 0xcc, 0x40, 0xb2, 0x67, 0x1e, 0x50, 0x56, 0xfe, 0x90, 0x7f, 0x94, 0x32,
+ 0x81, 0xb6, 0xeb, 0xd7, 0xd4, 0xfb, 0x50, 0x99, 0x08, 0x3e, 0x4f, 0x4c, 0x6d, 0x5d, 0x41, 0x68,
+ 0x89, 0x3b, 0x84, 0x9a, 0xe1, 0x90, 0x43, 0xa8, 0x8e, 0x16, 0xe7, 0x5e, 0xc4, 0x8c, 0x42, 0x75,
+ 0xb1, 0xf1, 0x3b, 0x30, 0x08, 0xac, 0x16, 0x1a, 0x41, 0x6e, 0x42, 0x79, 0xb4, 0xe8, 0x77, 0xf5,
+ 0x98, 0x8c, 0x35, 0x07, 0xbf, 0xda, 0x55, 0x6d, 0x90, 0xfb, 0x15, 0x6c, 0x16, 0xd7, 0xa1, 0x53,
+ 0xe2, 0x4c, 0xaf, 0x43, 0x15, 0x9d, 0x17, 0x57, 0xfb, 0x35, 0xc5, 0xf5, 0xf0, 0x00, 0x6a, 0xe6,
+ 0xa9, 0x4a, 0x1c, 0xa8, 0x3c, 0x3a, 0x1f, 0xf6, 0x1e, 0x36, 0x37, 0x48, 0x1d, 0xca, 0x67, 0x83,
+ 0xe1, 0xc3, 0xa6, 0x85, 0xd4, 0xf9, 0xe0, 0xbc, 0xd7, 0xb4, 0x0f, 0x6f, 0xc3, 0x66, 0xf1, 0xb1,
+ 0x4a, 0x1a, 0x50, 0x1b, 0x9e, 0x9e, 0x77, 0xdb, 0x83, 0xdf, 0x34, 0x37, 0xc8, 0x26, 0xd4, 0xfb,
+ 0xe7, 0xc3, 0x5e, 0xe7, 0x11, 0xed, 0x35, 0xad, 0xc3, 0x5f, 0x83, 0xb3, 0x7c, 0x4f, 0xa1, 0x86,
+ 0x76, 0xff, 0xbc, 0xdb, 0xdc, 0x20, 0x00, 0xd5, 0x61, 0xaf, 0x43, 0x7b, 0xa8, 0xb7, 0x06, 0xa5,
+ 0xe1, 0xf0, 0xac, 0x69, 0xe3, 0xae, 0x9d, 0xd3, 0xce, 0x59, 0xaf, 0x59, 0x42, 0xf2, 0xe1, 0x83,
+ 0x8b, 0xfb, 0xc3, 0x66, 0xf9, 0xf0, 0x13, 0xb8, 0xb1, 0xf6, 0x9e, 0x51, 0xab, 0xcf, 0x4e, 0x69,
+ 0x0f, 0x35, 0x35, 0xa0, 0x76, 0x41, 0xfb, 0x8f, 0x4f, 0x1f, 0xf6, 0x9a, 0x16, 0x0a, 0xbe, 0x1a,
+ 0x74, 0xbe, 0xec, 0x75, 0x9b, 0x76, 0xfb, 0xd6, 0xb7, 0x2f, 0x76, 0xad, 0xef, 0x5e, 0xec, 0x5a,
+ 0xdf, 0xbf, 0xd8, 0xb5, 0xfe, 0xfd, 0x62, 0xd7, 0xfa, 0xe6, 0xe5, 0xee, 0xc6, 0x77, 0x2f, 0x77,
+ 0x37, 0xbe, 0x7f, 0xb9, 0xbb, 0x31, 0xaa, 0xaa, 0xbf, 0x8e, 0x3e, 0xfe, 0x4f, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x87, 0x95, 0x80, 0x20, 0x7a, 0x12, 0x00, 0x00,
}
diff --git a/vendor/github.com/moby/buildkit/solver/pb/ops.proto b/vendor/github.com/moby/buildkit/solver/pb/ops.proto
index cbbbdae1..a24aad12 100644
--- a/vendor/github.com/moby/buildkit/solver/pb/ops.proto
+++ b/vendor/github.com/moby/buildkit/solver/pb/ops.proto
@@ -44,6 +44,7 @@ message ExecOp {
Meta meta = 1;
repeated Mount mounts = 2;
NetMode network = 3;
+ SecurityMode security = 4;
}
// Meta is a set of arguments for ExecOp.
@@ -64,6 +65,11 @@ enum NetMode {
NONE = 2;
}
+enum SecurityMode {
+ SANDBOX = 0;
+ INSECURE = 1; // privileged mode
+}
+
// Mount specifies how to mount an input Op as a filesystem.
message Mount {
int64 input = 1 [(gogoproto.customtype) = "InputIndex", (gogoproto.nullable) = false];
diff --git a/vendor/github.com/moby/buildkit/util/entitlements/entitlements.go b/vendor/github.com/moby/buildkit/util/entitlements/entitlements.go
index 4bd7f2a8..f30b8ccc 100644
--- a/vendor/github.com/moby/buildkit/util/entitlements/entitlements.go
+++ b/vendor/github.com/moby/buildkit/util/entitlements/entitlements.go
@@ -1,26 +1,19 @@
package entitlements
-import "github.com/pkg/errors"
+import (
+ "github.com/pkg/errors"
+)
type Entitlement string
const (
- EntitlementSecurityConfined Entitlement = "security.confined"
- EntitlementSecurityUnconfined Entitlement = "security.unconfined" // unimplemented
- EntitlementNetworkHost Entitlement = "network.host"
- EntitlementNetworkNone Entitlement = "network.none"
+ EntitlementSecurityInsecure Entitlement = "security.insecure"
+ EntitlementNetworkHost Entitlement = "network.host"
)
var all = map[Entitlement]struct{}{
- EntitlementSecurityConfined: {},
- EntitlementSecurityUnconfined: {},
- EntitlementNetworkHost: {},
- EntitlementNetworkNone: {},
-}
-
-var defaults = map[Entitlement]struct{}{
- EntitlementSecurityConfined: {},
- EntitlementNetworkNone: {},
+ EntitlementSecurityInsecure: {},
+ EntitlementNetworkHost: {},
}
func Parse(s string) (Entitlement, error) {
@@ -56,9 +49,6 @@ func WhiteList(allowed, supported []Entitlement) (Set, error) {
m[e] = struct{}{}
}
- for e := range defaults {
- m[e] = struct{}{}
- }
return Set(m), nil
}
diff --git a/vendor/github.com/moby/buildkit/util/entitlements/security_linux.go b/vendor/github.com/moby/buildkit/util/entitlements/security_linux.go
new file mode 100644
index 00000000..c4cfc6c6
--- /dev/null
+++ b/vendor/github.com/moby/buildkit/util/entitlements/security_linux.go
@@ -0,0 +1,67 @@
+package entitlements
+
+import (
+ "context"
+
+ "github.com/containerd/containerd/containers"
+ "github.com/containerd/containerd/oci"
+ specs "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+// WithInsecureSpec sets spec with All capability.
+func WithInsecureSpec() oci.SpecOpts {
+ return func(_ context.Context, _ oci.Client, _ *containers.Container, s *specs.Spec) error {
+ addCaps := []string{
+ "CAP_FSETID",
+ "CAP_KILL",
+ "CAP_FOWNER",
+ "CAP_MKNOD",
+ "CAP_CHOWN",
+ "CAP_DAC_OVERRIDE",
+ "CAP_NET_RAW",
+ "CAP_SETGID",
+ "CAP_SETUID",
+ "CAP_SETPCAP",
+ "CAP_SETFCAP",
+ "CAP_NET_BIND_SERVICE",
+ "CAP_SYS_CHROOT",
+ "CAP_AUDIT_WRITE",
+ "CAP_MAC_ADMIN",
+ "CAP_MAC_OVERRIDE",
+ "CAP_DAC_READ_SEARCH",
+ "CAP_SYS_PTRACE",
+ "CAP_SYS_MODULE",
+ "CAP_SYSLOG",
+ "CAP_SYS_RAWIO",
+ "CAP_SYS_ADMIN",
+ "CAP_LINUX_IMMUTABLE",
+ "CAP_SYS_BOOT",
+ "CAP_SYS_NICE",
+ "CAP_SYS_PACCT",
+ "CAP_SYS_TTY_CONFIG",
+ "CAP_SYS_TIME",
+ "CAP_WAKE_ALARM",
+ "CAP_AUDIT_READ",
+ "CAP_AUDIT_CONTROL",
+ "CAP_SYS_RESOURCE",
+ "CAP_BLOCK_SUSPEND",
+ "CAP_IPC_LOCK",
+ "CAP_IPC_OWNER",
+ "CAP_LEASE",
+ "CAP_NET_ADMIN",
+ "CAP_NET_BROADCAST",
+ }
+ for _, cap := range addCaps {
+ s.Process.Capabilities.Bounding = append(s.Process.Capabilities.Bounding, cap)
+ s.Process.Capabilities.Ambient = append(s.Process.Capabilities.Ambient, cap)
+ s.Process.Capabilities.Effective = append(s.Process.Capabilities.Effective, cap)
+ s.Process.Capabilities.Inheritable = append(s.Process.Capabilities.Inheritable, cap)
+ s.Process.Capabilities.Permitted = append(s.Process.Capabilities.Permitted, cap)
+ }
+ s.Linux.ReadonlyPaths = []string{}
+ s.Linux.MaskedPaths = []string{}
+ s.Process.ApparmorProfile = ""
+
+ return nil
+ }
+}
diff --git a/vendor/github.com/moby/buildkit/util/progress/progressui/display.go b/vendor/github.com/moby/buildkit/util/progress/progressui/display.go
index e615d683..96340197 100644
--- a/vendor/github.com/moby/buildkit/util/progress/progressui/display.go
+++ b/vendor/github.com/moby/buildkit/util/progress/progressui/display.go
@@ -5,10 +5,14 @@ import (
"context"
"fmt"
"io"
+ "os"
+ "sort"
+ "strconv"
"strings"
"time"
"github.com/containerd/console"
+ "github.com/jaguilar/vt100"
"github.com/moby/buildkit/client"
"github.com/morikuni/aec"
digest "github.com/opencontainers/go-digest"
@@ -27,14 +31,26 @@ func DisplaySolveStatus(ctx context.Context, phase string, c console.Console, w
disp.phase = "Building"
}
- t := newTrace(w)
+ t := newTrace(w, modeConsole)
+
+ tickerTimeout := 150 * time.Millisecond
+ displayTimeout := 100 * time.Millisecond
+
+ if v := os.Getenv("TTY_DISPLAY_RATE"); v != "" {
+ if r, err := strconv.ParseInt(v, 10, 64); err == nil {
+ tickerTimeout = time.Duration(r) * time.Millisecond
+ displayTimeout = time.Duration(r) * time.Millisecond
+ }
+ }
var done bool
- ticker := time.NewTicker(100 * time.Millisecond)
+ ticker := time.NewTicker(tickerTimeout)
defer ticker.Stop()
- displayLimiter := rate.NewLimiter(rate.Every(70*time.Millisecond), 1)
+ displayLimiter := rate.NewLimiter(rate.Every(displayTimeout), 1)
+ var height int
+ width, _ := disp.getSize()
for {
select {
case <-ctx.Done():
@@ -42,34 +58,43 @@ func DisplaySolveStatus(ctx context.Context, phase string, c console.Console, w
case <-ticker.C:
case ss, ok := <-ch:
if ok {
- t.update(ss)
+ t.update(ss, width)
} else {
done = true
}
}
if modeConsole {
+ width, height = disp.getSize()
if done {
- disp.print(t.displayInfo(), true)
+ disp.print(t.displayInfo(), width, height, true)
t.printErrorLogs(c)
return nil
} else if displayLimiter.Allow() {
- disp.print(t.displayInfo(), false)
+ ticker.Stop()
+ ticker = time.NewTicker(tickerTimeout)
+ disp.print(t.displayInfo(), width, height, false)
}
} else {
if done || displayLimiter.Allow() {
printer.print(t)
if done {
+ t.printErrorLogs(w)
return nil
}
+ ticker.Stop()
+ ticker = time.NewTicker(tickerTimeout)
}
}
}
}
+const termHeight = 6
+const termPad = 10
+
type displayInfo struct {
startTime time.Time
- jobs []job
+ jobs []*job
countTotal int
countCompleted int
}
@@ -81,6 +106,8 @@ type job struct {
status string
hasError bool
isCanceled bool
+ vertex *vertex
+ showTerm bool
}
type trace struct {
@@ -90,6 +117,7 @@ type trace struct {
byDigest map[digest.Digest]*vertex
nextIndex int
updates map[digest.Digest]struct{}
+ modeConsole bool
}
type vertex struct {
@@ -107,6 +135,13 @@ type vertex struct {
lastBlockTime *time.Time
count int
statusUpdates map[string]struct{}
+
+ jobs []*job
+ jobCached bool
+
+ term *vt100.VT100
+ termBytes int
+ termCount int
}
func (v *vertex) update(c int) {
@@ -121,11 +156,12 @@ type status struct {
*client.VertexStatus
}
-func newTrace(w io.Writer) *trace {
+func newTrace(w io.Writer, modeConsole bool) *trace {
return &trace{
- byDigest: make(map[digest.Digest]*vertex),
- updates: make(map[digest.Digest]struct{}),
- w: w,
+ byDigest: make(map[digest.Digest]*vertex),
+ updates: make(map[digest.Digest]struct{}),
+ w: w,
+ modeConsole: modeConsole,
}
}
@@ -140,41 +176,37 @@ func (t *trace) triggerVertexEvent(v *client.Vertex) {
old = *v
}
- var ev []string
+ changed := false
if v.Digest != old.Digest {
- ev = append(ev, fmt.Sprintf("%13s %s", "digest:", v.Digest))
+ changed = true
}
if v.Name != old.Name {
- ev = append(ev, fmt.Sprintf("%13s %q", "name:", v.Name))
+ changed = true
}
if v.Started != old.Started {
if v.Started != nil && old.Started == nil || !v.Started.Equal(*old.Started) {
- ev = append(ev, fmt.Sprintf("%13s %v", "started:", v.Started))
+ changed = true
}
}
if v.Completed != old.Completed && v.Completed != nil {
- ev = append(ev, fmt.Sprintf("%13s %v", "completed:", v.Completed))
- if v.Started != nil {
- ev = append(ev, fmt.Sprintf("%13s %v", "duration:", v.Completed.Sub(*v.Started)))
- }
+ changed = true
}
if v.Cached != old.Cached {
- ev = append(ev, fmt.Sprintf("%13s %v", "cached:", v.Cached))
+ changed = true
}
if v.Error != old.Error {
- ev = append(ev, fmt.Sprintf("%13s %q", "error:", v.Error))
+ changed = true
}
- if len(ev) > 0 {
- vtx.events = append(vtx.events, ev...)
- vtx.update(len(ev))
+ if changed {
+ vtx.update(1)
t.updates[v.Digest] = struct{}{}
}
t.byDigest[v.Digest].prev = v
}
-func (t *trace) update(s *client.SolveStatus) {
+func (t *trace) update(s *client.SolveStatus, termWidth int) {
for _, v := range s.Vertexes {
prev, ok := t.byDigest[v.Digest]
if !ok {
@@ -184,6 +216,9 @@ func (t *trace) update(s *client.SolveStatus) {
statusUpdates: make(map[string]struct{}),
index: t.nextIndex,
}
+ if t.modeConsole {
+ t.byDigest[v.Digest].term = vt100.NewVT100(termHeight, termWidth-termPad)
+ }
}
t.triggerVertexEvent(v)
if v.Started != nil && (prev == nil || prev.Started == nil) {
@@ -193,12 +228,14 @@ func (t *trace) update(s *client.SolveStatus) {
t.vertexes = append(t.vertexes, t.byDigest[v.Digest])
}
t.byDigest[v.Digest].Vertex = v
+ t.byDigest[v.Digest].jobCached = false
}
for _, s := range s.Statuses {
v, ok := t.byDigest[s.Vertex]
if !ok {
continue // shouldn't happen
}
+ v.jobCached = false
prev, ok := v.byID[s.ID]
if !ok {
v.byID[s.ID] = &status{VertexStatus: s}
@@ -216,6 +253,14 @@ func (t *trace) update(s *client.SolveStatus) {
if !ok {
continue // shouldn't happen
}
+ v.jobCached = false
+ if v.term != nil {
+ if v.term.Width != termWidth {
+ v.term.Resize(termHeight, termWidth-termPad)
+ }
+ v.termBytes += len(l.Data)
+ v.term.Write(l.Data) // error unhandled on purpose. don't trust vt100
+ }
i := 0
complete := split(l.Data, byte('\n'), func(dt []byte) {
if v.logsPartial && len(v.logs) != 0 && i == 0 {
@@ -262,10 +307,16 @@ func (t *trace) displayInfo() (d displayInfo) {
}
for _, v := range t.vertexes {
- j := job{
+ if v.jobCached {
+ d.jobs = append(d.jobs, v.jobs...)
+ continue
+ }
+ var jobs []*job
+ j := &job{
startTime: addTime(v.Started, t.localTimeDiff),
completedTime: addTime(v.Completed, t.localTimeDiff),
name: strings.Replace(v.Name, "\t", " ", -1),
+ vertex: v,
}
if v.Error != "" {
if strings.HasSuffix(v.Error, context.Canceled.Error()) {
@@ -280,9 +331,9 @@ func (t *trace) displayInfo() (d displayInfo) {
j.name = "CACHED " + j.name
}
j.name = v.indent + j.name
- d.jobs = append(d.jobs, j)
+ jobs = append(jobs, j)
for _, s := range v.statuses {
- j := job{
+ j := &job{
startTime: addTime(s.Started, t.localTimeDiff),
completedTime: addTime(s.Completed, t.localTimeDiff),
name: v.indent + "=> " + s.ID,
@@ -292,8 +343,11 @@ func (t *trace) displayInfo() (d displayInfo) {
} else if s.Current != 0 {
j.status = fmt.Sprintf("%.2f", units.Bytes(s.Current))
}
- d.jobs = append(d.jobs, j)
+ jobs = append(jobs, j)
}
+ d.jobs = append(d.jobs, jobs...)
+ v.jobs = jobs
+ v.jobCached = true
}
return d
@@ -332,20 +386,56 @@ type display struct {
repeated bool
}
-func (disp *display) print(d displayInfo, all bool) {
- // this output is inspired by Buck
+func (disp *display) getSize() (int, int) {
width := 80
height := 10
- size, err := disp.c.Size()
- if err == nil && size.Width > 0 && size.Height > 0 {
- width = int(size.Width)
- height = int(size.Height)
+ if disp.c != nil {
+ size, err := disp.c.Size()
+ if err == nil && size.Width > 0 && size.Height > 0 {
+ width = int(size.Width)
+ height = int(size.Height)
+ }
+ }
+ return width, height
+}
+
+func setupTerminals(jobs []*job, height int, all bool) []*job {
+ var candidates []*job
+ numInUse := 0
+ for _, j := range jobs {
+ if j.vertex != nil && j.vertex.termBytes > 0 && j.completedTime == nil {
+ candidates = append(candidates, j)
+ }
+ if j.completedTime == nil {
+ numInUse++
+ }
+ }
+ sort.Slice(candidates, func(i, j int) bool {
+ idxI := candidates[i].vertex.termBytes + candidates[i].vertex.termCount*50
+ idxJ := candidates[j].vertex.termBytes + candidates[j].vertex.termCount*50
+ return idxI > idxJ
+ })
+
+ numFree := height - 2 - numInUse
+ numToHide := 0
+ termLimit := termHeight + 3
+
+ for i := 0; numFree > termLimit && i < len(candidates); i++ {
+ candidates[i].showTerm = true
+ numToHide += candidates[i].vertex.term.UsedHeight()
+ numFree -= termLimit
}
if !all {
- d.jobs = wrapHeight(d.jobs, height-2)
+ jobs = wrapHeight(jobs, height-2-numToHide)
}
+ return jobs
+}
+
+func (disp *display) print(d displayInfo, width, height int, all bool) {
+ // this output is inspired by Buck
+ d.jobs = setupTerminals(d.jobs, height, all)
b := aec.EmptyBuilder
for i := 0; i <= disp.lineCount; i++ {
b = b.Up(1)
@@ -395,11 +485,12 @@ func (disp *display) print(d displayInfo, all bool) {
if left < 12 { // too small screen to show progress
continue
}
- if len(j.name) > left {
- j.name = j.name[:left]
+ name := j.name
+ if len(name) > left {
+ name = name[:left]
}
- out := pfx + j.name
+ out := pfx + name
if showStatus {
out += " " + status
}
@@ -416,17 +507,68 @@ func (disp *display) print(d displayInfo, all bool) {
}
fmt.Fprint(disp.c, out)
lineCount++
+ if j.showTerm {
+ term := j.vertex.term
+ term.Resize(termHeight, width-termPad)
+ for _, l := range term.Content {
+ if !isEmpty(l) {
+ out := aec.Apply(fmt.Sprintf(" => => # %s\n", string(l)), aec.Faint)
+ fmt.Fprint(disp.c, out)
+ lineCount++
+ }
+ }
+ j.vertex.termCount++
+ j.showTerm = false
+ }
+ }
+ // override previous content
+ if diff := disp.lineCount - lineCount; diff > 0 {
+ for i := 0; i < diff; i++ {
+ fmt.Fprintln(disp.c, strings.Repeat(" ", width))
+ }
+ fmt.Fprint(disp.c, aec.EmptyBuilder.Up(uint(diff)).Column(0).ANSI)
}
disp.lineCount = lineCount
}
+func isEmpty(l []rune) bool {
+ for _, r := range l {
+ if r != ' ' {
+ return false
+ }
+ }
+ return true
+}
+
func align(l, r string, w int) string {
return fmt.Sprintf("%-[2]*[1]s %[3]s", l, w-len(r)-1, r)
}
-func wrapHeight(j []job, limit int) []job {
+func wrapHeight(j []*job, limit int) []*job {
+ var wrapped []*job
+ wrapped = append(wrapped, j...)
if len(j) > limit {
- j = j[len(j)-limit:]
+ wrapped = wrapped[len(j)-limit:]
+
+ // wrap things around if incomplete jobs were cut
+ var invisible []*job
+ for _, j := range j[:len(j)-limit] {
+ if j.completedTime == nil {
+ invisible = append(invisible, j)
+ }
+ }
+
+ if l := len(invisible); l > 0 {
+ rewrapped := make([]*job, 0, len(wrapped))
+ for _, j := range wrapped {
+ if j.completedTime == nil || l <= 0 {
+ rewrapped = append(rewrapped, j)
+ }
+ l--
+ }
+ freespace := len(wrapped) - len(rewrapped)
+ wrapped = append(invisible[len(invisible)-freespace:], rewrapped...)
+ }
}
- return j
+ return wrapped
}
diff --git a/vendor/github.com/moby/buildkit/util/progress/progressui/printer.go b/vendor/github.com/moby/buildkit/util/progress/progressui/printer.go
index 3794105a..2278796d 100644
--- a/vendor/github.com/moby/buildkit/util/progress/progressui/printer.go
+++ b/vendor/github.com/moby/buildkit/util/progress/progressui/printer.go
@@ -1,8 +1,12 @@
package progressui
import (
+ "context"
"fmt"
"io"
+ "os"
+ "sort"
+ "strings"
"time"
digest "github.com/opencontainers/go-digest"
@@ -20,9 +24,10 @@ type lastStatus struct {
}
type textMux struct {
- w io.Writer
- current digest.Digest
- last map[string]lastStatus
+ w io.Writer
+ current digest.Digest
+ last map[string]lastStatus
+ notFirst bool
}
func (p *textMux) printVtx(t *trace, dgst digest.Digest) {
@@ -43,10 +48,22 @@ func (p *textMux) printVtx(t *trace, dgst digest.Digest) {
}
old.logsOffset = 0
old.count = 0
- fmt.Fprintf(p.w, "#%d ...\n", v.index)
+ fmt.Fprintf(p.w, "#%d ...\n", old.index)
+ }
+
+ if p.notFirst {
+ fmt.Fprintln(p.w, "")
+ } else {
+ p.notFirst = true
+ }
+
+ if os.Getenv("PROGRESS_NO_TRUNC") == "1" {
+ fmt.Fprintf(p.w, "#%d %s\n", v.index, v.Name)
+ fmt.Fprintf(p.w, "#%d %s\n", v.index, v.Digest)
+ } else {
+ fmt.Fprintf(p.w, "#%d %s\n", v.index, limitString(v.Name, 72))
}
- fmt.Fprintf(p.w, "\n#%d %s\n", v.index, limitString(v.Name, 72))
}
if len(v.events) != 0 {
@@ -127,18 +144,46 @@ func (p *textMux) printVtx(t *trace, dgst digest.Digest) {
}
p.current = dgst
-
if v.Completed != nil {
p.current = ""
v.count = 0
- fmt.Fprintf(p.w, "\n")
+
+ if v.Error != "" {
+ if v.logsPartial {
+ fmt.Fprintln(p.w, "")
+ }
+ if strings.HasSuffix(v.Error, context.Canceled.Error()) {
+ fmt.Fprintf(p.w, "#%d CANCELED\n", v.index)
+ } else {
+ fmt.Fprintf(p.w, "#%d ERROR: %s\n", v.index, v.Error)
+ }
+ } else if v.Cached {
+ fmt.Fprintf(p.w, "#%d CACHED\n", v.index)
+ } else {
+ tm := ""
+ if v.Started != nil {
+ tm = fmt.Sprintf(" %.1fs", v.Completed.Sub(*v.Started).Seconds())
+ }
+ fmt.Fprintf(p.w, "#%d DONE%s\n", v.index, tm)
+ }
+
}
delete(t.updates, dgst)
}
-func (p *textMux) print(t *trace) {
+func sortCompleted(t *trace, m map[digest.Digest]struct{}) []digest.Digest {
+ out := make([]digest.Digest, 0, len(m))
+ for k := range m {
+ out = append(out, k)
+ }
+ sort.Slice(out, func(i, j int) bool {
+ return t.byDigest[out[i]].Completed.Before(*t.byDigest[out[j]].Completed)
+ })
+ return out
+}
+func (p *textMux) print(t *trace) {
completed := map[digest.Digest]struct{}{}
rest := map[digest.Digest]struct{}{}
@@ -161,7 +206,7 @@ func (p *textMux) print(t *trace) {
p.printVtx(t, current)
}
- for dgst := range completed {
+ for _, dgst := range sortCompleted(t, completed) {
if dgst != current {
p.printVtx(t, dgst)
}
diff --git a/vendor/github.com/tonistiigi/fsutil/fs.go b/vendor/github.com/tonistiigi/fsutil/fs.go
index 132850c9..a9467e94 100644
--- a/vendor/github.com/tonistiigi/fsutil/fs.go
+++ b/vendor/github.com/tonistiigi/fsutil/fs.go
@@ -3,9 +3,11 @@ package fsutil
import (
"context"
"io"
+ "io/ioutil"
"os"
"path"
"path/filepath"
+ "sort"
"strings"
"github.com/pkg/errors"
@@ -37,36 +39,80 @@ func (fs *fs) Open(p string) (io.ReadCloser, error) {
return os.Open(filepath.Join(fs.root, p))
}
-func SubDirFS(fs FS, stat types.Stat) FS {
- return &subDirFS{fs: fs, stat: stat}
+type Dir struct {
+ Stat types.Stat
+ FS FS
+}
+
+func SubDirFS(dirs []Dir) (FS, error) {
+ sort.Slice(dirs, func(i, j int) bool {
+ return dirs[i].Stat.Path < dirs[j].Stat.Path
+ })
+ m := map[string]Dir{}
+ for _, d := range dirs {
+ if path.Base(d.Stat.Path) != d.Stat.Path {
+ return nil, errors.Errorf("subdir %s must be single file", d.Stat.Path)
+ }
+ if _, ok := m[d.Stat.Path]; ok {
+ return nil, errors.Errorf("invalid path %s", d.Stat.Path)
+ }
+ m[d.Stat.Path] = d
+ }
+ return &subDirFS{m: m, dirs: dirs}, nil
}
type subDirFS struct {
- fs FS
- stat types.Stat
+ m map[string]Dir
+ dirs []Dir
}
func (fs *subDirFS) Walk(ctx context.Context, fn filepath.WalkFunc) error {
- main := &StatInfo{Stat: &fs.stat}
- if !main.IsDir() {
- return errors.Errorf("fs subdir not mode directory")
- }
- if main.Name() != fs.stat.Path {
- return errors.Errorf("subdir path must be single file")
- }
- if err := fn(fs.stat.Path, main, nil); err != nil {
- return err
- }
- return fs.fs.Walk(ctx, func(p string, fi os.FileInfo, err error) error {
- stat, ok := fi.Sys().(*types.Stat)
- if !ok {
- return errors.Wrapf(err, "invalid fileinfo without stat info: %s", p)
+ for _, d := range fs.dirs {
+ fi := &StatInfo{Stat: &d.Stat}
+ if !fi.IsDir() {
+ return errors.Errorf("fs subdir %s not mode directory", d.Stat.Path)
}
- stat.Path = path.Join(fs.stat.Path, stat.Path)
- return fn(filepath.Join(fs.stat.Path, p), &StatInfo{stat}, nil)
- })
+ if err := fn(d.Stat.Path, fi, nil); err != nil {
+ return err
+ }
+ if err := d.FS.Walk(ctx, func(p string, fi os.FileInfo, err error) error {
+ stat, ok := fi.Sys().(*types.Stat)
+ if !ok {
+ return errors.Wrapf(err, "invalid fileinfo without stat info: %s", p)
+ }
+ stat.Path = path.Join(d.Stat.Path, stat.Path)
+ if stat.Linkname != "" {
+ if fi.Mode()&os.ModeSymlink != 0 {
+ if strings.HasPrefix(stat.Linkname, "/") {
+ stat.Linkname = path.Join("/"+d.Stat.Path, stat.Linkname)
+ }
+ } else {
+ stat.Linkname = path.Join(d.Stat.Path, stat.Linkname)
+ }
+ }
+ return fn(filepath.Join(d.Stat.Path, p), &StatInfo{stat}, nil)
+ }); err != nil {
+ return err
+ }
+ }
+ return nil
}
func (fs *subDirFS) Open(p string) (io.ReadCloser, error) {
- return fs.fs.Open(strings.TrimPrefix(p, fs.stat.Path+"/"))
+ parts := strings.SplitN(filepath.Clean(p), string(filepath.Separator), 2)
+ if len(parts) == 0 {
+ return ioutil.NopCloser(&emptyReader{}), nil
+ }
+ d, ok := fs.m[parts[0]]
+ if !ok {
+ return nil, os.ErrNotExist
+ }
+ return d.FS.Open(parts[1])
+}
+
+type emptyReader struct {
+}
+
+func (*emptyReader) Read([]byte) (int, error) {
+ return 0, io.EOF
}
diff --git a/vendor/github.com/tonistiigi/fsutil/tarwriter.go b/vendor/github.com/tonistiigi/fsutil/tarwriter.go
new file mode 100644
index 00000000..8dea63ba
--- /dev/null
+++ b/vendor/github.com/tonistiigi/fsutil/tarwriter.go
@@ -0,0 +1,72 @@
+package fsutil
+
+import (
+ "archive/tar"
+ "context"
+ "io"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/pkg/errors"
+ "github.com/tonistiigi/fsutil/types"
+)
+
+func WriteTar(ctx context.Context, fs FS, w io.Writer) error {
+ tw := tar.NewWriter(w)
+ err := fs.Walk(ctx, func(path string, fi os.FileInfo, err error) error {
+ stat, ok := fi.Sys().(*types.Stat)
+ if !ok {
+ return errors.Wrapf(err, "invalid fileinfo without stat info: %s", path)
+ }
+ hdr, err := tar.FileInfoHeader(fi, stat.Linkname)
+ if err != nil {
+ return err
+ }
+
+ name := filepath.ToSlash(path)
+ if fi.IsDir() && !strings.HasSuffix(name, "/") {
+ name += "/"
+ }
+ hdr.Name = name
+
+ hdr.Uid = int(stat.Uid)
+ hdr.Gid = int(stat.Gid)
+ hdr.Devmajor = stat.Devmajor
+ hdr.Devminor = stat.Devminor
+ hdr.Linkname = stat.Linkname
+ if hdr.Linkname != "" {
+ hdr.Size = 0
+ hdr.Typeflag = tar.TypeLink
+ }
+
+ if len(stat.Xattrs) > 0 {
+ hdr.PAXRecords = map[string]string{}
+ }
+ for k, v := range stat.Xattrs {
+ hdr.PAXRecords["SCHILY.xattr."+k] = string(v)
+ }
+
+ if err := tw.WriteHeader(hdr); err != nil {
+ return errors.Wrap(err, "failed to write file header")
+ }
+
+ if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 && hdr.Linkname == "" {
+ rc, err := fs.Open(path)
+ if err != nil {
+ return err
+ }
+ if _, err := io.Copy(tw, rc); err != nil {
+ return err
+ }
+ if err := rc.Close(); err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+ return tw.Close()
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c6118478..80ab6927 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -37,12 +37,15 @@ github.com/containerd/containerd/sys
github.com/containerd/containerd/api/services/content/v1
github.com/containerd/containerd/content/proxy
github.com/containerd/containerd/services/content/contentserver
-github.com/containerd/containerd
github.com/containerd/containerd/containers
+github.com/containerd/containerd/oci
+github.com/containerd/containerd
github.com/containerd/containerd/images
github.com/containerd/containerd/namespaces
github.com/containerd/containerd/remotes
github.com/containerd/containerd/remotes/docker
+github.com/containerd/containerd/mount
+github.com/containerd/containerd/snapshots
github.com/containerd/containerd/api/services/containers/v1
github.com/containerd/containerd/api/services/diff/v1
github.com/containerd/containerd/api/services/events/v1
@@ -64,15 +67,12 @@ github.com/containerd/containerd/images/archive
github.com/containerd/containerd/images/oci
github.com/containerd/containerd/leases
github.com/containerd/containerd/leases/proxy
-github.com/containerd/containerd/mount
-github.com/containerd/containerd/oci
github.com/containerd/containerd/pkg/dialer
github.com/containerd/containerd/plugin
github.com/containerd/containerd/remotes/docker/schema1
github.com/containerd/containerd/rootfs
github.com/containerd/containerd/runtime/linux/runctypes
github.com/containerd/containerd/runtime/v2/runc/options
-github.com/containerd/containerd/snapshots
github.com/containerd/containerd/snapshots/proxy
github.com/containerd/containerd/labels
github.com/containerd/containerd/reference
@@ -87,8 +87,8 @@ github.com/containerd/continuity/devices
github.com/containerd/continuity/driver
github.com/containerd/continuity/proto
github.com/containerd/continuity/sysx
-github.com/containerd/continuity/syscallx
github.com/containerd/continuity/fs
+github.com/containerd/continuity/syscallx
# github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448
github.com/containerd/fifo
# github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20
@@ -116,8 +116,8 @@ github.com/docker/cli/cli/version
github.com/docker/cli/internal/containerizedengine
github.com/docker/cli/opts
github.com/docker/cli/types
-github.com/docker/cli/cli/connhelper/commandconn
github.com/docker/cli/cli/config/credentials
+github.com/docker/cli/cli/connhelper/commandconn
github.com/docker/cli/cli/connhelper/ssh
github.com/docker/cli/kubernetes
github.com/docker/cli/cli/manifest/types
@@ -238,6 +238,8 @@ github.com/hashicorp/go-version
github.com/imdario/mergo
# github.com/inconshreveable/mousetrap v1.0.0
github.com/inconshreveable/mousetrap
+# github.com/jaguilar/vt100 v0.0.0-20150826170717-2703a27b14ea => github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305
+github.com/jaguilar/vt100
# github.com/json-iterator/go v1.1.6
github.com/json-iterator/go
# github.com/konsorten/go-windows-terminal-sequences v1.0.1
@@ -246,7 +248,7 @@ github.com/konsorten/go-windows-terminal-sequences
github.com/matttproud/golang_protobuf_extensions/pbutil
# github.com/miekg/pkcs11 v0.0.0-20190322140431-074fd7a1ed19
github.com/miekg/pkcs11
-# github.com/moby/buildkit v0.4.1-0.20190326070013-325bd96b6b62
+# github.com/moby/buildkit v0.4.1-0.20190405144722-cbfb5c476a09
github.com/moby/buildkit/client
github.com/moby/buildkit/session
github.com/moby/buildkit/session/secrets/secretsprovider
@@ -337,7 +339,7 @@ github.com/theupdateframework/notary/trustmanager/yubikey
github.com/theupdateframework/notary/tuf
github.com/theupdateframework/notary/tuf/utils
github.com/theupdateframework/notary/tuf/validation
-# github.com/tonistiigi/fsutil v0.0.0-20190319020005-1bdbf124ad49
+# github.com/tonistiigi/fsutil v0.0.0-20190327153851-3bbb99cdbd76
github.com/tonistiigi/fsutil/types
github.com/tonistiigi/fsutil
# github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea