Update buildkit to 0.11.0-rc2 (#3882)

Seems buildkit breaks API compatibility with previous OCI implementation
 in new RC release, let's update it

Signed-off-by: Petr Fedchenkov <giggsoff@gmail.com>

Signed-off-by: Petr Fedchenkov <giggsoff@gmail.com>
This commit is contained in:
Petr Fedchenkov 2022-12-15 13:53:38 +03:00 committed by GitHub
parent 893bee6b81
commit 8b04a8c92a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 3175 additions and 485 deletions

View File

@ -23,7 +23,7 @@ require (
github.com/gophercloud/utils v0.0.0-20181029231510-34f5991525d1 github.com/gophercloud/utils v0.0.0-20181029231510-34f5991525d1
github.com/hashicorp/go-version v1.2.0 github.com/hashicorp/go-version v1.2.0
github.com/klauspost/pgzip v1.2.5 github.com/klauspost/pgzip v1.2.5
github.com/moby/buildkit v0.11.0-rc1.0.20221213132957-c0ac5e8b9b51 github.com/moby/buildkit v0.11.0-rc2
github.com/moby/hyperkit v0.0.0-20180416161519-d65b09c1c28a github.com/moby/hyperkit v0.0.0-20180416161519-d65b09c1c28a
//github.com/moby/moby v20.10.3-0.20220728162118-71cb54cec41e+incompatible // indirect //github.com/moby/moby v20.10.3-0.20220728162118-71cb54cec41e+incompatible // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6

View File

@ -1066,8 +1066,8 @@ github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/moby/buildkit v0.8.1/go.mod h1:/kyU1hKy/aYCuP39GZA9MaKioovHku57N6cqlKZIaiQ= github.com/moby/buildkit v0.8.1/go.mod h1:/kyU1hKy/aYCuP39GZA9MaKioovHku57N6cqlKZIaiQ=
github.com/moby/buildkit v0.10.1-0.20220403220257-10e6f94bf90d/go.mod h1:WvwAZv8aRScHkqc/+X46cRC2CKMKpqcaX+pRvUTtPes= github.com/moby/buildkit v0.10.1-0.20220403220257-10e6f94bf90d/go.mod h1:WvwAZv8aRScHkqc/+X46cRC2CKMKpqcaX+pRvUTtPes=
github.com/moby/buildkit v0.11.0-rc1.0.20221213132957-c0ac5e8b9b51 h1:JSFjonNJAABHC33y9osJ5YtvMiAJPB4ZMNQnkJE6TRI= github.com/moby/buildkit v0.11.0-rc2 h1:ZgurjAHikHjF1cz4aas6lMIQCOtj2/AERjUEKWbaFKE=
github.com/moby/buildkit v0.11.0-rc1.0.20221213132957-c0ac5e8b9b51/go.mod h1:f3jvilDvcG14z+gzPpA2lcWRwIRyFiNTo5bMwHiYDk0= github.com/moby/buildkit v0.11.0-rc2/go.mod h1:f3jvilDvcG14z+gzPpA2lcWRwIRyFiNTo5bMwHiYDk0=
github.com/moby/hyperkit v0.0.0-20180416161519-d65b09c1c28a h1:hExo7kltIidoitYnXsnqfvkJXG3YEMbHuQbf9nOMvow= github.com/moby/hyperkit v0.0.0-20180416161519-d65b09c1c28a h1:hExo7kltIidoitYnXsnqfvkJXG3YEMbHuQbf9nOMvow=
github.com/moby/hyperkit v0.0.0-20180416161519-d65b09c1c28a/go.mod h1:zGAVB/FkAf4ozkR8CCuj4LcVuErrNsj9APTDFvhOckw= github.com/moby/hyperkit v0.0.0-20180416161519-d65b09c1c28a/go.mod h1:zGAVB/FkAf4ozkR8CCuj4LcVuErrNsj9APTDFvhOckw=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=

View File

@ -14,10 +14,7 @@ import (
const ( const (
buildersEnvVar = "LINUXKIT_BUILDERS" buildersEnvVar = "LINUXKIT_BUILDERS"
envVarCacheDir = "LINUXKIT_CACHE" envVarCacheDir = "LINUXKIT_CACHE"
// this is the most recent manifest pointed to by moby/buildkit:master as of 2022-12-13, with the latest commit defaultBuilderImage = "moby/buildkit:v0.11.0-rc2"
// c0ac5e8b9b51603c5a93795fcf1373d6d44d3a85.
// Once there is a normal semver tag later than this, we should switch to it.
defaultBuilderImage = "moby/buildkit@sha256:daadc9f6dc5829c9dfa68ef9f4292c2d5b2fddf848046e02e43db53037373dda"
) )
func pkgBuild(args []string) { func pkgBuild(args []string) {

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,7 @@ import "github.com/moby/buildkit/solver/pb/ops.proto";
import "github.com/moby/buildkit/api/types/worker.proto"; import "github.com/moby/buildkit/api/types/worker.proto";
// import "github.com/containerd/containerd/api/types/descriptor.proto"; // import "github.com/containerd/containerd/api/types/descriptor.proto";
import "github.com/gogo/googleapis/google/rpc/status.proto"; import "github.com/gogo/googleapis/google/rpc/status.proto";
import "github.com/moby/buildkit/sourcepolicy/pb/policy.proto";
option (gogoproto.sizer_all) = true; option (gogoproto.sizer_all) = true;
option (gogoproto.marshaler_all) = true; option (gogoproto.marshaler_all) = true;
@ -23,6 +24,7 @@ service Control {
rpc Info(InfoRequest) returns (InfoResponse); rpc Info(InfoRequest) returns (InfoResponse);
rpc ListenBuildHistory(BuildHistoryRequest) returns (stream BuildHistoryEvent); rpc ListenBuildHistory(BuildHistoryRequest) returns (stream BuildHistoryEvent);
rpc UpdateBuildHistory(UpdateBuildHistoryRequest) returns (UpdateBuildHistoryResponse);
} }
message PruneRequest { message PruneRequest {
@ -66,6 +68,8 @@ message SolveRequest {
CacheOptions Cache = 8 [(gogoproto.nullable) = false]; CacheOptions Cache = 8 [(gogoproto.nullable) = false];
repeated string Entitlements = 9 [(gogoproto.customtype) = "github.com/moby/buildkit/util/entitlements.Entitlement" ]; repeated string Entitlements = 9 [(gogoproto.customtype) = "github.com/moby/buildkit/util/entitlements.Entitlement" ];
map<string, pb.Definition> FrontendInputs = 10; map<string, pb.Definition> FrontendInputs = 10;
bool Internal = 11; // Internal builds are not recorded in build history
moby.buildkit.v1.sourcepolicy.Policy SourcePolicy = 12;
} }
message CacheOptions { message CacheOptions {
@ -171,6 +175,7 @@ message InfoResponse {
message BuildHistoryRequest { message BuildHistoryRequest {
bool ActiveOnly = 1; bool ActiveOnly = 1;
string Ref = 2; string Ref = 2;
bool EarlyExit = 3;
} }
enum BuildHistoryEventType { enum BuildHistoryEventType {
@ -179,7 +184,6 @@ enum BuildHistoryEventType {
DELETED = 2; DELETED = 2;
} }
message BuildHistoryEvent { message BuildHistoryEvent {
BuildHistoryEventType type = 1; BuildHistoryEventType type = 1;
BuildHistoryRecord record = 2; BuildHistoryRecord record = 2;
@ -198,12 +202,21 @@ message BuildHistoryRecord {
BuildResultInfo Result = 10; BuildResultInfo Result = 10;
map<string, BuildResultInfo> Results = 11; map<string, BuildResultInfo> Results = 11;
int32 Generation = 12; int32 Generation = 12;
Descriptor trace = 13;
bool pinned = 14;
// TODO: tags // TODO: tags
// TODO: steps/cache summary // TODO: steps/cache summary
// TODO: unclipped logs // TODO: unclipped logs
// TODO: pinning
} }
message UpdateBuildHistoryRequest {
string Ref = 1;
bool Pinned = 2;
bool Delete = 3;
}
message UpdateBuildHistoryResponse {}
message Descriptor { message Descriptor {
string media_type = 1; string media_type = 1;
string digest = 2 [(gogoproto.customtype) = "github.com/opencontainers/go-digest.Digest", (gogoproto.nullable) = false]; string digest = 2 [(gogoproto.customtype) = "github.com/opencontainers/go-digest.Digest", (gogoproto.nullable) = false];

View File

@ -9,6 +9,7 @@ import (
"os" "os"
"strings" "strings"
contentapi "github.com/containerd/containerd/api/services/content/v1"
"github.com/containerd/containerd/defaults" "github.com/containerd/containerd/defaults"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
controlapi "github.com/moby/buildkit/api/services/control" controlapi "github.com/moby/buildkit/api/services/control"
@ -172,6 +173,10 @@ func (c *Client) ControlClient() controlapi.ControlClient {
return controlapi.NewControlClient(c.conn) return controlapi.NewControlClient(c.conn)
} }
func (c *Client) ContentClient() contentapi.ContentClient {
return contentapi.NewContentClient(c.conn)
}
func (c *Client) Dialer() session.Dialer { func (c *Client) Dialer() session.Dialer {
return grpchijack.Dialer(c.ControlClient()) return grpchijack.Dialer(c.ControlClient())
} }

View File

@ -42,9 +42,16 @@ const (
) )
type ResolveImageConfigOpt struct { type ResolveImageConfigOpt struct {
ResolverType
Platform *ocispecs.Platform Platform *ocispecs.Platform
ResolveMode string ResolveMode string
LogName string LogName string
ResolverType // default is ResolverTypeRegistry
SessionID string Store ResolveImageConfigOptStore
}
type ResolveImageConfigOptStore struct {
SessionID string
StoreID string
} }

View File

@ -4,7 +4,6 @@ import (
"context" "context"
_ "crypto/sha256" // for opencontainers/go-digest _ "crypto/sha256" // for opencontainers/go-digest
"encoding/json" "encoding/json"
"fmt"
"os" "os"
"strconv" "strconv"
"strings" "strings"
@ -455,7 +454,7 @@ func Differ(t DiffType, required bool) LocalOption {
}) })
} }
func OCILayout(store string, digest digest.Digest, opts ...OCILayoutOption) State { func OCILayout(ref string, opts ...OCILayoutOption) State {
gi := &OCILayoutInfo{} gi := &OCILayoutInfo{}
for _, o := range opts { for _, o := range opts {
@ -464,17 +463,17 @@ func OCILayout(store string, digest digest.Digest, opts ...OCILayoutOption) Stat
attrs := map[string]string{} attrs := map[string]string{}
if gi.sessionID != "" { if gi.sessionID != "" {
attrs[pb.AttrOCILayoutSessionID] = gi.sessionID attrs[pb.AttrOCILayoutSessionID] = gi.sessionID
addCap(&gi.Constraints, pb.CapSourceOCILayoutSessionID)
} }
if gi.storeID != "" {
if ll := gi.layerLimit; ll != nil { attrs[pb.AttrOCILayoutStoreID] = gi.storeID
attrs[pb.AttrOCILayoutLayerLimit] = strconv.FormatInt(int64(*ll), 10) }
addCap(&gi.Constraints, pb.CapSourceOCILayoutLayerLimit) if gi.layerLimit != nil {
attrs[pb.AttrOCILayoutLayerLimit] = strconv.FormatInt(int64(*gi.layerLimit), 10)
} }
addCap(&gi.Constraints, pb.CapSourceOCILayout) addCap(&gi.Constraints, pb.CapSourceOCILayout)
source := NewSource(fmt.Sprintf("oci-layout://%s@%s", store, digest), attrs, gi.Constraints) source := NewSource("oci-layout://"+ref, attrs, gi.Constraints)
return NewState(source.Output()) return NewState(source.Output())
} }
@ -488,9 +487,10 @@ func (fn ociLayoutOptionFunc) SetOCILayoutOption(li *OCILayoutInfo) {
fn(li) fn(li)
} }
func OCISessionID(id string) OCILayoutOption { func OCIStore(sessionID string, storeID string) OCILayoutOption {
return ociLayoutOptionFunc(func(oi *OCILayoutInfo) { return ociLayoutOptionFunc(func(oi *OCILayoutInfo) {
oi.sessionID = id oi.sessionID = sessionID
oi.storeID = storeID
}) })
} }
@ -503,6 +503,7 @@ func OCILayerLimit(limit int) OCILayoutOption {
type OCILayoutInfo struct { type OCILayoutInfo struct {
constraintsWrapper constraintsWrapper
sessionID string sessionID string
storeID string
layerLimit *int layerLimit *int
} }

View File

@ -22,6 +22,7 @@ import (
"github.com/moby/buildkit/session/filesync" "github.com/moby/buildkit/session/filesync"
"github.com/moby/buildkit/session/grpchijack" "github.com/moby/buildkit/session/grpchijack"
"github.com/moby/buildkit/solver/pb" "github.com/moby/buildkit/solver/pb"
spb "github.com/moby/buildkit/sourcepolicy/pb"
"github.com/moby/buildkit/util/bklog" "github.com/moby/buildkit/util/bklog"
"github.com/moby/buildkit/util/entitlements" "github.com/moby/buildkit/util/entitlements"
ocispecs "github.com/opencontainers/image-spec/specs-go/v1" ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
@ -46,6 +47,8 @@ type SolveOpt struct {
AllowedEntitlements []entitlements.Entitlement AllowedEntitlements []entitlements.Entitlement
SharedSession *session.Session // TODO: refactor to better session syncing SharedSession *session.Session // TODO: refactor to better session syncing
SessionPreInitialized bool // TODO: refactor to better session syncing SessionPreInitialized bool // TODO: refactor to better session syncing
Internal bool
SourcePolicy *spb.Policy
} }
type ExportEntry struct { type ExportEntry struct {
@ -259,6 +262,8 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
FrontendInputs: frontendInputs, FrontendInputs: frontendInputs,
Cache: cacheOpt.options, Cache: cacheOpt.options,
Entitlements: opt.AllowedEntitlements, Entitlements: opt.AllowedEntitlements,
Internal: opt.Internal,
SourcePolicy: opt.SourcePolicy,
}) })
if err != nil { if err != nil {
return errors.Wrap(err, "failed to solve") return errors.Wrap(err, "failed to solve")
@ -350,54 +355,6 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
return res, nil return res, nil
} }
func NewSolveStatus(resp *controlapi.StatusResponse) *SolveStatus {
s := &SolveStatus{}
for _, v := range resp.Vertexes {
s.Vertexes = append(s.Vertexes, &Vertex{
Digest: v.Digest,
Inputs: v.Inputs,
Name: v.Name,
Started: v.Started,
Completed: v.Completed,
Error: v.Error,
Cached: v.Cached,
ProgressGroup: v.ProgressGroup,
})
}
for _, v := range resp.Statuses {
s.Statuses = append(s.Statuses, &VertexStatus{
ID: v.ID,
Vertex: v.Vertex,
Name: v.Name,
Total: v.Total,
Current: v.Current,
Timestamp: v.Timestamp,
Started: v.Started,
Completed: v.Completed,
})
}
for _, v := range resp.Logs {
s.Logs = append(s.Logs, &VertexLog{
Vertex: v.Vertex,
Stream: int(v.Stream),
Data: v.Msg,
Timestamp: v.Timestamp,
})
}
for _, v := range resp.Warnings {
s.Warnings = append(s.Warnings, &VertexWarning{
Vertex: v.Vertex,
Level: int(v.Level),
Short: v.Short,
Detail: v.Detail,
URL: v.Url,
SourceInfo: v.Info,
Range: v.Ranges,
})
}
return s
}
func prepareSyncedDirs(def *llb.Definition, localDirs map[string]string) (filesync.StaticDirSource, error) { func prepareSyncedDirs(def *llb.Definition, localDirs map[string]string) (filesync.StaticDirSource, error) {
for _, d := range localDirs { for _, d := range localDirs {
fi, err := os.Stat(d) fi, err := os.Stat(d)

View File

@ -0,0 +1,125 @@
package client
import (
controlapi "github.com/moby/buildkit/api/services/control"
)
var emptyLogVertexSize int
func init() {
emptyLogVertex := controlapi.VertexLog{}
emptyLogVertexSize = emptyLogVertex.Size()
}
func NewSolveStatus(resp *controlapi.StatusResponse) *SolveStatus {
s := &SolveStatus{}
for _, v := range resp.Vertexes {
s.Vertexes = append(s.Vertexes, &Vertex{
Digest: v.Digest,
Inputs: v.Inputs,
Name: v.Name,
Started: v.Started,
Completed: v.Completed,
Error: v.Error,
Cached: v.Cached,
ProgressGroup: v.ProgressGroup,
})
}
for _, v := range resp.Statuses {
s.Statuses = append(s.Statuses, &VertexStatus{
ID: v.ID,
Vertex: v.Vertex,
Name: v.Name,
Total: v.Total,
Current: v.Current,
Timestamp: v.Timestamp,
Started: v.Started,
Completed: v.Completed,
})
}
for _, v := range resp.Logs {
s.Logs = append(s.Logs, &VertexLog{
Vertex: v.Vertex,
Stream: int(v.Stream),
Data: v.Msg,
Timestamp: v.Timestamp,
})
}
for _, v := range resp.Warnings {
s.Warnings = append(s.Warnings, &VertexWarning{
Vertex: v.Vertex,
Level: int(v.Level),
Short: v.Short,
Detail: v.Detail,
URL: v.Url,
SourceInfo: v.Info,
Range: v.Ranges,
})
}
return s
}
func (ss *SolveStatus) Marshal() (out []*controlapi.StatusResponse) {
logSize := 0
for {
retry := false
sr := controlapi.StatusResponse{}
for _, v := range ss.Vertexes {
sr.Vertexes = append(sr.Vertexes, &controlapi.Vertex{
Digest: v.Digest,
Inputs: v.Inputs,
Name: v.Name,
Started: v.Started,
Completed: v.Completed,
Error: v.Error,
Cached: v.Cached,
ProgressGroup: v.ProgressGroup,
})
}
for _, v := range ss.Statuses {
sr.Statuses = append(sr.Statuses, &controlapi.VertexStatus{
ID: v.ID,
Vertex: v.Vertex,
Name: v.Name,
Current: v.Current,
Total: v.Total,
Timestamp: v.Timestamp,
Started: v.Started,
Completed: v.Completed,
})
}
for i, v := range ss.Logs {
sr.Logs = append(sr.Logs, &controlapi.VertexLog{
Vertex: v.Vertex,
Stream: int64(v.Stream),
Msg: v.Data,
Timestamp: v.Timestamp,
})
logSize += len(v.Data) + emptyLogVertexSize
// avoid logs growing big and split apart if they do
if logSize > 1024*1024 {
ss.Vertexes = nil
ss.Statuses = nil
ss.Logs = ss.Logs[i+1:]
retry = true
break
}
}
for _, v := range ss.Warnings {
sr.Warnings = append(sr.Warnings, &controlapi.VertexWarning{
Vertex: v.Vertex,
Level: int64(v.Level),
Short: v.Short,
Detail: v.Detail,
Info: v.SourceInfo,
Ranges: v.Range,
Url: v.URL,
})
}
out = append(out, &sr)
if !retry {
break
}
}
return
}

View File

@ -873,8 +873,8 @@ func contextByNameFunc(c client.Client, sessionID string) func(context.Context,
p = &pp p = &pp
} }
if p != nil { if p != nil {
name := name + "::" + platforms.Format(platforms.Normalize(*p)) pname := name + "::" + platforms.Format(platforms.Normalize(*p))
st, img, err := contextByName(ctx, c, sessionID, name, p, resolveMode) st, img, err := contextByName(ctx, c, sessionID, name, pname, p, resolveMode)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -882,20 +882,20 @@ func contextByNameFunc(c client.Client, sessionID string) func(context.Context,
return st, img, nil return st, img, nil
} }
} }
return contextByName(ctx, c, sessionID, name, p, resolveMode) return contextByName(ctx, c, sessionID, name, name, p, resolveMode)
} }
} }
func contextByName(ctx context.Context, c client.Client, sessionID, name string, platform *ocispecs.Platform, resolveMode string) (*llb.State, *dockerfile2llb.Image, error) { func contextByName(ctx context.Context, c client.Client, sessionID, name string, pname string, platform *ocispecs.Platform, resolveMode string) (*llb.State, *dockerfile2llb.Image, error) {
opts := c.BuildOpts().Opts opts := c.BuildOpts().Opts
v, ok := opts[contextPrefix+name] v, ok := opts[contextPrefix+pname]
if !ok { if !ok {
return nil, nil, nil return nil, nil, nil
} }
vv := strings.SplitN(v, ":", 2) vv := strings.SplitN(v, ":", 2)
if len(vv) != 2 { if len(vv) != 2 {
return nil, nil, errors.Errorf("invalid context specifier %s for %s", v, name) return nil, nil, errors.Errorf("invalid context specifier %s for %s", v, pname)
} }
// allow git@ without protocol for SSH URLs for backwards compatibility // allow git@ without protocol for SSH URLs for backwards compatibility
if strings.HasPrefix(vv[0], "git@") { if strings.HasPrefix(vv[0], "git@") {
@ -910,7 +910,7 @@ func contextByName(ctx context.Context, c client.Client, sessionID, name string,
} }
imgOpt := []llb.ImageOption{ imgOpt := []llb.ImageOption{
llb.WithCustomName("[context " + name + "] " + ref), llb.WithCustomName("[context " + pname + "] " + ref),
} }
if platform != nil { if platform != nil {
imgOpt = append(imgOpt, llb.Platform(*platform)) imgOpt = append(imgOpt, llb.Platform(*platform))
@ -926,9 +926,8 @@ func contextByName(ctx context.Context, c client.Client, sessionID, name string,
_, data, err := c.ResolveImageConfig(ctx, named.String(), llb.ResolveImageConfigOpt{ _, data, err := c.ResolveImageConfig(ctx, named.String(), llb.ResolveImageConfigOpt{
Platform: platform, Platform: platform,
ResolveMode: resolveMode, ResolveMode: resolveMode,
LogName: fmt.Sprintf("[context %s] load metadata for %s", name, ref), LogName: fmt.Sprintf("[context %s] load metadata for %s", pname, ref),
ResolverType: llb.ResolverTypeRegistry, ResolverType: llb.ResolverTypeRegistry,
SessionID: sessionID,
}) })
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -955,7 +954,7 @@ func contextByName(ctx context.Context, c client.Client, sessionID, name string,
case "http", "https": case "http", "https":
st, ok := detectGitContext(v, true) st, ok := detectGitContext(v, true)
if !ok { if !ok {
httpst := llb.HTTP(v, llb.WithCustomName("[context "+name+"] "+v)) httpst := llb.HTTP(v, llb.WithCustomName("[context "+pname+"] "+v))
st = &httpst st = &httpst
} }
return st, nil, nil return st, nil, nil
@ -969,25 +968,31 @@ func contextByName(ctx context.Context, c client.Client, sessionID, name string,
if !ok { if !ok {
return nil, nil, errors.Errorf("oci-layout reference %q has no name", ref.String()) return nil, nil, errors.Errorf("oci-layout reference %q has no name", ref.String())
} }
if reference.Domain(named) != "" { dgstd, ok := named.(reference.Digested)
return nil, nil, errors.Errorf("oci-layout reference %q has domain", ref.String())
}
if strings.Contains(reference.Path(named), "/") {
return nil, nil, errors.Errorf("oci-layout reference %q name is multi-part", ref.String())
}
digested, ok := ref.(reference.Digested)
if !ok { if !ok {
return nil, nil, errors.Errorf("oci-layout reference %q does not have digest", ref.String()) return nil, nil, errors.Errorf("oci-layout reference %q has no digest", named.String())
} }
// We use store id as the host here, the image name will be ignored // for the dummy ref primarily used in log messages, we can use the
// (since image lookup is not currently supported) // original name, since the store key may not be significant
id := fmt.Sprintf("%s/image@%s", named.Name(), digested.Digest()) dummyRef, err := reference.ParseNormalizedNamed(name)
_, data, err := c.ResolveImageConfig(ctx, id, llb.ResolveImageConfigOpt{ if err != nil {
return nil, nil, errors.Wrapf(err, "could not parse oci-layout reference %q", name)
}
dummyRef, err = reference.WithDigest(dummyRef, dgstd.Digest())
if err != nil {
return nil, nil, errors.Wrapf(err, "could not wrap %q with digest", name)
}
_, data, err := c.ResolveImageConfig(ctx, dummyRef.String(), llb.ResolveImageConfigOpt{
Platform: platform, Platform: platform,
ResolveMode: resolveMode, ResolveMode: resolveMode,
LogName: fmt.Sprintf("[context %s] load metadata for %s", name, ref), LogName: fmt.Sprintf("[context %s] load metadata for %s", pname, dummyRef.String()),
ResolverType: llb.ResolverTypeOCILayout, ResolverType: llb.ResolverTypeOCILayout,
Store: llb.ResolveImageConfigOptStore{
SessionID: sessionID,
StoreID: named.Name(),
},
}) })
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -999,15 +1004,14 @@ func contextByName(ctx context.Context, c client.Client, sessionID, name string,
} }
ociOpt := []llb.OCILayoutOption{ ociOpt := []llb.OCILayoutOption{
llb.WithCustomName("[context " + name + "] OCI load from client"), llb.WithCustomName("[context " + pname + "] OCI load from client"),
llb.OCISessionID(c.BuildOpts().SessionID), llb.OCIStore(c.BuildOpts().SessionID, named.Name()),
} }
if platform != nil { if platform != nil {
ociOpt = append(ociOpt, llb.Platform(*platform)) ociOpt = append(ociOpt, llb.Platform(*platform))
} }
st := llb.OCILayout( st := llb.OCILayout(
named.Name(), dummyRef.String(),
digested.Digest(),
ociOpt..., ociOpt...,
) )
st, err = st.WithImageConfig(data) st, err = st.WithImageConfig(data)
@ -1019,8 +1023,8 @@ func contextByName(ctx context.Context, c client.Client, sessionID, name string,
st := llb.Local(vv[1], st := llb.Local(vv[1],
llb.SessionID(c.BuildOpts().SessionID), llb.SessionID(c.BuildOpts().SessionID),
llb.FollowPaths([]string{dockerignoreFilename}), llb.FollowPaths([]string{dockerignoreFilename}),
llb.SharedKeyHint("context:"+name+"-"+dockerignoreFilename), llb.SharedKeyHint("context:"+pname+"-"+dockerignoreFilename),
llb.WithCustomName("[context "+name+"] load "+dockerignoreFilename), llb.WithCustomName("[context "+pname+"] load "+dockerignoreFilename),
llb.Differ(llb.DiffNone, false), llb.Differ(llb.DiffNone, false),
) )
def, err := st.Marshal(ctx) def, err := st.Marshal(ctx)
@ -1049,9 +1053,9 @@ func contextByName(ctx context.Context, c client.Client, sessionID, name string,
} }
} }
st = llb.Local(vv[1], st = llb.Local(vv[1],
llb.WithCustomName("[context "+name+"] load from client"), llb.WithCustomName("[context "+pname+"] load from client"),
llb.SessionID(c.BuildOpts().SessionID), llb.SessionID(c.BuildOpts().SessionID),
llb.SharedKeyHint("context:"+name), llb.SharedKeyHint("context:"+pname),
llb.ExcludePatterns(excludes), llb.ExcludePatterns(excludes),
) )
return &st, nil, nil return &st, nil, nil
@ -1062,7 +1066,7 @@ func contextByName(ctx context.Context, c client.Client, sessionID, name string,
} }
st, ok := inputs[vv[1]] st, ok := inputs[vv[1]]
if !ok { if !ok {
return nil, nil, errors.Errorf("invalid input %s for %s", vv[1], name) return nil, nil, errors.Errorf("invalid input %s for %s", vv[1], pname)
} }
md, ok := opts[inputMetadataPrefix+vv[1]] md, ok := opts[inputMetadataPrefix+vv[1]]
if ok { if ok {
@ -1077,14 +1081,14 @@ func contextByName(ctx context.Context, c client.Client, sessionID, name string,
return nil, nil, err return nil, nil, err
} }
if err := json.Unmarshal(dtic, &img); err != nil { if err := json.Unmarshal(dtic, &img); err != nil {
return nil, nil, errors.Wrapf(err, "failed to parse image config for %s", name) return nil, nil, errors.Wrapf(err, "failed to parse image config for %s", pname)
} }
} }
return &st, img, nil return &st, img, nil
} }
return &st, nil, nil return &st, nil, nil
default: default:
return nil, nil, errors.Errorf("unsupported context source %s for %s", vv[0], name) return nil, nil, errors.Errorf("unsupported context source %s for %s", vv[0], pname)
} }
} }

View File

@ -8,6 +8,7 @@ import (
"github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/solver/pb" "github.com/moby/buildkit/solver/pb"
"github.com/moby/buildkit/solver/result" "github.com/moby/buildkit/solver/result"
spb "github.com/moby/buildkit/sourcepolicy/pb"
"github.com/moby/buildkit/util/apicaps" "github.com/moby/buildkit/util/apicaps"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
ocispecs "github.com/opencontainers/image-spec/specs-go/v1" ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
@ -128,6 +129,7 @@ type SolveRequest struct {
FrontendOpt map[string]string FrontendOpt map[string]string
FrontendInputs map[string]*pb.Definition FrontendInputs map[string]*pb.Definition
CacheImports []CacheOptionsEntry CacheImports []CacheOptionsEntry
SourcePolicies []*spb.Policy
} }
type CacheOptionsEntry struct { type CacheOptionsEntry struct {

View File

@ -382,6 +382,7 @@ func (c *grpcClient) Solve(ctx context.Context, creq client.SolveRequest) (res *
AllowResultReturn: true, AllowResultReturn: true,
AllowResultArrayRef: true, AllowResultArrayRef: true,
CacheImports: cacheImports, CacheImports: cacheImports,
SourcePolicies: creq.SourcePolicies,
} }
// backwards compatibility with inline return // backwards compatibility with inline return
@ -488,7 +489,15 @@ func (c *grpcClient) ResolveImageConfig(ctx context.Context, ref string, opt llb
OSFeatures: platform.OSFeatures, OSFeatures: platform.OSFeatures,
} }
} }
resp, err := c.client.ResolveImageConfig(ctx, &pb.ResolveImageConfigRequest{Ref: ref, Platform: p, ResolveMode: opt.ResolveMode, LogName: opt.LogName, ResolverType: int32(opt.ResolverType), SessionID: opt.SessionID}) resp, err := c.client.ResolveImageConfig(ctx, &pb.ResolveImageConfigRequest{
ResolverType: int32(opt.ResolverType),
Ref: ref,
Platform: p,
ResolveMode: opt.ResolveMode,
LogName: opt.LogName,
SessionID: opt.Store.SessionID,
StoreID: opt.Store.StoreID,
})
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }

View File

@ -11,7 +11,8 @@ import (
proto "github.com/gogo/protobuf/proto" proto "github.com/gogo/protobuf/proto"
types1 "github.com/moby/buildkit/api/types" types1 "github.com/moby/buildkit/api/types"
pb "github.com/moby/buildkit/solver/pb" pb "github.com/moby/buildkit/solver/pb"
pb1 "github.com/moby/buildkit/util/apicaps/pb" pb1 "github.com/moby/buildkit/sourcepolicy/pb"
pb2 "github.com/moby/buildkit/util/apicaps/pb"
github_com_opencontainers_go_digest "github.com/opencontainers/go-digest" github_com_opencontainers_go_digest "github.com/opencontainers/go-digest"
types "github.com/tonistiigi/fsutil/types" types "github.com/tonistiigi/fsutil/types"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
@ -92,7 +93,8 @@ type Result struct {
// *Result_Refs // *Result_Refs
Result isResult_Result `protobuf_oneof:"result"` Result isResult_Result `protobuf_oneof:"result"`
Metadata map[string][]byte `protobuf:"bytes,10,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Metadata map[string][]byte `protobuf:"bytes,10,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Attestations map[string]*Attestations `protobuf:"bytes,11,rep,name=attestations,proto3" json:"attestations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // 11 was used during development and is reserved for old attestation format
Attestations map[string]*Attestations `protobuf:"bytes,12,rep,name=attestations,proto3" json:"attestations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -740,6 +742,7 @@ type ResolveImageConfigRequest struct {
LogName string `protobuf:"bytes,4,opt,name=LogName,proto3" json:"LogName,omitempty"` LogName string `protobuf:"bytes,4,opt,name=LogName,proto3" json:"LogName,omitempty"`
ResolverType int32 `protobuf:"varint,5,opt,name=ResolverType,proto3" json:"ResolverType,omitempty"` ResolverType int32 `protobuf:"varint,5,opt,name=ResolverType,proto3" json:"ResolverType,omitempty"`
SessionID string `protobuf:"bytes,6,opt,name=SessionID,proto3" json:"SessionID,omitempty"` SessionID string `protobuf:"bytes,6,opt,name=SessionID,proto3" json:"SessionID,omitempty"`
StoreID string `protobuf:"bytes,7,opt,name=StoreID,proto3" json:"StoreID,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -820,6 +823,13 @@ func (m *ResolveImageConfigRequest) GetSessionID() string {
return "" return ""
} }
func (m *ResolveImageConfigRequest) GetStoreID() string {
if m != nil {
return m.StoreID
}
return ""
}
type ResolveImageConfigResponse struct { type ResolveImageConfigResponse struct {
Digest github_com_opencontainers_go_digest.Digest `protobuf:"bytes,1,opt,name=Digest,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"Digest"` Digest github_com_opencontainers_go_digest.Digest `protobuf:"bytes,1,opt,name=Digest,proto3,customtype=github.com/opencontainers/go-digest.Digest" json:"Digest"`
Config []byte `protobuf:"bytes,2,opt,name=Config,proto3" json:"Config,omitempty"` Config []byte `protobuf:"bytes,2,opt,name=Config,proto3" json:"Config,omitempty"`
@ -884,6 +894,7 @@ type SolveRequest struct {
// apicaps:CapFrontendInputs // apicaps:CapFrontendInputs
FrontendInputs map[string]*pb.Definition `protobuf:"bytes,13,rep,name=FrontendInputs,proto3" json:"FrontendInputs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` FrontendInputs map[string]*pb.Definition `protobuf:"bytes,13,rep,name=FrontendInputs,proto3" json:"FrontendInputs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Evaluate bool `protobuf:"varint,14,opt,name=Evaluate,proto3" json:"Evaluate,omitempty"` Evaluate bool `protobuf:"varint,14,opt,name=Evaluate,proto3" json:"Evaluate,omitempty"`
SourcePolicies []*pb1.Policy `protobuf:"bytes,15,rep,name=SourcePolicies,proto3" json:"SourcePolicies,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -992,6 +1003,13 @@ func (m *SolveRequest) GetEvaluate() bool {
return false return false
} }
func (m *SolveRequest) GetSourcePolicies() []*pb1.Policy {
if m != nil {
return m.SourcePolicies
}
return nil
}
// CacheOptionsEntry corresponds to the control.CacheOptionsEntry // CacheOptionsEntry corresponds to the control.CacheOptionsEntry
type CacheOptionsEntry struct { type CacheOptionsEntry struct {
Type string `protobuf:"bytes,1,opt,name=Type,proto3" json:"Type,omitempty"` Type string `protobuf:"bytes,1,opt,name=Type,proto3" json:"Type,omitempty"`
@ -1608,8 +1626,8 @@ func (m *PingRequest) XXX_DiscardUnknown() {
var xxx_messageInfo_PingRequest proto.InternalMessageInfo var xxx_messageInfo_PingRequest proto.InternalMessageInfo
type PongResponse struct { type PongResponse struct {
FrontendAPICaps []pb1.APICap `protobuf:"bytes,1,rep,name=FrontendAPICaps,proto3" json:"FrontendAPICaps"` FrontendAPICaps []pb2.APICap `protobuf:"bytes,1,rep,name=FrontendAPICaps,proto3" json:"FrontendAPICaps"`
LLBCaps []pb1.APICap `protobuf:"bytes,2,rep,name=LLBCaps,proto3" json:"LLBCaps"` LLBCaps []pb2.APICap `protobuf:"bytes,2,rep,name=LLBCaps,proto3" json:"LLBCaps"`
Workers []*types1.WorkerRecord `protobuf:"bytes,3,rep,name=Workers,proto3" json:"Workers,omitempty"` Workers []*types1.WorkerRecord `protobuf:"bytes,3,rep,name=Workers,proto3" json:"Workers,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
@ -1649,14 +1667,14 @@ func (m *PongResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_PongResponse proto.InternalMessageInfo var xxx_messageInfo_PongResponse proto.InternalMessageInfo
func (m *PongResponse) GetFrontendAPICaps() []pb1.APICap { func (m *PongResponse) GetFrontendAPICaps() []pb2.APICap {
if m != nil { if m != nil {
return m.FrontendAPICaps return m.FrontendAPICaps
} }
return nil return nil
} }
func (m *PongResponse) GetLLBCaps() []pb1.APICap { func (m *PongResponse) GetLLBCaps() []pb2.APICap {
if m != nil { if m != nil {
return m.LLBCaps return m.LLBCaps
} }
@ -2609,157 +2627,161 @@ func init() {
func init() { proto.RegisterFile("gateway.proto", fileDescriptor_f1a937782ebbded5) } func init() { proto.RegisterFile("gateway.proto", fileDescriptor_f1a937782ebbded5) }
var fileDescriptor_f1a937782ebbded5 = []byte{ var fileDescriptor_f1a937782ebbded5 = []byte{
// 2395 bytes of a gzipped FileDescriptorProto // 2452 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x39, 0xcd, 0x6f, 0x1b, 0xc7, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x59, 0xcf, 0x6f, 0x1b, 0xc7,
0xf5, 0x5a, 0x91, 0x12, 0xc9, 0xc7, 0x0f, 0xd1, 0x13, 0x27, 0x3f, 0x66, 0x11, 0x38, 0xf2, 0x3a, 0xf5, 0xd7, 0x8a, 0x14, 0x25, 0x3d, 0x52, 0x14, 0x3d, 0x76, 0xf2, 0xa5, 0x17, 0x81, 0x23, 0xaf,
0x51, 0x64, 0xc5, 0x21, 0xfd, 0xa3, 0x1d, 0xc8, 0xb5, 0x5b, 0x27, 0xd6, 0x17, 0xa4, 0x58, 0xb2, 0x63, 0x45, 0x56, 0x9c, 0xa5, 0xbf, 0xb2, 0x0d, 0xb9, 0x76, 0xeb, 0xc4, 0xfa, 0x05, 0x29, 0x96,
0xd9, 0x91, 0x0b, 0x17, 0x41, 0x0a, 0x74, 0xc5, 0x1d, 0xd2, 0x5b, 0xaf, 0x76, 0xb7, 0xbb, 0x43, 0x6c, 0x76, 0xe4, 0xc2, 0x45, 0x90, 0x02, 0x5d, 0x71, 0x87, 0xf4, 0xd6, 0xab, 0xdd, 0xed, 0xee,
0xcb, 0x4a, 0x2e, 0xed, 0xad, 0xc8, 0xa9, 0xa7, 0xde, 0x82, 0x02, 0x2d, 0xd0, 0x73, 0x7b, 0xe9, 0xd0, 0x32, 0x93, 0x4b, 0x7b, 0x28, 0x50, 0xe4, 0xd4, 0x53, 0x6f, 0x41, 0x81, 0x16, 0xe8, 0xb9,
0xad, 0x3d, 0x07, 0xe8, 0xa5, 0x97, 0x5e, 0x7a, 0x08, 0x0a, 0xff, 0x11, 0x05, 0x7a, 0x2b, 0xde, 0xfd, 0x03, 0xda, 0x73, 0x80, 0x5e, 0x7a, 0xee, 0x21, 0x28, 0xfc, 0x0f, 0xf4, 0x56, 0xa0, 0xb7,
0xcc, 0x2c, 0x39, 0xfc, 0xd0, 0x92, 0xac, 0x4f, 0x9c, 0x79, 0xf3, 0x3e, 0xe6, 0x7d, 0xbf, 0x59, 0xe2, 0xcd, 0xcc, 0x92, 0xc3, 0x1f, 0x5a, 0x92, 0xf5, 0x89, 0x33, 0x6f, 0xde, 0x8f, 0x79, 0xef,
0x42, 0xb9, 0x6b, 0x73, 0x76, 0x66, 0x9f, 0xd7, 0xc3, 0x28, 0xe0, 0x01, 0x79, 0xfb, 0x34, 0x38, 0xcd, 0x7b, 0xf3, 0x99, 0x25, 0x2c, 0xb5, 0x1c, 0xce, 0xce, 0x9c, 0x8e, 0x1d, 0xc5, 0x21, 0x0f,
0x39, 0xaf, 0x9f, 0xf4, 0x5c, 0xcf, 0x79, 0xee, 0xf2, 0xfa, 0x8b, 0xff, 0xaf, 0x77, 0xa2, 0xc0, 0xc9, 0xe5, 0xd3, 0xf0, 0xa4, 0x63, 0x9f, 0xb4, 0x3d, 0xdf, 0x7d, 0xe9, 0x71, 0xfb, 0xd5, 0xff,
0xe7, 0xcc, 0x77, 0xcc, 0x8f, 0xba, 0x2e, 0x7f, 0xd6, 0x3b, 0xa9, 0xb7, 0x83, 0xd3, 0x46, 0x37, 0xdb, 0xcd, 0x38, 0x0c, 0x38, 0x0b, 0x5c, 0xf3, 0xe3, 0x96, 0xc7, 0x5f, 0xb4, 0x4f, 0xec, 0x46,
0xe8, 0x06, 0x0d, 0x41, 0x71, 0xd2, 0xeb, 0x88, 0x9d, 0xd8, 0x88, 0x95, 0xe4, 0x64, 0x36, 0x47, 0x78, 0x5a, 0x6b, 0x85, 0xad, 0xb0, 0x26, 0x24, 0x4e, 0xda, 0x4d, 0x31, 0x13, 0x13, 0x31, 0x92,
0xd1, 0xbb, 0x41, 0xd0, 0xf5, 0x98, 0x1d, 0xba, 0xb1, 0x5a, 0x36, 0xa2, 0xb0, 0xdd, 0x88, 0xb9, 0x9a, 0xcc, 0x8d, 0x41, 0xf6, 0x56, 0x18, 0xb6, 0x7c, 0xe6, 0x44, 0x5e, 0xa2, 0x86, 0xb5, 0x38,
0xcd, 0x7b, 0xb1, 0xa2, 0xb9, 0xa1, 0xd1, 0xe0, 0x45, 0x1a, 0xc9, 0x45, 0x1a, 0x71, 0xe0, 0xbd, 0x6a, 0xd4, 0x12, 0xee, 0xf0, 0x76, 0xa2, 0x64, 0x6e, 0x6a, 0x32, 0xb8, 0x91, 0x5a, 0xba, 0x91,
0x60, 0x51, 0x23, 0x3c, 0x69, 0x04, 0x61, 0x82, 0xdd, 0xb8, 0x10, 0xdb, 0x0e, 0xdd, 0x06, 0x3f, 0x5a, 0x12, 0xfa, 0xaf, 0x58, 0x5c, 0x8b, 0x4e, 0x6a, 0x61, 0x94, 0x72, 0xd7, 0xce, 0xe5, 0x76,
0x0f, 0x59, 0xdc, 0x38, 0x0b, 0xa2, 0xe7, 0x2c, 0x52, 0x04, 0xb7, 0x2e, 0x24, 0xe8, 0x71, 0xd7, 0x22, 0xaf, 0xc6, 0x3b, 0x11, 0x4b, 0x6a, 0x67, 0x61, 0xfc, 0x92, 0xc5, 0x4a, 0xe0, 0xf6, 0xb9,
0x43, 0xaa, 0xb6, 0x1d, 0xc6, 0x28, 0x04, 0x7f, 0x15, 0x91, 0xae, 0x36, 0x0f, 0x7c, 0x37, 0xe6, 0x02, 0x6d, 0xee, 0xf9, 0x28, 0xd5, 0x70, 0xa2, 0x04, 0x8d, 0xe0, 0xaf, 0x12, 0xd2, 0xdd, 0xe6,
0xae, 0xdb, 0x75, 0x1b, 0x9d, 0x58, 0xd0, 0x48, 0x29, 0xa8, 0x84, 0x44, 0xb7, 0xfe, 0x96, 0x85, 0x61, 0xe0, 0x25, 0xdc, 0xf3, 0x5a, 0x5e, 0xad, 0x99, 0x08, 0x19, 0x69, 0x05, 0x9d, 0x50, 0xec,
0x65, 0xca, 0xe2, 0x9e, 0xc7, 0xc9, 0x1a, 0x94, 0x23, 0xd6, 0xd9, 0x61, 0x61, 0xc4, 0xda, 0x36, 0x77, 0x33, 0x5c, 0x68, 0xc7, 0x0d, 0x16, 0x85, 0xbe, 0xd7, 0xe8, 0xa0, 0x0d, 0x39, 0x92, 0x62,
0x67, 0x4e, 0xcd, 0x58, 0x35, 0xd6, 0x0b, 0xfb, 0x0b, 0x74, 0x18, 0x4c, 0x7e, 0x04, 0x95, 0x88, 0xd6, 0xdf, 0xf2, 0x50, 0xa0, 0x2c, 0x69, 0xfb, 0x9c, 0xac, 0xc2, 0x52, 0xcc, 0x9a, 0x3b, 0x2c,
0x75, 0x62, 0x0d, 0x71, 0x71, 0xd5, 0x58, 0x2f, 0x36, 0x3f, 0xac, 0x5f, 0xe8, 0x8c, 0x3a, 0x65, 0x8a, 0x59, 0xc3, 0xe1, 0xcc, 0xad, 0x1a, 0x2b, 0xc6, 0xda, 0xe2, 0xfe, 0x0c, 0xed, 0x27, 0x93,
0x9d, 0x23, 0x3b, 0x1c, 0x90, 0xec, 0x2f, 0xd0, 0x11, 0x26, 0xa4, 0x09, 0x99, 0x88, 0x75, 0x6a, 0x1f, 0x41, 0x39, 0x66, 0xcd, 0x44, 0x63, 0x9c, 0x5d, 0x31, 0xd6, 0x8a, 0x1b, 0x1f, 0xd9, 0xe7,
0x19, 0xc1, 0xeb, 0x4a, 0x3a, 0xaf, 0xfd, 0x05, 0x8a, 0xc8, 0x64, 0x13, 0xb2, 0xc8, 0xa5, 0x96, 0xe6, 0xd0, 0xa6, 0xac, 0x79, 0xe4, 0x44, 0x3d, 0x91, 0xfd, 0x19, 0x3a, 0xa0, 0x84, 0x6c, 0x40,
0x15, 0x44, 0x57, 0xa7, 0x5e, 0x60, 0x7f, 0x81, 0x0a, 0x02, 0xf2, 0x10, 0xf2, 0xa7, 0x8c, 0xdb, 0x2e, 0x66, 0xcd, 0x6a, 0x4e, 0xe8, 0xba, 0x92, 0xad, 0x6b, 0x7f, 0x86, 0x22, 0x33, 0xd9, 0x84,
0x8e, 0xcd, 0xed, 0x1a, 0xac, 0x66, 0xd6, 0x8b, 0xcd, 0x46, 0x2a, 0x31, 0x1a, 0xa8, 0x7e, 0xa4, 0x3c, 0x6a, 0xa9, 0xe6, 0x85, 0xd0, 0xd5, 0xb1, 0x1b, 0xd8, 0x9f, 0xa1, 0x42, 0x80, 0x3c, 0x86,
0x28, 0x76, 0x7d, 0x1e, 0x9d, 0xd3, 0x3e, 0x03, 0xf2, 0x14, 0x4a, 0x36, 0xe7, 0x0c, 0xad, 0xea, 0x85, 0x53, 0xc6, 0x1d, 0xd7, 0xe1, 0x4e, 0x15, 0x56, 0x72, 0x6b, 0xc5, 0x8d, 0x5a, 0xa6, 0x30,
0x06, 0x7e, 0x5c, 0x2b, 0x0a, 0x86, 0xb7, 0xa6, 0x33, 0x7c, 0xa0, 0x51, 0x49, 0xa6, 0x43, 0x8c, 0x06, 0xc8, 0x3e, 0x52, 0x12, 0xbb, 0x01, 0x8f, 0x3b, 0xb4, 0xab, 0x80, 0x3c, 0x87, 0x92, 0xc3,
0xcc, 0x7b, 0x50, 0x1e, 0x92, 0x49, 0xaa, 0x90, 0x79, 0xce, 0xce, 0xa5, 0x63, 0x28, 0x2e, 0xc9, 0x39, 0xc3, 0x64, 0x78, 0x61, 0x90, 0x54, 0x4b, 0x42, 0xe1, 0xed, 0xf1, 0x0a, 0x1f, 0x69, 0x52,
0x65, 0x58, 0x7a, 0x61, 0x7b, 0x3d, 0x26, 0x7c, 0x50, 0xa2, 0x72, 0x73, 0x77, 0xf1, 0x8e, 0x61, 0x52, 0x69, 0x9f, 0x22, 0xf3, 0x01, 0x2c, 0xf5, 0xd9, 0x24, 0x15, 0xc8, 0xbd, 0x64, 0x1d, 0x99,
0x3e, 0x83, 0x4b, 0x63, 0xfc, 0x27, 0x30, 0xf8, 0x81, 0xce, 0xa0, 0xd8, 0xfc, 0x20, 0xe5, 0xd6, 0x18, 0x8a, 0x43, 0x72, 0x09, 0xe6, 0x5e, 0x39, 0x7e, 0x9b, 0x89, 0x1c, 0x94, 0xa8, 0x9c, 0xdc,
0x3a, 0x3b, 0x4d, 0xd2, 0x56, 0x1e, 0x96, 0x23, 0xa1, 0x90, 0xf5, 0x1b, 0x03, 0xaa, 0xa3, 0xae, 0x9f, 0xbd, 0x67, 0x98, 0x2f, 0xe0, 0xc2, 0x90, 0xfe, 0x11, 0x0a, 0x7e, 0xa0, 0x2b, 0x28, 0x6e,
0x26, 0x07, 0xca, 0x49, 0x86, 0x30, 0xcb, 0xc7, 0x73, 0x44, 0x09, 0x02, 0x94, 0x61, 0x04, 0x0b, 0x7c, 0x98, 0xb1, 0x6b, 0x5d, 0x9d, 0x66, 0x69, 0x6b, 0x01, 0x0a, 0xb1, 0x70, 0xc8, 0xfa, 0xad,
0x73, 0x13, 0x0a, 0x7d, 0xd0, 0x34, 0x63, 0x14, 0xb4, 0x2b, 0x5a, 0x9b, 0x90, 0xa1, 0xac, 0x43, 0x01, 0x95, 0xc1, 0x54, 0x93, 0x03, 0x95, 0x24, 0x43, 0x84, 0xe5, 0xee, 0x14, 0xa7, 0x04, 0x09,
0x2a, 0xb0, 0xe8, 0xaa, 0xb8, 0xa6, 0x8b, 0xae, 0x43, 0x56, 0x21, 0xe3, 0xb0, 0x8e, 0x52, 0xbd, 0x2a, 0x30, 0x42, 0x85, 0xb9, 0x09, 0x8b, 0x5d, 0xd2, 0xb8, 0x60, 0x2c, 0x6a, 0x5b, 0xb4, 0x36,
0x52, 0x0f, 0x4f, 0xea, 0x3b, 0xac, 0xe3, 0xfa, 0x2e, 0xaa, 0x48, 0xf1, 0xc8, 0xfa, 0x9d, 0x81, 0x21, 0x47, 0x59, 0x93, 0x94, 0x61, 0xd6, 0x53, 0xe7, 0x9a, 0xce, 0x7a, 0x2e, 0x59, 0x81, 0x9c,
0xf9, 0x81, 0xd7, 0x22, 0x9f, 0x0c, 0xe9, 0x31, 0x3d, 0xda, 0xc7, 0x6e, 0xff, 0x34, 0xfd, 0xf6, 0xcb, 0x9a, 0xca, 0xf5, 0xb2, 0x1d, 0x9d, 0xd8, 0x3b, 0xac, 0xe9, 0x05, 0x1e, 0xba, 0x48, 0x71,
0xb7, 0x87, 0x3d, 0x31, 0x25, 0x05, 0x74, 0xed, 0x7e, 0x0c, 0x25, 0xdd, 0x37, 0x64, 0x1f, 0x8a, 0xc9, 0xfa, 0xbd, 0x81, 0xf5, 0x81, 0xdb, 0x22, 0x9f, 0xf4, 0xf9, 0x31, 0xfe, 0xb4, 0x0f, 0xed,
0x5a, 0x1c, 0xa9, 0x0b, 0xaf, 0xcd, 0xe6, 0x59, 0xaa, 0x93, 0x5a, 0x7f, 0xc8, 0x40, 0x51, 0x3b, 0xfe, 0x79, 0xf6, 0xee, 0xef, 0xf4, 0x67, 0x62, 0x4c, 0x09, 0xe8, 0xde, 0xfd, 0x18, 0x4a, 0x7a,
0x24, 0xf7, 0x21, 0xfb, 0xdc, 0xf5, 0xa5, 0x09, 0x2b, 0xcd, 0x8d, 0xd9, 0x58, 0x3e, 0x74, 0x7d, 0x6e, 0xc8, 0x3e, 0x14, 0xb5, 0x73, 0xa4, 0x36, 0xbc, 0x3a, 0x59, 0x66, 0xa9, 0x2e, 0x6a, 0xfd,
0x87, 0x0a, 0x3a, 0xd2, 0xd2, 0xf2, 0x6e, 0x51, 0x5c, 0xeb, 0xf6, 0x6c, 0x3c, 0x2e, 0x4c, 0xbe, 0x31, 0x07, 0x45, 0x6d, 0x91, 0x3c, 0x84, 0xfc, 0x4b, 0x2f, 0x90, 0x21, 0x2c, 0x6f, 0xac, 0x4f,
0x9b, 0x73, 0x94, 0x0d, 0x59, 0x34, 0x08, 0x64, 0x43, 0x9b, 0x3f, 0x13, 0x45, 0xa3, 0x40, 0xc5, 0xa6, 0xf2, 0xb1, 0x17, 0xb8, 0x54, 0xc8, 0x91, 0xba, 0x56, 0x77, 0xb3, 0x62, 0x5b, 0x77, 0x26,
0x9a, 0xdc, 0x84, 0x37, 0x5c, 0xff, 0x49, 0xc0, 0x83, 0x56, 0xc4, 0x1c, 0x17, 0x83, 0xef, 0xc9, 0xd3, 0x71, 0x6e, 0xf1, 0xdd, 0x9a, 0xa2, 0x6d, 0xc8, 0xa6, 0x41, 0x20, 0x1f, 0x39, 0xfc, 0x85,
0x79, 0xc8, 0x6a, 0x4b, 0x02, 0x65, 0xd2, 0x11, 0x69, 0x41, 0x45, 0x82, 0x8f, 0x7b, 0x27, 0x3f, 0x68, 0x1a, 0x8b, 0x54, 0x8c, 0xc9, 0x2d, 0xb8, 0xe8, 0x05, 0xcf, 0x42, 0x1e, 0xd6, 0x63, 0xe6,
0x63, 0x6d, 0x1e, 0xd7, 0x96, 0x85, 0x3e, 0xeb, 0x29, 0x57, 0x38, 0xd0, 0x09, 0xe8, 0x08, 0xfd, 0x7a, 0x78, 0xf8, 0x9e, 0x75, 0x22, 0x56, 0x9d, 0x13, 0x2c, 0xa3, 0x96, 0x48, 0x1d, 0xca, 0x92,
0x6b, 0x65, 0xbb, 0xf5, 0x27, 0x03, 0xca, 0x43, 0xec, 0xc9, 0xa7, 0x43, 0xae, 0xba, 0x31, 0xeb, 0x7c, 0xdc, 0x3e, 0xf9, 0x19, 0x6b, 0xf0, 0xa4, 0x5a, 0x10, 0xfe, 0xac, 0x65, 0x6c, 0xe1, 0x40,
0xb5, 0x34, 0x67, 0x7d, 0x06, 0xcb, 0x8e, 0xdb, 0x65, 0x31, 0x17, 0xae, 0x2a, 0x6c, 0x35, 0xbf, 0x17, 0xa0, 0x03, 0xf2, 0x6f, 0x55, 0xed, 0xd6, 0x9f, 0x0d, 0x58, 0xea, 0x53, 0x4f, 0x3e, 0xed,
0xfd, 0xee, 0xdd, 0x85, 0x7f, 0x7e, 0xf7, 0xee, 0x86, 0xd6, 0x62, 0x82, 0x90, 0xf9, 0xed, 0xc0, 0x4b, 0xd5, 0xcd, 0x49, 0xb7, 0xa5, 0x25, 0xeb, 0x33, 0x28, 0xb8, 0x5e, 0x8b, 0x25, 0x5c, 0xa4,
0xe7, 0xb6, 0xeb, 0xb3, 0x08, 0x3b, 0xe5, 0x47, 0x92, 0xa4, 0xbe, 0x23, 0x7e, 0xa8, 0xe2, 0x80, 0x6a, 0x71, 0x6b, 0xe3, 0xdb, 0xef, 0xde, 0x9f, 0xf9, 0xc7, 0x77, 0xef, 0xaf, 0x6b, 0x57, 0x4d,
0x46, 0xf7, 0xed, 0x53, 0x26, 0xfc, 0x54, 0xa0, 0x62, 0x6d, 0x71, 0x28, 0x53, 0xc6, 0x7b, 0x91, 0x18, 0xb1, 0xa0, 0x11, 0x06, 0xdc, 0xf1, 0x02, 0x16, 0xe3, 0x05, 0xfb, 0xb1, 0x14, 0xb1, 0x77,
0x4f, 0xd9, 0xcf, 0x7b, 0x88, 0xf4, 0xbd, 0xa4, 0x90, 0x88, 0x4b, 0x4f, 0x2b, 0xe8, 0x88, 0x48, 0xc4, 0x0f, 0x55, 0x1a, 0x30, 0xe8, 0x81, 0x73, 0xca, 0x44, 0x9e, 0x16, 0xa9, 0x18, 0x5b, 0x1c,
0x15, 0x01, 0x59, 0x87, 0x25, 0x16, 0x45, 0x41, 0xa4, 0x92, 0x87, 0xd4, 0x65, 0xcf, 0xae, 0x47, 0x96, 0x28, 0xe3, 0xed, 0x38, 0xa0, 0xec, 0xe7, 0x6d, 0x64, 0xfa, 0x5e, 0xda, 0x48, 0xc4, 0xa6,
0x61, 0xbb, 0x7e, 0x2c, 0x7a, 0x36, 0x95, 0x08, 0x56, 0x15, 0x2a, 0x89, 0xd4, 0x38, 0x0c, 0xfc, 0xc7, 0x35, 0x74, 0x64, 0xa4, 0x4a, 0x80, 0xac, 0xc1, 0x1c, 0x8b, 0xe3, 0x30, 0x56, 0xc5, 0x43,
0x98, 0x59, 0x2b, 0x68, 0xba, 0xb0, 0xc7, 0x63, 0x75, 0x0f, 0xeb, 0xaf, 0x06, 0x54, 0x12, 0x88, 0x6c, 0x79, 0xd5, 0xdb, 0x71, 0xd4, 0xb0, 0x8f, 0xc5, 0x55, 0x4f, 0x25, 0x83, 0x55, 0x81, 0x72,
0xc4, 0x21, 0x5f, 0x40, 0x71, 0x50, 0x1a, 0x92, 0x1a, 0x70, 0x37, 0xd5, 0xa8, 0x3a, 0xbd, 0x56, 0x6a, 0x35, 0x89, 0xc2, 0x20, 0x61, 0xd6, 0x32, 0x86, 0x2e, 0x6a, 0xf3, 0x44, 0xed, 0xc3, 0xfa,
0x57, 0x54, 0x49, 0xd0, 0xd9, 0x99, 0x8f, 0xa0, 0x3a, 0x8a, 0x30, 0xc1, 0xfb, 0xef, 0x0d, 0x17, 0xab, 0x01, 0xe5, 0x94, 0x22, 0x79, 0xc8, 0x17, 0x50, 0xec, 0xb5, 0x86, 0xb4, 0x07, 0xdc, 0xcf,
0x88, 0xd1, 0x7a, 0xa5, 0x45, 0xc3, 0x3f, 0x0c, 0x78, 0x9b, 0x32, 0x31, 0x84, 0x1c, 0x9c, 0xda, 0x0c, 0xaa, 0x2e, 0xaf, 0xf5, 0x15, 0xd5, 0x12, 0x74, 0x75, 0xe6, 0x13, 0xa8, 0x0c, 0x32, 0x8c,
0x5d, 0xb6, 0x1d, 0xf8, 0x1d, 0xb7, 0x9b, 0x98, 0xb9, 0x2a, 0x8a, 0x61, 0xc2, 0x19, 0xeb, 0xe2, 0xc8, 0xfe, 0x07, 0xfd, 0x0d, 0x62, 0xb0, 0x5f, 0x69, 0xa7, 0xe1, 0x5f, 0x06, 0x5c, 0xa6, 0x4c,
0x3a, 0xe4, 0x5b, 0x9e, 0xcd, 0x3b, 0x41, 0x74, 0xaa, 0x98, 0x97, 0x90, 0x79, 0x02, 0xa3, 0xfd, 0x60, 0x97, 0x83, 0x53, 0xa7, 0xc5, 0xb6, 0xc3, 0xa0, 0xe9, 0xb5, 0xd2, 0x30, 0x57, 0x44, 0x33,
0x53, 0xb2, 0x0a, 0x45, 0xc5, 0xf8, 0x28, 0x70, 0x12, 0x77, 0xea, 0x20, 0x52, 0x83, 0xdc, 0x61, 0x4c, 0x35, 0x63, 0x5f, 0x5c, 0x83, 0x85, 0xba, 0xef, 0xf0, 0x66, 0x18, 0x9f, 0x2a, 0xe5, 0x25,
0xd0, 0x7d, 0x84, 0xce, 0x96, 0x19, 0x96, 0x6c, 0x89, 0x05, 0x25, 0x85, 0x18, 0xf5, 0xb3, 0x6b, 0x54, 0x9e, 0xd2, 0x68, 0x77, 0x95, 0xac, 0x40, 0x51, 0x29, 0x3e, 0x0a, 0xdd, 0x34, 0x9d, 0x3a,
0x89, 0x0e, 0xc1, 0xc8, 0x3b, 0x50, 0x38, 0x66, 0x71, 0xec, 0x06, 0xfe, 0xc1, 0x4e, 0x6d, 0x59, 0x89, 0x54, 0x61, 0xfe, 0x30, 0x6c, 0x3d, 0xc1, 0x64, 0xcb, 0x0a, 0x4b, 0xa7, 0xc4, 0x82, 0x92,
0xd0, 0x0f, 0x00, 0xd6, 0x2f, 0x0c, 0x30, 0x27, 0xe9, 0xa5, 0x9c, 0xf4, 0x19, 0x2c, 0xcb, 0xb0, 0x62, 0x8c, 0xbb, 0xd5, 0x35, 0x47, 0xfb, 0x68, 0xe4, 0x3d, 0x58, 0x3c, 0x66, 0x49, 0xe2, 0x85,
0x93, 0xba, 0xfd, 0x6f, 0x01, 0x2b, 0x7f, 0xc9, 0x5b, 0xb0, 0x2c, 0xb9, 0xab, 0x5c, 0x53, 0x3b, 0xc1, 0xc1, 0x4e, 0xb5, 0x20, 0xe4, 0x7b, 0x04, 0xd4, 0x7d, 0xcc, 0xc3, 0x98, 0x1d, 0xec, 0x54,
0xeb, 0xcf, 0x4b, 0x50, 0x3a, 0xc6, 0x0b, 0x24, 0xd6, 0xac, 0x03, 0x0c, 0x9c, 0xa0, 0x02, 0x77, 0xe7, 0xa5, 0x6e, 0x35, 0xb5, 0x7e, 0x61, 0x80, 0x39, 0xca, 0x63, 0x95, 0xbe, 0xcf, 0xa0, 0x20,
0xd4, 0x35, 0x1a, 0x06, 0x31, 0x21, 0xbf, 0xa7, 0x82, 0x44, 0xf5, 0xa9, 0xfe, 0x9e, 0x7c, 0x0e, 0x0f, 0xa4, 0xf4, 0xfa, 0x7f, 0x3b, 0xca, 0xf2, 0x97, 0xbc, 0x0b, 0x05, 0xa9, 0x5d, 0x55, 0xa1,
0xc5, 0x64, 0xfd, 0x38, 0xe4, 0xb5, 0x8c, 0x88, 0xb2, 0x3b, 0x29, 0x51, 0xa6, 0xdf, 0xa4, 0xae, 0x9a, 0x59, 0xbf, 0x2a, 0x40, 0xe9, 0x18, 0x37, 0x90, 0xc6, 0xd9, 0x06, 0xe8, 0xa5, 0x47, 0x1d,
0x91, 0xaa, 0x18, 0xd3, 0x20, 0xe4, 0x06, 0x5c, 0xb2, 0x3d, 0x2f, 0x38, 0x53, 0x89, 0x23, 0x52, 0xe9, 0xc1, 0xa4, 0x69, 0x1c, 0xc4, 0x84, 0x85, 0x3d, 0x75, 0x7c, 0xd4, 0x0d, 0xd6, 0x9d, 0x93,
0x40, 0xb8, 0x20, 0x4f, 0xc7, 0x0f, 0xb0, 0x20, 0x6a, 0xc0, 0x07, 0x51, 0x64, 0x9f, 0x63, 0xcc, 0xcf, 0xa1, 0x98, 0x8e, 0x9f, 0x46, 0xbc, 0x9a, 0x13, 0xe7, 0xef, 0x5e, 0xc6, 0xf9, 0xd3, 0x77,
0x2c, 0x0b, 0xfc, 0x49, 0x47, 0x58, 0x9b, 0xf6, 0x5c, 0xdf, 0xf6, 0x6a, 0x20, 0x70, 0xe4, 0x06, 0x62, 0x6b, 0xa2, 0xea, 0xf4, 0x69, 0x14, 0x72, 0x13, 0x2e, 0x38, 0xbe, 0x1f, 0x9e, 0xa9, 0x92,
0x7d, 0xbe, 0xfb, 0x32, 0x0c, 0x22, 0xce, 0xa2, 0x07, 0x9c, 0x47, 0xb5, 0xa2, 0x30, 0xe6, 0x10, 0x12, 0xc5, 0x21, 0x92, 0xb3, 0x40, 0x87, 0x17, 0xb0, 0x55, 0x6a, 0xc4, 0x47, 0x71, 0xec, 0x74,
0x8c, 0xb4, 0xa0, 0xb4, 0x6d, 0xb7, 0x9f, 0xb1, 0x83, 0x53, 0x04, 0xc6, 0xb5, 0x92, 0x50, 0x3b, 0xf0, 0x34, 0x15, 0x04, 0xff, 0xa8, 0x25, 0xec, 0x5a, 0x7b, 0x5e, 0xe0, 0xf8, 0x55, 0x10, 0x3c,
0xad, 0x62, 0x09, 0xf4, 0xc7, 0xa1, 0x3e, 0x38, 0xe9, 0x1c, 0x48, 0x1b, 0x2a, 0x89, 0xea, 0x32, 0x72, 0x82, 0xa7, 0x61, 0xf7, 0x75, 0x14, 0xc6, 0x9c, 0xc5, 0x8f, 0x38, 0x8f, 0xab, 0x45, 0x11,
0x0f, 0x6b, 0x65, 0xc1, 0xf3, 0xde, 0xbc, 0xa6, 0x94, 0xd4, 0x52, 0xc4, 0x08, 0x4b, 0x74, 0xe4, 0xcc, 0x3e, 0x1a, 0xa9, 0x43, 0x69, 0xdb, 0x69, 0xbc, 0x60, 0x07, 0xa7, 0x48, 0x4c, 0x91, 0x55,
0x2e, 0xa6, 0x9c, 0xcd, 0x59, 0xad, 0x22, 0x74, 0xee, 0xef, 0xcd, 0xfb, 0x50, 0x1d, 0xf5, 0xc6, 0x56, 0x2f, 0x13, 0xec, 0x4f, 0x23, 0x1d, 0x52, 0xe9, 0x1a, 0x48, 0x03, 0xca, 0xa9, 0xeb, 0xb2,
0x3c, 0xf3, 0x8a, 0xf9, 0x43, 0x78, 0x63, 0xc2, 0x15, 0x5e, 0xab, 0x26, 0xfc, 0xd1, 0x80, 0x4b, 0x42, 0xab, 0x4b, 0x42, 0xe7, 0x83, 0x69, 0x43, 0x29, 0xa5, 0xa5, 0x89, 0x01, 0x95, 0x98, 0xc8,
0x63, 0x76, 0xc3, 0xba, 0x2c, 0x72, 0x51, 0xb2, 0x14, 0x6b, 0x72, 0x04, 0x4b, 0xe8, 0x97, 0x58, 0x5d, 0x2c, 0x46, 0x87, 0xb3, 0x6a, 0x59, 0xf8, 0xdc, 0x9d, 0x93, 0x23, 0x28, 0x1f, 0x0b, 0x40,
0x75, 0xe8, 0xcd, 0x79, 0x1c, 0x51, 0x17, 0x94, 0xd2, 0x60, 0x92, 0x8b, 0x79, 0x07, 0x60, 0x00, 0x5e, 0x47, 0x18, 0xee, 0xb1, 0xa4, 0xba, 0x2c, 0x36, 0x70, 0x7d, 0x78, 0x03, 0x3a, 0x70, 0xb7,
0x9c, 0x6b, 0x6a, 0xfb, 0x02, 0xca, 0xca, 0x2b, 0x2a, 0xc1, 0xab, 0xb2, 0xd9, 0x2b, 0x62, 0x6c, 0x05, 0x7b, 0x87, 0x0e, 0x08, 0x9b, 0x0f, 0xa1, 0x32, 0x98, 0xdc, 0x69, 0x80, 0x91, 0xf9, 0x43,
0xe6, 0x83, 0x96, 0x91, 0x99, 0xb3, 0x65, 0x58, 0x5f, 0xc1, 0x0a, 0x65, 0xb6, 0xb3, 0xe7, 0x7a, 0xb8, 0x38, 0xc2, 0xa3, 0xb7, 0x6a, 0x3e, 0x7f, 0x32, 0xe0, 0xc2, 0x50, 0x1a, 0xf0, 0x02, 0x10,
0xec, 0xe2, 0xca, 0x88, 0xd9, 0xea, 0x7a, 0xac, 0x85, 0x03, 0x43, 0x92, 0xad, 0x6a, 0x4f, 0xee, 0x45, 0x2f, 0x55, 0x8a, 0x31, 0x39, 0x82, 0x39, 0x4c, 0x73, 0xa2, 0xa0, 0xc0, 0xe6, 0x34, 0x79,
0xc2, 0x12, 0xb5, 0xfd, 0x2e, 0x53, 0xa2, 0xdf, 0x4b, 0x11, 0x2d, 0x84, 0x20, 0x2e, 0x95, 0x24, 0xb5, 0x85, 0xa4, 0x8c, 0xbf, 0xd4, 0x62, 0xde, 0x03, 0xe8, 0x11, 0xa7, 0x82, 0x87, 0x5f, 0xc0,
0xd6, 0x3d, 0x28, 0xf4, 0x61, 0x58, 0x6b, 0x1e, 0x77, 0x3a, 0x31, 0x93, 0x75, 0x2b, 0x43, 0xd5, 0x92, 0x4a, 0xb2, 0xea, 0x17, 0x15, 0x89, 0x2a, 0x94, 0x30, 0xa2, 0x86, 0xde, 0xdd, 0x94, 0x9b,
0x0e, 0xe1, 0x87, 0xcc, 0xef, 0x2a, 0xd1, 0x19, 0xaa, 0x76, 0xd6, 0x1a, 0x4e, 0xd9, 0xc9, 0xcd, 0xf2, 0x6e, 0xb2, 0xbe, 0x82, 0x65, 0xca, 0x1c, 0x77, 0xcf, 0xf3, 0xd9, 0xf9, 0x2d, 0x18, 0x8b,
0x95, 0x69, 0x08, 0x64, 0x77, 0x70, 0xaa, 0x32, 0x44, 0x82, 0x89, 0xb5, 0xe5, 0x60, 0xab, 0xb3, 0xdf, 0xf3, 0x59, 0x1d, 0x91, 0x49, 0x5a, 0xfc, 0x6a, 0x4e, 0xee, 0xc3, 0x1c, 0x75, 0x82, 0x16,
0x9d, 0x1d, 0x37, 0xba, 0x58, 0xc1, 0x1a, 0xe4, 0x76, 0xdc, 0x48, 0xd3, 0x2f, 0xd9, 0x92, 0x35, 0x53, 0xa6, 0x3f, 0xc8, 0x30, 0x2d, 0x8c, 0x20, 0x2f, 0x95, 0x22, 0xd6, 0x03, 0x58, 0xec, 0xd2,
0x6c, 0x82, 0x6d, 0xaf, 0xe7, 0xa0, 0xb6, 0x9c, 0x45, 0xbe, 0xaa, 0xf6, 0x23, 0x50, 0xeb, 0x13, 0xb0, 0x75, 0x3d, 0x6d, 0x36, 0x13, 0x26, 0xdb, 0x60, 0x8e, 0xaa, 0x19, 0xd2, 0x0f, 0x59, 0xd0,
0x69, 0x47, 0x21, 0x45, 0x5d, 0xe6, 0x06, 0xe4, 0x98, 0xcf, 0x23, 0x97, 0x25, 0x9d, 0x92, 0xd4, 0x52, 0xa6, 0x73, 0x54, 0xcd, 0xac, 0x55, 0x84, 0xf3, 0xe9, 0xce, 0x55, 0x68, 0x08, 0xe4, 0x77,
0xe5, 0x03, 0xb4, 0x2e, 0x1e, 0xa0, 0xa2, 0x23, 0xd3, 0x04, 0xc5, 0xda, 0x84, 0x15, 0x04, 0xa4, 0x10, 0xbe, 0x19, 0xa2, 0x5e, 0xc5, 0xd8, 0x72, 0xf1, 0x4e, 0x75, 0xdc, 0x1d, 0x2f, 0x3e, 0xdf,
0x3b, 0x82, 0x40, 0x56, 0xbb, 0xa4, 0x58, 0x5b, 0x77, 0xa1, 0x3a, 0x20, 0x54, 0xa2, 0xd7, 0x20, 0xc1, 0x2a, 0xcc, 0xef, 0x78, 0xb1, 0xe6, 0x5f, 0x3a, 0x25, 0xab, 0x78, 0xdb, 0x36, 0xfc, 0xb6,
0x8b, 0x23, 0xa3, 0x2a, 0xc4, 0x93, 0xe4, 0x8a, 0x73, 0xeb, 0x1a, 0xac, 0x24, 0xd9, 0x7a, 0xa1, 0x8b, 0xde, 0x72, 0x16, 0x07, 0xea, 0x5a, 0x19, 0xa0, 0x5a, 0x9f, 0xc8, 0x38, 0x0a, 0x2b, 0x6a,
0x50, 0x8b, 0x40, 0x75, 0x80, 0xa4, 0xa6, 0x85, 0x32, 0x14, 0x5b, 0xae, 0x9f, 0x34, 0x53, 0xeb, 0x33, 0x37, 0x61, 0x9e, 0x05, 0x3c, 0xc6, 0x32, 0x92, 0x57, 0x32, 0xb1, 0xe5, 0x03, 0xd9, 0x16,
0x95, 0x01, 0xa5, 0x56, 0xe0, 0x0f, 0x9a, 0x50, 0x0b, 0x56, 0x92, 0xd4, 0x7d, 0xd0, 0x3a, 0xd8, 0x0f, 0x64, 0x71, 0xf5, 0xd3, 0x94, 0xc5, 0xda, 0x84, 0x65, 0x24, 0x64, 0x27, 0x82, 0x40, 0x5e,
0xb6, 0xc3, 0xc4, 0x06, 0xab, 0xe3, 0xf1, 0xa1, 0x9e, 0xf0, 0x75, 0x89, 0xb8, 0x95, 0xc5, 0x7e, 0xdb, 0xa4, 0x18, 0x5b, 0xf7, 0xa1, 0xd2, 0x13, 0x54, 0xa6, 0x57, 0x21, 0x8f, 0xd8, 0x54, 0xf5,
0x45, 0x47, 0xc9, 0xc9, 0xa7, 0x90, 0x3b, 0x3c, 0xdc, 0x12, 0x9c, 0x16, 0xe7, 0xe2, 0x94, 0x90, 0xf5, 0x51, 0x76, 0xc5, 0xba, 0x75, 0x0d, 0x96, 0xd3, 0xe2, 0x3f, 0xd7, 0xa8, 0x45, 0xa0, 0xd2,
0x91, 0xfb, 0x90, 0x7b, 0x2a, 0xbe, 0x2c, 0xc4, 0xaa, 0xa7, 0x4c, 0x88, 0x55, 0x69, 0x21, 0x89, 0x63, 0x52, 0xb0, 0x64, 0x09, 0x8a, 0x75, 0x2f, 0x48, 0x6f, 0x6d, 0xeb, 0x8d, 0x01, 0xa5, 0x7a,
0x46, 0x59, 0x3b, 0x88, 0x1c, 0x9a, 0x10, 0x59, 0xff, 0x36, 0xa0, 0xf8, 0xd4, 0x1e, 0x0c, 0x6a, 0x18, 0xf4, 0xee, 0xb4, 0x3a, 0x2c, 0xa7, 0xa5, 0xfb, 0xa8, 0x7e, 0xb0, 0xed, 0x44, 0x69, 0x0c,
0x83, 0xc9, 0xf0, 0x35, 0x1a, 0xad, 0x9a, 0x0c, 0x2f, 0xc3, 0x92, 0xc7, 0x5e, 0x30, 0x4f, 0xc5, 0x56, 0x86, 0xcf, 0x87, 0xfa, 0xc4, 0x60, 0x4b, 0xc6, 0xad, 0x3c, 0x5e, 0x7f, 0x74, 0x50, 0x9c,
0xb8, 0xdc, 0x20, 0x34, 0x7e, 0x16, 0x44, 0x32, 0xad, 0x4b, 0x54, 0x6e, 0x30, 0x21, 0x1c, 0xc6, 0x7c, 0x0a, 0xf3, 0x87, 0x87, 0x5b, 0x42, 0xd3, 0xec, 0x54, 0x9a, 0x52, 0x31, 0xf2, 0x10, 0xe6,
0x6d, 0xd7, 0xab, 0x65, 0x57, 0x33, 0xd8, 0x94, 0xe5, 0x0e, 0x3d, 0xd7, 0x8b, 0x3c, 0x35, 0xae, 0x9f, 0x8b, 0x2f, 0x1f, 0x89, 0xba, 0xa2, 0x46, 0x9c, 0x55, 0x19, 0x21, 0xc9, 0x46, 0x59, 0x23,
0xe3, 0x92, 0x58, 0x90, 0x75, 0xfd, 0x4e, 0x20, 0x1a, 0x96, 0x2a, 0x8b, 0xc7, 0x41, 0x2f, 0x6a, 0x8c, 0x5d, 0x9a, 0x0a, 0x59, 0xff, 0x36, 0xa0, 0xf8, 0xdc, 0xe9, 0x21, 0xc2, 0x1e, 0x04, 0x7d,
0xb3, 0x03, 0xbf, 0x13, 0x50, 0x71, 0x46, 0xae, 0xc2, 0x72, 0x84, 0xf9, 0x17, 0xd7, 0x72, 0xc2, 0x8b, 0x7b, 0x5b, 0x41, 0xd0, 0x4b, 0x30, 0xe7, 0xb3, 0x57, 0xcc, 0x57, 0x67, 0x5c, 0x4e, 0x90,
0x28, 0x05, 0xc4, 0x92, 0x59, 0xaa, 0x0e, 0xac, 0x0a, 0x94, 0xa4, 0xde, 0xca, 0xf9, 0xbf, 0x5e, 0x9a, 0xbc, 0x08, 0x63, 0x59, 0xd6, 0x25, 0x2a, 0x27, 0x58, 0x10, 0x2e, 0xe3, 0x8e, 0xe7, 0x57,
0x84, 0x37, 0x1e, 0xb1, 0xb3, 0xed, 0x44, 0xaf, 0xc4, 0x20, 0xab, 0x50, 0xec, 0xc3, 0x0e, 0x76, 0xf3, 0x2b, 0x39, 0xbc, 0xe3, 0xe5, 0x0c, 0x33, 0xd7, 0x8e, 0x7d, 0xf5, 0x2e, 0xc0, 0x21, 0xb1,
0x54, 0x08, 0xe9, 0x20, 0x14, 0x76, 0x14, 0xf4, 0x7c, 0x9e, 0xf8, 0x50, 0x08, 0x13, 0x10, 0xaa, 0x20, 0xef, 0x05, 0xcd, 0x50, 0xdc, 0x7f, 0xaa, 0x2d, 0xca, 0x16, 0x7d, 0x10, 0x34, 0x43, 0x2a,
0x0e, 0xc8, 0xfb, 0x90, 0x7b, 0xc4, 0xf8, 0x59, 0x10, 0x3d, 0x17, 0x5a, 0x57, 0x9a, 0x45, 0xc4, 0xd6, 0xc8, 0x55, 0x28, 0xc4, 0x58, 0x7f, 0x49, 0x75, 0x5e, 0x04, 0x65, 0x11, 0xb9, 0x64, 0x95,
0x79, 0xc4, 0x38, 0xce, 0x55, 0x34, 0x39, 0xc3, 0x61, 0x2d, 0x4c, 0x86, 0xb5, 0xec, 0xa4, 0x61, 0xaa, 0x05, 0xab, 0x0c, 0x25, 0xe9, 0xb7, 0x4a, 0xfe, 0x6f, 0x66, 0xe1, 0xe2, 0x13, 0x76, 0xb6,
0x2d, 0x39, 0x25, 0x9b, 0x50, 0x6c, 0x07, 0x7e, 0xcc, 0x23, 0xdb, 0x45, 0xc1, 0x4b, 0x02, 0xf9, 0x9d, 0xfa, 0x95, 0x06, 0x64, 0x05, 0x8a, 0x5d, 0xda, 0xc1, 0x8e, 0x3a, 0x42, 0x3a, 0x09, 0x8d,
0x4d, 0x44, 0x96, 0x8e, 0xdd, 0x1e, 0x1c, 0x52, 0x1d, 0x93, 0x6c, 0x00, 0xb0, 0x97, 0x3c, 0xb2, 0x1d, 0x85, 0xed, 0x80, 0xa7, 0x39, 0x14, 0xc6, 0x04, 0x85, 0xaa, 0x05, 0x72, 0x1d, 0xe6, 0x9f,
0xf7, 0x83, 0xb8, 0xff, 0xb0, 0x01, 0xa4, 0x43, 0xc0, 0x41, 0x8b, 0x6a, 0xa7, 0xd6, 0x5b, 0x70, 0x30, 0x7e, 0x16, 0xc6, 0x2f, 0x85, 0xd7, 0xe5, 0x8d, 0x22, 0xf2, 0x3c, 0x61, 0x1c, 0x01, 0x1c,
0x79, 0xd8, 0x22, 0xca, 0x54, 0xf7, 0xe0, 0xff, 0x28, 0xf3, 0x98, 0x1d, 0xb3, 0xf9, 0xad, 0x65, 0x4d, 0xd7, 0x10, 0x15, 0x46, 0x29, 0x2a, 0xcc, 0x8f, 0x42, 0x85, 0xe9, 0x2a, 0xd9, 0x84, 0x62,
0x99, 0x50, 0x1b, 0x27, 0x56, 0x8c, 0xff, 0x93, 0x81, 0xe2, 0xee, 0x4b, 0xd6, 0x3e, 0x62, 0x71, 0x23, 0x0c, 0x12, 0x1e, 0x3b, 0x1e, 0x1a, 0x9e, 0x13, 0xcc, 0xef, 0x20, 0xb3, 0x4c, 0xec, 0x76,
0x6c, 0x77, 0xc5, 0xc8, 0xd8, 0x8a, 0x82, 0x36, 0x8b, 0xe3, 0x3e, 0xaf, 0x01, 0x80, 0x7c, 0x1f, 0x6f, 0x91, 0xea, 0x9c, 0x64, 0x1d, 0x80, 0xbd, 0xe6, 0xb1, 0xb3, 0x1f, 0x26, 0xdd, 0x17, 0x14,
0xb2, 0x07, 0xbe, 0xcb, 0x55, 0x7f, 0x5c, 0x4b, 0x9d, 0xd8, 0x5d, 0xae, 0x78, 0xee, 0x2f, 0x50, 0xa0, 0x1c, 0x12, 0x0e, 0xea, 0x54, 0x5b, 0xb5, 0xde, 0x85, 0x4b, 0xfd, 0x11, 0x51, 0xa1, 0x7a,
0x41, 0x45, 0xee, 0x42, 0x16, 0xab, 0xcb, 0x2c, 0x15, 0xde, 0xd1, 0x68, 0x91, 0x86, 0x6c, 0x89, 0x00, 0xff, 0x47, 0x99, 0xcf, 0x9c, 0x84, 0x4d, 0x1f, 0x2d, 0xcb, 0x84, 0xea, 0xb0, 0xb0, 0x52,
0x2f, 0x6b, 0xee, 0x97, 0x4c, 0x79, 0x69, 0x3d, 0xbd, 0x35, 0xb9, 0x5f, 0xb2, 0x01, 0x07, 0x45, 0xfc, 0x9f, 0x1c, 0x14, 0x77, 0x5f, 0xb3, 0xc6, 0x11, 0x4b, 0x12, 0xa7, 0x25, 0xb0, 0x69, 0x3d,
0x49, 0x76, 0x21, 0x77, 0xcc, 0xed, 0x88, 0x33, 0x47, 0x79, 0xef, 0x7a, 0xda, 0x04, 0x23, 0x31, 0x0e, 0x1b, 0x2c, 0x49, 0xba, 0xba, 0x7a, 0x04, 0xf2, 0x7d, 0xc8, 0x1f, 0x04, 0x1e, 0x57, 0xf7,
0x07, 0x5c, 0x12, 0x5a, 0x34, 0xc2, 0xee, 0x4b, 0x97, 0xab, 0x6c, 0x48, 0x33, 0x02, 0xa2, 0x69, 0xe3, 0x6a, 0xe6, 0xd3, 0xc0, 0xe3, 0x4a, 0xe7, 0xfe, 0x0c, 0x15, 0x52, 0xe4, 0x3e, 0xe4, 0xb1,
0x8a, 0xe0, 0x16, 0xa9, 0x77, 0x02, 0x9f, 0xd5, 0x72, 0x53, 0xa9, 0x11, 0x4d, 0xa3, 0xc6, 0x2d, 0xbb, 0x4c, 0xd2, 0xe1, 0x5d, 0x4d, 0x16, 0x65, 0xc8, 0x96, 0xf8, 0x84, 0xe7, 0x7d, 0xc9, 0x54,
0x9a, 0xe1, 0xd8, 0xed, 0xe2, 0x60, 0x98, 0x9f, 0x6a, 0x06, 0x89, 0xa8, 0x99, 0x41, 0x02, 0xb6, 0x96, 0xd6, 0xb2, 0xaf, 0x26, 0xef, 0x4b, 0xd6, 0xd3, 0xa0, 0x24, 0xc9, 0x2e, 0x22, 0x6b, 0x27,
0x72, 0xb0, 0x24, 0xc6, 0x20, 0xeb, 0xb7, 0x06, 0x14, 0x35, 0x3f, 0xcd, 0x90, 0x77, 0xef, 0x40, 0xe6, 0xcc, 0x55, 0xd9, 0xbb, 0x91, 0x05, 0x88, 0x24, 0x67, 0x4f, 0x4b, 0x2a, 0x8b, 0x41, 0xd8,
0x16, 0x5f, 0xd5, 0xca, 0xff, 0x79, 0x91, 0x75, 0x8c, 0xdb, 0x54, 0x40, 0xb1, 0x70, 0xec, 0x39, 0x7d, 0xed, 0x71, 0x55, 0x0d, 0x59, 0x41, 0x40, 0x36, 0xcd, 0x11, 0x9c, 0xa2, 0xf4, 0x4e, 0x18,
0xb2, 0x28, 0x96, 0x29, 0x2e, 0x11, 0xf2, 0x84, 0x9f, 0x0b, 0x97, 0xe5, 0x29, 0x2e, 0xc9, 0x0d, 0x30, 0x81, 0xed, 0xb3, 0xa5, 0x91, 0x4d, 0x93, 0xc6, 0x29, 0x86, 0xe1, 0xd8, 0x6b, 0x21, 0xce,
0xc8, 0x1f, 0xb3, 0x76, 0x2f, 0x72, 0xf9, 0xb9, 0x70, 0x42, 0xa5, 0x59, 0x15, 0xe5, 0x44, 0xc1, 0x5c, 0x18, 0x1b, 0x06, 0xc9, 0xa8, 0x85, 0x41, 0x12, 0xb6, 0xe6, 0x61, 0x4e, 0xc0, 0x20, 0xeb,
0x44, 0x72, 0xf6, 0x31, 0xac, 0x87, 0x18, 0x9c, 0x83, 0x0b, 0x12, 0xc8, 0x6e, 0xe3, 0x43, 0x09, 0x77, 0x06, 0x14, 0xb5, 0x3c, 0x4d, 0x50, 0x77, 0xef, 0x41, 0x1e, 0x9f, 0xef, 0x2a, 0xff, 0x0b,
0x6f, 0x56, 0xa6, 0x62, 0x8d, 0x6f, 0xd5, 0xdd, 0x69, 0x6f, 0xd5, 0xdd, 0xe4, 0xad, 0x3a, 0xec, 0xa2, 0xea, 0x18, 0x77, 0xa8, 0xa0, 0x62, 0xe3, 0xd8, 0x73, 0x65, 0x53, 0x5c, 0xa2, 0x38, 0x44,
0x54, 0xec, 0x3e, 0x9a, 0x91, 0xad, 0x07, 0x50, 0xe8, 0x07, 0x1e, 0xa9, 0xc0, 0xe2, 0x9e, 0xa3, 0xca, 0x33, 0xde, 0x11, 0x29, 0x5b, 0xa0, 0x38, 0x24, 0x37, 0x61, 0xe1, 0x98, 0x35, 0xda, 0xb1,
0x24, 0x2d, 0xee, 0x39, 0xa8, 0xca, 0xee, 0xe3, 0x3d, 0x21, 0x25, 0x4f, 0x71, 0xd9, 0x1f, 0x12, 0xc7, 0x3b, 0x22, 0x09, 0xe5, 0x8d, 0x8a, 0x68, 0x27, 0x8a, 0x26, 0x8a, 0xb3, 0xcb, 0x61, 0x3d,
0x32, 0xda, 0x90, 0xb0, 0x89, 0xaf, 0x70, 0x2d, 0xfa, 0x10, 0x89, 0x06, 0x67, 0x71, 0x72, 0x65, 0xc6, 0xc3, 0xd9, 0xdb, 0x20, 0x81, 0xfc, 0x36, 0xbe, 0xc8, 0x70, 0x67, 0x4b, 0x54, 0x8c, 0xf1,
0x5c, 0x4b, 0x35, 0xbc, 0x58, 0xf0, 0x12, 0x6a, 0x78, 0xb1, 0x75, 0x0d, 0xca, 0x43, 0xfe, 0x42, 0x51, 0xbc, 0x3b, 0xee, 0x51, 0xbc, 0x9b, 0x3e, 0x8a, 0xfb, 0x93, 0x8a, 0xb7, 0x8f, 0x16, 0x64,
0x24, 0xf1, 0xec, 0x53, 0xb3, 0x24, 0xae, 0x37, 0x18, 0xac, 0x8c, 0x7c, 0x09, 0x22, 0xef, 0xc3, 0xeb, 0x11, 0x2c, 0x76, 0x0f, 0x1e, 0x29, 0xc3, 0xec, 0x9e, 0xab, 0x2c, 0xcd, 0xee, 0xb9, 0xe8,
0xb2, 0xfc, 0xe2, 0x50, 0x5d, 0x30, 0xdf, 0xfe, 0xfa, 0x9b, 0xd5, 0x37, 0x47, 0x10, 0xe4, 0x21, 0xca, 0xee, 0xd3, 0x3d, 0x61, 0x65, 0x81, 0xe2, 0xb0, 0x0b, 0x12, 0x72, 0x1a, 0x48, 0xd8, 0xc4,
0xa2, 0x6d, 0xf5, 0x7c, 0xc7, 0x63, 0x55, 0x63, 0x22, 0x9a, 0x3c, 0x34, 0xb3, 0xbf, 0xfa, 0xfd, 0xe7, 0xbe, 0x76, 0xfa, 0x90, 0x89, 0x86, 0x67, 0x49, 0xba, 0x65, 0x1c, 0x4b, 0x37, 0xfc, 0x44,
0x95, 0x85, 0x0d, 0x1b, 0x2e, 0x8d, 0x7d, 0xc5, 0x20, 0xd7, 0x20, 0x7b, 0xcc, 0xbc, 0x4e, 0x22, 0xe8, 0x12, 0x6e, 0xf8, 0x89, 0x75, 0x0d, 0x96, 0xfa, 0xf2, 0x85, 0x4c, 0xe2, 0x7d, 0xa9, 0xb0,
0x66, 0x0c, 0x01, 0x0f, 0xc9, 0x55, 0xc8, 0x50, 0xfb, 0xac, 0x6a, 0x98, 0xb5, 0xaf, 0xbf, 0x59, 0x24, 0x8e, 0xd7, 0x19, 0x2c, 0x0f, 0x7c, 0x72, 0x22, 0xd7, 0xa1, 0x20, 0x3f, 0x6d, 0x54, 0x66,
0xbd, 0x3c, 0xfe, 0x29, 0xc4, 0x3e, 0x93, 0x22, 0x9a, 0x7f, 0x01, 0x28, 0x1c, 0x1e, 0x6e, 0x6d, 0xcc, 0xcb, 0x5f, 0x7f, 0xb3, 0xf2, 0xce, 0x00, 0x83, 0x5c, 0x44, 0xb6, 0xad, 0x76, 0xe0, 0xfa,
0x45, 0xae, 0xd3, 0x65, 0xe4, 0x97, 0x06, 0x90, 0xf1, 0x97, 0x28, 0xb9, 0x9d, 0x9e, 0xe3, 0x93, 0xac, 0x62, 0x8c, 0x64, 0x93, 0x8b, 0x66, 0xfe, 0xd7, 0x7f, 0xb8, 0x32, 0xb3, 0xee, 0xc0, 0x85,
0x1f, 0xe4, 0xe6, 0xc7, 0x73, 0x52, 0xa9, 0x49, 0xe3, 0x73, 0x58, 0x12, 0xe3, 0x31, 0xf9, 0x60, 0xa1, 0xcf, 0x25, 0xe4, 0x1a, 0xe4, 0x8f, 0x99, 0xdf, 0x4c, 0xcd, 0x0c, 0x31, 0xe0, 0x22, 0xb9,
0xc6, 0x67, 0x8d, 0xb9, 0x3e, 0x1d, 0x51, 0xf1, 0x6e, 0x43, 0x3e, 0x19, 0x31, 0xc9, 0x46, 0xea, 0x0a, 0x39, 0xea, 0x9c, 0x55, 0x0c, 0xb3, 0xfa, 0xf5, 0x37, 0x2b, 0x97, 0x86, 0xbf, 0xb9, 0x38,
0xf5, 0x86, 0x26, 0x68, 0xf3, 0xc3, 0x99, 0x70, 0x95, 0x90, 0x9f, 0x42, 0x4e, 0x4d, 0x8e, 0xe4, 0x67, 0xd2, 0xc4, 0xc6, 0x5f, 0x00, 0x16, 0x0f, 0x0f, 0xb7, 0xb6, 0x62, 0xcf, 0x6d, 0x31, 0xf2,
0xfa, 0x14, 0xba, 0xc1, 0x0c, 0x6b, 0x6e, 0xcc, 0x82, 0x3a, 0x50, 0x23, 0x99, 0x10, 0x53, 0xd5, 0x4b, 0x03, 0xc8, 0xf0, 0xc3, 0x96, 0xdc, 0xc9, 0xae, 0xf1, 0xd1, 0x2f, 0x7f, 0xf3, 0xee, 0x94,
0x18, 0x99, 0x3f, 0x53, 0xd5, 0x18, 0x1b, 0x39, 0xdb, 0x83, 0x87, 0x60, 0xaa, 0x90, 0x91, 0x79, 0x52, 0x0a, 0x69, 0x7c, 0x0e, 0x73, 0x02, 0x1e, 0x93, 0x0f, 0x27, 0x7c, 0x25, 0x99, 0x6b, 0xe3,
0x33, 0x55, 0xc8, 0xe8, 0xd8, 0x49, 0x9e, 0x42, 0x16, 0xc7, 0x4e, 0x92, 0x56, 0x7e, 0xb5, 0xb9, 0x19, 0x95, 0xee, 0x06, 0x2c, 0xa4, 0x10, 0x93, 0xac, 0x67, 0x6e, 0xaf, 0x0f, 0x41, 0x9b, 0x1f,
0xd4, 0x4c, 0x8b, 0x89, 0xa1, 0x79, 0xf5, 0x27, 0xd8, 0xa6, 0xc4, 0x9b, 0x3f, 0xbd, 0x41, 0x69, 0x4d, 0xc4, 0xab, 0x8c, 0xfc, 0x14, 0xe6, 0x15, 0x72, 0x24, 0x37, 0xc6, 0xc8, 0xf5, 0x30, 0xac,
0x1f, 0xea, 0xcc, 0xeb, 0x33, 0x60, 0x0e, 0xd8, 0xab, 0xf7, 0xf2, 0xfa, 0x0c, 0x5f, 0xcb, 0xa6, 0xb9, 0x3e, 0x09, 0x6b, 0xcf, 0x8d, 0x14, 0x21, 0x66, 0xba, 0x31, 0x80, 0x3f, 0x33, 0xdd, 0x18,
0xb3, 0x1f, 0xf9, 0x2e, 0x17, 0x40, 0x49, 0x9f, 0x3e, 0x48, 0x3d, 0x85, 0x74, 0xc2, 0xe0, 0x66, 0x82, 0x9c, 0x8d, 0xde, 0xbb, 0x32, 0xd3, 0xc8, 0x00, 0xde, 0xcc, 0x34, 0x32, 0x08, 0x3b, 0xc9,
0x36, 0x66, 0xc6, 0x57, 0x02, 0xbf, 0xc2, 0xb7, 0xd7, 0xf0, 0x64, 0x42, 0x9a, 0xa9, 0xe6, 0x98, 0x73, 0xc8, 0x23, 0xec, 0x24, 0x59, 0xed, 0x57, 0xc3, 0xa5, 0x66, 0xd6, 0x99, 0xe8, 0xc3, 0xab,
0x38, 0x03, 0x99, 0xb7, 0xe6, 0xa2, 0x51, 0xc2, 0x6d, 0x39, 0xf9, 0xa8, 0xe9, 0x86, 0xa4, 0x37, 0x3f, 0xc1, 0x6b, 0x4a, 0x7c, 0x42, 0xc8, 0xbe, 0xa0, 0xb4, 0x2f, 0x82, 0xe6, 0x8d, 0x09, 0x38,
0xf2, 0xfe, 0x84, 0x64, 0xce, 0x88, 0xb7, 0x6e, 0xdc, 0x34, 0x30, 0xce, 0x70, 0xe2, 0x4d, 0xe5, 0x7b, 0xea, 0xd5, 0xf3, 0x7b, 0x6d, 0x82, 0xcf, 0x72, 0xe3, 0xd5, 0x0f, 0x7c, 0x00, 0x0c, 0xa1,
0xad, 0x3d, 0x05, 0x52, 0xe3, 0x4c, 0x1f, 0x9d, 0xb7, 0x4a, 0xdf, 0xbe, 0xba, 0x62, 0xfc, 0xfd, 0xa4, 0xa3, 0x0f, 0x62, 0x67, 0x88, 0x8e, 0x00, 0x6e, 0x66, 0x6d, 0x62, 0x7e, 0x65, 0xf0, 0x2b,
0xd5, 0x15, 0xe3, 0x5f, 0xaf, 0xae, 0x18, 0x27, 0xcb, 0xe2, 0xef, 0xc7, 0x5b, 0xff, 0x0d, 0x00, 0x7c, 0x7b, 0xf5, 0x23, 0x13, 0xb2, 0x91, 0x19, 0x8e, 0x91, 0x18, 0xc8, 0xbc, 0x3d, 0x95, 0x8c,
0x00, 0xff, 0xff, 0x76, 0x21, 0x31, 0x33, 0xd0, 0x1d, 0x00, 0x00, 0x32, 0xee, 0x48, 0xe4, 0xa3, 0xd0, 0x0d, 0xc9, 0xbe, 0xc8, 0xbb, 0x08, 0xc9, 0x9c, 0x90, 0x6f,
0xcd, 0xb8, 0x65, 0xe0, 0x39, 0x43, 0xc4, 0x9b, 0xa9, 0x5b, 0x7b, 0x0a, 0x64, 0x9e, 0x33, 0x1d,
0x3a, 0x6f, 0x95, 0xbe, 0x7d, 0x73, 0xc5, 0xf8, 0xfb, 0x9b, 0x2b, 0xc6, 0x3f, 0xdf, 0x5c, 0x31,
0x4e, 0x0a, 0xe2, 0x7f, 0xce, 0xdb, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xc4, 0x91, 0xe5, 0xca,
0x70, 0x1e, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@ -3370,7 +3392,7 @@ func (m *Result) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0xa dAtA[i] = 0xa
i = encodeVarintGateway(dAtA, i, uint64(baseI-i)) i = encodeVarintGateway(dAtA, i, uint64(baseI-i))
i-- i--
dAtA[i] = 0x5a dAtA[i] = 0x62
} }
} }
if len(m.Metadata) > 0 { if len(m.Metadata) > 0 {
@ -3992,6 +4014,13 @@ func (m *ResolveImageConfigRequest) MarshalToSizedBuffer(dAtA []byte) (int, erro
i -= len(m.XXX_unrecognized) i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized)
} }
if len(m.StoreID) > 0 {
i -= len(m.StoreID)
copy(dAtA[i:], m.StoreID)
i = encodeVarintGateway(dAtA, i, uint64(len(m.StoreID)))
i--
dAtA[i] = 0x3a
}
if len(m.SessionID) > 0 { if len(m.SessionID) > 0 {
i -= len(m.SessionID) i -= len(m.SessionID)
copy(dAtA[i:], m.SessionID) copy(dAtA[i:], m.SessionID)
@ -4105,6 +4134,20 @@ func (m *SolveRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized) i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized)
} }
if len(m.SourcePolicies) > 0 {
for iNdEx := len(m.SourcePolicies) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.SourcePolicies[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGateway(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x7a
}
}
if m.Evaluate { if m.Evaluate {
i-- i--
if m.Evaluate { if m.Evaluate {
@ -5911,6 +5954,10 @@ func (m *ResolveImageConfigRequest) Size() (n int) {
if l > 0 { if l > 0 {
n += 1 + l + sovGateway(uint64(l)) n += 1 + l + sovGateway(uint64(l))
} }
l = len(m.StoreID)
if l > 0 {
n += 1 + l + sovGateway(uint64(l))
}
if m.XXX_unrecognized != nil { if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized) n += len(m.XXX_unrecognized)
} }
@ -5994,6 +6041,12 @@ func (m *SolveRequest) Size() (n int) {
if m.Evaluate { if m.Evaluate {
n += 2 n += 2
} }
if len(m.SourcePolicies) > 0 {
for _, e := range m.SourcePolicies {
l = e.Size()
n += 1 + l + sovGateway(uint64(l))
}
}
if m.XXX_unrecognized != nil { if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized) n += len(m.XXX_unrecognized)
} }
@ -6919,7 +6972,7 @@ func (m *Result) Unmarshal(dAtA []byte) error {
} }
m.Metadata[mapkey] = mapvalue m.Metadata[mapkey] = mapvalue
iNdEx = postIndex iNdEx = postIndex
case 11: case 12:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Attestations", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Attestations", wireType)
} }
@ -8715,6 +8768,38 @@ func (m *ResolveImageConfigRequest) Unmarshal(dAtA []byte) error {
} }
m.SessionID = string(dAtA[iNdEx:postIndex]) m.SessionID = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex iNdEx = postIndex
case 7:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field StoreID", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGateway
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGateway
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGateway
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.StoreID = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipGateway(dAtA[iNdEx:]) skippy, err := skipGateway(dAtA[iNdEx:])
@ -9355,6 +9440,40 @@ func (m *SolveRequest) Unmarshal(dAtA []byte) error {
} }
} }
m.Evaluate = bool(v != 0) m.Evaluate = bool(v != 0)
case 15:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field SourcePolicies", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGateway
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGateway
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGateway
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.SourcePolicies = append(m.SourcePolicies, &pb1.Policy{})
if err := m.SourcePolicies[len(m.SourcePolicies)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipGateway(dAtA[iNdEx:]) skippy, err := skipGateway(dAtA[iNdEx:])
@ -10708,7 +10827,7 @@ func (m *PongResponse) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.FrontendAPICaps = append(m.FrontendAPICaps, pb1.APICap{}) m.FrontendAPICaps = append(m.FrontendAPICaps, pb2.APICap{})
if err := m.FrontendAPICaps[len(m.FrontendAPICaps)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.FrontendAPICaps[len(m.FrontendAPICaps)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
@ -10742,7 +10861,7 @@ func (m *PongResponse) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.LLBCaps = append(m.LLBCaps, pb1.APICap{}) m.LLBCaps = append(m.LLBCaps, pb2.APICap{})
if err := m.LLBCaps[len(m.LLBCaps)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { if err := m.LLBCaps[len(m.LLBCaps)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }

View File

@ -8,6 +8,7 @@ import "github.com/moby/buildkit/solver/pb/ops.proto";
import "github.com/moby/buildkit/api/types/worker.proto"; import "github.com/moby/buildkit/api/types/worker.proto";
import "github.com/moby/buildkit/util/apicaps/pb/caps.proto"; import "github.com/moby/buildkit/util/apicaps/pb/caps.proto";
import "github.com/tonistiigi/fsutil/types/stat.proto"; import "github.com/tonistiigi/fsutil/types/stat.proto";
import "github.com/moby/buildkit/sourcepolicy/pb/policy.proto";
option (gogoproto.sizer_all) = true; option (gogoproto.sizer_all) = true;
@ -50,7 +51,8 @@ message Result {
RefMap refs = 4; RefMap refs = 4;
} }
map<string, bytes> metadata = 10; map<string, bytes> metadata = 10;
map<string, Attestations> attestations = 11; // 11 was used during development and is reserved for old attestation format
map<string, Attestations> attestations = 12;
} }
message RefMapDeprecated { message RefMapDeprecated {
@ -121,6 +123,7 @@ message ResolveImageConfigRequest {
string LogName = 4; string LogName = 4;
int32 ResolverType = 5; int32 ResolverType = 5;
string SessionID = 6; string SessionID = 6;
string StoreID = 7;
} }
message ResolveImageConfigResponse { message ResolveImageConfigResponse {
@ -147,6 +150,8 @@ message SolveRequest {
map<string, pb.Definition> FrontendInputs = 13; map<string, pb.Definition> FrontendInputs = 13;
bool Evaluate = 14; bool Evaluate = 14;
repeated moby.buildkit.v1.sourcepolicy.Policy SourcePolicies = 15;
} }
// CacheOptionsEntry corresponds to the control.CacheOptionsEntry // CacheOptionsEntry corresponds to the control.CacheOptionsEntry

View File

@ -237,6 +237,7 @@ type Job struct {
values sync.Map values sync.Map
id string id string
startedTime time.Time startedTime time.Time
completedTime time.Time
progressCloser func() progressCloser func()
SessionID string SessionID string
@ -557,9 +558,12 @@ func (j *Job) walkProvenance(ctx context.Context, e Edge, f func(ProvenanceProvi
return nil return nil
} }
func (j *Job) Discard() error { func (j *Job) CloseProgress() {
defer j.progressCloser() j.progressCloser()
j.pw.Close()
}
func (j *Job) Discard() error {
j.list.mu.Lock() j.list.mu.Lock()
defer j.list.mu.Unlock() defer j.list.mu.Unlock()
@ -589,6 +593,13 @@ func (j *Job) StartedTime() time.Time {
return j.startedTime return j.startedTime
} }
func (j *Job) RegisterCompleteTime() time.Time {
if j.completedTime.IsZero() {
j.completedTime = time.Now()
}
return j.completedTime
}
func (j *Job) InContext(ctx context.Context, f func(context.Context, session.Group) error) error { func (j *Job) InContext(ctx context.Context, f func(context.Context, session.Group) error) error {
return f(progress.WithProgress(ctx, j.pw), session.NewGroup(j.SessionID)) return f(progress.WithProgress(ctx, j.pw), session.NewGroup(j.SessionID))
} }

View File

@ -29,6 +29,7 @@ const AttrImageRecordType = "image.recordtype"
const AttrImageLayerLimit = "image.layerlimit" const AttrImageLayerLimit = "image.layerlimit"
const AttrOCILayoutSessionID = "oci.session" const AttrOCILayoutSessionID = "oci.session"
const AttrOCILayoutStoreID = "oci.store"
const AttrOCILayoutLayerLimit = "oci.layerlimit" const AttrOCILayoutLayerLimit = "oci.layerlimit"
const AttrLocalDiffer = "local.differ" const AttrLocalDiffer = "local.differ"

View File

@ -36,8 +36,6 @@ const (
CapSourceHTTPUIDGID apicaps.CapID = "soruce.http.uidgid" CapSourceHTTPUIDGID apicaps.CapID = "soruce.http.uidgid"
CapSourceOCILayout apicaps.CapID = "source.ocilayout" CapSourceOCILayout apicaps.CapID = "source.ocilayout"
CapSourceOCILayoutSessionID apicaps.CapID = "source.ocilayout.sessionid"
CapSourceOCILayoutLayerLimit apicaps.CapID = "source.ocilayout.layerlimit"
CapBuildOpLLBFileName apicaps.CapID = "source.buildop.llbfilename" CapBuildOpLLBFileName apicaps.CapID = "source.buildop.llbfilename"
@ -86,6 +84,8 @@ const (
// CapSourceDateEpoch is the capability to automatically handle the date epoch // CapSourceDateEpoch is the capability to automatically handle the date epoch
CapSourceDateEpoch apicaps.CapID = "exporter.sourcedateepoch" CapSourceDateEpoch apicaps.CapID = "exporter.sourcedateepoch"
CapSourcePolicy apicaps.CapID = "source.policy"
) )
func init() { func init() {
@ -221,18 +221,6 @@ func init() {
Status: apicaps.CapStatusExperimental, Status: apicaps.CapStatusExperimental,
}) })
Caps.Init(apicaps.Cap{
ID: CapSourceOCILayoutSessionID,
Enabled: true,
Status: apicaps.CapStatusExperimental,
})
Caps.Init(apicaps.Cap{
ID: CapSourceOCILayoutLayerLimit,
Enabled: true,
Status: apicaps.CapStatusExperimental,
})
Caps.Init(apicaps.Cap{ Caps.Init(apicaps.Cap{
ID: CapSourceHTTPUIDGID, ID: CapSourceHTTPUIDGID,
Enabled: true, Enabled: true,
@ -465,4 +453,10 @@ func init() {
Enabled: true, Enabled: true,
Status: apicaps.CapStatusExperimental, Status: apicaps.CapStatusExperimental,
}) })
Caps.Init(apicaps.Cap{
ID: CapSourcePolicy,
Enabled: true,
Status: apicaps.CapStatusExperimental,
})
} }

View File

@ -0,0 +1,3 @@
package moby_buildkit_v1_sourcepolicy //nolint:revive
//go:generate protoc -I=. --gogofaster_out=plugins=grpc:. policy.proto

View File

@ -0,0 +1,62 @@
package moby_buildkit_v1_sourcepolicy //nolint:revive
import (
"github.com/gogo/protobuf/proto"
"github.com/pkg/errors"
)
// MarshalJSON implements json.Marshaler with custom marshaling for PolicyAction.
// It gives the string form of the enum value.
func (a PolicyAction) MarshalJSON() ([]byte, error) {
return proto.MarshalJSONEnum(PolicyAction_name, int32(a))
}
func (a *PolicyAction) UnmarshalJSON(data []byte) error {
val, err := proto.UnmarshalJSONEnum(PolicyAction_value, data, a.String())
if err != nil {
return err
}
_, ok := PolicyAction_name[val]
if !ok {
return errors.Errorf("invalid PolicyAction value: %d", val)
}
*a = PolicyAction(val)
return nil
}
func (a AttrMatch) MarshalJSON() ([]byte, error) {
return proto.MarshalJSONEnum(AttrMatch_name, int32(a))
}
func (a *AttrMatch) UnmarshalJSON(data []byte) error {
val, err := proto.UnmarshalJSONEnum(AttrMatch_value, data, a.String())
if err != nil {
return err
}
_, ok := AttrMatch_name[val]
if !ok {
return errors.Errorf("invalid AttrMatch value: %d", val)
}
*a = AttrMatch(val)
return nil
}
func (a MatchType) MarshalJSON() ([]byte, error) {
return proto.MarshalJSONEnum(MatchType_name, int32(a))
}
func (a *MatchType) UnmarshalJSON(data []byte) error {
val, err := proto.UnmarshalJSONEnum(MatchType_value, data, a.String())
if err != nil {
return err
}
_, ok := AttrMatch_name[val]
if !ok {
return errors.Errorf("invalid MatchType value: %d", val)
}
*a = MatchType(val)
return nil
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,64 @@
syntax = "proto3";
package moby.buildkit.v1.sourcepolicy;
// Rule defines the action(s) to take when a source is matched
message Rule {
PolicyAction action = 1;
Selector selector = 2;
Update updates = 3;
}
// Update contains updates to the matched build step after rule is applied
message Update {
string identifier = 1;
map<string, string> attrs = 2;
}
// Selector identifies a source to match a policy to
message Selector {
string identifier = 1;
// MatchType is the type of match to perform on the source identifier
MatchType match_type = 2;
repeated AttrConstraint constraints = 3;
}
// PolicyAction defines the action to take when a source is matched
enum PolicyAction {
ALLOW = 0;
DENY = 1;
CONVERT = 2;
}
// AttrConstraint defines a constraint on a source attribute
message AttrConstraint {
string key = 1;
string value = 2;
AttrMatch condition = 3;
}
// AttrMatch defines the condition to match a source attribute
enum AttrMatch {
EQUAL = 0;
NOTEQUAL = 1;
MATCHES = 2;
}
// Policy is the list of rules the policy engine will perform
message Policy {
int64 version = 1; // Currently 1
repeated Rule rules = 2;
}
// Match type is used to determine how a rule source is matched
enum MatchType {
// WILDCARD is the default matching type.
// It may first attempt to due an exact match but will follow up with a wildcard match
// For something more powerful, use REGEX
WILDCARD = 0;
// EXACT treats the source identifier as a litteral string match
EXACT = 1;
// REGEX treats the source identifier as a regular expression
// With regex matching you can also use match groups to replace values in the destination identifier
REGEX = 2;
}

View File

@ -35,9 +35,14 @@ func (mr *MultiReader) Reader(ctx context.Context) Reader {
isBehind := len(mr.sent) > 0 isBehind := len(mr.sent) > 0
select {
case <-mr.done:
isBehind = true
default:
if !isBehind { if !isBehind {
mr.writers[w] = closeWriter mr.writers[w] = closeWriter
} }
}
go func() { go func() {
if isBehind { if isBehind {
@ -74,9 +79,6 @@ func (mr *MultiReader) Reader(ctx context.Context) Reader {
case <-ctx.Done(): case <-ctx.Done():
close() close()
return return
case <-mr.done:
close()
return
default: default:
} }
} }

View File

@ -118,12 +118,22 @@ func (pr *progressReader) Read(ctx context.Context) ([]*Progress, error) {
done := make(chan struct{}) done := make(chan struct{})
defer close(done) defer close(done)
go func() { go func() {
prdone := pr.ctx.Done()
for {
select { select {
case <-done: case <-done:
return
case <-ctx.Done(): case <-ctx.Done():
pr.mu.Lock() pr.mu.Lock()
pr.cond.Broadcast() pr.cond.Broadcast()
pr.mu.Unlock() pr.mu.Unlock()
return
case <-prdone:
pr.mu.Lock()
pr.cond.Broadcast()
pr.mu.Unlock()
prdone = nil
}
} }
}() }()
pr.mu.Lock() pr.mu.Lock()

View File

@ -438,7 +438,7 @@ github.com/matttproud/golang_protobuf_extensions/pbutil
# github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b # github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b
## explicit ## explicit
github.com/mitchellh/go-ps github.com/mitchellh/go-ps
# github.com/moby/buildkit v0.11.0-rc1.0.20221213132957-c0ac5e8b9b51 # github.com/moby/buildkit v0.11.0-rc2
## explicit; go 1.18 ## explicit; go 1.18
github.com/moby/buildkit/api/services/control github.com/moby/buildkit/api/services/control
github.com/moby/buildkit/api/types github.com/moby/buildkit/api/types
@ -481,6 +481,7 @@ github.com/moby/buildkit/solver/internal/pipe
github.com/moby/buildkit/solver/pb github.com/moby/buildkit/solver/pb
github.com/moby/buildkit/solver/result github.com/moby/buildkit/solver/result
github.com/moby/buildkit/source/types github.com/moby/buildkit/source/types
github.com/moby/buildkit/sourcepolicy/pb
github.com/moby/buildkit/util/apicaps github.com/moby/buildkit/util/apicaps
github.com/moby/buildkit/util/apicaps/pb github.com/moby/buildkit/util/apicaps/pb
github.com/moby/buildkit/util/appdefaults github.com/moby/buildkit/util/appdefaults