vendor: update buildkit and dockerd

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi 2019-04-06 13:19:36 -07:00
parent f0142b9e8b
commit 9129a49409
29 changed files with 1686 additions and 284 deletions

View File

@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1.0-experimental # syntax=docker/dockerfile:1.0-experimental
ARG DOCKERD_VERSION=18.09 ARG DOCKERD_VERSION=19.03-rc
ARG CLI_VERSION=19.03 ARG CLI_VERSION=19.03
FROM docker:$DOCKERD_VERSION AS dockerd-release FROM docker:$DOCKERD_VERSION AS dockerd-release
@ -54,11 +54,13 @@ FROM binaries-$TARGETOS AS binaries
FROM alpine AS demo-env FROM alpine AS demo-env
RUN apk add --no-cache iptables tmux git 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 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/entrypoint.sh /usr/local/bin
COPY ./hack/demo-env/tmux.conf /root/.tmux.conf COPY ./hack/demo-env/tmux.conf /root/.tmux.conf
COPY --from=dockerd-release /usr/local/bin /usr/local/bin 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 WORKDIR /work
COPY ./hack/demo-env/examples . COPY ./hack/demo-env/examples .

4
go.mod
View File

@ -53,7 +53,7 @@ require (
github.com/mattn/go-sqlite3 v1.10.0 // indirect github.com/mattn/go-sqlite3 v1.10.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/miekg/pkcs11 v0.0.0-20190322140431-074fd7a1ed19 // 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/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/opencontainers/go-digest v1.0.0-rc1 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 k8s.io/client-go v2.0.0-alpha.0.0.20180806134042-1f13a808da65+incompatible // indirect
vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787 // indirect vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787 // indirect
) )
replace github.com/jaguilar/vt100 => github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305

10
go.sum
View File

@ -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/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 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 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.20190405144722-cbfb5c476a09 h1:OHOk/ObJ9P40As+zA6PNN8w1ZulvpVQyYtSzkWjDEyQ=
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/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 h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 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= 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/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 h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0=
github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY= 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-20190327153851-3bbb99cdbd76 h1:eGfgYrNUSD448sa4mxH6nQpyZfN39QH0mLB7QaKIjus=
github.com/tonistiigi/fsutil v0.0.0-20190319020005-1bdbf124ad49/go.mod h1:pzh7kdwkDRh+Bx8J30uqaKJ1M4QrSH/um8fcIXeM8rc= 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 h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0=
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk= 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-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/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= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=

1
vendor/github.com/jaguilar/vt100/.travis.yml generated vendored Normal file
View File

@ -0,0 +1 @@
language: go

22
vendor/github.com/jaguilar/vt100/LICENSE generated vendored Normal file
View File

@ -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.

54
vendor/github.com/jaguilar/vt100/README.md generated vendored Normal file
View File

@ -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.

288
vendor/github.com/jaguilar/vt100/command.go generated vendored Normal file
View File

@ -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
}

5
vendor/github.com/jaguilar/vt100/go.mod generated vendored Normal file
View File

@ -0,0 +1,5 @@
module github.com/jaguilar/vt100
go 1.12
require github.com/stretchr/testify v1.3.0

7
vendor/github.com/jaguilar/vt100/go.sum generated vendored Normal file
View File

@ -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=

97
vendor/github.com/jaguilar/vt100/scanner.go generated vendored Normal file
View File

@ -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.
}
}
}

435
vendor/github.com/jaguilar/vt100/vt100.go generated vendored Normal file
View File

@ -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(`<pre style="color:white;background-color:black;">`)
// 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("</span>")
}
if f != (Format{}) {
buf.WriteString(`<span style="` + f.css() + `">`)
}
lastFormat = f
}
if s := maybeEscapeRune(r); s != "" {
buf.WriteString(s)
} else {
buf.WriteRune(r)
}
}
buf.WriteRune('\n')
}
buf.WriteString("</pre>")
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 "&amp;"
case '\'':
return "&#39;"
case '<':
return "&lt;"
case '>':
return "&gt;"
case '"':
return "&quot;"
}
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
}

View File

