Compare commits

..

41 Commits

Author SHA1 Message Date
Tõnis Tiigi
00ed17df6d Merge pull request #1569 from tonistiigi/v0.10.2-picks
[v0.10] cherry-picks for v0.10.2
2023-01-30 11:57:04 -08:00
CrazyMax
cfb71fab97 build: better message output for git provenance
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 6db696748b)
2023-01-30 11:46:51 -08:00
CrazyMax
f62342768b build: silently fail if git remote not found
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 4789d2219c)
2023-01-30 11:46:42 -08:00
Tonis Tiigi
7776652a4d build: fix multi-node merge to read descriptor from result
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit c33b310b48)
2023-01-30 11:46:12 -08:00
Akihiro Suda
5a4f80f3ce bake: SOURCE_DATE_EPOCH: fix panic: assignment to entry in nil map
Fix issue 1562

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
(cherry picked from commit 1f56f51740)
2023-01-30 11:45:50 -08:00
CrazyMax
b5ea79e277 build: fix preferred platform not taken account
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 49b3c0dba5)
2023-01-30 11:45:15 -08:00
Tõnis Tiigi
481796f84f Merge pull request #1556 from crazy-max/0.10.1_cherry_picks
[v0.10] cherry-picks for v0.10.1
2023-01-26 11:02:55 -08:00
Tonis Tiigi
0090d49e57 vendor: update buildkit to v0.11.2
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit f6da7ee135)
2023-01-26 10:34:57 -08:00
CrazyMax
389ac0c3d1 build: set remote origin url
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit c1058c17aa)
2023-01-26 13:36:58 +01:00
Justin Chadwell
2bb8ce2f57 build: create error group per opt
Using the syncronization primitive, we can avoid needing to create a
separate wait group.

This allows us to sidestep the issue where the wait group could be
completed, but the build invocation functions had not terminated - if
one of the functions was to terminate with an error, then it was
possible to encounter a race condition, where the result handling code
would begin executing, despite an error.

The refactor to use a separate error group which more elegantly handles
the concept of function returns and errors, ensures that we can't
encounter this issue.

Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 8b7aa1a168)
2023-01-26 13:36:57 +01:00
Justin Chadwell
65cea456fd build: reorder error group funcs
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 1180d919f5)
2023-01-26 13:36:57 +01:00
Justin Chadwell
f7bd5b99da build: use copy for BuildWithResultHandler loop vars
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 347417ee12)
2023-01-26 13:36:57 +01:00
Justin Chadwell
8c14407fa2 imagetools: silence intoto warnings
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 7145e021f9)
2023-01-26 13:36:57 +01:00
CrazyMax
5245a2b3ff rm: do not check for context builders when removing inactive
This change has been introduced in e7b5ee7518
but we should not check context builders when removing inactive
ones.

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 6cd0c11ab1)
2023-01-26 13:36:28 +01:00
Tonis Tiigi
44d99d4573 build: mark capabilities request as internal
So it doesn't show up in the History API.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit be55b41427)
2023-01-26 13:35:46 +01:00
David Karlsson
14942a266e docs: fix broken link in buildx_bake CLI reference
Signed-off-by: David Karlsson <david.karlsson@docker.com>
(cherry picked from commit ba8fa6c403)
2023-01-26 13:33:13 +01:00
CrazyMax
123febf107 ci: fix typo in docs-release workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 523a16aa35)
2023-01-26 13:32:58 +01:00
Batuhan Apaydın
3f5f7c5228 fix the directory of the buildx binary
Signed-off-by: Batuhan Apaydın <batuhan.apaydin@trendyol.com>
(cherry picked from commit edb16f8aab)
2023-01-26 13:32:34 +01:00
Justin Chadwell
6d935625a6 Merge pull request #1546 from jedevc/v0.10-inspect-lazy-attestations
[v0.10] Lazily load attestation data in imagetools inspect
2023-01-24 12:41:13 +00:00
Justin Chadwell
e640dc6041 Merge pull request #1545 from jedevc/v0.10-error-on-attestations-docker
[v0.10] build: error when using docker exporter and attestations
2023-01-24 12:41:03 +00:00
Justin Chadwell
08244b12b5 Merge pull request #1544 from jedevc/v0.10-bump-ci
[v0.10] Bump Buildx and BuildKit versions in GitHub actions
2023-01-24 12:40:52 +00:00
Justin Chadwell
78d8b926db inspect: lazily load attestation data
Delay loading the attestation data immediately, and only compute it upon
request. We do this using a deferred function which allows to define the
computation in the same place as before, but perform the computation
later.

With this patch, we ensure that the attestation data is only pulled from
the remote if it is actually referenced in the format string -
otherwise, we can skip it, for improved performance.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-24 12:10:57 +00:00
Justin Chadwell
19291d900e inspect: move attestation loading to struct methods
This refactor ensures that the attestations are not output in the JSON
output for "{{ json . }}", and additionally allows future refactors to
dynamically load the attestation contents, ensuring faster performance
when attestations are not used in the output.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-24 12:10:57 +00:00
Justin Chadwell
ed9b4a7169 build: error when using docker exporter and attestations
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 43a748fd15)
Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-24 12:07:43 +00:00
Justin Chadwell
033d5629c0 build: avoid compatability error when attestations disabled
We should avoid erroring with attestations support compatability errors
when a user has specified --provenance=false.

A user may wish to enable --provenance=false that works across buildkit
versions, but currently it will fail on old versions - this patch fixes
this, to silently ignore the provenance flag for this check if it's set
to disabled.

Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 15a80b56b5)
Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-24 12:07:34 +00:00
Justin Chadwell
7cd5add568 ci: update buildkit release version in build pipeline
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit c1ab55a3f2)
Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-24 11:50:58 +00:00
Justin Chadwell
2a000096fa ci: update buildx release version in build pipeline
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit bc1d590ca7)
Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-24 11:50:53 +00:00
Tõnis Tiigi
b7781447d7 Merge pull request #1530 from thaJeztah/0.10_backport_update_buildkit
[0.10 backport] vendor: github.com/moby/buildkit v0.11.1
2023-01-24 00:50:03 -08:00
Sebastiaan van Stijn
f6ba0a23f8 vendor: github.com/moby/buildkit v0.11.1
full diff: https://github.com/moby/buildkit/compare/v0.11.0...v0.11.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 01e1c28dd9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-18 20:58:27 +01:00
CrazyMax
bf4b95fc3a Merge pull request #1524 from jedevc/v0.10-docs-reference-attest
[0.10] docs: add reference for new attest family of flags
2023-01-17 16:24:18 +01:00
Justin Chadwell
467586dc8d docs: add reference for new attest family of flags
Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-17 13:48:19 +00:00
Tõnis Tiigi
8764628976 Merge pull request #1501 from tonistiigi/v0.10-picks
[v0.10] cherry-picks
2023-01-09 16:10:12 -08:00
Justin Chadwell
583fe71740 docs: update with new inspect output
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 9818055b0e)
2023-01-09 15:53:42 -08:00
Justin Chadwell
9fb3ff1a27 inspect: change additional spdxs to not have duplicates
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 484823c97d)
2023-01-09 15:53:37 -08:00
Justin Chadwell
9d4f38c5fa inspect: provide access to multiple spdx documents
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 3ce17b01dc)
2023-01-09 15:53:34 -08:00
Justin Chadwell
793082f543 inspect: parse sbom and provenance into json structs
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit e68c566c1c)
2023-01-09 15:53:29 -08:00
Justin Chadwell
fe6f697205 inspect: break after first matching attestation
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 19d16aa941)
2023-01-09 15:53:13 -08:00
Tonis Tiigi
fd3fb752d3 github: update CI to buildkit v0.11
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit 571871b084)
2023-01-09 15:52:51 -08:00
CrazyMax
7fcea64eb4 Merge pull request #1496 from thaJeztah/0.10_backport_docs_updates
[0.10 backport] update anchor-links and cli-docs-tool v0.5.1
2023-01-09 15:52:56 +01:00
Sebastiaan van Stijn
05e0ce4953 go.mod: update cli-docs-tool v0.5.1 and re-generate docs
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c97500b117)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-09 13:05:27 +01:00
Sebastiaan van Stijn
f8d9d1e776 docs: update anchor links
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit b8285c17e6)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-09 13:05:27 +01:00
49 changed files with 1087 additions and 792 deletions

View File

@@ -21,8 +21,8 @@ on:
- 'docs/**'
env:
BUILDX_VERSION: "v0.10.0-rc1"
BUILDKIT_IMAGE: "moby/buildkit:v0.11.0-rc3"
BUILDX_VERSION: "v0.10.0"
BUILDKIT_IMAGE: "moby/buildkit:v0.11.1"
REPO_SLUG: "docker/buildx-bin"
DESTDIR: "./bin"

View File

@@ -3,7 +3,7 @@ name: docs-release
on:
release:
types:
- releases
- released
jobs:
open-pr:

View File

@@ -1,4 +1,4 @@
# syntax=docker/dockerfile-upstream:master
# syntax=docker/dockerfile-upstream:1.5.0
ARG GO_VERSION=1.19
ARG XX_VERSION=1.1.2

View File

@@ -147,7 +147,7 @@ To remove this alias, run [`docker buildx uninstall`](docs/reference/buildx_unin
# Buildx 0.6+
$ docker buildx bake "https://github.com/docker/buildx.git"
$ mkdir -p ~/.docker/cli-plugins
$ mv ./bin/buildx ~/.docker/cli-plugins/docker-buildx
$ mv ./bin/build/buildx ~/.docker/cli-plugins/docker-buildx
# Docker 19.03+
$ DOCKER_BUILDKIT=1 docker build --platform=local -o . "https://github.com/docker/buildx.git"

View File

@@ -144,6 +144,9 @@ func ReadTargets(ctx context.Context, files []File, targets, overrides []string,
// The logic is purposely duplicated from `build/build`.go for keeping this visible in `bake --print`.
if v := os.Getenv("SOURCE_DATE_EPOCH"); v != "" {
for _, f := range m {
if f.Args == nil {
f.Args = make(map[string]*string)
}
if _, ok := f.Args["SOURCE_DATE_EPOCH"]; !ok {
f.Args["SOURCE_DATE_EPOCH"] = &v
}

View File

@@ -6,6 +6,7 @@ import (
"context"
"crypto/rand"
_ "crypto/sha256" // ensure digests can be computed
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
@@ -228,7 +229,9 @@ func resolveDrivers(ctx context.Context, nodes []builder.Node, opt map[string]Op
func(i int, c *client.Client) {
eg.Go(func() error {
clients[i].Build(ctx, client.SolveOpt{}, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
clients[i].Build(ctx, client.SolveOpt{
Internal: true,
}, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
bopts[i] = c.BuildOpts()
return nil, nil
}, nil)
@@ -447,6 +450,25 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
so.FrontendAttrs["multi-platform"] = "true"
}
attests := make(map[string]string)
for k, v := range opt.Attests {
if v != nil {
attests[k] = *v
}
}
supportsAttestations := bopts.LLBCaps.Contains(apicaps.CapID("exporter.image.attestations"))
if len(attests) > 0 {
if !supportsAttestations {
return nil, nil, errors.Errorf("attestations are not supported by the current buildkitd")
}
for k, v := range attests {
so.FrontendAttrs[k] = v
}
}
if _, ok := opt.Attests["attest:provenance"]; !ok && supportsAttestations {
so.FrontendAttrs["attest:provenance"] = "mode=min,inline-only=true"
}
switch len(opt.Exports) {
case 1:
// valid
@@ -504,7 +526,7 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
return nil, nil, notSupported(nodeDriver, driver.OCIExporter)
}
if e.Type == "docker" {
if len(opt.Platforms) > 1 {
if len(opt.Platforms) > 1 || len(attests) > 0 {
return nil, nil, errors.Errorf("docker exporter does not currently support exporting manifest lists")
}
if e.Output == nil {
@@ -588,21 +610,6 @@ func toSolveOpt(ctx context.Context, node builder.Node, multiDriver bool, opt Op
}
}
if len(opt.Attests) > 0 {
if !bopts.LLBCaps.Contains(apicaps.CapID("exporter.image.attestations")) {
return nil, nil, errors.Errorf("attestations are not supported by the current buildkitd")
}
for k, v := range opt.Attests {
if v == nil {
continue
}
so.FrontendAttrs[k] = *v
}
}
if _, ok := opt.Attests["attest:provenance"]; !ok {
so.FrontendAttrs["attest:provenance"] = "mode=min,inline-only=true"
}
// set platforms
if len(opt.Platforms) != 0 {
pp := make([]string, len(opt.Platforms))
@@ -946,26 +953,190 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
if multiTarget {
span, ctx = tracing.StartSpan(ctx, k)
}
baseCtx := ctx
res := make([]*client.SolveResponse, len(dps))
wg := &sync.WaitGroup{}
wg.Add(len(dps))
eg2, ctx := errgroup.WithContext(ctx)
var pushNames string
var insecurePush bool
for i, dp := range dps {
i, dp, so := i, dp, *dp.so
if multiDriver {
for i, e := range so.Exports {
switch e.Type {
case "oci", "tar":
return errors.Errorf("%s for multi-node builds currently not supported", e.Type)
case "image":
if pushNames == "" && e.Attrs["push"] != "" {
if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok {
pushNames = e.Attrs["name"]
if pushNames == "" {
return errors.Errorf("tag is needed when pushing to registry")
}
names, err := toRepoOnly(e.Attrs["name"])
if err != nil {
return err
}
if ok, _ := strconv.ParseBool(e.Attrs["registry.insecure"]); ok {
insecurePush = true
}
e.Attrs["name"] = names
e.Attrs["push-by-digest"] = "true"
so.Exports[i].Attrs = e.Attrs
}
}
}
}
}
pw := progress.WithPrefix(w, k, multiTarget)
c := clients[dp.driverIndex]
eg2.Go(func() error {
pw = progress.ResetTime(pw)
if err := waitContextDeps(ctx, dp.driverIndex, results, &so); err != nil {
return err
}
frontendInputs := make(map[string]*pb.Definition)
for key, st := range so.FrontendInputs {
def, err := st.Marshal(ctx)
if err != nil {
return err
}
frontendInputs[key] = def.ToPB()
}
req := gateway.SolveRequest{
Frontend: so.Frontend,
FrontendInputs: frontendInputs,
FrontendOpt: make(map[string]string),
}
for k, v := range so.FrontendAttrs {
req.FrontendOpt[k] = v
}
so.Frontend = ""
so.FrontendInputs = nil
ch, done := progress.NewChannel(pw)
defer func() { <-done }()
cc := c
var printRes map[string][]byte
rr, err := c.Build(ctx, so, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
var isFallback bool
var origErr error
for {
if opt.PrintFunc != nil {
if _, ok := req.FrontendOpt["frontend.caps"]; !ok {
req.FrontendOpt["frontend.caps"] = "moby.buildkit.frontend.subrequests+forward"
} else {
req.FrontendOpt["frontend.caps"] += ",moby.buildkit.frontend.subrequests+forward"
}
req.FrontendOpt["requestid"] = "frontend." + opt.PrintFunc.Name
if isFallback {
req.FrontendOpt["build-arg:BUILDKIT_SYNTAX"] = printFallbackImage
}
}
res, err := c.Solve(ctx, req)
if err != nil {
if origErr != nil {
return nil, err
}
var reqErr *errdefs.UnsupportedSubrequestError
if !isFallback {
if errors.As(err, &reqErr) {
switch reqErr.Name {
case "frontend.outline", "frontend.targets":
isFallback = true
origErr = err
continue
}
return nil, err
}
// buildkit v0.8 vendored in Docker 20.10 does not support typed errors
if strings.Contains(err.Error(), "unsupported request frontend.outline") || strings.Contains(err.Error(), "unsupported request frontend.targets") {
isFallback = true
origErr = err
continue
}
}
return nil, err
}
if opt.PrintFunc != nil {
printRes = res.Metadata
}
results.Set(resultKey(dp.driverIndex, k), res)
if resultHandleFunc != nil {
resultHandleFunc(dp.driverIndex, &ResultContext{cc, res})
}
return res, nil
}
}, ch)
if err != nil {
return err
}
res[i] = rr
if rr.ExporterResponse == nil {
rr.ExporterResponse = map[string]string{}
}
for k, v := range printRes {
rr.ExporterResponse[k] = string(v)
}
node := nodes[dp.driverIndex].Driver
if node.IsMobyDriver() {
for _, e := range so.Exports {
if e.Type == "moby" && e.Attrs["push"] != "" {
if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok {
pushNames = e.Attrs["name"]
if pushNames == "" {
return errors.Errorf("tag is needed when pushing to registry")
}
pw := progress.ResetTime(pw)
pushList := strings.Split(pushNames, ",")
for _, name := range pushList {
if err := progress.Wrap(fmt.Sprintf("pushing %s with docker", name), pw.Write, func(l progress.SubLogger) error {
return pushWithMoby(ctx, node, name, l)
}); err != nil {
return err
}
}
remoteDigest, err := remoteDigestWithMoby(ctx, node, pushList[0])
if err == nil && remoteDigest != "" {
// old daemons might not have containerimage.config.digest set
// in response so use containerimage.digest value for it if available
if _, ok := rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey]; !ok {
if v, ok := rr.ExporterResponse[exptypes.ExporterImageDigestKey]; ok {
rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey] = v
}
}
rr.ExporterResponse[exptypes.ExporterImageDigestKey] = remoteDigest
} else if err != nil {
return err
}
}
}
}
}
return nil
})
}
eg.Go(func() (err error) {
ctx := baseCtx
defer func() {
if span != nil {
tracing.FinishWithError(span, err)
}
}()
pw := progress.WithPrefix(w, "default", false)
wg.Wait()
select {
case <-ctx.Done():
return ctx.Err()
default:
if err := eg2.Wait(); err != nil {
return err
}
respMu.Lock()
@@ -987,7 +1158,24 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
descs := make([]specs.Descriptor, 0, len(res))
for _, r := range res {
s, ok := r.ExporterResponse[exptypes.ExporterImageDigestKey]
s, ok := r.ExporterResponse[exptypes.ExporterImageDescriptorKey]
if ok {
dt, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return err
}
var desc specs.Descriptor
if err := json.Unmarshal(dt, &desc); err != nil {
return errors.Wrapf(err, "failed to unmarshal descriptor %s", s)
}
descs = append(descs, desc)
continue
}
// This is fallback for some very old buildkit versions.
// Note that the mediatype isn't really correct as most of the time it is image manifest and
// not manifest list but actually both are handled because for Docker mediatypes the
// mediatype value in the Accpet header does not seem to matter.
s, ok = r.ExporterResponse[exptypes.ExporterImageDigestKey]
if ok {
descs = append(descs, specs.Descriptor{
Digest: digest.Digest(s),
@@ -1071,176 +1259,6 @@ func BuildWithResultHandler(ctx context.Context, nodes []builder.Node, opt map[s
return nil
})
for i, dp := range dps {
so := *dp.so
if multiDriver {
for i, e := range so.Exports {
switch e.Type {
case "oci", "tar":
return errors.Errorf("%s for multi-node builds currently not supported", e.Type)
case "image":
if pushNames == "" && e.Attrs["push"] != "" {
if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok {
pushNames = e.Attrs["name"]
if pushNames == "" {
return errors.Errorf("tag is needed when pushing to registry")
}
names, err := toRepoOnly(e.Attrs["name"])
if err != nil {
return err
}
if ok, _ := strconv.ParseBool(e.Attrs["registry.insecure"]); ok {
insecurePush = true
}
e.Attrs["name"] = names
e.Attrs["push-by-digest"] = "true"
so.Exports[i].Attrs = e.Attrs
}
}
}
}
}
func(i int, dp driverPair, so client.SolveOpt) {
pw := progress.WithPrefix(w, k, multiTarget)
c := clients[dp.driverIndex]
eg.Go(func() error {
pw = progress.ResetTime(pw)
defer wg.Done()
if err := waitContextDeps(ctx, dp.driverIndex, results, &so); err != nil {
return err
}
frontendInputs := make(map[string]*pb.Definition)
for key, st := range so.FrontendInputs {
def, err := st.Marshal(ctx)
if err != nil {
return err
}
frontendInputs[key] = def.ToPB()
}
req := gateway.SolveRequest{
Frontend: so.Frontend,
FrontendInputs: frontendInputs,
FrontendOpt: make(map[string]string),
}
for k, v := range so.FrontendAttrs {
req.FrontendOpt[k] = v
}
so.Frontend = ""
so.FrontendInputs = nil
ch, done := progress.NewChannel(pw)
defer func() { <-done }()
cc := c
var printRes map[string][]byte
rr, err := c.Build(ctx, so, "buildx", func(ctx context.Context, c gateway.Client) (*gateway.Result, error) {
var isFallback bool
var origErr error
for {
if opt.PrintFunc != nil {
if _, ok := req.FrontendOpt["frontend.caps"]; !ok {
req.FrontendOpt["frontend.caps"] = "moby.buildkit.frontend.subrequests+forward"
} else {
req.FrontendOpt["frontend.caps"] += ",moby.buildkit.frontend.subrequests+forward"
}
req.FrontendOpt["requestid"] = "frontend." + opt.PrintFunc.Name
if isFallback {
req.FrontendOpt["build-arg:BUILDKIT_SYNTAX"] = printFallbackImage
}
}
res, err := c.Solve(ctx, req)
if err != nil {
if origErr != nil {
return nil, err
}
var reqErr *errdefs.UnsupportedSubrequestError
if !isFallback {
if errors.As(err, &reqErr) {
switch reqErr.Name {
case "frontend.outline", "frontend.targets":
isFallback = true
origErr = err
continue
}
return nil, err
}
// buildkit v0.8 vendored in Docker 20.10 does not support typed errors
if strings.Contains(err.Error(), "unsupported request frontend.outline") || strings.Contains(err.Error(), "unsupported request frontend.targets") {
isFallback = true
origErr = err
continue
}
}
return nil, err
}
if opt.PrintFunc != nil {
printRes = res.Metadata
}
results.Set(resultKey(dp.driverIndex, k), res)
if resultHandleFunc != nil {
resultHandleFunc(dp.driverIndex, &ResultContext{cc, res})
}
return res, nil
}
}, ch)
if err != nil {
return err
}
res[i] = rr
if rr.ExporterResponse == nil {
rr.ExporterResponse = map[string]string{}
}
for k, v := range printRes {
rr.ExporterResponse[k] = string(v)
}
node := nodes[dp.driverIndex].Driver
if node.IsMobyDriver() {
for _, e := range so.Exports {
if e.Type == "moby" && e.Attrs["push"] != "" {
if ok, _ := strconv.ParseBool(e.Attrs["push"]); ok {
pushNames = e.Attrs["name"]
if pushNames == "" {
return errors.Errorf("tag is needed when pushing to registry")
}
pw := progress.ResetTime(pw)
pushList := strings.Split(pushNames, ",")
for _, name := range pushList {
if err := progress.Wrap(fmt.Sprintf("pushing %s with docker", name), pw.Write, func(l progress.SubLogger) error {
return pushWithMoby(ctx, node, name, l)
}); err != nil {
return err
}
}
remoteDigest, err := remoteDigestWithMoby(ctx, node, pushList[0])
if err == nil && remoteDigest != "" {
// old daemons might not have containerimage.config.digest set
// in response so use containerimage.digest value for it if available
if _, ok := rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey]; !ok {
if v, ok := rr.ExporterResponse[exptypes.ExporterImageDigestKey]; ok {
rr.ExporterResponse[exptypes.ExporterImageConfigDigestKey] = v
}
}
rr.ExporterResponse[exptypes.ExporterImageDigestKey] = remoteDigest
} else if err != nil {
return err
}
}
}
}
}
return nil
})
}(i, dp, so)
}
return nil
}(k)
if err != nil {

View File

@@ -52,20 +52,20 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st
gitc, err := gitutil.New(gitutil.WithContext(ctx), gitutil.WithWorkingDir(wd))
if err != nil {
if st, err := os.Stat(path.Join(wd, ".git")); err == nil && st.IsDir() {
return res, errors.New("git was not found in the system. Current commit information was not captured by the build")
return res, errors.New("buildx: git was not found in the system. Current commit information was not captured by the build")
}
return
}
if !gitc.IsInsideWorkTree() {
if st, err := os.Stat(path.Join(wd, ".git")); err == nil && st.IsDir() {
return res, errors.New("failed to read current commit information with git rev-parse --is-inside-work-tree")
return res, errors.New("buildx: failed to read current commit information with git rev-parse --is-inside-work-tree")
}
return res, nil
}
if sha, err := gitc.FullCommit(); err != nil {
return res, errors.Wrapf(err, "failed to get git commit")
return res, errors.Wrapf(err, "buildx: failed to get git commit")
} else if sha != "" {
if gitc.IsDirty() {
sha += "-dirty"
@@ -78,9 +78,7 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st
}
}
if rurl, err := gitc.RemoteURL(); err != nil {
return res, errors.Wrapf(err, "failed to get git remote url")
} else if rurl != "" {
if rurl, err := gitc.RemoteURL(); err == nil && rurl != "" {
if setGitLabels {
res["label:"+specs.AnnotationSource] = rurl
}
@@ -91,7 +89,7 @@ func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath st
if setGitLabels {
if root, err := gitc.RootDir(); err != nil {
return res, errors.Wrapf(err, "failed to get git root dir")
return res, errors.Wrapf(err, "buildx: failed to get git root dir")
} else if root != "" {
if dockerfilePath == "" {
dockerfilePath = filepath.Join(wd, "Dockerfile")

View File

@@ -26,7 +26,7 @@ func setupTest(tb testing.TB) {
gitutil.GitAdd(c, tb, "Dockerfile")
gitutil.GitCommit(c, tb, "initial commit")
gitutil.GitSetRemote(c, tb, "git@github.com:docker/buildx.git")
gitutil.GitSetRemote(c, tb, "origin", "git@github.com:docker/buildx.git")
}
func TestGetGitAttributesNotGitRepo(t *testing.T) {

View File

@@ -62,6 +62,7 @@ func (b *Builder) LoadNodes(ctx context.Context, withData bool) (_ []Node, err e
node := Node{
Node: n,
ProxyConfig: storeutil.GetProxyConfig(b.opts.dockerCli),
Platforms: n.Platforms,
}
defer func() {
b.nodes[i] = node

View File

@@ -470,7 +470,7 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
flags := cmd.Flags()
flags.StringSliceVar(&options.extraHosts, "add-host", []string{}, `Add a custom host-to-IP mapping (format: "host:ip")`)
flags.SetAnnotation("add-host", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#add-entries-to-container-hosts-file---add-host"})
flags.SetAnnotation("add-host", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#add-host"})
flags.StringSliceVar(&options.allow, "allow", []string{}, `Allow extra privileged entitlement (e.g., "network.host", "security.insecure")`)
@@ -481,12 +481,12 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
flags.StringArrayVar(&options.cacheTo, "cache-to", []string{}, `Cache export destinations (e.g., "user/app:cache", "type=local,dest=path/to/dir")`)
flags.StringVar(&options.cgroupParent, "cgroup-parent", "", "Optional parent cgroup for the container")
flags.SetAnnotation("cgroup-parent", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#use-a-custom-parent-cgroup---cgroup-parent"})
flags.SetAnnotation("cgroup-parent", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent"})
flags.StringArrayVar(&options.contexts, "build-context", []string{}, "Additional build contexts (e.g., name=path)")
flags.StringVarP(&options.dockerfileName, "file", "f", "", `Name of the Dockerfile (default: "PATH/Dockerfile")`)
flags.SetAnnotation("file", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#specify-a-dockerfile--f"})
flags.SetAnnotation("file", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#file"})
flags.StringVar(&options.imageIDFile, "iidfile", "", "Write the image ID to the file")
@@ -517,10 +517,10 @@ func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
flags.StringArrayVar(&options.ssh, "ssh", []string{}, `SSH agent socket or keys to expose to the build (format: "default|<id>[=<socket>|<key>[,<key>]]")`)
flags.StringArrayVarP(&options.tags, "tag", "t", []string{}, `Name and optionally a tag (format: "name:tag")`)
flags.SetAnnotation("tag", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#tag-an-image--t"})
flags.SetAnnotation("tag", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#tag"})
flags.StringVar(&options.target, "target", "", "Set the target build stage to build")
flags.SetAnnotation("target", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#specifying-target-build-stage---target"})
flags.SetAnnotation("target", annotation.ExternalURL, []string{"https://docs.docker.com/engine/reference/commandline/build/#target"})
flags.Var(options.ulimits, "ulimit", "Ulimit options")

View File

@@ -141,9 +141,6 @@ func rmAllInactive(ctx context.Context, txn *store.Txn, dockerCli command.Cli, i
if err != nil {
return errors.Wrapf(err, "cannot load %s", b.Name)
}
if cb := b.ContextName(); cb != "" {
return errors.Errorf("context builder cannot be removed, run `docker context rm %s` to remove this context", cb)
}
if b.Dynamic {
return nil
}

View File

@@ -1,3 +1,3 @@
# Defining additional build contexts and linking targets
Moved to [docs.docker.com](https://docs.docker.com/build/customize/bake/build-contexts)
Moved to [docs.docker.com](https://docs.docker.com/build/bake/build-contexts)

View File

@@ -1,3 +1,3 @@
# Building from Compose file
Moved to [docs.docker.com](https://docs.docker.com/build/customize/bake/compose-file)
Moved to [docs.docker.com](https://docs.docker.com/build/bake/compose-file)

View File

@@ -1,3 +1,3 @@
# Configuring builds
Moved to [docs.docker.com](https://docs.docker.com/build/customize/bake/configuring-build)
Moved to [docs.docker.com](https://docs.docker.com/build/bake/configuring-build)

View File

@@ -1,3 +1,3 @@
# Bake file definition
Moved to [docs.docker.com](https://docs.docker.com/build/customize/bake/file-definition)
Moved to [docs.docker.com](https://docs.docker.com/build/bake/file-definition)

View File

@@ -1,3 +1,3 @@
# User defined HCL functions
Moved to [docs.docker.com](https://docs.docker.com/build/customize/bake/hcl-funcs)
Moved to [docs.docker.com](https://docs.docker.com/build/bake/hcl-funcs)

View File

@@ -1,3 +1,3 @@
# High-level build options with Bake
Moved to [docs.docker.com](https://docs.docker.com/build/customize/bake)
Moved to [docs.docker.com](https://docs.docker.com/build/bake)

View File

@@ -9,29 +9,29 @@ Extended build capabilities with BuildKit
### Subcommands
| Name | Description |
| --- | --- |
| [`bake`](buildx_bake.md) | Build from a file |
| [`build`](buildx_build.md) | Start a build |
| [`create`](buildx_create.md) | Create a new builder instance |
| [`du`](buildx_du.md) | Disk usage |
| [`imagetools`](buildx_imagetools.md) | Commands to work on images in registry |
| [`inspect`](buildx_inspect.md) | Inspect current builder instance |
| [`install`](buildx_install.md) | Install buildx as a 'docker builder' alias |
| [`ls`](buildx_ls.md) | List builder instances |
| [`prune`](buildx_prune.md) | Remove build cache |
| [`rm`](buildx_rm.md) | Remove a builder instance |
| [`stop`](buildx_stop.md) | Stop builder instance |
| [`uninstall`](buildx_uninstall.md) | Uninstall the 'docker builder' alias |
| [`use`](buildx_use.md) | Set the current builder instance |
| [`version`](buildx_version.md) | Show buildx version information |
| Name | Description |
|:-------------------------------------|:-------------------------------------------|
| [`bake`](buildx_bake.md) | Build from a file |
| [`build`](buildx_build.md) | Start a build |
| [`create`](buildx_create.md) | Create a new builder instance |
| [`du`](buildx_du.md) | Disk usage |
| [`imagetools`](buildx_imagetools.md) | Commands to work on images in registry |
| [`inspect`](buildx_inspect.md) | Inspect current builder instance |
| [`install`](buildx_install.md) | Install buildx as a 'docker builder' alias |
| [`ls`](buildx_ls.md) | List builder instances |
| [`prune`](buildx_prune.md) | Remove build cache |
| [`rm`](buildx_rm.md) | Remove a builder instance |
| [`stop`](buildx_stop.md) | Stop builder instance |
| [`uninstall`](buildx_uninstall.md) | Uninstall the 'docker builder' alias |
| [`use`](buildx_use.md) | Set the current builder instance |
| [`version`](buildx_version.md) | Show buildx version information |
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| Name | Type | Default | Description |
|:------------------------|:---------|:--------|:-----------------------------------------|
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
<!---MARKER_GEN_END-->

View File

@@ -13,20 +13,20 @@ Build from a file
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`-f`](#file), [`--file`](#file) | `stringArray` | | Build definition file |
| `--load` | | | Shorthand for `--set=*.output=type=docker` |
| `--metadata-file` | `string` | | Write build result metadata to the file |
| [`--no-cache`](#no-cache) | | | Do not use cache when building the image |
| [`--print`](#print) | | | Print the options without building |
| [`--progress`](#progress) | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
| `--provenance` | `string` | | Shorthand for `--set=*.attest=type=provenance` |
| [`--pull`](#pull) | | | Always attempt to pull all referenced images |
| `--push` | | | Shorthand for `--set=*.output=type=registry` |
| `--sbom` | `string` | | Shorthand for `--set=*.attest=type=sbom` |
| [`--set`](#set) | `stringArray` | | Override target value (e.g., `targetpattern.key=value`) |
| Name | Type | Default | Description |
|:---------------------------------|:--------------|:--------|:-----------------------------------------------------------------------------------------|
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`-f`](#file), [`--file`](#file) | `stringArray` | | Build definition file |
| `--load` | | | Shorthand for `--set=*.output=type=docker` |
| `--metadata-file` | `string` | | Write build result metadata to the file |
| [`--no-cache`](#no-cache) | | | Do not use cache when building the image |
| [`--print`](#print) | | | Print the options without building |
| [`--progress`](#progress) | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
| [`--provenance`](#provenance) | `string` | | Shorthand for `--set=*.attest=type=provenance` |
| [`--pull`](#pull) | | | Always attempt to pull all referenced images |
| `--push` | | | Shorthand for `--set=*.output=type=registry` |
| [`--sbom`](#sbom) | `string` | | Shorthand for `--set=*.attest=type=sbom` |
| [`--set`](#set) | `stringArray` | | Override target value (e.g., `targetpattern.key=value`) |
<!---MARKER_GEN_END-->
@@ -36,7 +36,7 @@ Build from a file
Bake is a high-level build command. Each specified target will run in parallel
as part of the build.
Read [High-level build options with Bake](https://docs.docker.com/build/customize/bake/)
Read [High-level build options with Bake](https://docs.docker.com/build/bake/)
guide for introduction to writing bake files.
> **Note**
@@ -87,7 +87,7 @@ target "db" {
$ docker buildx bake -f docker-bake.dev.hcl db webapp-release
```
See our [file definition](https://docs.docker.com/build/customize/bake/file-definition/)
See our [file definition](https://docs.docker.com/build/bake/file-definition/)
guide for more details.
### <a name="no-cache"></a> Do not use cache when building the image (--no-cache)
@@ -125,10 +125,18 @@ $ docker buildx bake -f docker-bake.hcl --print db
Same as [`build --progress`](buildx_build.md#progress).
### <a name="provenance"></a> Create provenance attestations (--provenance)
Same as [`build --provenance`](buildx_build.md#provenance).
### <a name="pull"></a> Always attempt to pull a newer version of the image (--pull)
Same as `build --pull`.
### <a name="sbom"></a> Create SBOM attestations (--sbom)
Same as [`build --sbom`](buildx_build.md#sbom).
### <a name="set"></a> Override target configurations from command line (--set)
```

View File

@@ -13,41 +13,41 @@ Start a build
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`--add-host`](https://docs.docker.com/engine/reference/commandline/build/#add-entries-to-container-hosts-file---add-host) | `stringSlice` | | Add a custom host-to-IP mapping (format: `host:ip`) |
| [`--allow`](#allow) | `stringSlice` | | Allow extra privileged entitlement (e.g., `network.host`, `security.insecure`) |
| `--attest` | `stringArray` | | Attestation parameters (format: `type=sbom,generator=image`) |
| [`--build-arg`](#build-arg) | `stringArray` | | Set build-time variables |
| [`--build-context`](#build-context) | `stringArray` | | Additional build contexts (e.g., name=path) |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`--cache-from`](#cache-from) | `stringArray` | | External cache sources (e.g., `user/app:cache`, `type=local,src=path/to/dir`) |
| [`--cache-to`](#cache-to) | `stringArray` | | Cache export destinations (e.g., `user/app:cache`, `type=local,dest=path/to/dir`) |
| [`--cgroup-parent`](https://docs.docker.com/engine/reference/commandline/build/#use-a-custom-parent-cgroup---cgroup-parent) | `string` | | Optional parent cgroup for the container |
| [`-f`](https://docs.docker.com/engine/reference/commandline/build/#specify-a-dockerfile--f), [`--file`](https://docs.docker.com/engine/reference/commandline/build/#specify-a-dockerfile--f) | `string` | | Name of the Dockerfile (default: `PATH/Dockerfile`) |
| `--iidfile` | `string` | | Write the image ID to the file |
| `--invoke` | `string` | | Invoke a command after the build [experimental] |
| `--label` | `stringArray` | | Set metadata for an image |
| [`--load`](#load) | | | Shorthand for `--output=type=docker` |
| [`--metadata-file`](#metadata-file) | `string` | | Write build result metadata to the file |
| `--network` | `string` | `default` | Set the networking mode for the `RUN` instructions during build |
| `--no-cache` | | | Do not use cache when building the image |
| `--no-cache-filter` | `stringArray` | | Do not cache specified stages |
| [`-o`](#output), [`--output`](#output) | `stringArray` | | Output destination (format: `type=local,dest=path`) |
| [`--platform`](#platform) | `stringArray` | | Set target platform for build |
| `--print` | `string` | | Print result of information request (e.g., outline, targets) [experimental] |
| [`--progress`](#progress) | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
| `--provenance` | `string` | | Shortand for `--attest=type=provenance` |
| `--pull` | | | Always attempt to pull all referenced images |
| [`--push`](#push) | | | Shorthand for `--output=type=registry` |
| `-q`, `--quiet` | | | Suppress the build output and print image ID on success |
| `--sbom` | `string` | | Shorthand for `--attest=type=sbom` |
| [`--secret`](#secret) | `stringArray` | | Secret to expose to the build (format: `id=mysecret[,src=/local/secret]`) |
| [`--shm-size`](#shm-size) | `bytes` | `0` | Size of `/dev/shm` |
| [`--ssh`](#ssh) | `stringArray` | | SSH agent socket or keys to expose to the build (format: `default\|<id>[=<socket>\|<key>[,<key>]]`) |
| [`-t`](https://docs.docker.com/engine/reference/commandline/build/#tag-an-image--t), [`--tag`](https://docs.docker.com/engine/reference/commandline/build/#tag-an-image--t) | `stringArray` | | Name and optionally a tag (format: `name:tag`) |
| [`--target`](https://docs.docker.com/engine/reference/commandline/build/#specifying-target-build-stage---target) | `string` | | Set the target build stage to build |
| [`--ulimit`](#ulimit) | `ulimit` | | Ulimit options |
| Name | Type | Default | Description |
|:-------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------|:----------|:----------------------------------------------------------------------------------------------------|
| [`--add-host`](https://docs.docker.com/engine/reference/commandline/build/#add-host) | `stringSlice` | | Add a custom host-to-IP mapping (format: `host:ip`) |
| [`--allow`](#allow) | `stringSlice` | | Allow extra privileged entitlement (e.g., `network.host`, `security.insecure`) |
| [`--attest`](#attest) | `stringArray` | | Attestation parameters (format: `type=sbom,generator=image`) |
| [`--build-arg`](#build-arg) | `stringArray` | | Set build-time variables |
| [`--build-context`](#build-context) | `stringArray` | | Additional build contexts (e.g., name=path) |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`--cache-from`](#cache-from) | `stringArray` | | External cache sources (e.g., `user/app:cache`, `type=local,src=path/to/dir`) |
| [`--cache-to`](#cache-to) | `stringArray` | | Cache export destinations (e.g., `user/app:cache`, `type=local,dest=path/to/dir`) |
| [`--cgroup-parent`](https://docs.docker.com/engine/reference/commandline/build/#cgroup-parent) | `string` | | Optional parent cgroup for the container |
| [`-f`](https://docs.docker.com/engine/reference/commandline/build/#file), [`--file`](https://docs.docker.com/engine/reference/commandline/build/#file) | `string` | | Name of the Dockerfile (default: `PATH/Dockerfile`) |
| `--iidfile` | `string` | | Write the image ID to the file |
| `--invoke` | `string` | | Invoke a command after the build [experimental] |
| `--label` | `stringArray` | | Set metadata for an image |
| [`--load`](#load) | | | Shorthand for `--output=type=docker` |
| [`--metadata-file`](#metadata-file) | `string` | | Write build result metadata to the file |
| `--network` | `string` | `default` | Set the networking mode for the `RUN` instructions during build |
| `--no-cache` | | | Do not use cache when building the image |
| `--no-cache-filter` | `stringArray` | | Do not cache specified stages |
| [`-o`](#output), [`--output`](#output) | `stringArray` | | Output destination (format: `type=local,dest=path`) |
| [`--platform`](#platform) | `stringArray` | | Set target platform for build |
| `--print` | `string` | | Print result of information request (e.g., outline, targets) [experimental] |
| [`--progress`](#progress) | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
| [`--provenance`](#provenance) | `string` | | Shortand for `--attest=type=provenance` |
| `--pull` | | | Always attempt to pull all referenced images |
| [`--push`](#push) | | | Shorthand for `--output=type=registry` |
| `-q`, `--quiet` | | | Suppress the build output and print image ID on success |
| [`--sbom`](#sbom) | `string` | | Shorthand for `--attest=type=sbom` |
| [`--secret`](#secret) | `stringArray` | | Secret to expose to the build (format: `id=mysecret[,src=/local/secret]`) |
| [`--shm-size`](#shm-size) | `bytes` | `0` | Size of `/dev/shm` |
| [`--ssh`](#ssh) | `stringArray` | | SSH agent socket or keys to expose to the build (format: `default\|<id>[=<socket>\|<key>[,<key>]]`) |
| [`-t`](https://docs.docker.com/engine/reference/commandline/build/#tag), [`--tag`](https://docs.docker.com/engine/reference/commandline/build/#tag) | `stringArray` | | Name and optionally a tag (format: `name:tag`) |
| [`--target`](https://docs.docker.com/engine/reference/commandline/build/#target) | `string` | | Set the target build stage to build |
| [`--ulimit`](#ulimit) | `ulimit` | | Ulimit options |
<!---MARKER_GEN_END-->
@@ -66,6 +66,30 @@ here we'll document a subset of the new flags.
## Examples
### <a name="attest"></a> Create attestations (--attest)
```
--attest=type=sbom,...
--attest=type=provenance,...
```
Create [image attestations](https://docs.docker.com/build/attestations/).
BuildKit currently supports:
- `sbom` - Software Bill of Materials.
Use `--attest=type=sbom` to generate an SBOM for an image at build-time.
Alternatively, you can use the [`--sbom` shorthand](#sbom).
For more information, see [here](https://docs.docker.com/build/attestations/sbom/).
- `provenance` - SLSA Provenance
Use `--attest=type=provenance` to generate provenance for an image at
build-time. Alternatively, you can use the [`--provenance` shorthand](#provenance).
For more information, see [here](https://docs.docker.com/build/attestations/slsa-provenance/).
### <a name="allow"></a> Allow extra privileged entitlement (--allow)
```
@@ -90,7 +114,7 @@ $ docker buildx build --allow security.insecure .
### <a name="build-arg"></a> Set build-time variables (--build-arg)
Same as [`docker build` command](https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables---build-arg).
Same as [`docker build` command](https://docs.docker.com/engine/reference/commandline/build/#build-arg).
There are also useful built-in build args like:
@@ -451,11 +475,21 @@ $ docker buildx build --load --progress=plain .
> Check also our [Color output controls guide](https://github.com/docker/buildx/blob/master/docs/guides/color-output.md)
> for modifying the colors that are used to output information to the terminal.
### <a name="provenance"></a> Create provenance attestations (--provenance)
Shorthand for [`--attest=type=provenance`](#attest). Enables provenance
attestations for the build result.
### <a name="push"></a> Push the build result to a registry (--push)
Shorthand for [`--output=type=registry`](#registry). Will automatically push the
build result to registry.
### <a name="sbom"></a> Create SBOM attestations (--sbom)
Shorthand for [`--attest=type=sbom`](#attest). Enables SBOM attestations for
the build result.
### <a name="secret"></a> Secret to expose to the build (--secret)
```

View File

@@ -9,19 +9,19 @@ Create a new builder instance
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`--append`](#append) | | | Append a node to builder instead of changing it |
| `--bootstrap` | | | Boot builder after creation |
| [`--buildkitd-flags`](#buildkitd-flags) | `string` | | Flags for buildkitd daemon |
| [`--config`](#config) | `string` | | BuildKit config file |
| [`--driver`](#driver) | `string` | | Driver to use (available: `docker-container`, `kubernetes`, `remote`) |
| [`--driver-opt`](#driver-opt) | `stringArray` | | Options for the driver |
| [`--leave`](#leave) | | | Remove a node from builder instead of changing it |
| [`--name`](#name) | `string` | | Builder instance name |
| [`--node`](#node) | `string` | | Create/modify node with given name |
| [`--platform`](#platform) | `stringArray` | | Fixed platforms for current node |
| [`--use`](#use) | | | Set the current builder instance |
| Name | Type | Default | Description |
|:----------------------------------------|:--------------|:--------|:----------------------------------------------------------------------|
| [`--append`](#append) | | | Append a node to builder instead of changing it |
| `--bootstrap` | | | Boot builder after creation |
| [`--buildkitd-flags`](#buildkitd-flags) | `string` | | Flags for buildkitd daemon |
| [`--config`](#config) | `string` | | BuildKit config file |
| [`--driver`](#driver) | `string` | | Driver to use (available: `docker-container`, `kubernetes`, `remote`) |
| [`--driver-opt`](#driver-opt) | `stringArray` | | Options for the driver |
| [`--leave`](#leave) | | | Remove a node from builder instead of changing it |
| [`--name`](#name) | `string` | | Builder instance name |
| [`--node`](#node) | `string` | | Create/modify node with given name |
| [`--platform`](#platform) | `stringArray` | | Fixed platforms for current node |
| [`--use`](#use) | | | Set the current builder instance |
<!---MARKER_GEN_END-->

View File

@@ -9,11 +9,11 @@ Disk usage
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| `--filter` | `filter` | | Provide filter values |
| `--verbose` | | | Provide a more verbose output |
| Name | Type | Default | Description |
|:------------------------|:---------|:--------|:-----------------------------------------|
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| `--filter` | `filter` | | Provide filter values |
| `--verbose` | | | Provide a more verbose output |
<!---MARKER_GEN_END-->

View File

@@ -9,17 +9,17 @@ Commands to work on images in registry
### Subcommands
| Name | Description |
| --- | --- |
| [`create`](buildx_imagetools_create.md) | Create a new image based on source images |
| [`inspect`](buildx_imagetools_inspect.md) | Show details of an image in the registry |
| Name | Description |
|:------------------------------------------|:------------------------------------------|
| [`create`](buildx_imagetools_create.md) | Create a new image based on source images |
| [`inspect`](buildx_imagetools_inspect.md) | Show details of an image in the registry |
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| Name | Type | Default | Description |
|:------------------------|:---------|:--------|:-----------------------------------------|
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
<!---MARKER_GEN_END-->

View File

@@ -9,14 +9,14 @@ Create a new image based on source images
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`--append`](#append) | | | Append to existing manifest |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`--dry-run`](#dry-run) | | | Show final image instead of pushing |
| [`-f`](#file), [`--file`](#file) | `stringArray` | | Read source descriptor from file |
| `--progress` | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
| [`-t`](#tag), [`--tag`](#tag) | `stringArray` | | Set reference for new image |
| Name | Type | Default | Description |
|:---------------------------------|:--------------|:--------|:-----------------------------------------------------------------------------------------|
| [`--append`](#append) | | | Append to existing manifest |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`--dry-run`](#dry-run) | | | Show final image instead of pushing |
| [`-f`](#file), [`--file`](#file) | `stringArray` | | Read source descriptor from file |
| `--progress` | `string` | `auto` | Set type of progress output (`auto`, `plain`, `tty`). Use plain to show container output |
| [`-t`](#tag), [`--tag`](#tag) | `stringArray` | | Set reference for new image |
<!---MARKER_GEN_END-->

View File

@@ -9,11 +9,11 @@ Show details of an image in the registry
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`--format`](#format) | `string` | `{{.Manifest}}` | Format the output using the given Go template |
| [`--raw`](#raw) | | | Show original, unformatted JSON manifest |
| Name | Type | Default | Description |
|:------------------------|:---------|:----------------|:----------------------------------------------|
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`--format`](#format) | `string` | `{{.Manifest}}` | Format the output using the given Go template |
| [`--raw`](#raw) | | | Show original, unformatted JSON manifest |
<!---MARKER_GEN_END-->
@@ -287,69 +287,57 @@ $ docker buildx imagetools inspect moby/buildkit:master --format "{{json .Manife
Following command provides [SLSA](https://github.com/moby/buildkit/blob/master/docs/attestations/slsa-provenance.md) JSON output:
```console
$ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .SLSA}}"
$ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .Provenance}}"
```
```json
{
"Provenance": {
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v0.2",
"subject": [
"SLSA": {
"builder": {
"id": ""
},
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"name": "pkg:docker/crazymax/buildkit@attest?platform=linux%2Famd64",
"uri": "pkg:docker/docker/buildkit-syft-scanner@stable-1",
"digest": {
"sha256": "fbd10fe50b4b174bb9ea273e2eb9827fa8bf5c88edd8635a93dc83e0d1aecb55"
"sha256": "b45f1d207e16c3a3a5a10b254ad8ad358d01f7ea090d382b95c6b2ee2b3ef765"
}
},
{
"uri": "pkg:docker/alpine@latest?platform=linux%2Famd64",
"digest": {
"sha256": "8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4"
}
}
],
"predicate": {
"builder": {
"id": ""
},
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/docker/buildkit-syft-scanner@stable-1",
"digest": {
"sha256": "b45f1d207e16c3a3a5a10b254ad8ad358d01f7ea090d382b95c6b2ee2b3ef765"
"invocation": {
"configSource": {},
"parameters": {
"frontend": "dockerfile.v0",
"locals": [
{
"name": "context"
},
{
"name": "dockerfile"
}
},
{
"uri": "pkg:docker/alpine@latest?platform=linux%2Famd64",
"digest": {
"sha256": "8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4"
}
}
],
"invocation": {
"configSource": {},
"parameters": {
"frontend": "dockerfile.v0",
"locals": [
{
"name": "context"
},
{
"name": "dockerfile"
}
]
},
"environment": {
"platform": "linux/amd64"
}
]
},
"metadata": {
"buildInvocationID": "02tdha2xkbxvin87mz9drhag4",
"buildStartedOn": "2022-12-01T11:50:07.264704131Z",
"buildFinishedOn": "2022-12-01T11:50:08.243788739Z",
"reproducible": false,
"completeness": {
"parameters": true,
"environment": true,
"materials": false
},
"https://mobyproject.org/buildkit@v1#metadata": {}
"environment": {
"platform": "linux/amd64"
}
},
"metadata": {
"buildInvocationID": "02tdha2xkbxvin87mz9drhag4",
"buildStartedOn": "2022-12-01T11:50:07.264704131Z",
"buildFinishedOn": "2022-12-01T11:50:08.243788739Z",
"reproducible": false,
"completeness": {
"parameters": true,
"environment": true,
"materials": false
},
"https://mobyproject.org/buildkit@v1#metadata": {}
}
}
}
@@ -363,32 +351,20 @@ $ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .SB
```json
{
"SPDX": {
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://spdx.dev/Document",
"subject": [
{
"name": "pkg:docker/crazymax/buildkit@attest?platform=linux%2Famd64",
"digest": {
"sha256": "fbd10fe50b4b174bb9ea273e2eb9827fa8bf5c88edd8635a93dc83e0d1aecb55"
}
}
],
"predicate": {
"SPDXID": "SPDXRef-DOCUMENT",
"creationInfo": {
"created": "2022-12-01T11:46:48.063400162Z",
"creators": [
"Tool: syft-v0.60.3",
"Tool: buildkit-1ace2bb",
"Organization: Anchore, Inc"
],
"licenseListVersion": "3.18"
},
"dataLicense": "CC0-1.0",
"documentNamespace": "https://anchore.com/syft/dir/run/src/core-0a4ccc6d-1a72-4c3a-a40e-3df1a2ffca94",
"files": [...],
"spdxVersion": "SPDX-2.2"
}
"SPDXID": "SPDXRef-DOCUMENT",
"creationInfo": {
"created": "2022-12-01T11:46:48.063400162Z",
"creators": [
"Tool: syft-v0.60.3",
"Tool: buildkit-1ace2bb",
"Organization: Anchore, Inc"
],
"licenseListVersion": "3.18"
},
"dataLicense": "CC0-1.0",
"documentNamespace": "https://anchore.com/syft/dir/run/src/core-0a4ccc6d-1a72-4c3a-a40e-3df1a2ffca94",
"files": [...],
"spdxVersion": "SPDX-2.2"
}
}
```
@@ -465,97 +441,73 @@ $ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .}}
}
]
},
"SLSA": {
"Provenance": {
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v0.2",
"subject": [
"Provenance": {
"SLSA": {
"builder": {
"id": ""
},
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"name": "pkg:docker/crazymax/buildkit@attest?platform=linux%2Famd64",
"uri": "pkg:docker/docker/buildkit-syft-scanner@stable-1",
"digest": {
"sha256": "fbd10fe50b4b174bb9ea273e2eb9827fa8bf5c88edd8635a93dc83e0d1aecb55"
"sha256": "b45f1d207e16c3a3a5a10b254ad8ad358d01f7ea090d382b95c6b2ee2b3ef765"
}
},
{
"uri": "pkg:docker/alpine@latest?platform=linux%2Famd64",
"digest": {
"sha256": "8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4"
}
}
],
"predicate": {
"builder": {
"id": ""
},
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/docker/buildkit-syft-scanner@stable-1",
"digest": {
"sha256": "b45f1d207e16c3a3a5a10b254ad8ad358d01f7ea090d382b95c6b2ee2b3ef765"
"invocation": {
"configSource": {},
"parameters": {
"frontend": "dockerfile.v0",
"locals": [
{
"name": "context"
},
{
"name": "dockerfile"
}
},
{
"uri": "pkg:docker/alpine@latest?platform=linux%2Famd64",
"digest": {
"sha256": "8914eb54f968791faf6a8638949e480fef81e697984fba772b3976835194c6d4"
}
}
],
"invocation": {
"configSource": {},
"parameters": {
"frontend": "dockerfile.v0",
"locals": [
{
"name": "context"
},
{
"name": "dockerfile"
}
]
},
"environment": {
"platform": "linux/amd64"
}
]
},
"metadata": {
"buildInvocationID": "02tdha2xkbxvin87mz9drhag4",
"buildStartedOn": "2022-12-01T11:50:07.264704131Z",
"buildFinishedOn": "2022-12-01T11:50:08.243788739Z",
"reproducible": false,
"completeness": {
"parameters": true,
"environment": true,
"materials": false
},
"https://mobyproject.org/buildkit@v1#metadata": {}
"environment": {
"platform": "linux/amd64"
}
},
"metadata": {
"buildInvocationID": "02tdha2xkbxvin87mz9drhag4",
"buildStartedOn": "2022-12-01T11:50:07.264704131Z",
"buildFinishedOn": "2022-12-01T11:50:08.243788739Z",
"reproducible": false,
"completeness": {
"parameters": true,
"environment": true,
"materials": false
},
"https://mobyproject.org/buildkit@v1#metadata": {}
}
}
},
"SBOM": {
"SPDX": {
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://spdx.dev/Document",
"subject": [
{
"name": "pkg:docker/crazymax/buildkit@attest?platform=linux%2Famd64",
"digest": {
"sha256": "fbd10fe50b4b174bb9ea273e2eb9827fa8bf5c88edd8635a93dc83e0d1aecb55"
}
}
],
"predicate": {
"SPDXID": "SPDXRef-DOCUMENT",
"creationInfo": {
"created": "2022-12-01T11:46:48.063400162Z",
"creators": [
"Tool: syft-v0.60.3",
"Tool: buildkit-1ace2bb",
"Organization: Anchore, Inc"
],
"licenseListVersion": "3.18"
},
"dataLicense": "CC0-1.0",
"documentNamespace": "https://anchore.com/syft/dir/run/src/core-0a4ccc6d-1a72-4c3a-a40e-3df1a2ffca94",
"files": [...],
"spdxVersion": "SPDX-2.2"
}
"SPDXID": "SPDXRef-DOCUMENT",
"creationInfo": {
"created": "2022-12-01T11:46:48.063400162Z",
"creators": [
"Tool: syft-v0.60.3",
"Tool: buildkit-1ace2bb",
"Organization: Anchore, Inc"
],
"licenseListVersion": "3.18"
},
"dataLicense": "CC0-1.0",
"documentNamespace": "https://anchore.com/syft/dir/run/src/core-0a4ccc6d-1a72-4c3a-a40e-3df1a2ffca94",
"files": [...],
"spdxVersion": "SPDX-2.2"
}
}
}

View File

@@ -9,10 +9,10 @@ Inspect current builder instance
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`--bootstrap`](#bootstrap) | | | Ensure builder has booted before inspecting |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| Name | Type | Default | Description |
|:----------------------------|:---------|:--------|:--------------------------------------------|
| [`--bootstrap`](#bootstrap) | | | Ensure builder has booted before inspecting |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
<!---MARKER_GEN_END-->

View File

@@ -9,14 +9,14 @@ Remove build cache
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `-a`, `--all` | | | Include internal/frontend images |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| `--filter` | `filter` | | Provide filter values (e.g., `until=24h`) |
| `-f`, `--force` | | | Do not prompt for confirmation |
| `--keep-storage` | `bytes` | `0` | Amount of disk space to keep for cache |
| `--verbose` | | | Provide a more verbose output |
| Name | Type | Default | Description |
|:------------------------|:---------|:--------|:------------------------------------------|
| `-a`, `--all` | | | Include internal/frontend images |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| `--filter` | `filter` | | Provide filter values (e.g., `until=24h`) |
| `-f`, `--force` | | | Do not prompt for confirmation |
| `--keep-storage` | `bytes` | `0` | Amount of disk space to keep for cache |
| `--verbose` | | | Provide a more verbose output |
<!---MARKER_GEN_END-->

View File

@@ -9,13 +9,13 @@ Remove a builder instance
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`--all-inactive`](#all-inactive) | | | Remove all inactive builders |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`-f`](#force), [`--force`](#force) | | | Do not prompt for confirmation |
| [`--keep-daemon`](#keep-daemon) | | | Keep the buildkitd daemon running |
| [`--keep-state`](#keep-state) | | | Keep BuildKit state |
| Name | Type | Default | Description |
|:------------------------------------|:---------|:--------|:-----------------------------------------|
| [`--all-inactive`](#all-inactive) | | | Remove all inactive builders |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| [`-f`](#force), [`--force`](#force) | | | Do not prompt for confirmation |
| [`--keep-daemon`](#keep-daemon) | | | Keep the buildkitd daemon running |
| [`--keep-state`](#keep-state) | | | Keep BuildKit state |
<!---MARKER_GEN_END-->

View File

@@ -9,9 +9,9 @@ Stop builder instance
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| Name | Type | Default | Description |
|:------------------------|:---------|:--------|:-----------------------------------------|
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
<!---MARKER_GEN_END-->

View File

@@ -9,11 +9,11 @@ Set the current builder instance
### Options
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| `--default` | | | Set builder as default for current context |
| `--global` | | | Builder persists context changes |
| Name | Type | Default | Description |
|:------------------------|:---------|:--------|:-------------------------------------------|
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
| `--default` | | | Set builder as default for current context |
| `--global` | | | Builder persists context changes |
<!---MARKER_GEN_END-->

6
go.mod
View File

@@ -6,9 +6,9 @@ require (
github.com/aws/aws-sdk-go-v2/config v1.15.5
github.com/compose-spec/compose-go v1.6.0
github.com/containerd/console v1.0.3
github.com/containerd/containerd v1.6.14
github.com/containerd/containerd v1.6.16-0.20230124210447-1709cfe273d9
github.com/docker/cli v23.0.0-rc.1+incompatible
github.com/docker/cli-docs-tool v0.5.0
github.com/docker/cli-docs-tool v0.5.1
github.com/docker/distribution v2.8.1+incompatible
github.com/docker/docker v23.0.0-rc.1+incompatible
github.com/docker/go-units v0.5.0
@@ -16,7 +16,7 @@ require (
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/hashicorp/go-cty-funcs v0.0.0-20200930094925-2721b1e36840
github.com/hashicorp/hcl/v2 v2.8.2
github.com/moby/buildkit v0.11.0-rc4
github.com/moby/buildkit v0.11.2
github.com/moby/sys/mountinfo v0.6.2
github.com/morikuni/aec v1.0.0
github.com/opencontainers/go-digest v1.0.0

12
go.sum
View File

@@ -140,8 +140,8 @@ github.com/compose-spec/compose-go v1.6.0/go.mod h1:os+Ulh2jlZxY1XT1hbciERadjSUU
github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA=
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/containerd v1.6.14 h1:W+d0AJKVG3ioTZZyQwcw1Y3vvo6ZDYzAcjDcY4tkgGI=
github.com/containerd/containerd v1.6.14/go.mod h1:U2NnBPIhzJDm59xF7xB2MMHnKtggpZ+phKg8o2TKj2c=
github.com/containerd/containerd v1.6.16-0.20230124210447-1709cfe273d9 h1:zdFesNKUzj0PDylWScwyU6zv3KAKwYeSE1ZLUmi01wk=
github.com/containerd/containerd v1.6.16-0.20230124210447-1709cfe273d9/go.mod h1:1RdCUu95+gc2v9t3IL+zIlpClSmew7/0YS8O5eQZrOw=
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
github.com/containerd/fifo v1.0.0 h1:6PirWBr9/L7GDamKr+XM0IeUFXu5mf3M/BPpH9gaLBU=
@@ -165,8 +165,8 @@ github.com/distribution/distribution/v3 v3.0.0-20220725133111-4bf3547399eb h1:oC
github.com/distribution/distribution/v3 v3.0.0-20220725133111-4bf3547399eb/go.mod h1:28YO/VJk9/64+sTGNuYaBjWxrXTPrj0C0XmgTIOjxX4=
github.com/docker/cli v23.0.0-rc.1+incompatible h1:Vl3pcUK4/LFAD56Ys3BrqgAtuwpWd/IO3amuSL0ZbP0=
github.com/docker/cli v23.0.0-rc.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli-docs-tool v0.5.0 h1:EjGwI6EyB7YemHCC7R8mwXszJTbuq0T0pFuDC5bMhcE=
github.com/docker/cli-docs-tool v0.5.0/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o=
github.com/docker/cli-docs-tool v0.5.1 h1:jIk/cCZurZERhALPVKhqlNxTQGxn2kcI+56gE57PQXg=
github.com/docker/cli-docs-tool v0.5.1/go.mod h1:zMjqTFCU361PRh8apiXzeAZ1Q/xupbIwTusYpzCXS/o=
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v23.0.0-rc.1+incompatible h1:Dmn88McWuHc7BSNN1s6RtfhMmt6ZPQAYUEf7FhqpiQI=
@@ -401,8 +401,8 @@ github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZX
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/buildkit v0.11.0-rc4 h1:PxvzcqZn2IOrMzIS2nEqRQxk67xeSQnhdYxEj0YQuLM=
github.com/moby/buildkit v0.11.0-rc4/go.mod h1:v43oa6H2Fx/cdzc7j0UlUu8p6188yy1P3vrujAs99uw=
github.com/moby/buildkit v0.11.2 h1:hNNsYuRssvFnp/qJ8FifStEUzROl5riPAEwk7cRzMjg=
github.com/moby/buildkit v0.11.2/go.mod h1:b5hR8j3BZaOj5+gf6yielP9YLT9mU92zy3zZtdoUTrw=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=

View File

@@ -67,7 +67,15 @@ func (c *Git) RootDir() (string, error) {
}
func (c *Git) RemoteURL() (string, error) {
return c.clean(c.run("ls-remote", "--get-url"))
// Try to get the remote URL from the origin remote first
if ru, err := c.clean(c.run("remote", "get-url", "origin")); err == nil && ru != "" {
return ru, nil
}
// If that fails, try to get the remote URL from the upstream remote
if ru, err := c.clean(c.run("remote", "get-url", "upstream")); err == nil && ru != "" {
return ru, nil
}
return "", errors.New("no remote URL found for either origin or upstream")
}
func (c *Git) FullCommit() (string, error) {

View File

@@ -77,3 +77,89 @@ func TestGitDescribeTags(t *testing.T) {
require.NoError(t, err)
require.Equal(t, "v0.9.0", out)
}
func TestGitRemoteURL(t *testing.T) {
type remote struct {
name string
url string
}
cases := []struct {
name string
remotes []remote
expected string
fail bool
}{
{
name: "no remotes",
remotes: []remote{},
fail: true,
},
{
name: "origin",
remotes: []remote{
{
name: "origin",
url: "git@github.com:crazy-max/buildx.git",
},
},
expected: "git@github.com:crazy-max/buildx.git",
},
{
name: "upstream",
remotes: []remote{
{
name: "upstream",
url: "git@github.com:docker/buildx.git",
},
},
expected: "git@github.com:docker/buildx.git",
},
{
name: "origin and upstream",
remotes: []remote{
{
name: "upstream",
url: "git@github.com:docker/buildx.git",
},
{
name: "origin",
url: "git@github.com:crazy-max/buildx.git",
},
},
expected: "git@github.com:crazy-max/buildx.git",
},
{
name: "not found",
remotes: []remote{
{
name: "foo",
url: "git@github.com:docker/buildx.git",
},
},
fail: true,
},
}
for _, tt := range cases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
Mktmp(t)
c, err := New()
require.NoError(t, err)
GitInit(c, t)
GitCommit(c, t, "initial commit")
for _, r := range tt.remotes {
GitSetRemote(c, t, r.name, r.url)
}
ru, err := c.RemoteURL()
if tt.fail {
require.Error(t, err)
return
}
require.NoError(t, err)
require.Equal(t, tt.expected, ru)
})
}
}

View File

@@ -44,9 +44,9 @@ func GitAdd(c *Git, tb testing.TB, file string) {
require.NoError(tb, err)
}
func GitSetRemote(c *Git, tb testing.TB, url string) {
func GitSetRemote(c *Git, tb testing.TB, name string, url string) {
tb.Helper()
_, err := fakeGit(c, "remote", "add", "origin", url)
_, err := fakeGit(c, "remote", "add", name, url)
require.NoError(tb, err)
}

View File

@@ -11,6 +11,7 @@ import (
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/remotes"
"github.com/docker/distribution/reference"
"github.com/moby/buildkit/util/contentutil"
"github.com/opencontainers/go-digest"
@@ -151,8 +152,9 @@ func (r *Resolver) Combine(ctx context.Context, srcs []*Source) ([]byte, ocispec
}
func (r *Resolver) Push(ctx context.Context, ref reference.Named, desc ocispec.Descriptor, dt []byte) error {
ref = reference.TagNameOnly(ref)
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.in-toto+json", "intoto")
ref = reference.TagNameOnly(ref)
p, err := r.resolver().Pusher(ctx, ref.String())
if err != nil {
return err
@@ -173,6 +175,8 @@ func (r *Resolver) Push(ctx context.Context, ref reference.Named, desc ocispec.D
}
func (r *Resolver) Copy(ctx context.Context, src *Source, dest reference.Named) error {
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.in-toto+json", "intoto")
dest = reference.TagNameOnly(dest)
p, err := r.resolver().Pusher(ctx, dest.String())
if err != nil {

View File

@@ -46,9 +46,12 @@ type index struct {
}
type asset struct {
config *ocispec.Image
sbom *sbomStub
slsa *slsaStub
config *ocispec.Image
sbom *sbomStub
provenance *provenanceStub
deferredSbom func() (*sbomStub, error)
deferredProvenance func() (*provenanceStub, error)
}
type result struct {
@@ -255,61 +258,87 @@ func (l *loader) scanConfig(ctx context.Context, fetcher remotes.Fetcher, desc o
}
type sbomStub struct {
SPDX json.RawMessage `json:",omitempty"`
SPDX interface{} `json:",omitempty"`
AdditionalSPDXs []interface{} `json:",omitempty"`
}
func (l *loader) scanSBOM(ctx context.Context, fetcher remotes.Fetcher, r *result, refs []digest.Digest, as *asset) error {
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.in-toto+json", "intoto")
for _, dgst := range refs {
mfst, ok := r.manifests[dgst]
if !ok {
return errors.Errorf("referenced image %s not found", dgst)
}
for _, layer := range mfst.manifest.Layers {
if layer.MediaType == "application/vnd.in-toto+json" && layer.Annotations["in-toto.io/predicate-type"] == "https://spdx.dev/Document" {
_, err := remotes.FetchHandler(l.cache, fetcher)(ctx, layer)
if err != nil {
return err
}
dt, err := content.ReadBlob(ctx, l.cache, layer)
if err != nil {
return err
}
as.sbom = &sbomStub{
SPDX: dt,
as.deferredSbom = func() (*sbomStub, error) {
var sbom *sbomStub
for _, dgst := range refs {
mfst, ok := r.manifests[dgst]
if !ok {
return nil, errors.Errorf("referenced image %s not found", dgst)
}
for _, layer := range mfst.manifest.Layers {
if layer.MediaType == "application/vnd.in-toto+json" && layer.Annotations["in-toto.io/predicate-type"] == "https://spdx.dev/Document" {
_, err := remotes.FetchHandler(l.cache, fetcher)(ctx, layer)
if err != nil {
return nil, err
}
dt, err := content.ReadBlob(ctx, l.cache, layer)
if err != nil {
return nil, err
}
var spdx struct {
Predicate interface{} `json:"predicate"`
}
if err := json.Unmarshal(dt, &spdx); err != nil {
return nil, err
}
if sbom == nil {
sbom = &sbomStub{}
sbom.SPDX = spdx.Predicate
} else {
sbom.AdditionalSPDXs = append(sbom.AdditionalSPDXs, spdx.Predicate)
}
}
}
}
return sbom, nil
}
return nil
}
type slsaStub struct {
Provenance json.RawMessage `json:",omitempty"`
type provenanceStub struct {
SLSA interface{} `json:",omitempty"`
}
func (l *loader) scanProvenance(ctx context.Context, fetcher remotes.Fetcher, r *result, refs []digest.Digest, as *asset) error {
ctx = remotes.WithMediaTypeKeyPrefix(ctx, "application/vnd.in-toto+json", "intoto")
for _, dgst := range refs {
mfst, ok := r.manifests[dgst]
if !ok {
return errors.Errorf("referenced image %s not found", dgst)
}
for _, layer := range mfst.manifest.Layers {
if layer.MediaType == "application/vnd.in-toto+json" && strings.HasPrefix(layer.Annotations["in-toto.io/predicate-type"], "https://slsa.dev/provenance/") {
_, err := remotes.FetchHandler(l.cache, fetcher)(ctx, layer)
if err != nil {
return err
}
dt, err := content.ReadBlob(ctx, l.cache, layer)
if err != nil {
return err
}
as.slsa = &slsaStub{
Provenance: dt,
as.deferredProvenance = func() (*provenanceStub, error) {
var provenance *provenanceStub
for _, dgst := range refs {
mfst, ok := r.manifests[dgst]
if !ok {
return nil, errors.Errorf("referenced image %s not found", dgst)
}
for _, layer := range mfst.manifest.Layers {
if layer.MediaType == "application/vnd.in-toto+json" && strings.HasPrefix(layer.Annotations["in-toto.io/predicate-type"], "https://slsa.dev/provenance/") {
_, err := remotes.FetchHandler(l.cache, fetcher)(ctx, layer)
if err != nil {
return nil, err
}
dt, err := content.ReadBlob(ctx, l.cache, layer)
if err != nil {
return nil, err
}
var slsa struct {
Predicate interface{} `json:"predicate"`
}
if err := json.Unmarshal(dt, &slsa); err != nil {
return nil, err
}
provenance = &provenanceStub{
SLSA: slsa.Predicate,
}
break
}
}
}
return provenance, nil
}
return nil
}
@@ -328,30 +357,50 @@ func (r *result) Configs() map[string]*ocispec.Image {
return res
}
func (r *result) SLSA() map[string]slsaStub {
func (r *result) Provenance() (map[string]provenanceStub, error) {
if len(r.assets) == 0 {
return nil
return nil, nil
}
res := make(map[string]slsaStub)
res := make(map[string]provenanceStub)
for p, a := range r.assets {
if a.slsa == nil {
if a.deferredProvenance == nil {
continue
}
res[p] = *a.slsa
if a.provenance == nil {
provenance, err := a.deferredProvenance()
if err != nil {
return nil, err
}
if provenance == nil {
continue
}
a.provenance = provenance
}
res[p] = *a.provenance
}
return res
return res, nil
}
func (r *result) SBOM() map[string]sbomStub {
func (r *result) SBOM() (map[string]sbomStub, error) {
if len(r.assets) == 0 {
return nil
return nil, nil
}
res := make(map[string]sbomStub)
for p, a := range r.assets {
if a.sbom == nil {
if a.deferredSbom == nil {
continue
}
if a.sbom == nil {
sbom, err := a.deferredSbom()
if err != nil {
return nil, err
}
if sbom == nil {
continue
}
a.sbom = sbom
}
res[p] = *a.sbom
}
return res
return res, nil
}

View File

@@ -99,8 +99,6 @@ func (p *Printer) Print(raw bool, out io.Writer) error {
}
imageconfigs := res.Configs()
slsas := res.SLSA()
sboms := res.SBOM()
format := tpl.Root.String()
var mfst interface{}
@@ -142,44 +140,22 @@ func (p *Printer) Print(raw bool, out io.Writer) error {
}
default:
if len(res.platforms) > 1 {
return tpl.Execute(out, struct {
Name string `json:"name,omitempty"`
Manifest interface{} `json:"manifest,omitempty"`
Image map[string]*ocispecs.Image `json:"image,omitempty"`
SLSA map[string]slsaStub `json:"SLSA,omitempty"`
SBOM map[string]sbomStub `json:"SBOM,omitempty"`
}{
return tpl.Execute(out, tplInputs{
Name: p.name,
Manifest: mfst,
Image: imageconfigs,
SLSA: slsas,
SBOM: sboms,
result: res,
})
}
var ic *ocispecs.Image
for _, v := range imageconfigs {
ic = v
}
var slsa slsaStub
for _, v := range slsas {
slsa = v
}
var sbom sbomStub
for _, v := range sboms {
sbom = v
}
return tpl.Execute(out, struct {
Name string `json:"name,omitempty"`
Manifest interface{} `json:"manifest,omitempty"`
Image *ocispecs.Image `json:"image,omitempty"`
SLSA slsaStub `json:"SLSA,omitempty"`
SBOM sbomStub `json:"SBOM,omitempty"`
}{
return tpl.Execute(out, tplInput{
Name: p.name,
Manifest: mfst,
Image: ic,
SLSA: slsa,
SBOM: sbom,
result: res,
})
}
@@ -227,3 +203,49 @@ func (p *Printer) printManifestList(out io.Writer) error {
}
return w.Flush()
}
type tplInput struct {
Name string `json:"name,omitempty"`
Manifest interface{} `json:"manifest,omitempty"`
Image *ocispecs.Image `json:"image,omitempty"`
result *result
}
func (inp tplInput) SBOM() (sbomStub, error) {
sbom, err := inp.result.SBOM()
if err != nil {
return sbomStub{}, nil
}
for _, v := range sbom {
return v, nil
}
return sbomStub{}, nil
}
func (inp tplInput) Provenance() (provenanceStub, error) {
provenance, err := inp.result.Provenance()
if err != nil {
return provenanceStub{}, nil
}
for _, v := range provenance {
return v, nil
}
return provenanceStub{}, nil
}
type tplInputs struct {
Name string `json:"name,omitempty"`
Manifest interface{} `json:"manifest,omitempty"`
Image map[string]*ocispecs.Image `json:"image,omitempty"`
result *result
}
func (inp tplInputs) SBOM() (map[string]sbomStub, error) {
return inp.result.SBOM()
}
func (inp tplInputs) Provenance() (map[string]provenanceStub, error) {
return inp.result.Provenance()
}

View File

@@ -377,17 +377,24 @@ func (pw *pushWriter) Write(p []byte) (n int, err error) {
// If content has already been written, the bytes
// cannot be written and the caller must reset
if status.Offset > 0 {
status.Offset = 0
status.UpdatedAt = time.Now()
pw.tracker.SetStatus(pw.ref, status)
return 0, content.ErrReset
}
status.Offset = 0
status.UpdatedAt = time.Now()
pw.tracker.SetStatus(pw.ref, status)
return 0, content.ErrReset
default:
}
}
n, err = pw.pipe.Write(p)
if errors.Is(err, io.ErrClosedPipe) {
// if the pipe is closed, we might have the original error on the error
// channel - so we should try and get it
select {
case err2 := <-pw.errC:
err = err2
default:
}
}
status.Offset += int64(n)
status.UpdatedAt = time.Now()
pw.tracker.SetStatus(pw.ref, status)
@@ -428,7 +435,7 @@ func (pw *pushWriter) Digest() digest.Digest {
func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
// Check whether read has already thrown an error
if _, err := pw.pipe.Write([]byte{}); err != nil && err != io.ErrClosedPipe {
if _, err := pw.pipe.Write([]byte{}); err != nil && !errors.Is(err, io.ErrClosedPipe) {
return fmt.Errorf("pipe error before commit: %w", err)
}
@@ -439,9 +446,7 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
var resp *http.Response
select {
case err := <-pw.errC:
if err != nil {
return err
}
return err
case resp = <-pw.respC:
defer resp.Body.Close()
case p, ok := <-pw.pipeC:
@@ -453,18 +458,17 @@ func (pw *pushWriter) Commit(ctx context.Context, size int64, expected digest.Di
}
pw.pipe.CloseWithError(content.ErrReset)
pw.pipe = p
// If content has already been written, the bytes
// cannot be written again and the caller must reset
status, err := pw.tracker.GetStatus(pw.ref)
if err != nil {
return err
}
// If content has already been written, the bytes
// cannot be written again and the caller must reset
if status.Offset > 0 {
status.Offset = 0
status.UpdatedAt = time.Now()
pw.tracker.SetStatus(pw.ref, status)
return content.ErrReset
}
status.Offset = 0
status.UpdatedAt = time.Now()
pw.tracker.SetStatus(pw.ref, status)
return content.ErrReset
}
// 201 is specified return status, some registries return

View File

@@ -23,7 +23,7 @@ var (
Package = "github.com/containerd/containerd"
// Version holds the complete version number. Filled in at linking time.
Version = "1.6.14+unknown"
Version = "1.6.15+unknown"
// Revision is filled with the VCS (e.g. git) revision being used to build
// the program at linking time.

View File

@@ -1,5 +1,5 @@
[![PkgGoDev](https://img.shields.io/badge/go.dev-docs-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/docker/cli-docs-tool)
[![Test Status](https://img.shields.io/github/workflow/status/docker/cli-docs-tool/test?label=test&logo=github&style=flat-square)](https://github.com/docker/cli-docs-tool/actions?query=workflow%3Atest)
[![Test Status](https://img.shields.io/github/actions/workflow/status/docker/cli-docs-tool/test.yml?branch=main&label=test&logo=github&style=flat-square)](https://github.com/docker/cli-docs-tool/actions?query=workflow%3Atest)
[![Go Report Card](https://goreportcard.com/badge/github.com/docker/cli-docs-tool)](https://goreportcard.com/report/github.com/docker/cli-docs-tool)
## About

View File

@@ -20,7 +20,9 @@ import (
"log"
"os"
"path/filepath"
"regexp"
"strings"
"text/tabwriter"
"text/template"
"github.com/docker/cli-docs-tool/annotation"
@@ -28,6 +30,11 @@ import (
"github.com/spf13/pflag"
)
var (
nlRegexp = regexp.MustCompile(`\r?\n`)
adjustSep = regexp.MustCompile(`\|:---(\s+)`)
)
// GenMarkdownTree will generate a markdown page for this command and all
// descendants in the directory given.
func (c *Client) GenMarkdownTree(cmd *cobra.Command) error {
@@ -144,6 +151,42 @@ func mdMakeLink(txt, link string, f *pflag.Flag, isAnchor bool) string {
return "[" + txt + "](" + link + ")"
}
type mdTable struct {
out *strings.Builder
tabWriter *tabwriter.Writer
}
func newMdTable(headers ...string) *mdTable {
w := &strings.Builder{}
t := &mdTable{
out: w,
// Using tabwriter.Debug, which uses "|" as separator instead of tabs,
// which is what we want. It's a bit of a hack, but does the job :)
tabWriter: tabwriter.NewWriter(w, 5, 5, 1, ' ', tabwriter.Debug),
}
t.addHeader(headers...)
return t
}
func (t *mdTable) addHeader(cols ...string) {
t.AddRow(cols...)
_, _ = t.tabWriter.Write([]byte("|" + strings.Repeat(":---\t", len(cols)) + "\n"))
}
func (t *mdTable) AddRow(cols ...string) {
for i := range cols {
cols[i] = mdEscapePipe(cols[i])
}
_, _ = t.tabWriter.Write([]byte("| " + strings.Join(cols, "\t ") + "\t\n"))
}
func (t *mdTable) String() string {
_ = t.tabWriter.Flush()
return adjustSep.ReplaceAllStringFunc(t.out.String()+"\n", func(in string) string {
return strings.ReplaceAll(in, " ", "-")
})
}
func mdCmdOutput(cmd *cobra.Command, old string) (string, error) {
b := &strings.Builder{}
@@ -152,46 +195,41 @@ func mdCmdOutput(cmd *cobra.Command, old string) (string, error) {
desc = cmd.Long
}
if desc != "" {
fmt.Fprintf(b, "%s\n\n", desc)
b.WriteString(desc + "\n\n")
}
if aliases := getAliases(cmd); len(aliases) != 0 {
fmt.Fprint(b, "### Aliases\n\n")
fmt.Fprint(b, "`"+strings.Join(aliases, "`, `")+"`")
fmt.Fprint(b, "\n\n")
b.WriteString("### Aliases\n\n")
b.WriteString("`" + strings.Join(aliases, "`, `") + "`")
b.WriteString("\n\n")
}
if len(cmd.Commands()) != 0 {
fmt.Fprint(b, "### Subcommands\n\n")
fmt.Fprint(b, "| Name | Description |\n")
fmt.Fprint(b, "| --- | --- |\n")
b.WriteString("### Subcommands\n\n")
table := newMdTable("Name", "Description")
for _, c := range cmd.Commands() {
fmt.Fprintf(b, "| [`%s`](%s) | %s |\n", c.Name(), mdFilename(c), c.Short)
table.AddRow(fmt.Sprintf("[`%s`](%s)", c.Name(), mdFilename(c)), c.Short)
}
fmt.Fprint(b, "\n\n")
b.WriteString(table.String() + "\n")
}
// add inherited flags before checking for flags availability
cmd.Flags().AddFlagSet(cmd.InheritedFlags())
if cmd.Flags().HasAvailableFlags() {
fmt.Fprint(b, "### Options\n\n")
fmt.Fprint(b, "| Name | Type | Default | Description |\n")
fmt.Fprint(b, "| --- | --- | --- | --- |\n")
b.WriteString("### Options\n\n")
table := newMdTable("Name", "Type", "Default", "Description")
cmd.Flags().VisitAll(func(f *pflag.Flag) {
if f.Hidden {
return
}
isLink := strings.Contains(old, "<a name=\""+f.Name+"\"></a>")
fmt.Fprint(b, "| ")
var name string
if f.Shorthand != "" {
name := "`-" + f.Shorthand + "`"
name = mdMakeLink(name, f.Name, f, isLink)
fmt.Fprintf(b, "%s, ", name)
name = mdMakeLink("`-"+f.Shorthand+"`", f.Name, f, isLink)
name += ", "
}
name := "`--" + f.Name + "`"
name = mdMakeLink(name, f.Name, f, isLink)
name += mdMakeLink("`--"+f.Name+"`", f.Name, f, isLink)
var ftype string
if f.Value.Type() != "bool" {
@@ -216,9 +254,9 @@ func mdCmdOutput(cmd *cobra.Command, old string) (string, error) {
} else if cd, ok := cmd.Annotations[annotation.CodeDelimiter]; ok {
usage = strings.ReplaceAll(usage, cd, "`")
}
fmt.Fprintf(b, "%s | %s | %s | %s |\n", mdEscapePipe(name), mdEscapePipe(ftype), mdEscapePipe(defval), mdEscapePipe(usage))
table.AddRow(name, ftype, defval, mdReplaceNewline(usage))
})
fmt.Fprintln(b, "")
b.WriteString(table.String())
}
return b.String(), nil
@@ -227,3 +265,7 @@ func mdCmdOutput(cmd *cobra.Command, old string) (string, error) {
func mdEscapePipe(s string) string {
return strings.ReplaceAll(s, `|`, `\|`)
}
func mdReplaceNewline(s string) string {
return nlRegexp.ReplaceAllString(s, "<br>")
}

View File

@@ -1507,6 +1507,7 @@ type BuildHistoryRecord struct {
Pinned bool `protobuf:"varint,14,opt,name=pinned,proto3" json:"pinned,omitempty"`
NumCachedSteps int32 `protobuf:"varint,15,opt,name=numCachedSteps,proto3" json:"numCachedSteps,omitempty"`
NumTotalSteps int32 `protobuf:"varint,16,opt,name=numTotalSteps,proto3" json:"numTotalSteps,omitempty"`
NumCompletedSteps int32 `protobuf:"varint,17,opt,name=numCompletedSteps,proto3" json:"numCompletedSteps,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -1657,6 +1658,13 @@ func (m *BuildHistoryRecord) GetNumTotalSteps() int32 {
return 0
}
func (m *BuildHistoryRecord) GetNumCompletedSteps() int32 {
if m != nil {
return m.NumCompletedSteps
}
return 0
}
type UpdateBuildHistoryRequest struct {
Ref string `protobuf:"bytes,1,opt,name=Ref,proto3" json:"Ref,omitempty"`
Pinned bool `protobuf:"varint,2,opt,name=Pinned,proto3" json:"Pinned,omitempty"`
@@ -1978,148 +1986,149 @@ func init() {
func init() { proto.RegisterFile("control.proto", fileDescriptor_0c5120591600887d) }
var fileDescriptor_0c5120591600887d = []byte{
// 2246 bytes of a gzipped FileDescriptorProto
// 2261 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0xcd, 0x6e, 0x1b, 0xc9,
0x11, 0xde, 0xe1, 0x3f, 0x8b, 0x94, 0x4c, 0xb7, 0xbd, 0xc6, 0x64, 0xe2, 0x95, 0xe4, 0x59, 0x3b,
0x11, 0x1c, 0x7b, 0xa8, 0x65, 0xd6, 0xb1, 0x57, 0x4e, 0x1c, 0x8b, 0x22, 0xb3, 0x96, 0x63, 0xc3,
0xda, 0x96, 0xbc, 0x06, 0x16, 0x70, 0x82, 0x11, 0xd9, 0xa2, 0x07, 0x1a, 0xce, 0x4c, 0xba, 0x9b,
0x5a, 0x73, 0x1f, 0x20, 0xc0, 0xe6, 0x10, 0xe4, 0x12, 0xe4, 0x92, 0x7b, 0x4e, 0x39, 0xe7, 0x09,
0x02, 0x18, 0xc8, 0x25, 0xe7, 0x3d, 0x38, 0x81, 0x1f, 0x20, 0xc8, 0x31, 0xc7, 0xa0, 0x7f, 0x86,
0x1c, 0x92, 0x43, 0x89, 0xb2, 0x7d, 0x62, 0x57, 0x77, 0x55, 0x4d, 0x55, 0x75, 0x75, 0xf5, 0x57,
0x4d, 0x58, 0xea, 0x84, 0x01, 0xa7, 0xa1, 0xef, 0x44, 0x34, 0xe4, 0x21, 0xaa, 0xf5, 0xc3, 0x83,
0xa1, 0x73, 0x30, 0xf0, 0xfc, 0xee, 0x91, 0xc7, 0x9d, 0xe3, 0x4f, 0xac, 0x9b, 0x3d, 0x8f, 0xbf,
0x18, 0x1c, 0x38, 0x9d, 0xb0, 0x5f, 0xef, 0x85, 0xbd, 0xb0, 0x2e, 0x19, 0x0f, 0x06, 0x87, 0x92,
0x92, 0x84, 0x1c, 0x29, 0x05, 0xd6, 0x6a, 0x2f, 0x0c, 0x7b, 0x3e, 0x19, 0x73, 0x71, 0xaf, 0x4f,
0x18, 0x77, 0xfb, 0x91, 0x66, 0xb8, 0x91, 0xd0, 0x27, 0x3e, 0x56, 0x8f, 0x3f, 0x56, 0x67, 0xa1,
0x7f, 0x4c, 0x68, 0x3d, 0x3a, 0xa8, 0x87, 0x11, 0xd3, 0xdc, 0xf5, 0xb9, 0xdc, 0x6e, 0xe4, 0xd5,
0xf9, 0x30, 0x22, 0xac, 0xfe, 0x75, 0x48, 0x8f, 0x08, 0xd5, 0x02, 0x8d, 0x69, 0x73, 0x95, 0x3d,
0x6e, 0xe4, 0x31, 0x3d, 0xac, 0xd3, 0xa8, 0x53, 0x67, 0xdc, 0xe5, 0x83, 0xf8, 0x23, 0xb7, 0x4e,
0x30, 0x69, 0x40, 0x3b, 0x24, 0x0a, 0x7d, 0xaf, 0x33, 0x14, 0x86, 0xa9, 0x91, 0x12, 0xb3, 0x7f,
0x6b, 0x40, 0x75, 0x97, 0x0e, 0x02, 0x82, 0xc9, 0x6f, 0x06, 0x84, 0x71, 0x74, 0x09, 0x0a, 0x87,
0x9e, 0xcf, 0x09, 0x35, 0x8d, 0xb5, 0xec, 0x7a, 0x19, 0x6b, 0x0a, 0xd5, 0x20, 0xeb, 0xfa, 0xbe,
0x99, 0x59, 0x33, 0xd6, 0x4b, 0x58, 0x0c, 0xd1, 0x3a, 0x54, 0x8f, 0x08, 0x89, 0x5a, 0x03, 0xea,
0x72, 0x2f, 0x0c, 0xcc, 0xec, 0x9a, 0xb1, 0x9e, 0x6d, 0xe6, 0x5e, 0xbd, 0x5e, 0x35, 0xf0, 0xc4,
0x0a, 0xb2, 0xa1, 0x2c, 0xe8, 0xe6, 0x90, 0x13, 0x66, 0xe6, 0x12, 0x6c, 0xe3, 0x69, 0xfb, 0x3a,
0xd4, 0x5a, 0x1e, 0x3b, 0x7a, 0xca, 0xdc, 0xde, 0x69, 0xb6, 0xd8, 0x0f, 0xe1, 0x7c, 0x82, 0x97,
0x45, 0x61, 0xc0, 0x08, 0xba, 0x05, 0x05, 0x4a, 0x3a, 0x21, 0xed, 0x4a, 0xe6, 0x4a, 0xe3, 0x23,
0x67, 0x3a, 0x0d, 0x1c, 0x2d, 0x20, 0x98, 0xb0, 0x66, 0xb6, 0xff, 0x94, 0x85, 0x4a, 0x62, 0x1e,
0x2d, 0x43, 0x66, 0xa7, 0x65, 0x1a, 0x6b, 0xc6, 0x7a, 0x19, 0x67, 0x76, 0x5a, 0xc8, 0x84, 0xe2,
0xe3, 0x01, 0x77, 0x0f, 0x7c, 0xa2, 0x7d, 0x8f, 0x49, 0x74, 0x11, 0xf2, 0x3b, 0xc1, 0x53, 0x46,
0xa4, 0xe3, 0x25, 0xac, 0x08, 0x84, 0x20, 0xb7, 0xe7, 0x7d, 0x43, 0x94, 0x9b, 0x58, 0x8e, 0x91,
0x05, 0x85, 0x5d, 0x97, 0x92, 0x80, 0x9b, 0x79, 0xa1, 0xb7, 0x99, 0x31, 0x0d, 0xac, 0x67, 0x50,
0x13, 0xca, 0xdb, 0x94, 0xb8, 0x9c, 0x74, 0xb7, 0xb8, 0x59, 0x58, 0x33, 0xd6, 0x2b, 0x0d, 0xcb,
0x51, 0x9b, 0xec, 0xc4, 0xf9, 0xe7, 0xec, 0xc7, 0xf9, 0xd7, 0x2c, 0xbd, 0x7a, 0xbd, 0xfa, 0xc1,
0x1f, 0xfe, 0x25, 0x62, 0x37, 0x12, 0x43, 0xf7, 0x01, 0x1e, 0xb9, 0x8c, 0x3f, 0x65, 0x52, 0x49,
0xf1, 0x54, 0x25, 0x39, 0xa9, 0x20, 0x21, 0x83, 0x56, 0x00, 0x64, 0x10, 0xb6, 0xc3, 0x41, 0xc0,
0xcd, 0x92, 0xb4, 0x3d, 0x31, 0x83, 0xd6, 0xa0, 0xd2, 0x22, 0xac, 0x43, 0xbd, 0x48, 0x6e, 0x75,
0x59, 0x86, 0x27, 0x39, 0x25, 0x34, 0xa8, 0x08, 0xee, 0x0f, 0x23, 0x62, 0x82, 0x64, 0x48, 0xcc,
0x88, 0xbd, 0xdc, 0x7b, 0xe1, 0x52, 0xd2, 0x35, 0x2b, 0x32, 0x5c, 0x9a, 0x12, 0xf1, 0x55, 0x91,
0x60, 0x66, 0x55, 0x6e, 0x72, 0x4c, 0xda, 0xbf, 0x2b, 0x42, 0x75, 0x4f, 0x1c, 0xa7, 0x38, 0x1d,
0x6a, 0x90, 0xc5, 0xe4, 0x50, 0xef, 0x8d, 0x18, 0x22, 0x07, 0xa0, 0x45, 0x0e, 0xbd, 0xc0, 0x93,
0x56, 0x65, 0xa4, 0xe3, 0xcb, 0x4e, 0x74, 0xe0, 0x8c, 0x67, 0x71, 0x82, 0x03, 0x59, 0x50, 0x6a,
0xbf, 0x8c, 0x42, 0x2a, 0x52, 0x2a, 0x2b, 0xd5, 0x8c, 0x68, 0xf4, 0x0c, 0x96, 0xe2, 0xf1, 0x16,
0xe7, 0x54, 0x24, 0xaa, 0x48, 0xa3, 0x4f, 0x66, 0xd3, 0x28, 0x69, 0x94, 0x33, 0x21, 0xd3, 0x0e,
0x38, 0x1d, 0xe2, 0x49, 0x3d, 0xc2, 0xc3, 0x3d, 0xc2, 0x98, 0xb0, 0x50, 0x6e, 0x3f, 0x8e, 0x49,
0x61, 0xce, 0x2f, 0x68, 0x18, 0x70, 0x12, 0x74, 0xe5, 0xd6, 0x97, 0xf1, 0x88, 0x16, 0xe6, 0xc4,
0x63, 0x65, 0x4e, 0x71, 0x21, 0x73, 0x26, 0x64, 0xb4, 0x39, 0x13, 0x73, 0x68, 0x13, 0xf2, 0xdb,
0x6e, 0xe7, 0x05, 0x91, 0xbb, 0x5c, 0x69, 0xac, 0xcc, 0x2a, 0x94, 0xcb, 0x4f, 0xe4, 0xb6, 0x32,
0x79, 0x50, 0x3f, 0xc0, 0x4a, 0x04, 0xfd, 0x0a, 0xaa, 0xed, 0x80, 0x7b, 0xdc, 0x27, 0x7d, 0xb9,
0x63, 0x65, 0xb1, 0x63, 0xcd, 0xcd, 0xef, 0x5e, 0xaf, 0xfe, 0x64, 0x6e, 0xf9, 0x19, 0x70, 0xcf,
0xaf, 0x93, 0x84, 0x94, 0x93, 0x50, 0x81, 0x27, 0xf4, 0xa1, 0xaf, 0x60, 0x39, 0x36, 0x76, 0x27,
0x88, 0x06, 0x9c, 0x99, 0x20, 0xbd, 0x6e, 0x2c, 0xe8, 0xb5, 0x12, 0x52, 0x6e, 0x4f, 0x69, 0x12,
0xc1, 0xde, 0x09, 0x38, 0xa1, 0x81, 0xeb, 0xeb, 0x14, 0x1c, 0xd1, 0x68, 0x47, 0x64, 0x9a, 0xa8,
0x92, 0xbb, 0xb2, 0x36, 0x9a, 0x55, 0x19, 0x9a, 0x6b, 0xb3, 0x5f, 0x4d, 0xd6, 0x52, 0x47, 0x31,
0xe3, 0x09, 0x51, 0xeb, 0x3e, 0xa0, 0xd9, 0x94, 0x10, 0xa9, 0x7b, 0x44, 0x86, 0x71, 0xea, 0x1e,
0x91, 0xa1, 0xa8, 0x1e, 0xc7, 0xae, 0x3f, 0x50, 0x55, 0xa5, 0x8c, 0x15, 0xb1, 0x99, 0xb9, 0x63,
0x08, 0x0d, 0xb3, 0xbb, 0x78, 0x26, 0x0d, 0x5f, 0xc0, 0x85, 0x94, 0x88, 0xa4, 0xa8, 0xb8, 0x9a,
0x54, 0x31, 0x7b, 0x74, 0xc6, 0x2a, 0xed, 0xbf, 0x66, 0xa1, 0x9a, 0xcc, 0x0b, 0xb4, 0x01, 0x17,
0x94, 0x9f, 0x98, 0x1c, 0xb6, 0x48, 0x44, 0x49, 0x47, 0x14, 0x23, 0xad, 0x3c, 0x6d, 0x09, 0x35,
0xe0, 0xe2, 0x4e, 0x5f, 0x4f, 0xb3, 0x84, 0x48, 0x46, 0x1e, 0xfb, 0xd4, 0x35, 0x14, 0xc2, 0x87,
0x4a, 0x95, 0x8c, 0x44, 0x42, 0x28, 0x2b, 0xf3, 0xe2, 0xb3, 0x93, 0x93, 0xd7, 0x49, 0x95, 0x55,
0xe9, 0x91, 0xae, 0x17, 0xfd, 0x0c, 0x8a, 0x6a, 0x21, 0x3e, 0xff, 0x1f, 0x9f, 0xfc, 0x09, 0xa5,
0x2c, 0x96, 0x11, 0xe2, 0xca, 0x0f, 0x66, 0xe6, 0xcf, 0x20, 0xae, 0x65, 0xac, 0x07, 0x60, 0xcd,
0x37, 0xf9, 0x2c, 0x29, 0x60, 0xff, 0xc5, 0x80, 0xf3, 0x33, 0x1f, 0x12, 0x97, 0x93, 0x2c, 0xcf,
0x4a, 0x85, 0x1c, 0xa3, 0x16, 0xe4, 0x55, 0x81, 0xc9, 0x48, 0x83, 0x9d, 0x05, 0x0c, 0x76, 0x12,
0xd5, 0x45, 0x09, 0x5b, 0x77, 0x00, 0xde, 0x2e, 0x59, 0xed, 0xbf, 0x19, 0xb0, 0xa4, 0x0f, 0xb3,
0xbe, 0xc9, 0x5d, 0xa8, 0xc5, 0x47, 0x28, 0x9e, 0xd3, 0x77, 0xfa, 0xad, 0xb9, 0x75, 0x40, 0xb1,
0x39, 0xd3, 0x72, 0xca, 0xc6, 0x19, 0x75, 0xd6, 0x76, 0x9c, 0x57, 0x53, 0xac, 0x67, 0xb2, 0xfc,
0x0a, 0x2c, 0xed, 0x49, 0x08, 0x36, 0xf7, 0x82, 0xb2, 0xff, 0x6b, 0xc0, 0x72, 0xcc, 0xa3, 0xbd,
0xfb, 0x14, 0x4a, 0xc7, 0x84, 0x72, 0xf2, 0x92, 0x30, 0xed, 0x95, 0x39, 0xeb, 0xd5, 0x97, 0x92,
0x03, 0x8f, 0x38, 0xd1, 0x26, 0x94, 0x14, 0xdc, 0x23, 0xf1, 0x46, 0xad, 0xcc, 0x93, 0xd2, 0xdf,
0x1b, 0xf1, 0xa3, 0x3a, 0xe4, 0xfc, 0xb0, 0xc7, 0xf4, 0x99, 0xf9, 0xfe, 0x3c, 0xb9, 0x47, 0x61,
0x0f, 0x4b, 0x46, 0x74, 0x17, 0x4a, 0x5f, 0xbb, 0x34, 0xf0, 0x82, 0x5e, 0x7c, 0x0a, 0x56, 0xe7,
0x09, 0x3d, 0x53, 0x7c, 0x78, 0x24, 0x20, 0x00, 0x55, 0x41, 0xad, 0xa1, 0x87, 0x50, 0xe8, 0x7a,
0x3d, 0xc2, 0xb8, 0x0a, 0x49, 0xb3, 0x21, 0xee, 0x92, 0xef, 0x5e, 0xaf, 0x5e, 0x4f, 0x5c, 0x16,
0x61, 0x44, 0x02, 0x01, 0xdf, 0x5d, 0x2f, 0x20, 0x54, 0xc0, 0xdb, 0x9b, 0x4a, 0xc4, 0x69, 0xc9,
0x1f, 0xac, 0x35, 0x08, 0x5d, 0x9e, 0xba, 0x12, 0x64, 0xbd, 0x78, 0x3b, 0x5d, 0x4a, 0x83, 0x38,
0x06, 0x81, 0xdb, 0x27, 0x1a, 0x02, 0xc8, 0xb1, 0xc0, 0x27, 0x1d, 0x91, 0xe7, 0x5d, 0x89, 0xdc,
0x4a, 0x58, 0x53, 0x68, 0x13, 0x8a, 0x8c, 0xbb, 0x54, 0xd4, 0x9c, 0xfc, 0x82, 0xc0, 0x2a, 0x16,
0x40, 0xf7, 0xa0, 0xdc, 0x09, 0xfb, 0x91, 0x4f, 0x84, 0x74, 0x61, 0x41, 0xe9, 0xb1, 0x88, 0x48,
0x3d, 0x42, 0x69, 0x48, 0x25, 0xa4, 0x2b, 0x63, 0x45, 0xa0, 0xdb, 0xb0, 0x14, 0xd1, 0xb0, 0x47,
0x09, 0x63, 0x9f, 0xd3, 0x70, 0x10, 0xe9, 0x8b, 0xfc, 0xbc, 0x28, 0xde, 0xbb, 0xc9, 0x05, 0x3c,
0xc9, 0x67, 0xff, 0x27, 0x03, 0xd5, 0x64, 0x8a, 0xcc, 0x60, 0xdd, 0x87, 0x50, 0x50, 0x09, 0xa7,
0x72, 0xfd, 0xed, 0x62, 0xac, 0x34, 0xa4, 0xc6, 0xd8, 0x84, 0x62, 0x67, 0x40, 0x25, 0x10, 0x56,
0xf0, 0x38, 0x26, 0x85, 0xa7, 0x3c, 0xe4, 0xae, 0x2f, 0x63, 0x9c, 0xc5, 0x8a, 0x10, 0xd8, 0x78,
0xd4, 0x79, 0x9d, 0x0d, 0x1b, 0x8f, 0xc4, 0x92, 0xfb, 0x57, 0x7c, 0xa7, 0xfd, 0x2b, 0x9d, 0x79,
0xff, 0xec, 0xbf, 0x1b, 0x50, 0x1e, 0x9d, 0xad, 0x44, 0x74, 0x8d, 0x77, 0x8e, 0xee, 0x44, 0x64,
0x32, 0x6f, 0x17, 0x99, 0x4b, 0x50, 0x60, 0x9c, 0x12, 0xb7, 0xaf, 0x3a, 0x37, 0xac, 0x29, 0x51,
0xc5, 0xfa, 0xac, 0x27, 0x77, 0xa8, 0x8a, 0xc5, 0xd0, 0xfe, 0x9f, 0x01, 0x4b, 0x13, 0xc7, 0xfd,
0xbd, 0xfa, 0x72, 0x11, 0xf2, 0x3e, 0x39, 0x26, 0xaa, 0xb7, 0xcc, 0x62, 0x45, 0x88, 0x59, 0xf6,
0x22, 0xa4, 0x5c, 0x1a, 0x57, 0xc5, 0x8a, 0x10, 0x36, 0x77, 0x09, 0x77, 0x3d, 0x5f, 0xd6, 0xa5,
0x2a, 0xd6, 0x94, 0xb0, 0x79, 0x40, 0x7d, 0x8d, 0xaf, 0xc5, 0x10, 0xd9, 0x90, 0xf3, 0x82, 0xc3,
0x50, 0xa7, 0x8d, 0x44, 0x36, 0x0a, 0xa7, 0xed, 0x04, 0x87, 0x21, 0x96, 0x6b, 0xe8, 0x0a, 0x14,
0xa8, 0x1b, 0xf4, 0x48, 0x0c, 0xae, 0xcb, 0x82, 0x0b, 0x8b, 0x19, 0xac, 0x17, 0x6c, 0x1b, 0xaa,
0xb2, 0x3f, 0x7d, 0x4c, 0x98, 0xe8, 0x86, 0x44, 0x5a, 0x77, 0x5d, 0xee, 0x4a, 0xb7, 0xab, 0x58,
0x8e, 0xed, 0x1b, 0x80, 0x1e, 0x79, 0x8c, 0x3f, 0x93, 0x2d, 0x3c, 0x3b, 0xad, 0x79, 0xdd, 0x83,
0x0b, 0x13, 0xdc, 0xfa, 0x5a, 0xf8, 0xe9, 0x54, 0xfb, 0x7a, 0x75, 0xb6, 0xe2, 0xca, 0x97, 0x02,
0x47, 0x09, 0x4e, 0x75, 0xb1, 0x4b, 0x50, 0x91, 0x7e, 0xa9, 0x6f, 0xdb, 0x2e, 0x54, 0x15, 0xa9,
0x95, 0x7f, 0x01, 0xe7, 0x62, 0x45, 0x5f, 0x12, 0x2a, 0x5b, 0x11, 0x43, 0xc6, 0xe5, 0x87, 0xf3,
0xbe, 0xd2, 0x9c, 0x64, 0xc7, 0xd3, 0xf2, 0x36, 0x81, 0x0b, 0x92, 0xe7, 0x81, 0xc7, 0x78, 0x48,
0x87, 0xb1, 0xd7, 0x2b, 0x00, 0x5b, 0x1d, 0xee, 0x1d, 0x93, 0x27, 0x81, 0xaf, 0xae, 0xd1, 0x12,
0x4e, 0xcc, 0xc4, 0x57, 0x64, 0x66, 0xdc, 0xc3, 0x5d, 0x86, 0x72, 0xdb, 0xa5, 0xfe, 0xb0, 0xfd,
0xd2, 0xe3, 0xba, 0x95, 0x1e, 0x4f, 0xd8, 0xbf, 0x37, 0xe0, 0x7c, 0xf2, 0x3b, 0xed, 0x63, 0x51,
0x2e, 0xee, 0x42, 0x8e, 0xc7, 0x38, 0x66, 0x39, 0xcd, 0x89, 0x19, 0x11, 0x01, 0x75, 0xb0, 0x14,
0x4a, 0x44, 0x5a, 0x1d, 0x9c, 0xab, 0x27, 0x8b, 0x4f, 0x45, 0xfa, 0x1f, 0x25, 0x40, 0xb3, 0xcb,
0x29, 0xbd, 0x69, 0xb2, 0xb9, 0xcb, 0x4c, 0x35, 0x77, 0xcf, 0xa7, 0x9b, 0x3b, 0x75, 0x35, 0xdf,
0x5e, 0xc4, 0x92, 0x05, 0x5a, 0xbc, 0x3b, 0x50, 0x8e, 0xd1, 0x4d, 0x7c, 0x81, 0x5b, 0xb3, 0xaa,
0x47, 0x00, 0x68, 0xcc, 0x8c, 0xd6, 0xe3, 0x1b, 0x47, 0xdd, 0x75, 0x28, 0xae, 0x29, 0x34, 0xea,
0x38, 0x1a, 0x57, 0xe8, 0x5b, 0xe8, 0xde, 0xd9, 0xde, 0x2d, 0x72, 0xd3, 0x6f, 0x16, 0x4d, 0xa8,
0x6c, 0xc7, 0x85, 0xf2, 0x0c, 0x8f, 0x16, 0x49, 0x21, 0xb4, 0xa1, 0x81, 0x8d, 0x2a, 0xcd, 0x97,
0x67, 0x5d, 0x8c, 0x1f, 0x28, 0x42, 0xaa, 0x91, 0xcd, 0x61, 0x0a, 0xb4, 0x2c, 0xcb, 0x00, 0x6d,
0x2e, 0x14, 0xfb, 0x05, 0xf1, 0x25, 0xfa, 0x0c, 0x0a, 0x98, 0xb0, 0x81, 0xcf, 0xe5, 0x4b, 0x48,
0xa5, 0x71, 0x65, 0x8e, 0x76, 0xc5, 0x24, 0xcf, 0xaa, 0x16, 0x40, 0xbf, 0x84, 0xa2, 0x1a, 0x31,
0xb3, 0x32, 0xaf, 0xe5, 0x4f, 0xb1, 0x4c, 0xcb, 0xe8, 0x86, 0x42, 0x53, 0xe2, 0x38, 0x7e, 0x4e,
0x02, 0xa2, 0x5f, 0xe8, 0x44, 0x5b, 0x9b, 0xc7, 0x89, 0x19, 0xd4, 0x80, 0x3c, 0xa7, 0x6e, 0x87,
0x98, 0x4b, 0x0b, 0x84, 0x50, 0xb1, 0x8a, 0xc2, 0x16, 0x79, 0x41, 0x40, 0xba, 0xe6, 0xb2, 0x42,
0x4a, 0x8a, 0x42, 0x3f, 0x80, 0xe5, 0x60, 0xd0, 0x97, 0xcd, 0x42, 0x77, 0x8f, 0x93, 0x88, 0x99,
0xe7, 0xe4, 0xf7, 0xa6, 0x66, 0xd1, 0x55, 0x58, 0x0a, 0x06, 0xfd, 0x7d, 0x71, 0xc3, 0x2b, 0xb6,
0x9a, 0x64, 0x9b, 0x9c, 0x7c, 0x0f, 0x5d, 0xf0, 0xfb, 0xc0, 0xf8, 0xd6, 0x73, 0xa8, 0x26, 0x23,
0x9b, 0x22, 0x7b, 0x7b, 0xb2, 0x87, 0x5e, 0x60, 0xa7, 0x13, 0x2d, 0xc4, 0x73, 0xf8, 0xde, 0xd3,
0xa8, 0xeb, 0x72, 0x92, 0x56, 0x4b, 0x67, 0x6b, 0xca, 0x25, 0x28, 0xec, 0xaa, 0xd0, 0xab, 0xb7,
0x48, 0x4d, 0x89, 0xf9, 0x16, 0x11, 0xa7, 0x42, 0x17, 0x50, 0x4d, 0xd9, 0x97, 0xc1, 0x4a, 0x53,
0xaf, 0x82, 0x61, 0xff, 0x39, 0x03, 0x30, 0xde, 0x5e, 0xf4, 0x11, 0x40, 0x9f, 0x74, 0x3d, 0xf7,
0xd7, 0x7c, 0xdc, 0x22, 0x96, 0xe5, 0x8c, 0xec, 0x13, 0xc7, 0x60, 0x3e, 0xf3, 0xce, 0x60, 0x1e,
0x41, 0x8e, 0x79, 0xdf, 0x10, 0x0d, 0x3c, 0xe4, 0x18, 0x3d, 0x81, 0x8a, 0x1b, 0x04, 0x21, 0x97,
0x89, 0x19, 0xb7, 0xcf, 0x37, 0x4f, 0x4a, 0x48, 0x67, 0x6b, 0xcc, 0xaf, 0xf2, 0x3e, 0xa9, 0xc1,
0xba, 0x07, 0xb5, 0x69, 0x86, 0x33, 0xb5, 0x77, 0xdf, 0x1a, 0x70, 0x6e, 0x6a, 0xeb, 0xd0, 0xa7,
0xa3, 0x73, 0x6d, 0x2c, 0x70, 0x60, 0xe2, 0x23, 0x7d, 0x1f, 0xaa, 0x5b, 0x9c, 0x8b, 0x3a, 0xa6,
0x7c, 0x53, 0x0d, 0xdc, 0xc9, 0xb2, 0x13, 0x12, 0xf6, 0x1f, 0x8d, 0xf1, 0xcb, 0x65, 0x6a, 0x17,
0x7f, 0x77, 0xb2, 0x8b, 0xbf, 0x36, 0xbf, 0xdc, 0xbf, 0xcf, 0xe6, 0xfd, 0xfa, 0xcf, 0xe1, 0xc3,
0xd4, 0xab, 0x16, 0x55, 0xa0, 0xb8, 0xb7, 0xbf, 0x85, 0xf7, 0xdb, 0xad, 0xda, 0x07, 0xa8, 0x0a,
0xa5, 0xed, 0x27, 0x8f, 0x77, 0x1f, 0xb5, 0xf7, 0xdb, 0x35, 0x43, 0x2c, 0xb5, 0xda, 0x62, 0xdc,
0xaa, 0x65, 0x1a, 0xdf, 0x16, 0xa0, 0xb8, 0xad, 0xfe, 0xbd, 0x41, 0xfb, 0x50, 0x1e, 0x3d, 0xeb,
0x23, 0x3b, 0x25, 0x3a, 0x53, 0xff, 0x0f, 0x58, 0x1f, 0x9f, 0xc8, 0xa3, 0x4b, 0xf1, 0x03, 0xc8,
0xcb, 0x3f, 0x38, 0x50, 0x4a, 0xc3, 0x9c, 0xfc, 0xe7, 0xc3, 0x3a, 0xf9, 0x0f, 0x83, 0x0d, 0x43,
0x68, 0x92, 0xaf, 0x0d, 0x69, 0x9a, 0x92, 0xcf, 0x91, 0xd6, 0xea, 0x29, 0xcf, 0x14, 0xe8, 0x31,
0x14, 0x74, 0x0b, 0x96, 0xc6, 0x9a, 0x7c, 0x53, 0xb0, 0xd6, 0xe6, 0x33, 0x28, 0x65, 0x1b, 0x06,
0x7a, 0x3c, 0x7a, 0x61, 0x4e, 0x33, 0x2d, 0x89, 0x5f, 0xad, 0x53, 0xd6, 0xd7, 0x8d, 0x0d, 0x03,
0x7d, 0x05, 0x95, 0x04, 0x42, 0x45, 0x29, 0xf8, 0x68, 0x16, 0xee, 0x5a, 0xd7, 0x4e, 0xe1, 0xd2,
0x9e, 0xb7, 0x21, 0x27, 0x0f, 0x52, 0x4a, 0xb0, 0x13, 0x00, 0x36, 0xcd, 0xcc, 0x09, 0x40, 0x7b,
0xa0, 0x20, 0x37, 0x09, 0x92, 0xd9, 0x87, 0xae, 0x9d, 0x76, 0x53, 0xce, 0x4d, 0x9b, 0x99, 0x24,
0xde, 0x30, 0x50, 0x08, 0x68, 0xb6, 0x78, 0xa2, 0x1f, 0xa5, 0x64, 0xc9, 0xbc, 0x0a, 0x6e, 0xdd,
0x58, 0x8c, 0x59, 0x39, 0xd5, 0xac, 0xbe, 0x7a, 0xb3, 0x62, 0xfc, 0xf3, 0xcd, 0x8a, 0xf1, 0xef,
0x37, 0x2b, 0xc6, 0x41, 0x41, 0x62, 0xa0, 0x1f, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xca, 0xd0,
0xd7, 0x6e, 0xdd, 0x1c, 0x00, 0x00,
0x11, 0xde, 0x21, 0x25, 0xfe, 0x14, 0x29, 0x59, 0x6a, 0x7b, 0x8d, 0xc9, 0xc4, 0x2b, 0xc9, 0xb3,
0x76, 0x22, 0x38, 0xf6, 0x50, 0xcb, 0xac, 0x63, 0xaf, 0x9c, 0x38, 0x16, 0x45, 0x66, 0x2d, 0xc7,
0x82, 0xb5, 0x2d, 0x79, 0x0d, 0x2c, 0xe0, 0x04, 0x23, 0xb2, 0x45, 0x0f, 0x34, 0x9c, 0x99, 0x74,
0x37, 0xb5, 0xe6, 0x3e, 0x40, 0x80, 0xcd, 0x21, 0xc8, 0x25, 0xc8, 0x25, 0xf7, 0x9c, 0x72, 0xce,
0x13, 0x04, 0xf0, 0x31, 0xe7, 0x3d, 0x38, 0x81, 0x1f, 0x20, 0xc8, 0x31, 0xb9, 0x05, 0xfd, 0x33,
0xe4, 0x90, 0x33, 0x94, 0x28, 0xdb, 0x27, 0x76, 0x75, 0xd7, 0x57, 0x53, 0x55, 0x5d, 0x5d, 0x5d,
0xd5, 0x84, 0x85, 0x76, 0x18, 0x70, 0x1a, 0xfa, 0x4e, 0x44, 0x43, 0x1e, 0xa2, 0xa5, 0x5e, 0x78,
0x38, 0x70, 0x0e, 0xfb, 0x9e, 0xdf, 0x39, 0xf6, 0xb8, 0x73, 0xf2, 0x89, 0x75, 0xab, 0xeb, 0xf1,
0x17, 0xfd, 0x43, 0xa7, 0x1d, 0xf6, 0x6a, 0xdd, 0xb0, 0x1b, 0xd6, 0x24, 0xe3, 0x61, 0xff, 0x48,
0x52, 0x92, 0x90, 0x23, 0x25, 0xc0, 0x5a, 0xed, 0x86, 0x61, 0xd7, 0x27, 0x23, 0x2e, 0xee, 0xf5,
0x08, 0xe3, 0x6e, 0x2f, 0xd2, 0x0c, 0x37, 0x13, 0xf2, 0xc4, 0xc7, 0x6a, 0xf1, 0xc7, 0x6a, 0x2c,
0xf4, 0x4f, 0x08, 0xad, 0x45, 0x87, 0xb5, 0x30, 0x62, 0x9a, 0xbb, 0x36, 0x95, 0xdb, 0x8d, 0xbc,
0x1a, 0x1f, 0x44, 0x84, 0xd5, 0xbe, 0x0e, 0xe9, 0x31, 0xa1, 0x1a, 0x50, 0x9f, 0x54, 0x57, 0xe9,
0xe3, 0x46, 0x1e, 0xd3, 0xc3, 0x1a, 0x8d, 0xda, 0x35, 0xc6, 0x5d, 0xde, 0x8f, 0x3f, 0x72, 0xfb,
0x14, 0x95, 0xfa, 0xb4, 0x4d, 0xa2, 0xd0, 0xf7, 0xda, 0x03, 0xa1, 0x98, 0x1a, 0x29, 0x98, 0xfd,
0x5b, 0x03, 0xaa, 0x7b, 0xb4, 0x1f, 0x10, 0x4c, 0x7e, 0xd3, 0x27, 0x8c, 0xa3, 0xcb, 0x50, 0x38,
0xf2, 0x7c, 0x4e, 0xa8, 0x69, 0xac, 0xe5, 0xd7, 0xcb, 0x58, 0x53, 0x68, 0x09, 0xf2, 0xae, 0xef,
0x9b, 0xb9, 0x35, 0x63, 0xbd, 0x84, 0xc5, 0x10, 0xad, 0x43, 0xf5, 0x98, 0x90, 0xa8, 0xd9, 0xa7,
0x2e, 0xf7, 0xc2, 0xc0, 0xcc, 0xaf, 0x19, 0xeb, 0xf9, 0xc6, 0xdc, 0xab, 0xd7, 0xab, 0x06, 0x1e,
0x5b, 0x41, 0x36, 0x94, 0x05, 0xdd, 0x18, 0x70, 0xc2, 0xcc, 0xb9, 0x04, 0xdb, 0x68, 0xda, 0xbe,
0x01, 0x4b, 0x4d, 0x8f, 0x1d, 0x3f, 0x65, 0x6e, 0xf7, 0x2c, 0x5d, 0xec, 0x47, 0xb0, 0x9c, 0xe0,
0x65, 0x51, 0x18, 0x30, 0x82, 0x6e, 0x43, 0x81, 0x92, 0x76, 0x48, 0x3b, 0x92, 0xb9, 0x52, 0xff,
0xc8, 0x99, 0x0c, 0x03, 0x47, 0x03, 0x04, 0x13, 0xd6, 0xcc, 0xf6, 0x9f, 0xf2, 0x50, 0x49, 0xcc,
0xa3, 0x45, 0xc8, 0xed, 0x34, 0x4d, 0x63, 0xcd, 0x58, 0x2f, 0xe3, 0xdc, 0x4e, 0x13, 0x99, 0x50,
0xdc, 0xed, 0x73, 0xf7, 0xd0, 0x27, 0xda, 0xf6, 0x98, 0x44, 0x97, 0x60, 0x7e, 0x27, 0x78, 0xca,
0x88, 0x34, 0xbc, 0x84, 0x15, 0x81, 0x10, 0xcc, 0xed, 0x7b, 0xdf, 0x10, 0x65, 0x26, 0x96, 0x63,
0x64, 0x41, 0x61, 0xcf, 0xa5, 0x24, 0xe0, 0xe6, 0xbc, 0x90, 0xdb, 0xc8, 0x99, 0x06, 0xd6, 0x33,
0xa8, 0x01, 0xe5, 0x6d, 0x4a, 0x5c, 0x4e, 0x3a, 0x5b, 0xdc, 0x2c, 0xac, 0x19, 0xeb, 0x95, 0xba,
0xe5, 0xa8, 0x4d, 0x76, 0xe2, 0xf8, 0x73, 0x0e, 0xe2, 0xf8, 0x6b, 0x94, 0x5e, 0xbd, 0x5e, 0xfd,
0xe0, 0x0f, 0xff, 0x14, 0xbe, 0x1b, 0xc2, 0xd0, 0x03, 0x80, 0xc7, 0x2e, 0xe3, 0x4f, 0x99, 0x14,
0x52, 0x3c, 0x53, 0xc8, 0x9c, 0x14, 0x90, 0xc0, 0xa0, 0x15, 0x00, 0xe9, 0x84, 0xed, 0xb0, 0x1f,
0x70, 0xb3, 0x24, 0x75, 0x4f, 0xcc, 0xa0, 0x35, 0xa8, 0x34, 0x09, 0x6b, 0x53, 0x2f, 0x92, 0x5b,
0x5d, 0x96, 0xee, 0x49, 0x4e, 0x09, 0x09, 0xca, 0x83, 0x07, 0x83, 0x88, 0x98, 0x20, 0x19, 0x12,
0x33, 0x62, 0x2f, 0xf7, 0x5f, 0xb8, 0x94, 0x74, 0xcc, 0x8a, 0x74, 0x97, 0xa6, 0x84, 0x7f, 0x95,
0x27, 0x98, 0x59, 0x95, 0x9b, 0x1c, 0x93, 0xf6, 0xef, 0x8a, 0x50, 0xdd, 0x17, 0xc7, 0x29, 0x0e,
0x87, 0x25, 0xc8, 0x63, 0x72, 0xa4, 0xf7, 0x46, 0x0c, 0x91, 0x03, 0xd0, 0x24, 0x47, 0x5e, 0xe0,
0x49, 0xad, 0x72, 0xd2, 0xf0, 0x45, 0x27, 0x3a, 0x74, 0x46, 0xb3, 0x38, 0xc1, 0x81, 0x2c, 0x28,
0xb5, 0x5e, 0x46, 0x21, 0x15, 0x21, 0x95, 0x97, 0x62, 0x86, 0x34, 0x7a, 0x06, 0x0b, 0xf1, 0x78,
0x8b, 0x73, 0x2a, 0x02, 0x55, 0x84, 0xd1, 0x27, 0xe9, 0x30, 0x4a, 0x2a, 0xe5, 0x8c, 0x61, 0x5a,
0x01, 0xa7, 0x03, 0x3c, 0x2e, 0x47, 0x58, 0xb8, 0x4f, 0x18, 0x13, 0x1a, 0xca, 0xed, 0xc7, 0x31,
0x29, 0xd4, 0xf9, 0x05, 0x0d, 0x03, 0x4e, 0x82, 0x8e, 0xdc, 0xfa, 0x32, 0x1e, 0xd2, 0x42, 0x9d,
0x78, 0xac, 0xd4, 0x29, 0xce, 0xa4, 0xce, 0x18, 0x46, 0xab, 0x33, 0x36, 0x87, 0x36, 0x61, 0x7e,
0xdb, 0x6d, 0xbf, 0x20, 0x72, 0x97, 0x2b, 0xf5, 0x95, 0xb4, 0x40, 0xb9, 0xfc, 0x44, 0x6e, 0x2b,
0x93, 0x07, 0xf5, 0x03, 0xac, 0x20, 0xe8, 0x57, 0x50, 0x6d, 0x05, 0xdc, 0xe3, 0x3e, 0xe9, 0xc9,
0x1d, 0x2b, 0x8b, 0x1d, 0x6b, 0x6c, 0x7e, 0xf7, 0x7a, 0xf5, 0x27, 0x53, 0xd3, 0x4f, 0x9f, 0x7b,
0x7e, 0x8d, 0x24, 0x50, 0x4e, 0x42, 0x04, 0x1e, 0x93, 0x87, 0xbe, 0x82, 0xc5, 0x58, 0xd9, 0x9d,
0x20, 0xea, 0x73, 0x66, 0x82, 0xb4, 0xba, 0x3e, 0xa3, 0xd5, 0x0a, 0xa4, 0xcc, 0x9e, 0x90, 0x24,
0x9c, 0xbd, 0x13, 0x70, 0x42, 0x03, 0xd7, 0xd7, 0x21, 0x38, 0xa4, 0xd1, 0x8e, 0x88, 0x34, 0x91,
0x25, 0xf7, 0x64, 0x6e, 0x34, 0xab, 0xd2, 0x35, 0xd7, 0xd3, 0x5f, 0x4d, 0xe6, 0x52, 0x47, 0x31,
0xe3, 0x31, 0xa8, 0xf5, 0x00, 0x50, 0x3a, 0x24, 0x44, 0xe8, 0x1e, 0x93, 0x41, 0x1c, 0xba, 0xc7,
0x64, 0x20, 0xb2, 0xc7, 0x89, 0xeb, 0xf7, 0x55, 0x56, 0x29, 0x63, 0x45, 0x6c, 0xe6, 0xee, 0x1a,
0x42, 0x42, 0x7a, 0x17, 0xcf, 0x25, 0xe1, 0x0b, 0xb8, 0x98, 0xe1, 0x91, 0x0c, 0x11, 0xd7, 0x92,
0x22, 0xd2, 0x47, 0x67, 0x24, 0xd2, 0xfe, 0x6b, 0x1e, 0xaa, 0xc9, 0xb8, 0x40, 0x1b, 0x70, 0x51,
0xd9, 0x89, 0xc9, 0x51, 0x93, 0x44, 0x94, 0xb4, 0x45, 0x32, 0xd2, 0xc2, 0xb3, 0x96, 0x50, 0x1d,
0x2e, 0xed, 0xf4, 0xf4, 0x34, 0x4b, 0x40, 0x72, 0xf2, 0xd8, 0x67, 0xae, 0xa1, 0x10, 0x3e, 0x54,
0xa2, 0xa4, 0x27, 0x12, 0xa0, 0xbc, 0x8c, 0x8b, 0xcf, 0x4e, 0x0f, 0x5e, 0x27, 0x13, 0xab, 0xc2,
0x23, 0x5b, 0x2e, 0xfa, 0x19, 0x14, 0xd5, 0x42, 0x7c, 0xfe, 0x3f, 0x3e, 0xfd, 0x13, 0x4a, 0x58,
0x8c, 0x11, 0x70, 0x65, 0x07, 0x33, 0xe7, 0xcf, 0x01, 0xd7, 0x18, 0xeb, 0x21, 0x58, 0xd3, 0x55,
0x3e, 0x4f, 0x08, 0xd8, 0x7f, 0x31, 0x60, 0x39, 0xf5, 0x21, 0x71, 0x39, 0xc9, 0xf4, 0xac, 0x44,
0xc8, 0x31, 0x6a, 0xc2, 0xbc, 0x4a, 0x30, 0x39, 0xa9, 0xb0, 0x33, 0x83, 0xc2, 0x4e, 0x22, 0xbb,
0x28, 0xb0, 0x75, 0x17, 0xe0, 0xed, 0x82, 0xd5, 0xfe, 0x9b, 0x01, 0x0b, 0xfa, 0x30, 0xeb, 0x9b,
0xdc, 0x85, 0xa5, 0xf8, 0x08, 0xc5, 0x73, 0xfa, 0x4e, 0xbf, 0x3d, 0x35, 0x0f, 0x28, 0x36, 0x67,
0x12, 0xa7, 0x74, 0x4c, 0x89, 0xb3, 0xb6, 0xe3, 0xb8, 0x9a, 0x60, 0x3d, 0x97, 0xe6, 0x57, 0x61,
0x61, 0x5f, 0x96, 0x60, 0x53, 0x2f, 0x28, 0xfb, 0x3f, 0x06, 0x2c, 0xc6, 0x3c, 0xda, 0xba, 0x4f,
0xa1, 0x74, 0x42, 0x28, 0x27, 0x2f, 0x09, 0xd3, 0x56, 0x99, 0x69, 0xab, 0xbe, 0x94, 0x1c, 0x78,
0xc8, 0x89, 0x36, 0xa1, 0xa4, 0xca, 0x3d, 0x12, 0x6f, 0xd4, 0xca, 0x34, 0x94, 0xfe, 0xde, 0x90,
0x1f, 0xd5, 0x60, 0xce, 0x0f, 0xbb, 0x4c, 0x9f, 0x99, 0xef, 0x4f, 0xc3, 0x3d, 0x0e, 0xbb, 0x58,
0x32, 0xa2, 0x7b, 0x50, 0xfa, 0xda, 0xa5, 0x81, 0x17, 0x74, 0xe3, 0x53, 0xb0, 0x3a, 0x0d, 0xf4,
0x4c, 0xf1, 0xe1, 0x21, 0x40, 0x14, 0x54, 0x05, 0xb5, 0x86, 0x1e, 0x41, 0xa1, 0xe3, 0x75, 0x09,
0xe3, 0xca, 0x25, 0x8d, 0xba, 0xb8, 0x4b, 0xbe, 0x7b, 0xbd, 0x7a, 0x23, 0x71, 0x59, 0x84, 0x11,
0x09, 0x44, 0xf9, 0xee, 0x7a, 0x01, 0xa1, 0xa2, 0xbc, 0xbd, 0xa5, 0x20, 0x4e, 0x53, 0xfe, 0x60,
0x2d, 0x41, 0xc8, 0xf2, 0xd4, 0x95, 0x20, 0xf3, 0xc5, 0xdb, 0xc9, 0x52, 0x12, 0xc4, 0x31, 0x08,
0xdc, 0x1e, 0xd1, 0x25, 0x80, 0x1c, 0x8b, 0xfa, 0xa4, 0x2d, 0xe2, 0xbc, 0x23, 0x2b, 0xb7, 0x12,
0xd6, 0x14, 0xda, 0x84, 0x22, 0xe3, 0x2e, 0x15, 0x39, 0x67, 0x7e, 0xc6, 0xc2, 0x2a, 0x06, 0xa0,
0xfb, 0x50, 0x6e, 0x87, 0xbd, 0xc8, 0x27, 0x02, 0x5d, 0x98, 0x11, 0x3d, 0x82, 0x88, 0xd0, 0x23,
0x94, 0x86, 0x54, 0x96, 0x74, 0x65, 0xac, 0x08, 0x74, 0x07, 0x16, 0x22, 0x1a, 0x76, 0x29, 0x61,
0xec, 0x73, 0x1a, 0xf6, 0x23, 0x7d, 0x91, 0x2f, 0x8b, 0xe4, 0xbd, 0x97, 0x5c, 0xc0, 0xe3, 0x7c,
0xf6, 0xbf, 0x73, 0x50, 0x4d, 0x86, 0x48, 0xaa, 0xd6, 0x7d, 0x04, 0x05, 0x15, 0x70, 0x2a, 0xd6,
0xdf, 0xce, 0xc7, 0x4a, 0x42, 0xa6, 0x8f, 0x4d, 0x28, 0xb6, 0xfb, 0x54, 0x16, 0xc2, 0xaa, 0x3c,
0x8e, 0x49, 0x61, 0x29, 0x0f, 0xb9, 0xeb, 0x4b, 0x1f, 0xe7, 0xb1, 0x22, 0x44, 0x6d, 0x3c, 0xec,
0xbc, 0xce, 0x57, 0x1b, 0x0f, 0x61, 0xc9, 0xfd, 0x2b, 0xbe, 0xd3, 0xfe, 0x95, 0xce, 0xbd, 0x7f,
0xf6, 0xdf, 0x0d, 0x28, 0x0f, 0xcf, 0x56, 0xc2, 0xbb, 0xc6, 0x3b, 0x7b, 0x77, 0xcc, 0x33, 0xb9,
0xb7, 0xf3, 0xcc, 0x65, 0x28, 0x30, 0x4e, 0x89, 0xdb, 0x53, 0x9d, 0x1b, 0xd6, 0x94, 0xc8, 0x62,
0x3d, 0xd6, 0x95, 0x3b, 0x54, 0xc5, 0x62, 0x68, 0xff, 0xd7, 0x80, 0x85, 0xb1, 0xe3, 0xfe, 0x5e,
0x6d, 0xb9, 0x04, 0xf3, 0x3e, 0x39, 0x21, 0xaa, 0xb7, 0xcc, 0x63, 0x45, 0x88, 0x59, 0xf6, 0x22,
0xa4, 0x5c, 0x2a, 0x57, 0xc5, 0x8a, 0x10, 0x3a, 0x77, 0x08, 0x77, 0x3d, 0x5f, 0xe6, 0xa5, 0x2a,
0xd6, 0x94, 0xd0, 0xb9, 0x4f, 0x7d, 0x5d, 0x5f, 0x8b, 0x21, 0xb2, 0x61, 0xce, 0x0b, 0x8e, 0x42,
0x1d, 0x36, 0xb2, 0xb2, 0x51, 0x75, 0xda, 0x4e, 0x70, 0x14, 0x62, 0xb9, 0x86, 0xae, 0x42, 0x81,
0xba, 0x41, 0x97, 0xc4, 0xc5, 0x75, 0x59, 0x70, 0x61, 0x31, 0x83, 0xf5, 0x82, 0x6d, 0x43, 0x55,
0xf6, 0xa7, 0xbb, 0x84, 0x89, 0x6e, 0x48, 0x84, 0x75, 0xc7, 0xe5, 0xae, 0x34, 0xbb, 0x8a, 0xe5,
0xd8, 0xbe, 0x09, 0xe8, 0xb1, 0xc7, 0xf8, 0x33, 0xd9, 0xc2, 0xb3, 0xb3, 0x9a, 0xd7, 0x7d, 0xb8,
0x38, 0xc6, 0xad, 0xaf, 0x85, 0x9f, 0x4e, 0xb4, 0xaf, 0xd7, 0xd2, 0x19, 0x57, 0xbe, 0x14, 0x38,
0x0a, 0x38, 0xd1, 0xc5, 0x2e, 0x40, 0x45, 0xda, 0xa5, 0xbe, 0x6d, 0xbb, 0x50, 0x55, 0xa4, 0x16,
0xfe, 0x05, 0x5c, 0x88, 0x05, 0x7d, 0x49, 0xa8, 0x6c, 0x45, 0x0c, 0xe9, 0x97, 0x1f, 0x4e, 0xfb,
0x4a, 0x63, 0x9c, 0x1d, 0x4f, 0xe2, 0x6d, 0x02, 0x17, 0x25, 0xcf, 0x43, 0x8f, 0xf1, 0x90, 0x0e,
0x62, 0xab, 0x57, 0x00, 0xb6, 0xda, 0xdc, 0x3b, 0x21, 0x4f, 0x02, 0x5f, 0x5d, 0xa3, 0x25, 0x9c,
0x98, 0x89, 0xaf, 0xc8, 0xdc, 0xa8, 0x87, 0xbb, 0x02, 0xe5, 0x96, 0x4b, 0xfd, 0x41, 0xeb, 0xa5,
0xc7, 0x75, 0x2b, 0x3d, 0x9a, 0xb0, 0x7f, 0x6f, 0xc0, 0x72, 0xf2, 0x3b, 0xad, 0x13, 0x91, 0x2e,
0xee, 0xc1, 0x1c, 0x8f, 0xeb, 0x98, 0xc5, 0x2c, 0x23, 0x52, 0x10, 0x51, 0xea, 0x60, 0x09, 0x4a,
0x78, 0x5a, 0x1d, 0x9c, 0x6b, 0xa7, 0xc3, 0x27, 0x3c, 0xfd, 0xbf, 0x12, 0xa0, 0xf4, 0x72, 0x46,
0x6f, 0x9a, 0x6c, 0xee, 0x72, 0x13, 0xcd, 0xdd, 0xf3, 0xc9, 0xe6, 0x4e, 0x5d, 0xcd, 0x77, 0x66,
0xd1, 0x64, 0x86, 0x16, 0xef, 0x2e, 0x94, 0xe3, 0xea, 0x26, 0xbe, 0xc0, 0xad, 0xb4, 0xe8, 0x61,
0x01, 0x34, 0x62, 0x46, 0xeb, 0xf1, 0x8d, 0xa3, 0xee, 0x3a, 0x14, 0xe7, 0x14, 0x1a, 0xb5, 0x1d,
0x5d, 0x57, 0xe8, 0x5b, 0xe8, 0xfe, 0xf9, 0xde, 0x2d, 0xe6, 0x26, 0xdf, 0x2c, 0x1a, 0x50, 0xd9,
0x8e, 0x13, 0xe5, 0x39, 0x1e, 0x2d, 0x92, 0x20, 0xb4, 0xa1, 0x0b, 0x1b, 0x95, 0x9a, 0xaf, 0xa4,
0x4d, 0x8c, 0x1f, 0x28, 0x42, 0xaa, 0x2b, 0x9b, 0xa3, 0x8c, 0xd2, 0xb2, 0x2c, 0x1d, 0xb4, 0x39,
0x93, 0xef, 0x67, 0xac, 0x2f, 0xd1, 0x67, 0x50, 0xc0, 0x84, 0xf5, 0x7d, 0x2e, 0x5f, 0x42, 0x2a,
0xf5, 0xab, 0x53, 0xa4, 0x2b, 0x26, 0x79, 0x56, 0x35, 0x00, 0xfd, 0x12, 0x8a, 0x6a, 0xc4, 0xcc,
0xca, 0xb4, 0x96, 0x3f, 0x43, 0x33, 0x8d, 0xd1, 0x0d, 0x85, 0xa6, 0xc4, 0x71, 0xfc, 0x9c, 0x04,
0x44, 0xbf, 0xd0, 0x89, 0xb6, 0x76, 0x1e, 0x27, 0x66, 0x50, 0x1d, 0xe6, 0x39, 0x75, 0xdb, 0xc4,
0x5c, 0x98, 0xc1, 0x85, 0x8a, 0x55, 0x24, 0xb6, 0xc8, 0x0b, 0x02, 0xd2, 0x31, 0x17, 0x55, 0xa5,
0xa4, 0x28, 0xf4, 0x03, 0x58, 0x0c, 0xfa, 0x3d, 0xd9, 0x2c, 0x74, 0xf6, 0x39, 0x89, 0x98, 0x79,
0x41, 0x7e, 0x6f, 0x62, 0x16, 0x5d, 0x83, 0x85, 0xa0, 0xdf, 0x3b, 0x10, 0x37, 0xbc, 0x62, 0x5b,
0x92, 0x6c, 0xe3, 0x93, 0xe8, 0x26, 0x2c, 0x0b, 0x5c, 0xbc, 0xdb, 0x8a, 0x73, 0x59, 0x72, 0xa6,
0x17, 0xde, 0x43, 0xcf, 0xfc, 0x3e, 0x3a, 0x02, 0xeb, 0x39, 0x54, 0x93, 0xfb, 0x90, 0x81, 0xbd,
0x33, 0xde, 0x71, 0xcf, 0x10, 0x17, 0x89, 0x86, 0xe3, 0x39, 0x7c, 0xef, 0x69, 0xd4, 0x71, 0x39,
0xc9, 0xca, 0xbc, 0xe9, 0x0c, 0x74, 0x19, 0x0a, 0x7b, 0x6a, 0xa3, 0xd4, 0xcb, 0xa5, 0xa6, 0xc4,
0x7c, 0x93, 0x08, 0xe7, 0xe9, 0x74, 0xab, 0x29, 0xfb, 0x0a, 0x58, 0x59, 0xe2, 0x95, 0x33, 0xec,
0x3f, 0xe7, 0x00, 0x46, 0xc1, 0x80, 0x3e, 0x02, 0xe8, 0x91, 0x8e, 0xe7, 0xfe, 0x9a, 0x8f, 0x1a,
0xca, 0xb2, 0x9c, 0x91, 0x5d, 0xe5, 0xa8, 0xf4, 0xcf, 0xbd, 0x73, 0xe9, 0x8f, 0x60, 0x8e, 0x79,
0xdf, 0x10, 0x5d, 0xa6, 0xc8, 0x31, 0x7a, 0x02, 0x15, 0x37, 0x08, 0x42, 0x2e, 0xc3, 0x38, 0x6e,
0xb6, 0x6f, 0x9d, 0x16, 0xbe, 0xce, 0xd6, 0x88, 0x5f, 0x9d, 0x92, 0xa4, 0x04, 0xeb, 0x3e, 0x2c,
0x4d, 0x32, 0x9c, 0xab, 0x19, 0xfc, 0xd6, 0x80, 0x0b, 0x13, 0x5b, 0x87, 0x3e, 0x1d, 0x66, 0x01,
0x63, 0x86, 0xe3, 0x15, 0x27, 0x80, 0x07, 0x50, 0xdd, 0xe2, 0x5c, 0x64, 0x3d, 0x65, 0x9b, 0x6a,
0xf7, 0x4e, 0xc7, 0x8e, 0x21, 0xec, 0x3f, 0x1a, 0xa3, 0x77, 0xce, 0xcc, 0x9e, 0xff, 0xde, 0x78,
0xcf, 0x7f, 0x7d, 0xfa, 0xe5, 0xf0, 0x3e, 0x5b, 0xfd, 0x1b, 0x3f, 0x87, 0x0f, 0x33, 0x2f, 0x66,
0x54, 0x81, 0xe2, 0xfe, 0xc1, 0x16, 0x3e, 0x68, 0x35, 0x97, 0x3e, 0x40, 0x55, 0x28, 0x6d, 0x3f,
0xd9, 0xdd, 0x7b, 0xdc, 0x3a, 0x68, 0x2d, 0x19, 0x62, 0xa9, 0xd9, 0x12, 0xe3, 0xe6, 0x52, 0xae,
0xfe, 0x6d, 0x01, 0x8a, 0xdb, 0xea, 0xbf, 0x1e, 0x74, 0x00, 0xe5, 0xe1, 0x9f, 0x00, 0xc8, 0xce,
0xf0, 0xce, 0xc4, 0xbf, 0x09, 0xd6, 0xc7, 0xa7, 0xf2, 0xe8, 0xc4, 0xfd, 0x10, 0xe6, 0xe5, 0xdf,
0x21, 0x28, 0xa3, 0xbd, 0x4e, 0xfe, 0x4f, 0x62, 0x9d, 0xfe, 0xf7, 0xc2, 0x86, 0x21, 0x24, 0xc9,
0xb7, 0x89, 0x2c, 0x49, 0xc9, 0xc7, 0x4b, 0x6b, 0xf5, 0x8c, 0x47, 0x0d, 0xb4, 0x0b, 0x05, 0xdd,
0xb0, 0x65, 0xb1, 0x26, 0x5f, 0x20, 0xac, 0xb5, 0xe9, 0x0c, 0x4a, 0xd8, 0x86, 0x81, 0x76, 0x87,
0xef, 0xd1, 0x59, 0xaa, 0x25, 0xab, 0x5d, 0xeb, 0x8c, 0xf5, 0x75, 0x63, 0xc3, 0x40, 0x5f, 0x41,
0x25, 0x51, 0xcf, 0xa2, 0x8c, 0x6a, 0x2a, 0x5d, 0x1c, 0x5b, 0xd7, 0xcf, 0xe0, 0xd2, 0x96, 0xb7,
0x60, 0x4e, 0x1e, 0xa4, 0x0c, 0x67, 0x27, 0xca, 0xdd, 0x2c, 0x35, 0xc7, 0xca, 0xdf, 0x43, 0x55,
0xa0, 0x93, 0x20, 0x19, 0x7d, 0xe8, 0xfa, 0x59, 0xf7, 0xea, 0xd4, 0xb0, 0x49, 0x05, 0xf1, 0x86,
0x81, 0x42, 0x40, 0xe9, 0xe4, 0x89, 0x7e, 0x94, 0x11, 0x25, 0xd3, 0x32, 0xb8, 0x75, 0x73, 0x36,
0x66, 0x65, 0x54, 0xa3, 0xfa, 0xea, 0xcd, 0x8a, 0xf1, 0x8f, 0x37, 0x2b, 0xc6, 0xbf, 0xde, 0xac,
0x18, 0x87, 0x05, 0x59, 0x31, 0xfd, 0xf8, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x7c, 0xb8, 0xc3,
0x68, 0x0b, 0x1d, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -3963,6 +3972,13 @@ func (m *BuildHistoryRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if m.NumCompletedSteps != 0 {
i = encodeVarintControl(dAtA, i, uint64(m.NumCompletedSteps))
i--
dAtA[i] = 0x1
i--
dAtA[i] = 0x88
}
if m.NumTotalSteps != 0 {
i = encodeVarintControl(dAtA, i, uint64(m.NumTotalSteps))
i--
@@ -5107,6 +5123,9 @@ func (m *BuildHistoryRecord) Size() (n int) {
if m.NumTotalSteps != 0 {
n += 2 + sovControl(uint64(m.NumTotalSteps))
}
if m.NumCompletedSteps != 0 {
n += 2 + sovControl(uint64(m.NumCompletedSteps))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -10063,6 +10082,25 @@ func (m *BuildHistoryRecord) Unmarshal(dAtA []byte) error {
break
}
}
case 17:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field NumCompletedSteps", wireType)
}
m.NumCompletedSteps = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowControl
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.NumCompletedSteps |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipControl(dAtA[iNdEx:])

View File

@@ -206,6 +206,7 @@ message BuildHistoryRecord {
bool pinned = 14;
int32 numCachedSteps = 15;
int32 numTotalSteps = 16;
int32 numCompletedSteps = 17;
// TODO: tags
// TODO: unclipped logs
}

View File

@@ -49,6 +49,7 @@ type SolveOpt struct {
SessionPreInitialized bool // TODO: refactor to better session syncing
Internal bool
SourcePolicy *spb.Policy
Ref string
}
type ExportEntry struct {
@@ -95,6 +96,9 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
}
ref := identity.NewID()
if opt.Ref != "" {
ref = opt.Ref
}
eg, ctx := errgroup.WithContext(ctx)
statusContext, cancelStatus := context.WithCancel(context.Background())

View File

@@ -23,7 +23,12 @@ func Copy(ctx context.Context, conn io.ReadWriteCloser, stream Stream, closeStre
if err := stream.RecvMsg(p); err != nil {
if err == io.EOF {
// indicates client performed CloseSend, but they may still be
// reading data, so don't close conn yet
// reading data
if conn, ok := conn.(interface {
CloseWrite() error
}); ok {
conn.CloseWrite()
}
return nil
}
conn.Close()

View File

@@ -6,6 +6,7 @@ import (
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
"github.com/moby/buildkit/session"
digest "github.com/opencontainers/go-digest"
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
@@ -90,3 +91,23 @@ func (mp *MultiProvider) Add(dgst digest.Digest, p content.Provider) {
defer mp.mu.Unlock()
mp.sub[dgst] = p
}
func (mp *MultiProvider) UnlazySession(desc ocispecs.Descriptor) session.Group {
type unlazySession interface {
UnlazySession(ocispecs.Descriptor) session.Group
}
mp.mu.RLock()
if p, ok := mp.sub[desc.Digest]; ok {
mp.mu.RUnlock()
if cd, ok := p.(unlazySession); ok {
return cd.UnlazySession(desc)
}
} else {
mp.mu.RUnlock()
}
if cd, ok := mp.base.(unlazySession); ok {
return cd.UnlazySession(desc)
}
return nil
}

View File

@@ -16,7 +16,7 @@ func init() {
}
func otlpExporter() (sdktrace.SpanExporter, error) {
set := os.Getenv("OTEL_TRACES_EXPORTER") == "otpl" || os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT") != "" || os.Getenv("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT") != ""
set := os.Getenv("OTEL_TRACES_EXPORTER") == "otlp" || os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT") != "" || os.Getenv("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT") != ""
if !set {
return nil, nil
}

6
vendor/modules.txt vendored
View File

@@ -150,7 +150,7 @@ github.com/compose-spec/compose-go/types
# github.com/containerd/console v1.0.3
## explicit; go 1.13
github.com/containerd/console
# github.com/containerd/containerd v1.6.14
# github.com/containerd/containerd v1.6.16-0.20230124210447-1709cfe273d9
## explicit; go 1.17
github.com/containerd/containerd/api/services/content/v1
github.com/containerd/containerd/archive/compression
@@ -219,7 +219,7 @@ github.com/docker/cli/cli/streams
github.com/docker/cli/cli/trust
github.com/docker/cli/cli/version
github.com/docker/cli/opts
# github.com/docker/cli-docs-tool v0.5.0
# github.com/docker/cli-docs-tool v0.5.1
## explicit; go 1.18
github.com/docker/cli-docs-tool
github.com/docker/cli-docs-tool/annotation
@@ -433,7 +433,7 @@ github.com/mitchellh/go-wordwrap
# github.com/mitchellh/mapstructure v1.5.0
## explicit; go 1.14
github.com/mitchellh/mapstructure
# github.com/moby/buildkit v0.11.0-rc4
# github.com/moby/buildkit v0.11.2
## explicit; go 1.18
github.com/moby/buildkit/api/services/control
github.com/moby/buildkit/api/types