@ -5,10 +5,10 @@ import (
"context" "context"
"net" "net"
"net/url" "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. // ConnectionHelper allows to connect to a remote host with custom stream provider binary.
type ConnectionHelper struct { type ConnectionHelper struct {
// ContextDialer can be passed to grpc.WithContextDialer // 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 BuildKit-specific connection helper for the given URL.
// GetConnectionHelper returns nil without error when no helper is registered for the scheme. // GetConnectionHelper returns nil without error when no helper is registered for the scheme.
//
// docker://<container> URL requires BuildKit v0.5.0 or later in the container.
func GetConnectionHelper(daemonURL string) (*ConnectionHelper, error) { func GetConnectionHelper(daemonURL string) (*ConnectionHelper, error) {
u, err := url.Parse(daemonURL) u, err := url.Parse(daemonURL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
switch scheme := u.Scheme; scheme {
case "docker": fn, ok := helpers[u.Scheme]
container := u.Host if !ok {
return &ConnectionHelper{ return nil, nil
ContextDialer: func(ctx context.Context, addr string) (net.Conn, error) {
return commandconn.New(ctx, "docker", "exec", "-i", container, "buildctl", "dial-stdio")
},
}, 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
} }

View File

@ -3,6 +3,7 @@ package client
const ( const (
ExporterImage = "image" ExporterImage = "image"
ExporterLocal = "local" ExporterLocal = "local"
ExporterTar = "tar"
ExporterOCI = "oci" ExporterOCI = "oci"
ExporterDocker = "docker" ExporterDocker = "docker"
) )

View File

@ -20,6 +20,7 @@ type Meta struct {
ProxyEnv *ProxyEnv ProxyEnv *ProxyEnv
ExtraHosts []HostIP ExtraHosts []HostIP
Network pb.NetMode Network pb.NetMode
Security pb.SecurityMode
} }
func NewExecOp(root Output, meta Meta, readOnly bool, c Constraints) *ExecOp { func NewExecOp(root Output, meta Meta, readOnly bool, c Constraints) *ExecOp {
@ -52,7 +53,7 @@ type mount struct {
cacheID string cacheID string
tmpfs bool tmpfs bool
cacheSharing CacheMountSharingMode cacheSharing CacheMountSharingMode
// hasOutput bool noOutput bool
} }
type ExecOp struct { type ExecOp struct {
@ -79,6 +80,8 @@ func (e *ExecOp) AddMount(target string, source Output, opt ...MountOption) Outp
m.output = source m.output = source
} else if m.tmpfs { } else if m.tmpfs {
m.output = &output{vertex: e, err: errors.Errorf("tmpfs mount for %s can't be used as a parent", target)} 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 { } else {
o := &output{vertex: e, getIndex: e.getMountIndexFn(m)} o := &output{vertex: e, getIndex: e.getMountIndexFn(m)}
if p := e.constraints.Platform; p != nil { 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{ peo := &pb.ExecOp{
Meta: meta, Meta: meta,
Network: e.meta.Network, Network: e.meta.Network,
Security: e.meta.Security,
} }
if e.meta.Network != NetModeSandbox { if e.meta.Network != NetModeSandbox {
addCap(&e.constraints, pb.CapExecMetaNetwork) addCap(&e.constraints, pb.CapExecMetaNetwork)
} }
if e.meta.Security != SecurityModeInsecure {
addCap(&e.constraints, pb.CapExecMetaSecurity)
}
if p := e.meta.ProxyEnv; p != nil { if p := e.meta.ProxyEnv; p != nil {
peo.Meta.ProxyEnv = &pb.ProxyEnv{ peo.Meta.ProxyEnv = &pb.ProxyEnv{
HttpProxy: p.HttpProxy, HttpProxy: p.HttpProxy,
@ -242,7 +250,7 @@ func (e *ExecOp) Marshal(c *Constraints) (digest.Digest, []byte, *pb.OpMetadata,
} }
outputIndex := pb.OutputIndex(-1) outputIndex := pb.OutputIndex(-1)
if !m.readonly && m.cacheID == "" && !m.tmpfs { if !m.noOutput && !m.readonly && m.cacheID == "" && !m.tmpfs {
outputIndex = pb.OutputIndex(outIndex) outputIndex = pb.OutputIndex(outIndex)
outIndex++ outIndex++
} }
@ -338,7 +346,7 @@ func (e *ExecOp) getMountIndexFn(m *mount) func() (pb.OutputIndex, error) {
i := 0 i := 0
for _, m2 := range e.mounts { for _, m2 := range e.mounts {
if m2.readonly || m2.cacheID != "" { if m2.noOutput || m2.readonly || m2.cacheID != "" {
continue continue
} }
if m == m2 { 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 { func AsPersistentCacheDir(id string, sharing CacheMountSharingMode) MountOption {
return func(m *mount) { return func(m *mount) {
m.cacheID = id 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 { func Shlex(str string) RunOption {
return Shlexf(str) return Shlexf(str)
} }
@ -623,3 +641,8 @@ const (
NetModeHost = pb.NetMode_HOST NetModeHost = pb.NetMode_HOST
NetModeNone = pb.NetMode_NONE NetModeNone = pb.NetMode_NONE
) )
const (
SecurityModeInsecure = pb.SecurityMode_INSECURE
SecurityModeSandbox = pb.SecurityMode_SANDBOX
)

View File

@ -21,6 +21,7 @@ var (
keyExtraHost = contextKeyT("llb.exec.extrahost") keyExtraHost = contextKeyT("llb.exec.extrahost")
keyPlatform = contextKeyT("llb.platform") keyPlatform = contextKeyT("llb.platform")
keyNetwork = contextKeyT("llb.network") keyNetwork = contextKeyT("llb.network")
keySecurity = contextKeyT("llb.security")
) )
func addEnvf(key, value string, v ...interface{}) StateOption { func addEnvf(key, value string, v ...interface{}) StateOption {
@ -148,7 +149,6 @@ func network(v pb.NetMode) StateOption {
return s.WithValue(keyNetwork, v) return s.WithValue(keyNetwork, v)
} }
} }
func getNetwork(s State) pb.NetMode { func getNetwork(s State) pb.NetMode {
v := s.Value(keyNetwork) v := s.Value(keyNetwork)
if v != nil { if v != nil {
@ -158,6 +158,20 @@ func getNetwork(s State) pb.NetMode {
return NetModeSandbox 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 EnvList []KeyValue
type KeyValue struct { type KeyValue struct {

View File

@ -214,6 +214,7 @@ func (s State) Run(ro ...RunOption) ExecState {
ProxyEnv: ei.ProxyEnv, ProxyEnv: ei.ProxyEnv,
ExtraHosts: getExtraHosts(ei.State), ExtraHosts: getExtraHosts(ei.State),
Network: getNetwork(ei.State), Network: getNetwork(ei.State),
Security: getSecurity(ei.State),
} }
exec := NewExecOp(s.Output(), meta, ei.ReadonlyRootFS, ei.Constraints) 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 { func (s State) GetNetwork() pb.NetMode {
return getNetwork(s) 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 { func (s State) With(so ...StateOption) State {
for _, o := range so { for _, o := range so {

View File

@ -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") return nil, errors.New("output directory is required for local exporter")
} }
s.Allow(filesync.NewFSSyncTargetDir(ex.OutputDir)) s.Allow(filesync.NewFSSyncTargetDir(ex.OutputDir))
case ExporterOCI, ExporterDocker: case ExporterOCI, ExporterDocker, ExporterTar:
if ex.OutputDir != "" { if ex.OutputDir != "" {
return nil, errors.Errorf("output directory %s is not supported by %s exporter", ex.OutputDir, ex.Type) return nil, errors.Errorf("output directory %s is not supported by %s exporter", ex.OutputDir, ex.Type)
} }

View File

@ -57,7 +57,7 @@ func (wc *streamWriterCloser) Close() error {
return nil 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() st := time.Now()
defer func() { defer func() {
logrus.Debugf("diffcopy took: %v", time.Since(st)) 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, NotifyHashed: cf,
ContentHasher: ch, ContentHasher: ch,
ProgressCb: progress, ProgressCb: progress,
Filter: fsutil.FilterFunc(filter),
}) })
} }

View File

@ -129,7 +129,7 @@ type progressCb func(int, bool)
type protocol struct { type protocol struct {
name string name string
sendFn func(stream grpc.Stream, fs fsutil.FS, progress progressCb) error 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 { func isProtoSupported(p string) bool {
@ -158,6 +158,7 @@ type FSSendRequestOpt struct {
DestDir string DestDir string
CacheUpdater CacheUpdater CacheUpdater CacheUpdater
ProgressCb func(int, bool) ProgressCb func(int, bool)
Filter func(string, *fstypes.Stat) bool
} }
// CacheUpdater is an object capable of sending notifications for the cache hash changes // 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)) 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 // NewFSSyncTargetDir allows writing into a directory

View File

@ -33,6 +33,7 @@ const (
CapExecMetaBase apicaps.CapID = "exec.meta.base" CapExecMetaBase apicaps.CapID = "exec.meta.base"
CapExecMetaProxy apicaps.CapID = "exec.meta.proxyenv" CapExecMetaProxy apicaps.CapID = "exec.meta.proxyenv"
CapExecMetaNetwork apicaps.CapID = "exec.meta.network" CapExecMetaNetwork apicaps.CapID = "exec.meta.network"
CapExecMetaSecurity apicaps.CapID = "exec.meta.security"
CapExecMetaSetsDefaultPath apicaps.CapID = "exec.meta.setsdefaultpath" CapExecMetaSetsDefaultPath apicaps.CapID = "exec.meta.setsdefaultpath"
CapExecMountBind apicaps.CapID = "exec.mount.bind" CapExecMountBind apicaps.CapID = "exec.mount.bind"
CapExecMountCache apicaps.CapID = "exec.mount.cache" CapExecMountCache apicaps.CapID = "exec.mount.cache"
@ -180,6 +181,12 @@ func init() {
Status: apicaps.CapStatusExperimental, Status: apicaps.CapStatusExperimental,
}) })
Caps.Init(apicaps.Cap{
ID: CapExecMetaSecurity,
Enabled: true,
Status: apicaps.CapStatusExperimental,
})
Caps.Init(apicaps.Cap{ Caps.Init(apicaps.Cap{
ID: CapExecMountBind, ID: CapExecMountBind,
Enabled: true, Enabled: true,

View File

@ -54,7 +54,30 @@ func (x NetMode) String() string {
return proto.EnumName(NetMode_name, int32(x)) return proto.EnumName(NetMode_name, int32(x))
} }
func (NetMode) EnumDescriptor() ([]byte, []int) { 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 // 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)) return proto.EnumName(MountType_name, int32(x))
} }
func (MountType) EnumDescriptor() ([]byte, []int) { 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 // CacheSharingOpt defines different sharing modes for cache mount
@ -117,7 +140,7 @@ func (x CacheSharingOpt) String() string {
return proto.EnumName(CacheSharingOpt_name, int32(x)) return proto.EnumName(CacheSharingOpt_name, int32(x))
} }
func (CacheSharingOpt) EnumDescriptor() ([]byte, []int) { 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. // 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 (m *Op) String() string { return proto.CompactTextString(m) }
func (*Op) ProtoMessage() {} func (*Op) ProtoMessage() {}
func (*Op) Descriptor() ([]byte, []int) { 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 { func (m *Op) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -368,7 +391,7 @@ func (m *Platform) Reset() { *m = Platform{} }
func (m *Platform) String() string { return proto.CompactTextString(m) } func (m *Platform) String() string { return proto.CompactTextString(m) }
func (*Platform) ProtoMessage() {} func (*Platform) ProtoMessage() {}
func (*Platform) Descriptor() ([]byte, []int) { 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 { func (m *Platform) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -440,7 +463,7 @@ func (m *Input) Reset() { *m = Input{} }
func (m *Input) String() string { return proto.CompactTextString(m) } func (m *Input) String() string { return proto.CompactTextString(m) }
func (*Input) ProtoMessage() {} func (*Input) ProtoMessage() {}
func (*Input) Descriptor() ([]byte, []int) { 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 { func (m *Input) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -467,16 +490,17 @@ var xxx_messageInfo_Input proto.InternalMessageInfo
// ExecOp executes a command in a container. // ExecOp executes a command in a container.
type ExecOp struct { type ExecOp struct {
Meta *Meta `protobuf:"bytes,1,opt,name=meta,proto3" json:"meta,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"` 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"` 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) Reset() { *m = ExecOp{} }
func (m *ExecOp) String() string { return proto.CompactTextString(m) } func (m *ExecOp) String() string { return proto.CompactTextString(m) }
func (*ExecOp) ProtoMessage() {} func (*ExecOp) ProtoMessage() {}
func (*ExecOp) Descriptor() ([]byte, []int) { 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 { func (m *ExecOp) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -522,6 +546,13 @@ func (m *ExecOp) GetNetwork() NetMode {
return NetMode_UNSET 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 a set of arguments for ExecOp.
// Meta is unrelated to LLB metadata. // Meta is unrelated to LLB metadata.
// FIXME: rename (ExecContext? ExecArgs?) // FIXME: rename (ExecContext? ExecArgs?)
@ -538,7 +569,7 @@ func (m *Meta) Reset() { *m = Meta{} }
func (m *Meta) String() string { return proto.CompactTextString(m) } func (m *Meta) String() string { return proto.CompactTextString(m) }
func (*Meta) ProtoMessage() {} func (*Meta) ProtoMessage() {}
func (*Meta) Descriptor() ([]byte, []int) { 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 { func (m *Meta) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -622,7 +653,7 @@ func (m *Mount) Reset() { *m = Mount{} }
func (m *Mount) String() string { return proto.CompactTextString(m) } func (m *Mount) String() string { return proto.CompactTextString(m) }
func (*Mount) ProtoMessage() {} func (*Mount) ProtoMessage() {}
func (*Mount) Descriptor() ([]byte, []int) { 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 { func (m *Mount) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -708,7 +739,7 @@ func (m *CacheOpt) Reset() { *m = CacheOpt{} }
func (m *CacheOpt) String() string { return proto.CompactTextString(m) } func (m *CacheOpt) String() string { return proto.CompactTextString(m) }
func (*CacheOpt) ProtoMessage() {} func (*CacheOpt) ProtoMessage() {}
func (*CacheOpt) Descriptor() ([]byte, []int) { 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 { func (m *CacheOpt) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -766,7 +797,7 @@ func (m *SecretOpt) Reset() { *m = SecretOpt{} }
func (m *SecretOpt) String() string { return proto.CompactTextString(m) } func (m *SecretOpt) String() string { return proto.CompactTextString(m) }
func (*SecretOpt) ProtoMessage() {} func (*SecretOpt) ProtoMessage() {}
func (*SecretOpt) Descriptor() ([]byte, []int) { 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 { func (m *SecretOpt) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -845,7 +876,7 @@ func (m *SSHOpt) Reset() { *m = SSHOpt{} }
func (m *SSHOpt) String() string { return proto.CompactTextString(m) } func (m *SSHOpt) String() string { return proto.CompactTextString(m) }
func (*SSHOpt) ProtoMessage() {} func (*SSHOpt) ProtoMessage() {}
func (*SSHOpt) Descriptor() ([]byte, []int) { 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 { func (m *SSHOpt) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -918,7 +949,7 @@ func (m *SourceOp) Reset() { *m = SourceOp{} }
func (m *SourceOp) String() string { return proto.CompactTextString(m) } func (m *SourceOp) String() string { return proto.CompactTextString(m) }
func (*SourceOp) ProtoMessage() {} func (*SourceOp) ProtoMessage() {}
func (*SourceOp) Descriptor() ([]byte, []int) { 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 { func (m *SourceOp) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -970,7 +1001,7 @@ func (m *BuildOp) Reset() { *m = BuildOp{} }
func (m *BuildOp) String() string { return proto.CompactTextString(m) } func (m *BuildOp) String() string { return proto.CompactTextString(m) }
func (*BuildOp) ProtoMessage() {} func (*BuildOp) ProtoMessage() {}
func (*BuildOp) Descriptor() ([]byte, []int) { 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 { func (m *BuildOp) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1025,7 +1056,7 @@ func (m *BuildInput) Reset() { *m = BuildInput{} }
func (m *BuildInput) String() string { return proto.CompactTextString(m) } func (m *BuildInput) String() string { return proto.CompactTextString(m) }
func (*BuildInput) ProtoMessage() {} func (*BuildInput) ProtoMessage() {}
func (*BuildInput) Descriptor() ([]byte, []int) { 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 { func (m *BuildInput) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1066,7 +1097,7 @@ func (m *OpMetadata) Reset() { *m = OpMetadata{} }
func (m *OpMetadata) String() string { return proto.CompactTextString(m) } func (m *OpMetadata) String() string { return proto.CompactTextString(m) }
func (*OpMetadata) ProtoMessage() {} func (*OpMetadata) ProtoMessage() {}
func (*OpMetadata) Descriptor() ([]byte, []int) { 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 { func (m *OpMetadata) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1127,7 +1158,7 @@ func (m *ExportCache) Reset() { *m = ExportCache{} }
func (m *ExportCache) String() string { return proto.CompactTextString(m) } func (m *ExportCache) String() string { return proto.CompactTextString(m) }
func (*ExportCache) ProtoMessage() {} func (*ExportCache) ProtoMessage() {}
func (*ExportCache) Descriptor() ([]byte, []int) { 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 { func (m *ExportCache) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1170,7 +1201,7 @@ func (m *ProxyEnv) Reset() { *m = ProxyEnv{} }
func (m *ProxyEnv) String() string { return proto.CompactTextString(m) } func (m *ProxyEnv) String() string { return proto.CompactTextString(m) }
func (*ProxyEnv) ProtoMessage() {} func (*ProxyEnv) ProtoMessage() {}
func (*ProxyEnv) Descriptor() ([]byte, []int) { 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 { func (m *ProxyEnv) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1232,7 +1263,7 @@ func (m *WorkerConstraints) Reset() { *m = WorkerConstraints{} }
func (m *WorkerConstraints) String() string { return proto.CompactTextString(m) } func (m *WorkerConstraints) String() string { return proto.CompactTextString(m) }
func (*WorkerConstraints) ProtoMessage() {} func (*WorkerConstraints) ProtoMessage() {}
func (*WorkerConstraints) Descriptor() ([]byte, []int) { 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 { func (m *WorkerConstraints) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1277,7 +1308,7 @@ func (m *Definition) Reset() { *m = Definition{} }
func (m *Definition) String() string { return proto.CompactTextString(m) } func (m *Definition) String() string { return proto.CompactTextString(m) }
func (*Definition) ProtoMessage() {} func (*Definition) ProtoMessage() {}
func (*Definition) Descriptor() ([]byte, []int) { 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 { func (m *Definition) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1325,7 +1356,7 @@ func (m *HostIP) Reset() { *m = HostIP{} }
func (m *HostIP) String() string { return proto.CompactTextString(m) } func (m *HostIP) String() string { return proto.CompactTextString(m) }
func (*HostIP) ProtoMessage() {} func (*HostIP) ProtoMessage() {}
func (*HostIP) Descriptor() ([]byte, []int) { 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 { func (m *HostIP) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1372,7 +1403,7 @@ func (m *FileOp) Reset() { *m = FileOp{} }
func (m *FileOp) String() string { return proto.CompactTextString(m) } func (m *FileOp) String() string { return proto.CompactTextString(m) }
func (*FileOp) ProtoMessage() {} func (*FileOp) ProtoMessage() {}
func (*FileOp) Descriptor() ([]byte, []int) { 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 { func (m *FileOp) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1420,7 +1451,7 @@ func (m *FileAction) Reset() { *m = FileAction{} }
func (m *FileAction) String() string { return proto.CompactTextString(m) } func (m *FileAction) String() string { return proto.CompactTextString(m) }
func (*FileAction) ProtoMessage() {} func (*FileAction) ProtoMessage() {}
func (*FileAction) Descriptor() ([]byte, []int) { 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 { func (m *FileAction) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1645,7 +1676,7 @@ func (m *FileActionCopy) Reset() { *m = FileActionCopy{} }
func (m *FileActionCopy) String() string { return proto.CompactTextString(m) } func (m *FileActionCopy) String() string { return proto.CompactTextString(m) }
func (*FileActionCopy) ProtoMessage() {} func (*FileActionCopy) ProtoMessage() {}
func (*FileActionCopy) Descriptor() ([]byte, []int) { 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 { func (m *FileActionCopy) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1764,7 +1795,7 @@ func (m *FileActionMkFile) Reset() { *m = FileActionMkFile{} }
func (m *FileActionMkFile) String() string { return proto.CompactTextString(m) } func (m *FileActionMkFile) String() string { return proto.CompactTextString(m) }
func (*FileActionMkFile) ProtoMessage() {} func (*FileActionMkFile) ProtoMessage() {}
func (*FileActionMkFile) Descriptor() ([]byte, []int) { 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 { func (m *FileActionMkFile) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1841,7 +1872,7 @@ func (m *FileActionMkDir) Reset() { *m = FileActionMkDir{} }
func (m *FileActionMkDir) String() string { return proto.CompactTextString(m) } func (m *FileActionMkDir) String() string { return proto.CompactTextString(m) }
func (*FileActionMkDir) ProtoMessage() {} func (*FileActionMkDir) ProtoMessage() {}
func (*FileActionMkDir) Descriptor() ([]byte, []int) { 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 { func (m *FileActionMkDir) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1914,7 +1945,7 @@ func (m *FileActionRm) Reset() { *m = FileActionRm{} }
func (m *FileActionRm) String() string { return proto.CompactTextString(m) } func (m *FileActionRm) String() string { return proto.CompactTextString(m) }
func (*FileActionRm) ProtoMessage() {} func (*FileActionRm) ProtoMessage() {}
func (*FileActionRm) Descriptor() ([]byte, []int) { 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 { func (m *FileActionRm) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1969,7 +2000,7 @@ func (m *ChownOpt) Reset() { *m = ChownOpt{} }
func (m *ChownOpt) String() string { return proto.CompactTextString(m) } func (m *ChownOpt) String() string { return proto.CompactTextString(m) }
func (*ChownOpt) ProtoMessage() {} func (*ChownOpt) ProtoMessage() {}
func (*ChownOpt) Descriptor() ([]byte, []int) { 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 { func (m *ChownOpt) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2019,7 +2050,7 @@ func (m *UserOpt) Reset() { *m = UserOpt{} }
func (m *UserOpt) String() string { return proto.CompactTextString(m) } func (m *UserOpt) String() string { return proto.CompactTextString(m) }
func (*UserOpt) ProtoMessage() {} func (*UserOpt) ProtoMessage() {}
func (*UserOpt) Descriptor() ([]byte, []int) { 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 { func (m *UserOpt) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2159,7 +2190,7 @@ func (m *NamedUserOpt) Reset() { *m = NamedUserOpt{} }
func (m *NamedUserOpt) String() string { return proto.CompactTextString(m) } func (m *NamedUserOpt) String() string { return proto.CompactTextString(m) }
func (*NamedUserOpt) ProtoMessage() {} func (*NamedUserOpt) ProtoMessage() {}
func (*NamedUserOpt) Descriptor() ([]byte, []int) { 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 { func (m *NamedUserOpt) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2226,6 +2257,7 @@ func init() {
proto.RegisterType((*UserOpt)(nil), "pb.UserOpt") proto.RegisterType((*UserOpt)(nil), "pb.UserOpt")
proto.RegisterType((*NamedUserOpt)(nil), "pb.NamedUserOpt") proto.RegisterType((*NamedUserOpt)(nil), "pb.NamedUserOpt")
proto.RegisterEnum("pb.NetMode", NetMode_name, NetMode_value) 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.MountType", MountType_name, MountType_value)
proto.RegisterEnum("pb.CacheSharingOpt", CacheSharingOpt_name, CacheSharingOpt_value) proto.RegisterEnum("pb.CacheSharingOpt", CacheSharingOpt_name, CacheSharingOpt_value)
} }
@ -2470,6 +2502,11 @@ func (m *ExecOp) MarshalTo(dAtA []byte) (int, error) {
i++ i++
i = encodeVarintOps(dAtA, i, uint64(m.Network)) 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 return i, nil
} }
@ -3852,6 +3889,9 @@ func (m *ExecOp) Size() (n int) {
if m.Network != 0 { if m.Network != 0 {
n += 1 + sovOps(uint64(m.Network)) n += 1 + sovOps(uint64(m.Network))
} }
if m.Security != 0 {
n += 1 + sovOps(uint64(m.Security))
}
return n return n
} }
@ -5156,6 +5196,25 @@ func (m *ExecOp) Unmarshal(dAtA []byte) error {
break 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: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipOps(dAtA[iNdEx:]) skippy, err := skipOps(dAtA[iNdEx:])
@ -9171,129 +9230,132 @@ var (
ErrIntOverflowOps = fmt.Errorf("proto: integer overflow") 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{ var fileDescriptor_ops_0b9d2e829935306b = []byte{
// 1924 bytes of a gzipped FileDescriptorProto // 1978 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0x5f, 0x6f, 0x1b, 0xc7, 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, 0x11, 0xd7, 0x1d, 0xff, 0xde, 0x50, 0x92, 0xd9, 0x8d, 0x93, 0xb2, 0xaa, 0x2b, 0x29, 0x97, 0x34,
0x30, 0xb2, 0x4d, 0x01, 0x0a, 0x90, 0x04, 0x79, 0x28, 0x2a, 0xfe, 0x31, 0xc4, 0x24, 0x16, 0x85, 0x90, 0x65, 0x5b, 0x02, 0x14, 0x20, 0x09, 0xf2, 0x50, 0x54, 0xfc, 0x63, 0x88, 0x49, 0x2c, 0x0a,
0xa5, 0xed, 0x3c, 0x1a, 0xc7, 0xbb, 0x25, 0x75, 0x20, 0xef, 0xf6, 0xb0, 0xb7, 0xb4, 0xc4, 0x97, 0x4b, 0xdb, 0xe9, 0x9b, 0x71, 0xbc, 0x5b, 0x52, 0x07, 0xf2, 0x6e, 0x0f, 0x7b, 0x4b, 0x5b, 0x7c,
0x3e, 0xf8, 0x13, 0x04, 0x28, 0xd0, 0xb7, 0x3e, 0xf4, 0xa5, 0x40, 0x3f, 0x44, 0xdf, 0xf3, 0x18, 0xe9, 0x83, 0x3f, 0x41, 0x80, 0x02, 0x7d, 0x6b, 0x81, 0xbe, 0x14, 0xe8, 0x87, 0xe8, 0x7b, 0x1e,
0x14, 0x7d, 0x48, 0xfb, 0x90, 0x16, 0xf6, 0x17, 0x29, 0x66, 0x77, 0x8f, 0x77, 0xa4, 0x15, 0xd8, 0x83, 0xa2, 0x0f, 0x69, 0x1f, 0xd2, 0xc2, 0xfe, 0x22, 0xc5, 0xec, 0xee, 0xf1, 0x8e, 0xb4, 0x02,
0x46, 0x8b, 0x3e, 0x71, 0x76, 0xe6, 0xb7, 0xb3, 0xb3, 0x33, 0xb3, 0x33, 0x73, 0x04, 0x9b, 0xc7, 0xdb, 0x68, 0xd1, 0x27, 0xce, 0xcd, 0xfc, 0x76, 0x76, 0x76, 0x66, 0x76, 0x66, 0x96, 0xe0, 0xf0,
0x49, 0x3b, 0x16, 0x5c, 0x72, 0x62, 0xc5, 0xe3, 0xbd, 0xfb, 0xd3, 0x40, 0x5e, 0x2e, 0xc6, 0x6d, 0x24, 0x3d, 0x4a, 0x04, 0x97, 0x9c, 0xd8, 0xc9, 0x68, 0xe7, 0xde, 0x24, 0x94, 0x97, 0xf3, 0xd1,
0x8f, 0x87, 0xc7, 0x53, 0x3e, 0xe5, 0xc7, 0x4a, 0x34, 0x5e, 0x4c, 0xd4, 0x4a, 0x2d, 0x14, 0xa5, 0x91, 0xcf, 0xa3, 0xe3, 0x09, 0x9f, 0xf0, 0x63, 0x25, 0x1a, 0xcd, 0xc7, 0xea, 0x4b, 0x7d, 0x28,
0xb7, 0x38, 0x7f, 0xb2, 0xc0, 0x1a, 0xc6, 0xe4, 0x7d, 0xa8, 0x04, 0x51, 0xbc, 0x90, 0x49, 0xb3, 0x4a, 0x2f, 0x71, 0xff, 0x64, 0x83, 0x3d, 0x48, 0xc8, 0xfb, 0x50, 0x0d, 0xe3, 0x64, 0x2e, 0xd3,
0x70, 0x58, 0x6c, 0xd5, 0x4f, 0xec, 0x76, 0x3c, 0x6e, 0x0f, 0x90, 0x43, 0x8d, 0x80, 0x1c, 0x42, 0x96, 0xb5, 0x5f, 0x3a, 0x68, 0x9c, 0x38, 0x47, 0xc9, 0xe8, 0xa8, 0x8f, 0x1c, 0x6a, 0x04, 0x64,
0x89, 0x5d, 0x33, 0xaf, 0x69, 0x1d, 0x16, 0x5a, 0xf5, 0x13, 0x40, 0x40, 0xff, 0x9a, 0x79, 0xc3, 0x1f, 0xca, 0xec, 0x8a, 0xf9, 0x2d, 0x7b, 0xdf, 0x3a, 0x68, 0x9c, 0x00, 0x02, 0x7a, 0x57, 0xcc,
0xf8, 0x6c, 0x8b, 0x2a, 0x09, 0xf9, 0x08, 0x2a, 0x09, 0x5f, 0x08, 0x8f, 0x35, 0x8b, 0x0a, 0xb3, 0x1f, 0x24, 0x67, 0x1b, 0x54, 0x49, 0xc8, 0x47, 0x50, 0x4d, 0xf9, 0x5c, 0xf8, 0xac, 0x55, 0x52,
0x8d, 0x98, 0x91, 0xe2, 0x28, 0x94, 0x91, 0xa2, 0xa6, 0x49, 0x30, 0x67, 0xcd, 0x52, 0xa6, 0xe9, 0x98, 0x4d, 0xc4, 0x0c, 0x15, 0x47, 0xa1, 0x8c, 0x14, 0x35, 0x8d, 0xc3, 0x19, 0x6b, 0x95, 0x73,
0x41, 0x30, 0xd7, 0x18, 0x25, 0x21, 0x1f, 0x40, 0x79, 0xbc, 0x08, 0xe6, 0x7e, 0xb3, 0xac, 0x20, 0x4d, 0xf7, 0xc3, 0x99, 0xc6, 0x28, 0x09, 0xf9, 0x00, 0x2a, 0xa3, 0x79, 0x38, 0x0b, 0x5a, 0x15,
0x75, 0x84, 0x74, 0x90, 0xa1, 0x30, 0x5a, 0x46, 0x5a, 0x50, 0x8b, 0xe7, 0xae, 0x9c, 0x70, 0x11, 0x05, 0x69, 0x20, 0xa4, 0x8d, 0x0c, 0x85, 0xd1, 0x32, 0x72, 0x00, 0xf5, 0x64, 0xe6, 0xc9, 0x31,
0x36, 0x21, 0x3b, 0xf0, 0xc2, 0xf0, 0xe8, 0x4a, 0x4a, 0x3e, 0x83, 0xba, 0xc7, 0xa3, 0x44, 0x0a, 0x17, 0x51, 0x0b, 0xf2, 0x0d, 0x2f, 0x0c, 0x8f, 0x2e, 0xa5, 0xe4, 0x53, 0x68, 0xf8, 0x3c, 0x4e,
0x37, 0x88, 0x64, 0xd2, 0xac, 0x2b, 0xf0, 0xbb, 0x08, 0xfe, 0x86, 0x8b, 0x19, 0x13, 0xdd, 0x4c, 0xa5, 0xf0, 0xc2, 0x58, 0xa6, 0xad, 0x86, 0x02, 0xbf, 0x8b, 0xe0, 0xaf, 0xb9, 0x98, 0x32, 0xd1,
0x48, 0xf3, 0xc8, 0x4e, 0x09, 0x2c, 0x1e, 0x3b, 0x7f, 0x28, 0x40, 0x2d, 0xd5, 0x4a, 0x1c, 0xd8, 0xc9, 0x85, 0xb4, 0x88, 0x6c, 0x97, 0xc1, 0xe6, 0x89, 0xfb, 0x7b, 0x0b, 0xea, 0x99, 0x56, 0xe2,
0x3e, 0x15, 0xde, 0x65, 0x20, 0x99, 0x27, 0x17, 0x82, 0x35, 0x0b, 0x87, 0x85, 0x96, 0x4d, 0xd7, 0xc2, 0xe6, 0xa9, 0xf0, 0x2f, 0x43, 0xc9, 0x7c, 0x39, 0x17, 0xac, 0x65, 0xed, 0x5b, 0x07, 0x0e,
0x78, 0x64, 0x17, 0xac, 0xe1, 0x48, 0x39, 0xca, 0xa6, 0xd6, 0x70, 0x44, 0x9a, 0x50, 0x7d, 0xe2, 0x5d, 0xe1, 0x91, 0x6d, 0xb0, 0x07, 0x43, 0xe5, 0x28, 0x87, 0xda, 0x83, 0x21, 0x69, 0x41, 0xed,
0x8a, 0xc0, 0x8d, 0xa4, 0xf2, 0x8c, 0x4d, 0xd3, 0x25, 0xb9, 0x03, 0xf6, 0x70, 0xf4, 0x84, 0x89, 0xb1, 0x27, 0x42, 0x2f, 0x96, 0xca, 0x33, 0x0e, 0xcd, 0x3e, 0xc9, 0x2d, 0x70, 0x06, 0xc3, 0xc7,
0x24, 0xe0, 0x91, 0xf2, 0x87, 0x4d, 0x33, 0x06, 0xd9, 0x07, 0x18, 0x8e, 0x1e, 0x30, 0x17, 0x95, 0x4c, 0xa4, 0x21, 0x8f, 0x95, 0x3f, 0x1c, 0x9a, 0x33, 0xc8, 0x2e, 0xc0, 0x60, 0x78, 0x9f, 0x79,
0x26, 0xcd, 0xf2, 0x61, 0xb1, 0x65, 0xd3, 0x1c, 0xc7, 0xf9, 0x1d, 0x94, 0x55, 0x8c, 0xc8, 0x97, 0xa8, 0x34, 0x6d, 0x55, 0xf6, 0x4b, 0x07, 0x0e, 0x2d, 0x70, 0xdc, 0xdf, 0x42, 0x45, 0xc5, 0x88,
0x50, 0xf1, 0x83, 0x29, 0x4b, 0xa4, 0x36, 0xa7, 0x73, 0xf2, 0xdd, 0x8f, 0x07, 0x5b, 0xff, 0xfc, 0x7c, 0x01, 0xd5, 0x20, 0x9c, 0xb0, 0x54, 0x6a, 0x73, 0xda, 0x27, 0xdf, 0xfe, 0xb0, 0xb7, 0xf1,
0xf1, 0xe0, 0x28, 0x97, 0x0c, 0x3c, 0x66, 0x91, 0xc7, 0x23, 0xe9, 0x06, 0x11, 0x13, 0xc9, 0xf1, 0xcf, 0x1f, 0xf6, 0x0e, 0x0b, 0xc9, 0xc0, 0x13, 0x16, 0xfb, 0x3c, 0x96, 0x5e, 0x18, 0x33, 0x91,
0x94, 0xdf, 0xd7, 0x5b, 0xda, 0x3d, 0xf5, 0x43, 0x8d, 0x06, 0xf2, 0x31, 0x94, 0x83, 0xc8, 0x67, 0x1e, 0x4f, 0xf8, 0x3d, 0xbd, 0xe4, 0xa8, 0xab, 0x7e, 0xa8, 0xd1, 0x40, 0x6e, 0x43, 0x25, 0x8c,
0xd7, 0xca, 0xfe, 0x62, 0xe7, 0x1d, 0xa3, 0xaa, 0x3e, 0x5c, 0xc8, 0x78, 0x21, 0x07, 0x28, 0xa2, 0x03, 0x76, 0xa5, 0xec, 0x2f, 0xb5, 0xdf, 0x31, 0xaa, 0x1a, 0x83, 0xb9, 0x4c, 0xe6, 0xb2, 0x8f,
0x1a, 0xe1, 0xc4, 0x50, 0xd1, 0x29, 0x40, 0xee, 0x40, 0x29, 0x64, 0xd2, 0x55, 0xc7, 0xd7, 0x4f, 0x22, 0xaa, 0x11, 0xee, 0x1f, 0x2d, 0xa8, 0xea, 0x1c, 0x20, 0xb7, 0xa0, 0x1c, 0x31, 0xe9, 0xa9,
0x6a, 0xe8, 0xda, 0x87, 0x4c, 0xba, 0x54, 0x71, 0x31, 0xbb, 0x42, 0xbe, 0x40, 0xd7, 0x5b, 0x59, 0xfd, 0x1b, 0x27, 0x75, 0xf4, 0xed, 0x03, 0x26, 0x3d, 0xaa, 0xb8, 0x98, 0x5e, 0x11, 0x9f, 0xa3,
0x76, 0x3d, 0x44, 0x0e, 0x35, 0x02, 0xf2, 0x6b, 0xa8, 0x46, 0x4c, 0x5e, 0x71, 0x31, 0x53, 0x2e, 0xef, 0xed, 0x3c, 0xbd, 0x1e, 0x20, 0x87, 0x1a, 0x01, 0xf9, 0x25, 0xd4, 0x62, 0x26, 0x9f, 0x71,
0xda, 0xd5, 0x31, 0x3f, 0x67, 0xf2, 0x21, 0xf7, 0x19, 0x4d, 0x65, 0xce, 0x5f, 0x0a, 0x50, 0x42, 0x31, 0x55, 0x3e, 0xda, 0xd6, 0x41, 0x3f, 0x67, 0xf2, 0x01, 0x0f, 0x18, 0xcd, 0x64, 0xe4, 0x2e,
0xc5, 0x84, 0x40, 0xc9, 0x15, 0x53, 0x9d, 0xae, 0x36, 0x55, 0x34, 0x69, 0x40, 0x91, 0x45, 0xcf, 0xd4, 0x53, 0xe6, 0xcf, 0x45, 0x28, 0x17, 0xca, 0x5f, 0xdb, 0x27, 0x4d, 0x95, 0x65, 0x86, 0xa7,
0xd4, 0x19, 0x36, 0x45, 0x12, 0x39, 0xde, 0x95, 0x6f, 0x9c, 0x8e, 0x24, 0xee, 0x5b, 0x24, 0x4c, 0xc0, 0x4b, 0x84, 0xfb, 0x17, 0x0b, 0xca, 0x68, 0x06, 0x21, 0x50, 0xf6, 0xc4, 0x44, 0x67, 0xb7,
0x18, 0x5f, 0x2b, 0x9a, 0x7c, 0x0c, 0x76, 0x2c, 0xf8, 0xf5, 0xf2, 0x29, 0xee, 0x2e, 0xe7, 0x32, 0x43, 0x15, 0x4d, 0x9a, 0x50, 0x62, 0xf1, 0x53, 0x65, 0x91, 0x43, 0x91, 0x44, 0x8e, 0xff, 0x2c,
0x09, 0x99, 0xfd, 0xe8, 0x19, 0xad, 0xc5, 0x86, 0x22, 0x47, 0x00, 0xec, 0x5a, 0x0a, 0xf7, 0x8c, 0x30, 0x31, 0x42, 0x12, 0xd7, 0xcd, 0x53, 0x26, 0x4c, 0x68, 0x14, 0x4d, 0x6e, 0x83, 0x93, 0x08,
0x27, 0x32, 0x69, 0x56, 0xd4, 0x6d, 0x54, 0x02, 0x23, 0x63, 0x70, 0x41, 0x73, 0x52, 0xe7, 0x6f, 0x7e, 0xb5, 0x78, 0x82, 0xab, 0x2b, 0x85, 0xc4, 0x43, 0x66, 0x2f, 0x7e, 0x4a, 0xeb, 0x89, 0xa1,
0x16, 0x94, 0xd5, 0x25, 0x49, 0x0b, 0x5d, 0x1a, 0x2f, 0x74, 0x74, 0x8a, 0x1d, 0x62, 0x5c, 0x0a, 0xc8, 0x21, 0x00, 0xbb, 0x92, 0xc2, 0x3b, 0xe3, 0xa9, 0x4c, 0x5b, 0x55, 0x75, 0x76, 0x95, 0xef,
0x2a, 0x78, 0x2b, 0x8f, 0x62, 0x20, 0xf7, 0xa0, 0x96, 0xb0, 0x39, 0xf3, 0x24, 0x17, 0x26, 0x7f, 0xc8, 0xe8, 0x5f, 0xd0, 0x82, 0xd4, 0xfd, 0x9b, 0x0d, 0x15, 0xe5, 0x12, 0x72, 0x80, 0x11, 0x48,
0x56, 0x6b, 0x34, 0xdd, 0xc7, 0x10, 0xeb, 0xdb, 0x28, 0x9a, 0xdc, 0x85, 0x0a, 0x57, 0x71, 0x51, 0xe6, 0x3a, 0x98, 0xa5, 0x36, 0x31, 0x11, 0x00, 0x15, 0xeb, 0x65, 0x00, 0x30, 0xee, 0x3b, 0xe8,
0x17, 0xfa, 0x89, 0x68, 0x19, 0x08, 0x2a, 0x17, 0xcc, 0xf5, 0x79, 0x34, 0x5f, 0xaa, 0x6b, 0xd6, 0x8d, 0x19, 0xf3, 0x25, 0x17, 0x26, 0xdd, 0x96, 0xdf, 0x68, 0x7a, 0x80, 0x19, 0xa1, 0x4f, 0xa3,
0xe8, 0x6a, 0x4d, 0xee, 0x82, 0xad, 0x22, 0xf1, 0x68, 0x19, 0xb3, 0x66, 0x45, 0x45, 0x60, 0x67, 0x68, 0x72, 0x07, 0xaa, 0x5c, 0x85, 0x51, 0x1d, 0xe8, 0x47, 0x82, 0x6b, 0x20, 0xa8, 0x5c, 0x30,
0x15, 0x25, 0x64, 0xd2, 0x4c, 0x8e, 0x2f, 0xcf, 0x73, 0xbd, 0x4b, 0x36, 0x8c, 0x65, 0xf3, 0x76, 0x2f, 0xe0, 0xf1, 0x6c, 0xa1, 0x8e, 0x59, 0xa7, 0xcb, 0x6f, 0x72, 0x07, 0x1c, 0x15, 0xb7, 0x87,
0xe6, 0xaf, 0xae, 0xe1, 0xd1, 0x95, 0x14, 0xd5, 0x26, 0xcc, 0x13, 0x4c, 0x22, 0xf4, 0x5d, 0x05, 0x8b, 0x84, 0xb5, 0xaa, 0x2a, 0x0e, 0x5b, 0xcb, 0x98, 0x22, 0x93, 0xe6, 0x72, 0xbc, 0xa8, 0xbe,
0x55, 0x6a, 0x47, 0x29, 0x93, 0x66, 0x72, 0xe2, 0x40, 0x65, 0x34, 0x3a, 0x43, 0xe4, 0x7b, 0x59, 0xe7, 0x5f, 0xb2, 0x41, 0x22, 0x5b, 0x37, 0x73, 0x7f, 0x75, 0x0c, 0x8f, 0x2e, 0xa5, 0xa8, 0x36,
0x65, 0xd0, 0x1c, 0x6a, 0x24, 0xce, 0x00, 0x6a, 0xe9, 0x31, 0xf8, 0xcc, 0x06, 0x3d, 0xf3, 0x00, 0x65, 0xbe, 0x60, 0x12, 0xa1, 0xef, 0x2a, 0xe8, 0x96, 0x09, 0xaf, 0x66, 0xd2, 0x5c, 0x4e, 0x5c,
0xad, 0x41, 0x8f, 0xdc, 0x87, 0x6a, 0x72, 0xe9, 0x8a, 0x20, 0x9a, 0x2a, 0xdf, 0xed, 0x9e, 0xbc, 0xa8, 0x0e, 0x87, 0x67, 0x88, 0x7c, 0x2f, 0x2f, 0x24, 0x9a, 0x43, 0x8d, 0xc4, 0xed, 0x43, 0x3d,
0xb3, 0xb2, 0x6a, 0xa4, 0xf9, 0xa8, 0x29, 0xc5, 0x38, 0x1c, 0xec, 0x95, 0x19, 0xaf, 0xe8, 0x6a, 0xdb, 0x06, 0x6f, 0x65, 0xbf, 0x6b, 0xee, 0xab, 0xdd, 0xef, 0x92, 0x7b, 0x50, 0x4b, 0x2f, 0x3d,
0x40, 0x71, 0x11, 0xf8, 0x4a, 0xcf, 0x0e, 0x45, 0x12, 0x39, 0xd3, 0x40, 0xe7, 0xd2, 0x0e, 0x45, 0x11, 0xc6, 0x13, 0xe5, 0xbb, 0xed, 0x93, 0x77, 0x96, 0x56, 0x0d, 0x35, 0x1f, 0x35, 0x65, 0x18,
0x12, 0x03, 0x12, 0x72, 0x5f, 0xd7, 0xb1, 0x1d, 0xaa, 0x68, 0xf4, 0x31, 0x8f, 0x65, 0xc0, 0x23, 0x97, 0x83, 0xb3, 0x34, 0xe3, 0x15, 0x5d, 0x4d, 0x28, 0xcd, 0xc3, 0x40, 0xe9, 0xd9, 0xa2, 0x48,
0x77, 0x9e, 0xfa, 0x38, 0x5d, 0x3b, 0xf3, 0xf4, 0x7e, 0xff, 0x97, 0xd3, 0x7e, 0x5f, 0x80, 0x5a, 0x22, 0x67, 0x12, 0xea, 0x5c, 0xda, 0xa2, 0x48, 0x62, 0x40, 0x22, 0x1e, 0xe8, 0xb2, 0xb7, 0x45,
0x5a, 0x7c, 0xb1, 0x92, 0x04, 0x3e, 0x8b, 0x64, 0x30, 0x09, 0x98, 0x30, 0x07, 0xe7, 0x38, 0xe4, 0x15, 0x8d, 0x3e, 0xe6, 0x89, 0x0c, 0x79, 0xec, 0xcd, 0x32, 0x1f, 0x67, 0xdf, 0xee, 0x2c, 0x3b,
0x3e, 0x94, 0x5d, 0x29, 0x45, 0xfa, 0x40, 0x7f, 0x9e, 0xaf, 0xdc, 0xed, 0x53, 0x94, 0xf4, 0x23, 0xdf, 0xff, 0x65, 0xb7, 0xdf, 0x59, 0x50, 0xcf, 0x6a, 0x35, 0x16, 0x9e, 0x30, 0x60, 0xb1, 0x0c,
0x29, 0x96, 0x54, 0xa3, 0xf6, 0x3e, 0x07, 0xc8, 0x98, 0x68, 0xeb, 0x8c, 0x2d, 0x8d, 0x56, 0x24, 0xc7, 0x21, 0x13, 0x66, 0xe3, 0x02, 0x87, 0xdc, 0x83, 0x8a, 0x27, 0xa5, 0xc8, 0xae, 0xf3, 0x4f,
0xc9, 0x6d, 0x28, 0x3f, 0x73, 0xe7, 0x0b, 0x66, 0x72, 0x58, 0x2f, 0xbe, 0xb0, 0x3e, 0x2f, 0x38, 0x8b, 0x85, 0xfe, 0xe8, 0x14, 0x25, 0xbd, 0x58, 0x8a, 0x05, 0xd5, 0xa8, 0x9d, 0xcf, 0x00, 0x72,
0x7f, 0xb5, 0xa0, 0x6a, 0x2a, 0x39, 0xb9, 0x07, 0x55, 0x55, 0xc9, 0x8d, 0x45, 0x37, 0x3f, 0x8c, 0x26, 0xda, 0x3a, 0x65, 0x0b, 0xa3, 0x15, 0x49, 0x72, 0x13, 0x2a, 0x4f, 0xbd, 0xd9, 0x9c, 0x99,
0x14, 0x42, 0x8e, 0x57, 0x2d, 0x2a, 0x67, 0xa3, 0x51, 0xa5, 0x5b, 0x95, 0xb1, 0x31, 0x6b, 0x58, 0x1c, 0xd6, 0x1f, 0x9f, 0xdb, 0x9f, 0x59, 0xee, 0x5f, 0x6d, 0xa8, 0x99, 0xc2, 0x4f, 0xee, 0x42,
0x45, 0x9f, 0x4d, 0x4c, 0x2f, 0xda, 0x45, 0x74, 0x8f, 0x4d, 0x82, 0x28, 0x40, 0xff, 0x50, 0x14, 0x4d, 0x15, 0x7e, 0x63, 0xd1, 0xf5, 0x17, 0x23, 0x83, 0x90, 0xe3, 0x65, 0x47, 0x2b, 0xd8, 0x68,
0x91, 0x7b, 0xe9, 0xad, 0x4b, 0x4a, 0xe3, 0x7b, 0x79, 0x8d, 0xaf, 0x5e, 0x7a, 0x00, 0xf5, 0xdc, 0x54, 0xe9, 0xce, 0x66, 0x6c, 0xcc, 0xfb, 0x5b, 0x29, 0x60, 0x63, 0xd3, 0xba, 0xb6, 0x11, 0xdd,
0x31, 0x37, 0xdc, 0xfa, 0xc3, 0xfc, 0xad, 0xcd, 0x91, 0x4a, 0x9d, 0x6e, 0xa4, 0x99, 0x17, 0xfe, 0x65, 0xe3, 0x30, 0x0e, 0xd1, 0x3f, 0x14, 0x45, 0xe4, 0x6e, 0x76, 0xea, 0xb2, 0xd2, 0xf8, 0x5e,
0x0b, 0xff, 0x7d, 0x0a, 0x90, 0xa9, 0x7c, 0xf3, 0xc2, 0xe2, 0x3c, 0x2f, 0x02, 0x0c, 0x63, 0x2c, 0x51, 0xe3, 0xab, 0x87, 0xee, 0x43, 0xa3, 0xb0, 0xcd, 0x35, 0xa7, 0xfe, 0xb0, 0x78, 0x6a, 0xb3,
0x9d, 0xbe, 0xab, 0x2a, 0xf2, 0x76, 0x30, 0x8d, 0xb8, 0x60, 0x4f, 0xd5, 0x53, 0x55, 0xfb, 0x6b, 0xa5, 0x52, 0xa7, 0xfb, 0x6e, 0xee, 0x85, 0xff, 0xc2, 0x7f, 0x9f, 0x00, 0xe4, 0x2a, 0xdf, 0xbc,
0xb4, 0xae, 0x79, 0xea, 0xc5, 0x90, 0x53, 0xa8, 0xfb, 0x2c, 0xf1, 0x44, 0xa0, 0x12, 0xca, 0x38, 0xb0, 0xb8, 0xcf, 0x4b, 0x00, 0x83, 0x04, 0x4b, 0x67, 0xe0, 0xa9, 0xfa, 0xbd, 0x19, 0x4e, 0x62,
0xfd, 0x00, 0xef, 0x94, 0xe9, 0x69, 0xf7, 0x32, 0x84, 0xf6, 0x55, 0x7e, 0x0f, 0x39, 0x81, 0x6d, 0x2e, 0xd8, 0x13, 0x75, 0x55, 0xd5, 0xfa, 0x3a, 0x6d, 0x68, 0x9e, 0xba, 0x31, 0xe4, 0x14, 0x1a,
0x76, 0x1d, 0x73, 0x21, 0xcd, 0x29, 0xba, 0xe1, 0xdf, 0xd2, 0xa3, 0x03, 0xf2, 0xd5, 0x49, 0xb4, 0x01, 0x4b, 0x7d, 0x11, 0xaa, 0x84, 0x32, 0x4e, 0xdf, 0xc3, 0x33, 0xe5, 0x7a, 0x8e, 0xba, 0x39,
0xce, 0xb2, 0x05, 0x71, 0xa1, 0xe4, 0xb9, 0xb1, 0xee, 0x76, 0xf5, 0x93, 0xe6, 0xc6, 0x79, 0x5d, 0x42, 0xfb, 0xaa, 0xb8, 0x86, 0x9c, 0xc0, 0x26, 0xbb, 0x4a, 0xb8, 0x90, 0x66, 0x17, 0x3d, 0x1f,
0x37, 0xd6, 0x4e, 0xeb, 0x7c, 0x82, 0x77, 0x7d, 0xfe, 0xaf, 0x83, 0xbb, 0xb9, 0x16, 0x17, 0xf2, 0xdc, 0xd0, 0x93, 0x06, 0xf2, 0xd5, 0x4e, 0xb4, 0xc1, 0xf2, 0x0f, 0xe2, 0x41, 0xd9, 0xf7, 0x12,
0xf1, 0xf2, 0x58, 0xe5, 0xcb, 0x2c, 0x90, 0xc7, 0x0b, 0x19, 0xcc, 0x8f, 0xdd, 0x38, 0x40, 0x75, 0xdd, 0x1c, 0x1b, 0x27, 0xad, 0xb5, 0xfd, 0x3a, 0x5e, 0xa2, 0x9d, 0xd6, 0xfe, 0x18, 0xcf, 0xfa,
0xb8, 0x71, 0xd0, 0xa3, 0x4a, 0xf5, 0xde, 0x6f, 0xa0, 0xb1, 0x69, 0xf7, 0xdb, 0xc4, 0x60, 0xef, 0xfc, 0x5f, 0x7b, 0x77, 0x0a, 0x1d, 0x31, 0xe2, 0xa3, 0xc5, 0xb1, 0xca, 0x97, 0x69, 0x28, 0x8f,
0x33, 0xb0, 0x57, 0x76, 0xbc, 0x6e, 0x63, 0x2d, 0x1f, 0xbc, 0x0f, 0xa0, 0x9e, 0xbb, 0x37, 0x02, 0xe7, 0x32, 0x9c, 0x1d, 0x7b, 0x49, 0x88, 0xea, 0x70, 0x61, 0xbf, 0x4b, 0x95, 0xea, 0x9d, 0x5f,
0x9f, 0x28, 0xa0, 0xf6, 0xbe, 0x5e, 0x38, 0xcf, 0x71, 0xda, 0x48, 0xfb, 0xcd, 0xaf, 0x00, 0x2e, 0x41, 0x73, 0xdd, 0xee, 0xb7, 0x89, 0xc1, 0xce, 0xa7, 0xe0, 0x2c, 0xed, 0x78, 0xdd, 0xc2, 0x7a,
0xa5, 0x8c, 0x9f, 0xaa, 0x06, 0x64, 0x0e, 0xb1, 0x91, 0xa3, 0x10, 0xe4, 0x00, 0xea, 0xb8, 0x48, 0x31, 0x78, 0x1f, 0x40, 0xa3, 0x70, 0x6e, 0x04, 0x3e, 0x56, 0x40, 0xed, 0x7d, 0xfd, 0xe1, 0x3e,
0x8c, 0x5c, 0x5b, 0xaa, 0x76, 0x24, 0x1a, 0xf0, 0x4b, 0xb0, 0x27, 0xab, 0xed, 0xba, 0x71, 0xd4, 0xc7, 0xe1, 0x24, 0xeb, 0x37, 0xbf, 0x00, 0xb8, 0x94, 0x32, 0x79, 0xa2, 0x1a, 0x90, 0xd9, 0xc4,
0x26, 0xe9, 0xee, 0x5f, 0x40, 0x2d, 0xe2, 0x46, 0xa6, 0xfb, 0x61, 0x35, 0xe2, 0x4a, 0xe4, 0xdc, 0x41, 0x8e, 0x42, 0x90, 0x3d, 0x68, 0xe0, 0x47, 0x6a, 0xe4, 0xda, 0x52, 0xb5, 0x22, 0xd5, 0x80,
0x85, 0x9f, 0xbd, 0x32, 0x1a, 0x91, 0xf7, 0xa0, 0x32, 0x09, 0xe6, 0x52, 0x3d, 0x57, 0x6c, 0xb1, 0x9f, 0x83, 0x33, 0x5e, 0x2e, 0xd7, 0x8d, 0xa3, 0x3e, 0xce, 0x56, 0xff, 0x0c, 0xea, 0x31, 0x37,
0x66, 0xe5, 0xfc, 0xa3, 0x00, 0x90, 0x3d, 0x2d, 0xf4, 0x08, 0xbe, 0x3b, 0xc4, 0x6c, 0xeb, 0x77, 0x32, 0xdd, 0x0f, 0x6b, 0x31, 0x57, 0x22, 0xf7, 0x0e, 0xfc, 0xe4, 0x95, 0x49, 0x8a, 0xbc, 0x07,
0x36, 0x87, 0x5a, 0x68, 0x22, 0x68, 0xf2, 0xe8, 0xce, 0xfa, 0x73, 0x6c, 0xa7, 0x01, 0xd6, 0xb1, 0xd5, 0x71, 0x38, 0x93, 0xea, 0xba, 0x62, 0x8b, 0x35, 0x5f, 0xee, 0x3f, 0x2c, 0x80, 0xfc, 0x6a,
0x3d, 0x31, 0xb1, 0x7d, 0x9b, 0xf1, 0x65, 0x75, 0xc2, 0xde, 0x57, 0xb0, 0xb3, 0xa6, 0xee, 0x0d, 0xa1, 0x47, 0xf0, 0xde, 0x21, 0x66, 0x53, 0xdf, 0xb3, 0x19, 0xd4, 0x23, 0x13, 0x41, 0x93, 0x47,
0x5f, 0x6a, 0x96, 0x65, 0xf9, 0x90, 0xdd, 0x83, 0x8a, 0x6e, 0xed, 0x58, 0x7f, 0x91, 0x32, 0x6a, 0xb7, 0x56, 0xaf, 0xe3, 0x51, 0x16, 0x60, 0x1d, 0xdb, 0x13, 0x13, 0xdb, 0xb7, 0x99, 0x76, 0x96,
0x14, 0xad, 0xea, 0xf8, 0x45, 0x3a, 0xe8, 0x0d, 0x2e, 0x9c, 0x13, 0xa8, 0xe8, 0x49, 0x96, 0xb4, 0x3b, 0xec, 0x7c, 0x09, 0x5b, 0x2b, 0xea, 0xde, 0xf0, 0xa6, 0xe6, 0x59, 0x56, 0x0c, 0xd9, 0x5d,
0xa0, 0xea, 0x7a, 0x78, 0xb5, 0xb4, 0x5c, 0xed, 0xa6, 0x63, 0xee, 0xa9, 0x62, 0xd3, 0x54, 0xec, 0xa8, 0xea, 0xd6, 0x8e, 0xf5, 0x17, 0x29, 0xa3, 0x46, 0xd1, 0xaa, 0x8e, 0x5f, 0x64, 0x73, 0x61,
0xfc, 0xdd, 0x02, 0xc8, 0xf8, 0x6f, 0x31, 0x2b, 0x7c, 0x01, 0xbb, 0x09, 0xf3, 0x78, 0xe4, 0xbb, 0xff, 0xc2, 0x3d, 0x81, 0xaa, 0x1e, 0x7c, 0xc9, 0x01, 0xd4, 0x3c, 0x1f, 0x8f, 0x96, 0x95, 0xab,
0x62, 0xa9, 0xa4, 0x66, 0x62, 0xbb, 0x69, 0xcb, 0x06, 0x32, 0x37, 0x37, 0x14, 0x5f, 0x3f, 0x37, 0xed, 0x6c, 0x2a, 0x3e, 0x55, 0x6c, 0x9a, 0x89, 0xdd, 0xbf, 0xdb, 0x00, 0x39, 0xff, 0x2d, 0x66,
0xb4, 0xa0, 0xe4, 0xf1, 0x78, 0x69, 0x9e, 0x2f, 0x59, 0xbf, 0x48, 0x97, 0xc7, 0x4b, 0x9c, 0xdb, 0x85, 0xcf, 0x61, 0x3b, 0x65, 0x3e, 0x8f, 0x03, 0x4f, 0x2c, 0x94, 0xd4, 0x0c, 0x78, 0xd7, 0x2d,
0x11, 0x41, 0xda, 0x50, 0x09, 0x67, 0x6a, 0xb6, 0xd7, 0x63, 0xd4, 0xed, 0x75, 0xec, 0xc3, 0x19, 0x59, 0x43, 0x16, 0xe6, 0x86, 0xd2, 0xeb, 0xe7, 0x86, 0x03, 0x28, 0xfb, 0x3c, 0x59, 0x98, 0xeb,
0xd2, 0xf8, 0x25, 0xa0, 0x51, 0xe4, 0x2e, 0x94, 0xc3, 0x99, 0x1f, 0x08, 0x35, 0x71, 0xd4, 0x75, 0x4b, 0x56, 0x0f, 0xd2, 0xe1, 0xc9, 0x02, 0xc7, 0x7c, 0x44, 0x90, 0x23, 0xa8, 0x46, 0x53, 0xf5,
0xbf, 0xce, 0xc3, 0x7b, 0x81, 0xc0, 0x79, 0x5f, 0x61, 0x88, 0x03, 0x96, 0x08, 0x9b, 0x55, 0x85, 0x14, 0xd0, 0x63, 0xd4, 0xcd, 0x55, 0xec, 0x83, 0x29, 0xd2, 0xf8, 0x70, 0xd0, 0x28, 0x72, 0x07,
0x6c, 0x6c, 0x78, 0x33, 0x3c, 0xdb, 0xa2, 0x96, 0x08, 0x3b, 0x35, 0xa8, 0x68, 0xbf, 0x3a, 0x7f, 0x2a, 0xd1, 0x34, 0x08, 0x85, 0x9a, 0x38, 0x1a, 0xba, 0x5f, 0x17, 0xe1, 0xdd, 0x50, 0xe0, 0xf3,
0x2e, 0xc2, 0xee, 0xba, 0x95, 0x98, 0x07, 0x89, 0xf0, 0xd2, 0x3c, 0x48, 0x84, 0xb7, 0x1a, 0xa9, 0x40, 0x61, 0x88, 0x0b, 0xb6, 0x88, 0x5a, 0x35, 0x85, 0x6c, 0xae, 0x79, 0x33, 0x3a, 0xdb, 0xa0,
0xac, 0xdc, 0x48, 0xe5, 0x40, 0x99, 0x5f, 0x45, 0x4c, 0xe4, 0x3f, 0x62, 0xba, 0x97, 0xfc, 0x2a, 0xb6, 0x88, 0xda, 0x75, 0xa8, 0x6a, 0xbf, 0xba, 0x7f, 0x2e, 0xc1, 0xf6, 0xaa, 0x95, 0x98, 0x07,
0xc2, 0xe1, 0x41, 0x8b, 0xd6, 0x7a, 0x71, 0xd9, 0xf4, 0xe2, 0x0f, 0x61, 0x67, 0xc2, 0xe7, 0x73, 0xa9, 0xf0, 0xb3, 0x3c, 0x48, 0x85, 0xbf, 0x1c, 0xa9, 0xec, 0xc2, 0x48, 0xe5, 0x42, 0x85, 0x3f,
0x7e, 0x35, 0x5a, 0x86, 0xf3, 0x20, 0x9a, 0x99, 0x86, 0xbc, 0xce, 0x24, 0x2d, 0xb8, 0xe5, 0x07, 0x8b, 0x99, 0x28, 0xbe, 0x79, 0x3a, 0x97, 0xfc, 0x59, 0x8c, 0xc3, 0x83, 0x16, 0xad, 0xf4, 0xe2,
0x02, 0xcd, 0xe9, 0xf2, 0x48, 0xb2, 0x48, 0x4d, 0x91, 0x88, 0xdb, 0x64, 0x93, 0x2f, 0xe1, 0xd0, 0x8a, 0xe9, 0xc5, 0x1f, 0xc2, 0xd6, 0x98, 0xcf, 0x66, 0xfc, 0xd9, 0x70, 0x11, 0xcd, 0xc2, 0x78,
0x95, 0x92, 0x85, 0xb1, 0x7c, 0x1c, 0xc5, 0xae, 0x37, 0xeb, 0x71, 0x4f, 0xbd, 0xc7, 0x30, 0x76, 0x6a, 0x1a, 0xf2, 0x2a, 0x93, 0x1c, 0xc0, 0x8d, 0x20, 0x14, 0x68, 0x4e, 0x87, 0xc7, 0x92, 0xc5,
0x65, 0x30, 0x0e, 0xe6, 0x81, 0x5c, 0x2a, 0x67, 0xd4, 0xe8, 0x6b, 0x71, 0xe4, 0x23, 0xd8, 0xf5, 0x6a, 0x8a, 0x44, 0xdc, 0x3a, 0x9b, 0x7c, 0x01, 0xfb, 0x9e, 0x94, 0x2c, 0x4a, 0xe4, 0xa3, 0x38,
0x04, 0x73, 0x25, 0xeb, 0xb1, 0x44, 0x5e, 0xb8, 0xf2, 0xb2, 0x59, 0x53, 0x3b, 0x37, 0xb8, 0x78, 0xf1, 0xfc, 0x69, 0x97, 0xfb, 0xea, 0x3e, 0x46, 0x89, 0x27, 0xc3, 0x51, 0x38, 0xc3, 0x81, 0xb9,
0x07, 0x17, 0xad, 0xfd, 0x26, 0x98, 0xfb, 0x9e, 0x2b, 0xfc, 0xa6, 0xad, 0xef, 0xb0, 0xc6, 0x24, 0xa6, 0x96, 0xbe, 0x16, 0x47, 0x3e, 0x82, 0x6d, 0x5f, 0x30, 0x4f, 0xb2, 0x2e, 0x4b, 0xe5, 0x85,
0x6d, 0x20, 0x8a, 0xd1, 0x0f, 0x63, 0xb9, 0x5c, 0x41, 0x41, 0x41, 0x6f, 0x90, 0xe0, 0x47, 0x8e, 0x27, 0x2f, 0x5b, 0x75, 0xb5, 0x72, 0x8d, 0x8b, 0x67, 0xf0, 0xd0, 0xda, 0xaf, 0xc3, 0x59, 0xe0,
0x0c, 0x42, 0x96, 0x48, 0x37, 0x8c, 0xd5, 0xc7, 0x57, 0x91, 0x66, 0x0c, 0xe7, 0xdb, 0x02, 0x34, 0x7b, 0x22, 0x68, 0x39, 0xfa, 0x0c, 0x2b, 0x4c, 0x72, 0x04, 0x44, 0x31, 0x7a, 0x51, 0x22, 0x17,
0x36, 0x53, 0x04, 0x1d, 0x1c, 0xa3, 0x99, 0xe6, 0xb1, 0x21, 0xbd, 0x72, 0xba, 0x95, 0x73, 0x3a, 0x4b, 0x28, 0x28, 0xe8, 0x35, 0x12, 0x7c, 0x13, 0xc9, 0x30, 0x62, 0xa9, 0xf4, 0xa2, 0x44, 0xbd,
0x06, 0x10, 0xab, 0x0a, 0xc6, 0x6a, 0x9b, 0x2a, 0x3a, 0x0b, 0x60, 0xe9, 0xa7, 0x03, 0xb8, 0x66, 0xd5, 0x4a, 0x34, 0x67, 0xb8, 0xdf, 0x58, 0xd0, 0x5c, 0x4f, 0x11, 0x74, 0x70, 0x82, 0x66, 0x9a,
0x52, 0x79, 0xd3, 0xa4, 0x3f, 0x16, 0xe0, 0xd6, 0x46, 0x1a, 0xbe, 0xb1, 0x45, 0x87, 0x50, 0x0f, 0xcb, 0x86, 0xf4, 0xd2, 0xe9, 0x76, 0xc1, 0xe9, 0x18, 0x40, 0xac, 0x2a, 0x18, 0xab, 0x4d, 0xaa,
0xdd, 0x19, 0xbb, 0x70, 0x85, 0x0a, 0x6e, 0x51, 0x37, 0xd6, 0x1c, 0xeb, 0x7f, 0x60, 0x5f, 0x04, 0xe8, 0x3c, 0x80, 0xe5, 0x1f, 0x0f, 0xe0, 0x8a, 0x49, 0x95, 0x75, 0x93, 0xfe, 0x60, 0xc1, 0x8d,
0xdb, 0xf9, 0xdc, 0xbf, 0xd1, 0xb6, 0x34, 0x94, 0xe7, 0x5c, 0x3e, 0xe0, 0x8b, 0xc8, 0x37, 0xdd, 0xb5, 0x34, 0x7c, 0x63, 0x8b, 0xf6, 0xa1, 0x11, 0x79, 0x53, 0x76, 0xe1, 0x09, 0x15, 0xdc, 0x92,
0x68, 0x9d, 0xf9, 0x6a, 0xc0, 0x8b, 0x37, 0x04, 0xdc, 0x39, 0x87, 0x5a, 0x6a, 0x20, 0x39, 0x30, 0x6e, 0xac, 0x05, 0xd6, 0xff, 0xc0, 0xbe, 0x18, 0x36, 0x8b, 0xb9, 0x7f, 0xad, 0x6d, 0x59, 0x28,
0x1f, 0x50, 0x85, 0xec, 0xcb, 0xfc, 0x71, 0xc2, 0x04, 0xda, 0xae, 0xbf, 0xa6, 0xde, 0x87, 0xf2, 0xcf, 0xb9, 0xbc, 0xcf, 0xe7, 0x71, 0x60, 0xba, 0xd1, 0x2a, 0xf3, 0xd5, 0x80, 0x97, 0xae, 0x09,
0x54, 0xf0, 0x45, 0x6c, 0x6a, 0xeb, 0x1a, 0x42, 0x4b, 0x9c, 0x11, 0x54, 0x0d, 0x87, 0x1c, 0x41, 0xb8, 0x7b, 0x0e, 0xf5, 0xcc, 0x40, 0xb2, 0x67, 0x1e, 0x50, 0x56, 0xfe, 0x90, 0x7f, 0x94, 0x32,
0x65, 0xbc, 0x3c, 0x77, 0x43, 0x66, 0x14, 0xaa, 0x87, 0x8d, 0x6b, 0xdf, 0x20, 0xb0, 0x5a, 0x68, 0x81, 0xb6, 0xeb, 0xd7, 0xd4, 0xfb, 0x50, 0x99, 0x08, 0x3e, 0x4f, 0x4c, 0x6d, 0x5d, 0x41, 0x68,
0x04, 0xb9, 0x0d, 0xa5, 0xf1, 0x72, 0xd0, 0xd3, 0x63, 0x32, 0xd6, 0x1c, 0x5c, 0x75, 0x2a, 0xda, 0x89, 0x3b, 0x84, 0x9a, 0xe1, 0x90, 0x43, 0xa8, 0x8e, 0x16, 0xe7, 0x5e, 0xc4, 0x8c, 0x42, 0x75,
0x20, 0xe7, 0x6b, 0xd8, 0xce, 0xef, 0x43, 0xa7, 0x44, 0xa9, 0x5e, 0x9b, 0x2a, 0x3a, 0x2b, 0xae, 0xb1, 0xf1, 0x3b, 0x30, 0x08, 0xac, 0x16, 0x1a, 0x41, 0x6e, 0x42, 0x79, 0xb4, 0xe8, 0x77, 0xf5,
0xd6, 0x6b, 0x8a, 0xeb, 0x51, 0x0b, 0xaa, 0xe6, 0xe3, 0x93, 0xd8, 0x50, 0x7e, 0x7c, 0x3e, 0xea, 0x98, 0x8c, 0x35, 0x07, 0xbf, 0xda, 0x55, 0x6d, 0x90, 0xfb, 0x15, 0x6c, 0x16, 0xd7, 0xa1, 0x53,
0x3f, 0x6a, 0x6c, 0x91, 0x1a, 0x94, 0xce, 0x86, 0xa3, 0x47, 0x8d, 0x02, 0x52, 0xe7, 0xc3, 0xf3, 0xe2, 0x4c, 0xaf, 0x43, 0x15, 0x9d, 0x17, 0x57, 0xfb, 0x35, 0xc5, 0xf5, 0xf0, 0x00, 0x6a, 0xe6,
0x7e, 0xc3, 0x3a, 0xfa, 0x2d, 0xd8, 0xab, 0x8f, 0x24, 0x64, 0x77, 0x06, 0xe7, 0xbd, 0xc6, 0x16, 0xa9, 0x4a, 0x1c, 0xa8, 0x3c, 0x3a, 0x1f, 0xf6, 0x1e, 0x36, 0x37, 0x48, 0x1d, 0xca, 0x67, 0x83,
0x01, 0xa8, 0x8c, 0xfa, 0x5d, 0xda, 0x47, 0x70, 0x15, 0x8a, 0xa3, 0xd1, 0x59, 0xc3, 0x42, 0x55, 0xe1, 0xc3, 0xa6, 0x85, 0xd4, 0xf9, 0xe0, 0xbc, 0xd7, 0xb4, 0x0f, 0x6f, 0xc3, 0x66, 0xf1, 0xb1,
0xdd, 0xd3, 0xee, 0x59, 0xbf, 0x51, 0x44, 0xf2, 0xd1, 0xc3, 0x8b, 0x07, 0xa3, 0x46, 0xe9, 0xe8, 0x4a, 0x1a, 0x50, 0x1b, 0x9e, 0x9e, 0x77, 0xdb, 0x83, 0xdf, 0x34, 0x37, 0xc8, 0x26, 0xd4, 0xfb,
0x53, 0xb8, 0xb5, 0xf1, 0x91, 0xa2, 0x76, 0x9f, 0x9d, 0xd2, 0x3e, 0x6a, 0xaa, 0x43, 0xf5, 0x82, 0xe7, 0xc3, 0x5e, 0xe7, 0x11, 0xed, 0x35, 0xad, 0xc3, 0x5f, 0x83, 0xb3, 0x7c, 0x4f, 0xa1, 0x86,
0x0e, 0x9e, 0x9c, 0x3e, 0xea, 0x37, 0x0a, 0x28, 0xf8, 0x7a, 0xd8, 0xfd, 0xaa, 0xdf, 0x6b, 0x58, 0x76, 0xff, 0xbc, 0xdb, 0xdc, 0x20, 0x00, 0xd5, 0x61, 0xaf, 0x43, 0x7b, 0xa8, 0xb7, 0x06, 0xa5,
0x9d, 0x3b, 0xdf, 0xbd, 0xd8, 0x2f, 0x7c, 0xff, 0x62, 0xbf, 0xf0, 0xc3, 0x8b, 0xfd, 0xc2, 0xbf, 0xe1, 0xf0, 0xac, 0x69, 0xe3, 0xae, 0x9d, 0xd3, 0xce, 0x59, 0xaf, 0x59, 0x42, 0xf2, 0xe1, 0x83,
0x5f, 0xec, 0x17, 0xbe, 0x7d, 0xb9, 0xbf, 0xf5, 0xfd, 0xcb, 0xfd, 0xad, 0x1f, 0x5e, 0xee, 0x6f, 0x8b, 0xfb, 0xc3, 0x66, 0xf9, 0xf0, 0x13, 0xb8, 0xb1, 0xf6, 0x9e, 0x51, 0xab, 0xcf, 0x4e, 0x69,
0x8d, 0x2b, 0xea, 0x0f, 0x9e, 0x4f, 0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, 0x9b, 0x24, 0xd0, 0xaa, 0x0f, 0x35, 0x35, 0xa0, 0x76, 0x41, 0xfb, 0x8f, 0x4f, 0x1f, 0xf6, 0x9a, 0x16, 0x0a, 0xbe, 0x1a,
0x20, 0x12, 0x00, 0x00, 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,
} }

View File

@ -44,6 +44,7 @@ message ExecOp {
Meta meta = 1; Meta meta = 1;
repeated Mount mounts = 2; repeated Mount mounts = 2;
NetMode network = 3; NetMode network = 3;
SecurityMode security = 4;
} }
// Meta is a set of arguments for ExecOp. // Meta is a set of arguments for ExecOp.
@ -64,6 +65,11 @@ enum NetMode {
NONE = 2; NONE = 2;
} }
enum SecurityMode {
SANDBOX = 0;
INSECURE = 1; // privileged mode
}
// Mount specifies how to mount an input Op as a filesystem. // Mount specifies how to mount an input Op as a filesystem.
message Mount { message Mount {
int64 input = 1 [(gogoproto.customtype) = "InputIndex", (gogoproto.nullable) = false]; int64 input = 1 [(gogoproto.customtype) = "InputIndex", (gogoproto.nullable) = false];

View File

@ -1,26 +1,19 @@
package entitlements package entitlements
import "github.com/pkg/errors" import (
"github.com/pkg/errors"
)
type Entitlement string type Entitlement string
const ( const (
EntitlementSecurityConfined Entitlement = "security.confined" EntitlementSecurityInsecure Entitlement = "security.insecure"
EntitlementSecurityUnconfined Entitlement = "security.unconfined" // unimplemented EntitlementNetworkHost Entitlement = "network.host"
EntitlementNetworkHost Entitlement = "network.host"
EntitlementNetworkNone Entitlement = "network.none"
) )
var all = map[Entitlement]struct{}{ var all = map[Entitlement]struct{}{
EntitlementSecurityConfined: {}, EntitlementSecurityInsecure: {},
EntitlementSecurityUnconfined: {}, EntitlementNetworkHost: {},
EntitlementNetworkHost: {},
EntitlementNetworkNone: {},
}
var defaults = map[Entitlement]struct{}{
EntitlementSecurityConfined: {},
EntitlementNetworkNone: {},
} }
func Parse(s string) (Entitlement, error) { func Parse(s string) (Entitlement, error) {
@ -56,9 +49,6 @@ func WhiteList(allowed, supported []Entitlement) (Set, error) {
m[e] = struct{}{} m[e] = struct{}{}
} }
for e := range defaults {
m[e] = struct{}{}
}
return Set(m), nil return Set(m), nil
} }

View File

@ -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
}
}

View File

@ -5,10 +5,14 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"os"
"sort"
"strconv"
"strings" "strings"
"time" "time"
"github.com/containerd/console" "github.com/containerd/console"
"github.com/jaguilar/vt100"
"github.com/moby/buildkit/client" "github.com/moby/buildkit/client"
"github.com/morikuni/aec" "github.com/morikuni/aec"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
@ -27,14 +31,26 @@ func DisplaySolveStatus(ctx context.Context, phase string, c console.Console, w
disp.phase = "Building" 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 var done bool
ticker := time.NewTicker(100 * time.Millisecond) ticker := time.NewTicker(tickerTimeout)
defer ticker.Stop() 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 { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -42,34 +58,43 @@ func DisplaySolveStatus(ctx context.Context, phase string, c console.Console, w
case <-ticker.C: case <-ticker.C:
case ss, ok := <-ch: case ss, ok := <-ch:
if ok { if ok {
t.update(ss) t.update(ss, width)
} else { } else {
done = true done = true
} }
} }
if modeConsole { if modeConsole {
width, height = disp.getSize()
if done { if done {
disp.print(t.displayInfo(), true) disp.print(t.displayInfo(), width, height, true)
t.printErrorLogs(c) t.printErrorLogs(c)
return nil return nil
} else if displayLimiter.Allow() { } else if displayLimiter.Allow() {
disp.print(t.displayInfo(), false) ticker.Stop()
ticker = time.NewTicker(tickerTimeout)
disp.print(t.displayInfo(), width, height, false)
} }
} else { } else {
if done || displayLimiter.Allow() { if done || displayLimiter.Allow() {
printer.print(t) printer.print(t)
if done { if done {
t.printErrorLogs(w)
return nil return nil
} }
ticker.Stop()
ticker = time.NewTicker(tickerTimeout)
} }
} }
} }
} }
const termHeight = 6
const termPad = 10
type displayInfo struct { type displayInfo struct {
startTime time.Time startTime time.Time
jobs []job jobs []*job
countTotal int countTotal int
countCompleted int countCompleted int
} }
@ -81,6 +106,8 @@ type job struct {
status string status string
hasError bool hasError bool
isCanceled bool isCanceled bool
vertex *vertex
showTerm bool
} }
type trace struct { type trace struct {
@ -90,6 +117,7 @@ type trace struct {
byDigest map[digest.Digest]*vertex byDigest map[digest.Digest]*vertex
nextIndex int nextIndex int
updates map[digest.Digest]struct{} updates map[digest.Digest]struct{}
modeConsole bool
} }
type vertex struct { type vertex struct {
@ -107,6 +135,13 @@ type vertex struct {
lastBlockTime *time.Time lastBlockTime *time.Time
count int count int
statusUpdates map[string]struct{} statusUpdates map[string]struct{}
jobs []*job
jobCached bool
term *vt100.VT100
termBytes int
termCount int
} }
func (v *vertex) update(c int) { func (v *vertex) update(c int) {
@ -121,11 +156,12 @@ type status struct {
*client.VertexStatus *client.VertexStatus
} }
func newTrace(w io.Writer) *trace { func newTrace(w io.Writer, modeConsole bool) *trace {
return &trace{ return &trace{
byDigest: make(map[digest.Digest]*vertex), byDigest: make(map[digest.Digest]*vertex),
updates: make(map[digest.Digest]struct{}), updates: make(map[digest.Digest]struct{}),
w: w, w: w,
modeConsole: modeConsole,
} }
} }
@ -140,41 +176,37 @@ func (t *trace) triggerVertexEvent(v *client.Vertex) {
old = *v old = *v
} }
var ev []string changed := false
if v.Digest != old.Digest { if v.Digest != old.Digest {
ev = append(ev, fmt.Sprintf("%13s %s", "digest:", v.Digest)) changed = true
} }
if v.Name != old.Name { 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 != old.Started {
if v.Started != nil && old.Started == nil || !v.Started.Equal(*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 { if v.Completed != old.Completed && v.Completed != nil {
ev = append(ev, fmt.Sprintf("%13s %v", "completed:", v.Completed)) changed = true
if v.Started != nil {
ev = append(ev, fmt.Sprintf("%13s %v", "duration:", v.Completed.Sub(*v.Started)))
}
} }
if v.Cached != old.Cached { if v.Cached != old.Cached {
ev = append(ev, fmt.Sprintf("%13s %v", "cached:", v.Cached)) changed = true
} }
if v.Error != old.Error { if v.Error != old.Error {
ev = append(ev, fmt.Sprintf("%13s %q", "error:", v.Error)) changed = true
} }
if len(ev) > 0 { if changed {
vtx.events = append(vtx.events, ev...) vtx.update(1)
vtx.update(len(ev))
t.updates[v.Digest] = struct{}{} t.updates[v.Digest] = struct{}{}
} }
t.byDigest[v.Digest].prev = v 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 { for _, v := range s.Vertexes {
prev, ok := t.byDigest[v.Digest] prev, ok := t.byDigest[v.Digest]
if !ok { if !ok {
@ -184,6 +216,9 @@ func (t *trace) update(s *client.SolveStatus) {
statusUpdates: make(map[string]struct{}), statusUpdates: make(map[string]struct{}),
index: t.nextIndex, index: t.nextIndex,
} }
if t.modeConsole {
t.byDigest[v.Digest].term = vt100.NewVT100(termHeight, termWidth-termPad)
}
} }
t.triggerVertexEvent(v) t.triggerVertexEvent(v)
if v.Started != nil && (prev == nil || prev.Started == nil) { 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.vertexes = append(t.vertexes, t.byDigest[v.Digest])
} }
t.byDigest[v.Digest].Vertex = v t.byDigest[v.Digest].Vertex = v
t.byDigest[v.Digest].jobCached = false
} }
for _, s := range s.Statuses { for _, s := range s.Statuses {
v, ok := t.byDigest[s.Vertex] v, ok := t.byDigest[s.Vertex]
if !ok { if !ok {
continue // shouldn't happen continue // shouldn't happen
} }
v.jobCached = false
prev, ok := v.byID[s.ID] prev, ok := v.byID[s.ID]
if !ok { if !ok {
v.byID[s.ID] = &status{VertexStatus: s} v.byID[s.ID] = &status{VertexStatus: s}
@ -216,6 +253,14 @@ func (t *trace) update(s *client.SolveStatus) {
if !ok { if !ok {
continue // shouldn't happen 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 i := 0
complete := split(l.Data, byte('\n'), func(dt []byte) { complete := split(l.Data, byte('\n'), func(dt []byte) {
if v.logsPartial && len(v.logs) != 0 && i == 0 { if v.logsPartial && len(v.logs) != 0 && i == 0 {
@ -262,10 +307,16 @@ func (t *trace) displayInfo() (d displayInfo) {
} }
for _, v := range t.vertexes { 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), startTime: addTime(v.Started, t.localTimeDiff),
completedTime: addTime(v.Completed, t.localTimeDiff), completedTime: addTime(v.Completed, t.localTimeDiff),
name: strings.Replace(v.Name, "\t", " ", -1), name: strings.Replace(v.Name, "\t", " ", -1),
vertex: v,
} }
if v.Error != "" { if v.Error != "" {
if strings.HasSuffix(v.Error, context.Canceled.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 = "CACHED " + j.name
} }
j.name = v.indent + j.name j.name = v.indent + j.name
d.jobs = append(d.jobs, j) jobs = append(jobs, j)
for _, s := range v.statuses { for _, s := range v.statuses {
j := job{ j := &job{
startTime: addTime(s.Started, t.localTimeDiff), startTime: addTime(s.Started, t.localTimeDiff),
completedTime: addTime(s.Completed, t.localTimeDiff), completedTime: addTime(s.Completed, t.localTimeDiff),
name: v.indent + "=> " + s.ID, name: v.indent + "=> " + s.ID,
@ -292,8 +343,11 @@ func (t *trace) displayInfo() (d displayInfo) {
} else if s.Current != 0 { } else if s.Current != 0 {
j.status = fmt.Sprintf("%.2f", units.Bytes(s.Current)) 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 return d
@ -332,20 +386,56 @@ type display struct {
repeated bool repeated bool
} }
func (disp *display) print(d displayInfo, all bool) { func (disp *display) getSize() (int, int) {
// this output is inspired by Buck
width := 80 width := 80
height := 10 height := 10
size, err := disp.c.Size() if disp.c != nil {
if err == nil && size.Width > 0 && size.Height > 0 { size, err := disp.c.Size()
width = int(size.Width) if err == nil && size.Width > 0 && size.Height > 0 {
height = int(size.Height) 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 { 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 b := aec.EmptyBuilder
for i := 0; i <= disp.lineCount; i++ { for i := 0; i <= disp.lineCount; i++ {
b = b.Up(1) 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 if left < 12 { // too small screen to show progress
continue continue
} }
if len(j.name) > left { name := j.name
j.name = j.name[:left] if len(name) > left {
name = name[:left]
} }
out := pfx + j.name out := pfx + name
if showStatus { if showStatus {
out += " " + status out += " " + status
} }
@ -416,17 +507,68 @@ func (disp *display) print(d displayInfo, all bool) {
} }
fmt.Fprint(disp.c, out) fmt.Fprint(disp.c, out)
lineCount++ 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 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 { func align(l, r string, w int) string {
return fmt.Sprintf("%-[2]*[1]s %[3]s", l, w-len(r)-1, r) 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 { 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
} }

View File

@ -1,8 +1,12 @@
package progressui package progressui
import ( import (
"context"
"fmt" "fmt"
"io" "io"
"os"
"sort"
"strings"
"time" "time"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
@ -20,9 +24,10 @@ type lastStatus struct {
} }
type textMux struct { type textMux struct {
w io.Writer w io.Writer
current digest.Digest current digest.Digest
last map[string]lastStatus last map[string]lastStatus
notFirst bool
} }
func (p *textMux) printVtx(t *trace, dgst digest.Digest) { 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.logsOffset = 0
old.count = 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 { if len(v.events) != 0 {
@ -127,18 +144,46 @@ func (p *textMux) printVtx(t *trace, dgst digest.Digest) {
} }
p.current = dgst p.current = dgst
if v.Completed != nil { if v.Completed != nil {
p.current = "" p.current = ""
v.count = 0 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) 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{}{} completed := map[digest.Digest]struct{}{}
rest := map[digest.Digest]struct{}{} rest := map[digest.Digest]struct{}{}
@ -161,7 +206,7 @@ func (p *textMux) print(t *trace) {
p.printVtx(t, current) p.printVtx(t, current)
} }
for dgst := range completed { for _, dgst := range sortCompleted(t, completed) {
if dgst != current { if dgst != current {
p.printVtx(t, dgst) p.printVtx(t, dgst)
} }

View File

@ -3,9 +3,11 @@ package fsutil
import ( import (
"context" "context"
"io" "io"
"io/ioutil"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"sort"
"strings" "strings"
"github.com/pkg/errors" "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)) return os.Open(filepath.Join(fs.root, p))
} }
func SubDirFS(fs FS, stat types.Stat) FS { type Dir struct {
return &subDirFS{fs: fs, stat: stat} 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 { type subDirFS struct {
fs FS m map[string]Dir
stat types.Stat dirs []Dir
} }
func (fs *subDirFS) Walk(ctx context.Context, fn filepath.WalkFunc) error { func (fs *subDirFS) Walk(ctx context.Context, fn filepath.WalkFunc) error {
main := &StatInfo{Stat: &fs.stat} for _, d := range fs.dirs {
if !main.IsDir() { fi := &StatInfo{Stat: &d.Stat}
return errors.Errorf("fs subdir not mode directory") if !fi.IsDir() {
} return errors.Errorf("fs subdir %s not mode directory", d.Stat.Path)
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)
} }
stat.Path = path.Join(fs.stat.Path, stat.Path) if err := fn(d.Stat.Path, fi, nil); err != nil {
return fn(filepath.Join(fs.stat.Path, p), &StatInfo{stat}, 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) { 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
} }

72
vendor/github.com/tonistiigi/fsutil/tarwriter.go generated vendored Normal file
View File

@ -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()
}

18
vendor/modules.txt vendored
View File

@ -37,12 +37,15 @@ github.com/containerd/containerd/sys
github.com/containerd/containerd/api/services/content/v1 github.com/containerd/containerd/api/services/content/v1
github.com/containerd/containerd/content/proxy github.com/containerd/containerd/content/proxy
github.com/containerd/containerd/services/content/contentserver github.com/containerd/containerd/services/content/contentserver
github.com/containerd/containerd
github.com/containerd/containerd/containers github.com/containerd/containerd/containers
github.com/containerd/containerd/oci
github.com/containerd/containerd
github.com/containerd/containerd/images github.com/containerd/containerd/images
github.com/containerd/containerd/namespaces github.com/containerd/containerd/namespaces
github.com/containerd/containerd/remotes github.com/containerd/containerd/remotes
github.com/containerd/containerd/remotes/docker 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/containers/v1
github.com/containerd/containerd/api/services/diff/v1 github.com/containerd/containerd/api/services/diff/v1
github.com/containerd/containerd/api/services/events/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/images/oci
github.com/containerd/containerd/leases github.com/containerd/containerd/leases
github.com/containerd/containerd/leases/proxy 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/pkg/dialer
github.com/containerd/containerd/plugin github.com/containerd/containerd/plugin
github.com/containerd/containerd/remotes/docker/schema1 github.com/containerd/containerd/remotes/docker/schema1
github.com/containerd/containerd/rootfs github.com/containerd/containerd/rootfs
github.com/containerd/containerd/runtime/linux/runctypes github.com/containerd/containerd/runtime/linux/runctypes
github.com/containerd/containerd/runtime/v2/runc/options github.com/containerd/containerd/runtime/v2/runc/options
github.com/containerd/containerd/snapshots
github.com/containerd/containerd/snapshots/proxy github.com/containerd/containerd/snapshots/proxy
github.com/containerd/containerd/labels github.com/containerd/containerd/labels
github.com/containerd/containerd/reference github.com/containerd/containerd/reference
@ -87,8 +87,8 @@ github.com/containerd/continuity/devices
github.com/containerd/continuity/driver github.com/containerd/continuity/driver
github.com/containerd/continuity/proto github.com/containerd/continuity/proto
github.com/containerd/continuity/sysx github.com/containerd/continuity/sysx
github.com/containerd/continuity/syscallx
github.com/containerd/continuity/fs github.com/containerd/continuity/fs
github.com/containerd/continuity/syscallx
# github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448 # github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448
github.com/containerd/fifo github.com/containerd/fifo
# github.com/containerd/typeurl v0.0.0-20190228175220-2a93cfde8c20 # 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/internal/containerizedengine
github.com/docker/cli/opts github.com/docker/cli/opts
github.com/docker/cli/types github.com/docker/cli/types
github.com/docker/cli/cli/connhelper/commandconn
github.com/docker/cli/cli/config/credentials 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/cli/connhelper/ssh
github.com/docker/cli/kubernetes github.com/docker/cli/kubernetes
github.com/docker/cli/cli/manifest/types github.com/docker/cli/cli/manifest/types
@ -238,6 +238,8 @@ github.com/hashicorp/go-version
github.com/imdario/mergo github.com/imdario/mergo
# github.com/inconshreveable/mousetrap v1.0.0 # github.com/inconshreveable/mousetrap v1.0.0
github.com/inconshreveable/mousetrap 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 v1.1.6
github.com/json-iterator/go github.com/json-iterator/go
# github.com/konsorten/go-windows-terminal-sequences v1.0.1 # 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/matttproud/golang_protobuf_extensions/pbutil
# github.com/miekg/pkcs11 v0.0.0-20190322140431-074fd7a1ed19 # github.com/miekg/pkcs11 v0.0.0-20190322140431-074fd7a1ed19
github.com/miekg/pkcs11 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/client
github.com/moby/buildkit/session github.com/moby/buildkit/session
github.com/moby/buildkit/session/secrets/secretsprovider 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
github.com/theupdateframework/notary/tuf/utils github.com/theupdateframework/notary/tuf/utils
github.com/theupdateframework/notary/tuf/validation 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/types
github.com/tonistiigi/fsutil github.com/tonistiigi/fsutil
# github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea # github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea