Compare commits

...

73 Commits

Author SHA1 Message Date
Justin Chadwell 86bdced776
Merge pull request #1815 from jedevc/v0.10-vendor-buildkit 2 years ago
Justin Chadwell edb535f263 vendor: update buildkit to v0.11@348e79dfed17
Signed-off-by: Justin Chadwell <me@jedevc.com>
2 years ago
CrazyMax f16694cc5d
Merge pull request #1792 from jedevc/v0.10-bake-reference
[v0.10] docs: move and rewrite bake reference
2 years ago
David Karlsson e7db0ce587 docs: refactor bake file reference
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2 years ago
Tõnis Tiigi c513d34049
Merge pull request #1664 from crazy-max/v0.10_backport_stripcreds
[v0.10 backport] build: strip credentials from remote url on collecting Git provenance info
2 years ago
CrazyMax d455c07331
build: strip credentials from remote url on collecting Git provenance info
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2 years ago
Tõnis Tiigi 5ac3b4c4b6
Merge pull request #1662 from crazy-max/v0.10.4_picks
[v0.10] cherry-picks for v0.10.4
2 years ago
CrazyMax b1440b07f2
build: makes git dirty check opt-in
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2 years ago
David Karlsson a3286a0ab1
docs: added --platform=local example
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2 years ago
Tõnis Tiigi b79345c63e
Merge pull request #1645 from cpuguy83/0.10_env_no_provenance
[0.10] Add env var to disable default attestations
2 years ago
Brian Goff 23eb3c3ccd Add env var to disable default attestations
For certain cases we need to build with `--provenance=false`.
However not all build envs (especially in the OSS ethos) have the latest
buildx so just blanket setting `--provenance=false` will fail in these
cases.

Having an env var allows people to set the value without having to worry
about if the buildx version has the `--provenance` flag.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit bc9cb2c66a)
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2 years ago
CrazyMax 79e156beb1
Merge pull request #1636 from crazy-max/v0.10_backport_ci-update-ver
[v0.10 backport] ci: update buildx and buildkit to latest
2 years ago
CrazyMax c960d16da5
ci: update buildx and buildkit to latest
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit f1a5a3ec50)
2 years ago
CrazyMax b5b9de69d9
Merge pull request #1635 from crazy-max/v0.10_backport_fix-git-ambiguous
[v0.10 backport] build: fix git ambiguous argument
2 years ago
David Gageot 45863c4f16
Remove git warning: buildx/1633
Signed-off-by: David Gageot <david.gageot@docker.com>
(cherry picked from commit d4a4aaf509)
2 years ago
CrazyMax f2feea8bed
Merge pull request #1609 from crazy-max/0.10.3_cherry_picks
[v0.10] cherry-picks for v0.10.3
2 years ago
Justin Chadwell a73d07ff7a
imagetools: process com.docker.reference.* annotations
To give us the option later down the road of producing recommended OCI
names in BuildKit (using com instead of vnd, woops), we need to update
Buildx to be able to process both.

Ideally, if a Buildx/BuildKit release hadn't been made we could just
switch over, but since we have, we'd need to support both (at least for
a while, eventually we could consider deprecating+removing the vnd
variant).

Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 642f28f439)
2 years ago
Justin Chadwell 0fad89c3b9
bake: avoid nesting error diagnostics
With changes to the lazy evaluation, the evaluation order is no longer
fixed - this means that we can follow long and confusing paths to get to
an error.

Because of the co-recursive nature of the lazy evaluation, we need to
take special care that the original HCL diagnostics are not discarded
and are preserved so that the original source of the error can be
detected. Preserving the full trace is not necessary, and probably not
useful to the user - all of the file that is not lazily loaded will be
eagerly loaded after all struct blocks are loaded - so the error would
be found regardless.

Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit fbb4f4dec8)
2 years ago
CrazyMax 661af29d46
build: check reachable git commits
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit fd5884189c)
2 years ago
CrazyMax 02cf539a08
gitutil: override the locale to ensure consistent output
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit a8eb2a7fbe)
2 years ago
Justin Chadwell cc87bd104e
bake: avoid early-exit for resolution failures
With changes made to allow lazy evaluation, we were early exiting if an
undefined name was detected, either for a variable or a function.

This had two key implications:

1. The error messages changed, and became significantly less
   informative.

   For example, we went from:

   > Unknown variable; There is no variable named "FO". Did you mean "FOO"?, and 1 other diagnostic(s)

   To

   > Invalid expression; undefined variable "FO"

2. Any issues in our function detection from funcCalls which cause JSON
   functions to be erroneously detected cause invalid functions to be
   resolved, which causes new name resolution errors.

To avoid the above problems, we can defer the error from an undefined
name until HCL evaluation - which produces the more informative errors,
and does not suffer from incorrectly detecting JSON functions.

Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit dc8a2b0398)
2 years ago
Justin Chadwell 582cc04be6
build: add docs for boolean attestation flags
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 07548bc898)
2 years ago
CrazyMax ae278ce450
builder: fix docker context not validated
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 0e544fe835)
2 years ago
Justin Chadwell b66988c824
bake: fix loop references
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 48357ee0c6)
2 years ago
Tõnis Tiigi 00ed17df6d
Merge pull request #1569 from tonistiigi/v0.10.2-picks
[v0.10] cherry-picks for v0.10.2
2 years ago
CrazyMax cfb71fab97
build: better message output for git provenance
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 6db696748b)
2 years ago
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)
2 years ago
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)
2 years ago
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)
2 years ago
CrazyMax b5ea79e277
build: fix preferred platform not taken account
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 49b3c0dba5)
2 years ago
Tõnis Tiigi 481796f84f
Merge pull request #1556 from crazy-max/0.10.1_cherry_picks
[v0.10] cherry-picks for v0.10.1
2 years ago
Tonis Tiigi 0090d49e57
vendor: update buildkit to v0.11.2
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit f6da7ee135)
2 years ago
CrazyMax 389ac0c3d1
build: set remote origin url
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit c1058c17aa)
2 years ago
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)
2 years ago
Justin Chadwell 65cea456fd
build: reorder error group funcs
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 1180d919f5)
2 years ago
Justin Chadwell f7bd5b99da
build: use copy for BuildWithResultHandler loop vars
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 347417ee12)
2 years ago
Justin Chadwell 8c14407fa2
imagetools: silence intoto warnings
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 7145e021f9)
2 years ago
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)
2 years ago
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)
2 years ago
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)
2 years ago
CrazyMax 123febf107
ci: fix typo in docs-release workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 523a16aa35)
2 years ago
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)
2 years ago
Justin Chadwell 6d935625a6
Merge pull request #1546 from jedevc/v0.10-inspect-lazy-attestations
[v0.10] Lazily load attestation data in imagetools inspect
2 years ago
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
2 years ago
Justin Chadwell 08244b12b5
Merge pull request #1544 from jedevc/v0.10-bump-ci
[v0.10] Bump Buildx and BuildKit versions in GitHub actions
2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
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>
2 years ago
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
2 years ago
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>
2 years ago
CrazyMax bf4b95fc3a
Merge pull request #1524 from jedevc/v0.10-docs-reference-attest
[0.10] docs: add reference for new attest family of flags
2 years ago
Justin Chadwell 467586dc8d docs: add reference for new attest family of flags
Signed-off-by: Justin Chadwell <me@jedevc.com>
2 years ago
Tõnis Tiigi 8764628976
Merge pull request #1501 from tonistiigi/v0.10-picks
[v0.10] cherry-picks
2 years ago
Justin Chadwell 583fe71740
docs: update with new inspect output
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 9818055b0e)
2 years ago
Justin Chadwell 9fb3ff1a27
inspect: change additional spdxs to not have duplicates
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 484823c97d)
2 years ago
Justin Chadwell 9d4f38c5fa
inspect: provide access to multiple spdx documents
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 3ce17b01dc)
2 years ago
Justin Chadwell 793082f543
inspect: parse sbom and provenance into json structs
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit e68c566c1c)
2 years ago
Justin Chadwell fe6f697205
inspect: break after first matching attestation
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 19d16aa941)
2 years ago
Tonis Tiigi fd3fb752d3
github: update CI to buildkit v0.11
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit 571871b084)
2 years ago
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
2 years ago
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>
2 years ago
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>
2 years ago
CrazyMax 8a7a221a7f
imagetools inspect: handle provenance and sbom
use stub structs for SLSA/SBOM while waiting for
go-imageinspect library to be public.

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2 years ago
CrazyMax e4db8d2a21
imagetools inspect: missing annotations key
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2 years ago
Justin Chadwell 7394853ddf
vendor: update buildkit to v0.11.0-rc4
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
2 years ago
Justin Chadwell a8be6b576b
docs: update oci layout with tag resolution
Signed-off-by: Justin Chadwell <me@jedevc.com>
2 years ago
Justin Chadwell 8b960ededd
build: refactor reference parsing for image layouts
We allow any valid image reference format for the oci-layout, not just
limiting to name@digest, we additionally allow images of the form
name:tag@digest now.

The name of the reference is used to find the local directory to lookup
the store in, while the tag and digest are attached to a random identity
to generate the dummy reference sent to the oci-layout context.

This separation of the target to replace and the value to replace it
with ensures that any tag or digest set in the client is properly sent
across to the server. The tag is used when a digest was not specified,
and it is resolved in the context of the local directory before being
sent, using the same helpers as we use for the local cache expoter.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2 years ago
CrazyMax 4735a71fbd
e2e: use native k3s installation script
debianmaster/actions-k3s action gives some warnings in our e2e
workflow. This commit brings https://github.com/debianmaster/actions-k3s/blob/master/index.js
directly in the workflow through actions/github-script with
some changes to properly wait for nodes to be up.

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2 years ago
Tõnis Tiigi 37fce8cc06
Merge pull request #1489 from AkihiroSuda/cherrypick-1482-v0.10
[0.10] Propagate SOURCE_DATE_EPOCH from the client env
2 years ago
Akihiro Suda 82476ab039
Propagate SOURCE_DATE_EPOCH from the client env
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
(cherry picked from commit 0e6f5a155e)
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2 years ago

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

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

@ -20,6 +20,7 @@ on:
env:
DESTDIR: "./bin"
K3S_VERSION: "v1.21.2-k3s1"
jobs:
build:
@ -133,20 +134,67 @@ jobs:
-
name: Install k3s
if: matrix.driver == 'kubernetes'
uses: debianmaster/actions-k3s@b9cf3f599fd118699a3c8a0d18a2f2bda6cf4ce4
id: k3s
uses: actions/github-script@v6
with:
version: v1.21.2-k3s1
script: |
const fs = require('fs');
let wait = function(milliseconds) {
return new Promise((resolve, reject) => {
if (typeof(milliseconds) !== 'number') {
throw new Error('milleseconds not a number');
}
setTimeout(() => resolve("done!"), milliseconds)
});
}
try {
const kubeconfig="/tmp/buildkit-k3s/kubeconfig.yaml";
core.info(`storing kubeconfig in ${kubeconfig}`);
await exec.exec('docker', ["run", "-d",
"--privileged",
"--name=buildkit-k3s",
"-e", "K3S_KUBECONFIG_OUTPUT="+kubeconfig,
"-e", "K3S_KUBECONFIG_MODE=666",
"-v", "/tmp/buildkit-k3s:/tmp/buildkit-k3s",
"-p", "6443:6443",
"-p", "80:80",
"-p", "443:443",
"-p", "8080:8080",
"rancher/k3s:${{ env.K3S_VERSION }}", "server"
]);
await wait(10000);
core.exportVariable('KUBECONFIG', kubeconfig);
let nodeName;
for (let count = 1; count <= 5; count++) {
try {
const nodeNameOutput = await exec.getExecOutput("kubectl get nodes --no-headers -oname");
nodeName = nodeNameOutput.stdout
} catch (error) {
core.info(`Unable to resolve node name (${error.message}). Attempt ${count} of 5.`)
} finally {
if (nodeName) {
break;
}
await wait(5000);
}
}
if (!nodeName) {
throw new Error(`Unable to resolve node name after 5 attempts.`);
}
await exec.exec(`kubectl wait --for=condition=Ready ${nodeName}`);
} catch (error) {
core.setFailed(error.message);
}
-
name: Config k3s
name: Print KUBECONFIG
if: matrix.driver == 'kubernetes'
run: |
(set -x ; cat ${{ steps.k3s.outputs.kubeconfig }})
-
name: Check k3s nodes
if: matrix.driver == 'kubernetes'
run: |
kubectl get nodes
yq ${{ env.KUBECONFIG }}
-
name: Launch remote buildkitd
if: matrix.driver == 'remote'

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

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

@ -140,6 +140,19 @@ func ReadTargets(ctx context.Context, files []File, targets, overrides []string,
}
}
// Propagate SOURCE_DATE_EPOCH from the client env.
// 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
}
}
}
return m, n, nil
}
@ -577,7 +590,7 @@ type Target struct {
NoCache *bool `json:"no-cache,omitempty" hcl:"no-cache,optional" cty:"no-cache"`
NetworkMode *string `json:"-" hcl:"-" cty:"-"`
NoCacheFilter []string `json:"no-cache-filter,omitempty" hcl:"no-cache-filter,optional" cty:"no-cache-filter"`
// IMPORTANT: if you add more fields here, do not forget to update newOverrides and docs/manuals/bake/file-definition.md.
// IMPORTANT: if you add more fields here, do not forget to update newOverrides and docs/bake-reference.md.
// linked is a private field to mark a target used as a linked one
linked bool

@ -78,6 +78,7 @@ func ParseCompose(cfgs []compose.ConfigFile, envs map[string]string) (*Config, e
// compose does not support nil values for labels
labels := map[string]*string{}
for k, v := range s.Build.Labels {
v := v
labels[k] = &v
}

@ -670,6 +670,24 @@ func TestJSONFunctions(t *testing.T) {
require.Equal(t, ptrstr("pre-<FOO-abc>"), c.Targets[0].Args["v1"])
}
func TestJSONInvalidFunctions(t *testing.T) {
dt := []byte(`{
"target": {
"app": {
"args": {
"v1": "myfunc(\"foo\")"
}
}
}}`)
c, err := ParseFile(dt, "docker-bake.json")
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr(`myfunc("foo")`), c.Targets[0].Args["v1"])
}
func TestHCLFunctionInAttr(t *testing.T) {
dt := []byte(`
function "brace" {

@ -14,15 +14,7 @@ func funcCalls(exp hcl.Expression) ([]string, hcl.Diagnostics) {
if !ok {
fns, err := jsonFuncCallsRecursive(exp)
if err != nil {
return nil, hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid expression",
Detail: err.Error(),
Subject: exp.Range().Ptr(),
Context: exp.Range().Ptr(),
},
}
return nil, wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
}
return fns, nil
}

@ -62,7 +62,9 @@ type parser struct {
doneB map[*hcl.Block]map[string]struct{}
}
func (p *parser) loadDeps(exp hcl.Expression, exclude map[string]struct{}) hcl.Diagnostics {
var errUndefined = errors.New("undefined")
func (p *parser) loadDeps(exp hcl.Expression, exclude map[string]struct{}, allowMissing bool) hcl.Diagnostics {
fns, hcldiags := funcCalls(exp)
if hcldiags.HasErrors() {
return hcldiags
@ -70,15 +72,10 @@ func (p *parser) loadDeps(exp hcl.Expression, exclude map[string]struct{}) hcl.D
for _, fn := range fns {
if err := p.resolveFunction(fn); err != nil {
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid expression",
Detail: err.Error(),
Subject: exp.Range().Ptr(),
Context: exp.Range().Ptr(),
},
if allowMissing && errors.Is(err, errUndefined) {
continue
}
return wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
}
}
@ -128,27 +125,17 @@ func (p *parser) loadDeps(exp hcl.Expression, exclude map[string]struct{}) hcl.D
}
}
if err := p.resolveBlock(blocks[0], target); err != nil {
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid expression",
Detail: err.Error(),
Subject: v.SourceRange().Ptr(),
Context: v.SourceRange().Ptr(),
},
if allowMissing && errors.Is(err, errUndefined) {
continue
}
return wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
}
} else {
if err := p.resolveValue(v.RootName()); err != nil {
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid expression",
Detail: err.Error(),
Subject: v.SourceRange().Ptr(),
Context: v.SourceRange().Ptr(),
},
if allowMissing && errors.Is(err, errUndefined) {
continue
}
return wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
}
}
}
@ -167,7 +154,7 @@ func (p *parser) resolveFunction(name string) error {
if _, ok := p.ectx.Functions[name]; ok {
return nil
}
return errors.Errorf("undefined function %s", name)
return errors.Wrapf(errUndefined, "function %q does not exit", name)
}
if _, ok := p.progressF[name]; ok {
return errors.Errorf("function cycle not allowed for %s", name)
@ -217,7 +204,7 @@ func (p *parser) resolveFunction(name string) error {
return diags
}
if diags := p.loadDeps(f.Result.Expr, params); diags.HasErrors() {
if diags := p.loadDeps(f.Result.Expr, params, false); diags.HasErrors() {
return diags
}
@ -255,7 +242,7 @@ func (p *parser) resolveValue(name string) (err error) {
if _, builtin := p.opt.Vars[name]; !ok && !builtin {
vr, ok := p.vars[name]
if !ok {
return errors.Errorf("undefined variable %q", name)
return errors.Wrapf(errUndefined, "variable %q does not exit", name)
}
def = vr.Default
}
@ -270,7 +257,7 @@ func (p *parser) resolveValue(name string) (err error) {
return
}
if diags := p.loadDeps(def.Expr, nil); diags.HasErrors() {
if diags := p.loadDeps(def.Expr, nil, true); diags.HasErrors() {
return diags
}
vv, diags := def.Expr.Value(p.ectx)
@ -314,14 +301,7 @@ func (p *parser) resolveValue(name string) (err error) {
func (p *parser) resolveBlock(block *hcl.Block, target *hcl.BodySchema) (err error) {
name := block.Labels[0]
if err := p.opt.ValidateLabel(name); err != nil {
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid name",
Detail: err.Error(),
Subject: &block.LabelRanges[0],
},
}
return wrapErrorDiagnostic("Invalid name", err, &block.LabelRanges[0], &block.LabelRanges[0])
}
if _, ok := p.doneB[block]; !ok {
@ -395,7 +375,7 @@ func (p *parser) resolveBlock(block *hcl.Block, target *hcl.BodySchema) (err err
return diag
}
for _, a := range content.Attributes {
diag := p.loadDeps(a.Expr, nil)
diag := p.loadDeps(a.Expr, nil, true)
if diag.HasErrors() {
return diag
}
@ -573,15 +553,7 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
return diags
}
r := p.vars[k].Body.MissingItemRange()
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid value",
Detail: err.Error(),
Subject: &r,
Context: &r,
},
}
return wrapErrorDiagnostic("Invalid value", err, &r, &r)
}
}
@ -604,15 +576,7 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
}
}
}
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid function",
Detail: err.Error(),
Subject: subject,
Context: context,
},
}
return wrapErrorDiagnostic("Invalid function", err, subject, context)
}
}
@ -673,15 +637,7 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
continue
}
} else {
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid attribute",
Detail: err.Error(),
Subject: &b.LabelRanges[0],
Context: &b.DefRange,
},
}
return wrapErrorDiagnostic("Invalid block", err, &b.LabelRanges[0], &b.DefRange)
}
}
@ -726,21 +682,34 @@ func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
if diags, ok := err.(hcl.Diagnostics); ok {
return diags
}
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid attribute",
Detail: err.Error(),
Subject: &p.attrs[k].Range,
Context: &p.attrs[k].Range,
},
}
return wrapErrorDiagnostic("Invalid attribute", err, &p.attrs[k].Range, &p.attrs[k].Range)
}
}
return nil
}
// wrapErrorDiagnostic wraps an error into a hcl.Diagnostics object.
// If the error is already an hcl.Diagnostics object, it is returned as is.
func wrapErrorDiagnostic(message string, err error, subject *hcl.Range, context *hcl.Range) hcl.Diagnostics {
switch err := err.(type) {
case *hcl.Diagnostic:
return hcl.Diagnostics{err}
case hcl.Diagnostics:
return err
default:
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: message,
Detail: err.Error(),
Subject: subject,
Context: context,
},
}
}
}
func setLabel(v reflect.Value, lbl string) int {
// cache field index?
numFields := v.Elem().Type().NumField()

@ -34,9 +34,9 @@ func ReadRemoteFiles(ctx context.Context, nodes []builder.Node, url string, name
var files []File
var node *builder.Node
for _, n := range nodes {
for i, n := range nodes {
if n.Err == nil {
node = &n
node = &nodes[i]
continue
}
}

@ -6,6 +6,7 @@ import (
"context"
"crypto/rand"
_ "crypto/sha256" // ensure digests can be computed
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
@ -36,8 +37,10 @@ import (
"github.com/docker/docker/pkg/jsonmessage"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/client/ociindex"
"github.com/moby/buildkit/exporter/containerimage/exptypes"
gateway "github.com/moby/buildkit/frontend/gateway/client"
"github.com/moby/buildkit/identity"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/upload/uploadprovider"
"github.com/moby/buildkit/solver/errdefs"
@ -226,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)
@ -445,6 +450,36 @@ 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 {
const noAttestEnv = "BUILDX_NO_DEFAULT_ATTESTATIONS"
var noProv bool
if v, ok := os.LookupEnv(noAttestEnv); ok {
noProv, err = strconv.ParseBool(v)
if err != nil {
return nil, nil, errors.Wrap(err, "invalid "+noAttestEnv)
}
}
if !noProv {
so.FrontendAttrs["attest:provenance"] = "mode=min,inline-only=true"
}
}
switch len(opt.Exports) {
case 1:
// valid
@ -502,7 +537,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 {
@ -579,20 +614,12 @@ 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
// Propagate SOURCE_DATE_EPOCH from the client env
if v := os.Getenv("SOURCE_DATE_EPOCH"); v != "" {
if _, ok := so.FrontendAttrs["build-arg:SOURCE_DATE_EPOCH"]; !ok {
so.FrontendAttrs["build-arg:SOURCE_DATE_EPOCH"] = v
}
}
if _, ok := opt.Attests["attest:provenance"]; !ok {
so.FrontendAttrs["attest:provenance"] = "mode=min,inline-only=true"
}
// set platforms
if len(opt.Platforms) != 0 {
@ -937,26 +964,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()
@ -978,7 +1169,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),
@ -1062,176 +1270,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 {
@ -1490,26 +1528,63 @@ func LoadInputs(ctx context.Context, d driver.Driver, inp Inputs, pw progress.Wr
// handle OCI layout
if strings.HasPrefix(v.Path, "oci-layout://") {
pathAlone := strings.TrimPrefix(v.Path, "oci-layout://")
parts := strings.SplitN(pathAlone, "@", 2)
if len(parts) != 2 {
return nil, errors.Errorf("invalid oci-layout context %s, must be oci-layout:///path/to/layout@sha256:hash", v.Path)
localPath := pathAlone
localPath, dig, hasDigest := strings.Cut(localPath, "@")
localPath, tag, hasTag := strings.Cut(localPath, ":")
if !hasTag {
tag = "latest"
hasTag = true
}
localPath := parts[0]
dgst, err := digest.Parse(parts[1])
idx := ociindex.NewStoreIndex(localPath)
if !hasDigest {
// lookup by name
desc, err := idx.Get(tag)
if err != nil {
return nil, err
}
if desc != nil {
dig = string(desc.Digest)
hasDigest = true
}
}
if !hasDigest {
// lookup single
desc, err := idx.GetSingle()
if err != nil {
return nil, err
}
if desc != nil {
dig = string(desc.Digest)
hasDigest = true
}
}
if !hasDigest {
return nil, errors.Errorf("oci-layout reference %q could not be resolved", v.Path)
}
_, err := digest.Parse(dig)
if err != nil {
return nil, errors.Wrapf(err, "invalid oci-layout context %s, does not have proper hash, must be oci-layout:///path/to/layout@sha256:hash", v.Path)
return nil, errors.Wrapf(err, "invalid oci-layout digest %s", dig)
}
store, err := local.NewStore(localPath)
if err != nil {
return nil, errors.Wrapf(err, "invalid store at %s", localPath)
}
// now we can add it
storeName := identity.NewID()
if target.OCIStores == nil {
target.OCIStores = map[string]content.Store{}
}
target.OCIStores[k] = store
target.OCIStores[storeName] = store
layout := "oci-layout://" + storeName
if hasTag {
layout += ":" + tag
}
if hasDigest {
layout += "@" + dig
}
target.FrontendAttrs["context:"+k] = fmt.Sprintf("oci-layout:%s@%s", k, dgst.String())
target.FrontendAttrs["context:"+k] = layout
continue
}
st, err := os.Stat(v.Path)

@ -52,22 +52,28 @@ 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")
if sha, err := gitc.FullCommit(); err != nil && !gitutil.IsUnknownRevision(err) {
return res, errors.Wrapf(err, "buildx: failed to get git commit")
} else if sha != "" {
if gitc.IsDirty() {
checkDirty := false
if v, ok := os.LookupEnv("BUILDX_GIT_CHECK_DIRTY"); ok {
if v, err := strconv.ParseBool(v); err == nil {
checkDirty = v
}
}
if checkDirty && gitc.IsDirty() {
sha += "-dirty"
}
if setGitLabels {
@ -78,9 +84,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 +95,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")

@ -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) {
@ -131,6 +131,7 @@ func TestGetGitAttributes(t *testing.T) {
func TestGetGitAttributesDirty(t *testing.T) {
setupTest(t)
t.Setenv("BUILDX_GIT_CHECK_DIRTY", "true")
// make a change to test dirty flag
df := []byte("FROM alpine:edge\n")

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

@ -131,7 +131,7 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions) (err error
tgts, grps, err := bake.ReadTargets(ctx, files, targets, overrides, map[string]string{
// don't forget to update documentation if you add a new
// built-in variable: docs/manuals/bake/file-definition.md#built-in-variables
// built-in variable: docs/bake-reference.md#built-in-variables
"BAKE_CMD_CONTEXT": cmdContext,
"BAKE_LOCAL_PLATFORM": platforms.DefaultString(),
})

@ -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")

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

@ -0,0 +1,818 @@
# Bake file reference
The Bake file is a file for defining workflows that you run using `docker buildx bake`.
## File format
You can define your Bake file in the following file formats:
- HashiCorp Configuration Language (HCL)
- JSON
- YAML (Compose file)
By default, Bake uses the following lookup order to find the configuration file:
1. `docker-bake.override.hcl`
2. `docker-bake.hcl`
3. `docker-bake.override.json`
4. `docker-bake.json`
5. `docker-compose.yaml`
6. `docker-compose.yml`
Bake searches for the file in the current working directory.
You can specify the file location explicitly using the `--file` flag:
```console
$ docker buildx bake --file=../docker/bake.hcl --print
```
## Syntax
The Bake file supports the following property types:
- `target`: build targets
- `group`: collections of build targets
- `variable`: build arguments and variables
- `function`: custom Bake functions
You define properties as hierarchical blocks in the Bake file.
You can assign one or more attributes to a property.
The following snippet shows a JSON representation of a simple Bake file.
This Bake file defines three properties: a variable, a group, and a target.
```json
{
"variable": {
"TAG": {
"default": "latest"
}
},
"group": {
"default": {
"targets": ["webapp"]
}
},
"target": {
"webapp": {
"dockerfile": "Dockerfile",
"tags": ["docker.io/username/webapp:${TAG}"]
}
}
}
```
In the JSON representation of a Bake file, properties are objects,
and attributes are values assigned to those objects.
The following example shows the same Bake file in the HCL format:
```hcl
variable "TAG" {
"default" = "latest"
}
group "default" {
"targets" = ["latest"]
}
target "webapp" {
"dockerfile" = "Dockerfile"
"tags" = ["docker.io/username/webapp:${TAG}"]
}
```
HCL is the preferred format for Bake files.
Aside from syntactic differences,
HCL lets you use features that the JSON and YAML formats don't support.
The examples in this document use the HCL format.
## Target
A target reflects a single `docker build` invocation.
Consider the following build command:
```console
$ docker build \
--file=Dockerfile.webapp \
--tag=docker.io/username/webapp:latest \
https://github.com/username/webapp
```
You can express this command in a Bake file as follows:
```hcl
target "webapp" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
context = "https://github.com/username/webapp"
}
```
The following table shows the complete list of attributes that you can assign to a target:
| Name | Type | Description |
| ----------------------------------------------- | ------- | -------------------------------------------------------------------- |
| [`args`](#targetargs) | Map | Build arguments |
| [`attest`](#targetattest) | List | Build attestations |
| [`cache-from`](#targetcache-from) | List | External cache sources |
| [`cache-to`](#targetcache-to) | List | External cache destinations |
| [`context`](#targetcontext) | String | Set of files located in the specified path or URL |
| [`contexts`](#targetcontexts) | Map | Additional build contexts |
| [`dockerfile-inline`](#targetdockerfile-inline) | String | Inline Dockerfile string |
| [`dockerfile`](#targetdockerfile) | String | Dockerfile location |
| [`inherits`](#targetinherits) | List | Inherit attributes from other targets |
| [`labels`](#targetlabels) | Map | Metadata for images |
| [`no-cache-filter`](#targetno-cache-filter) | List | Disable build cache for specific stages |
| [`no-cache`](#targetno-cache) | Boolean | Disable build cache completely |
| [`output`](#targetoutput) | List | Output destinations |
| [`platforms`](#targetplatforms) | List | Target platforms |
| [`pull`](#targetpull) | Boolean | Always pull images |
| [`secret`](#targetsecret) | List | Secrets to expose to the build |
| [`ssh`](#targetssh) | List | SSH agent sockets or keys to expose to the build |
| [`tags`](#targettags) | List | Image names and tags |
| [`target`](#targettarget) | String | Target build stage |
### `target.args`
Use the `args` attribute to define build arguments for the target.
This has the same effect as passing a [`--build-arg`][build-arg] flag to the build command.
```hcl
target "default" {
args = {
VERSION = "0.0.0+unknown"
}
}
```
You can set `args` attributes to use `null` values.
Doing so forces the `target` to use the `ARG` value specified in the Dockerfile.
```hcl
variable "GO_VERSION" {
default = "1.20.3"
}
target "webapp" {
dockerfile = "webapp.Dockerfile"
tags = ["docker.io/username/webapp"]
}
target "db" {
args = {
GO_VERSION = null
}
dockerfile = "db.Dockerfile"
tags = ["docker.io/username/db"]
}
```
### `target.attest`
The `attest` attribute lets you apply [build attestations][attestations] to the target.
This attribute accepts the long-form CSV version of attestation parameters.
```hcl
target "default" {
attest = [
"type=provenance,mode=min",
"type=sbom"
]
}
```
### `target.cache-from`
Build cache sources.
The builder imports cache from the locations you specify.
It uses the [Buildx cache storage backends][cache-backends],
and it works the same way as the [`--cache-from`][cache-from] flag.
This takes a list value, so you can specify multiple cache sources.
```hcl
target "app" {
cache-from = [
"type=s3,region=eu-west-1,bucket=mybucket",
"user/repo:cache",
]
}
```
### `target.cache-to`
Build cache export destinations.
The builder exports its build cache to the locations you specify.
It uses the [Buildx cache storage backends][cache-backends],
and it works the same way as the [`--cache-to` flag][cache-to].
This takes a list value, so you can specify multiple cache export targets.
```hcl
target "app" {
cache-to = [
"type=s3,region=eu-west-1,bucket=mybucket",
"type=inline"
]
}
```
### `target.context`
Specifies the location of the build context to use for this target.
Accepts a URL or a directory path.
This is the same as the [build context][context] positional argument
that you pass to the build command.
```hcl
target "app" {
context = "./src/www"
}
```
This resolves to the current working directory (`"."`) by default.
```console
$ docker buildx bake --print -f - <<< 'target "default" {}'
[+] Building 0.0s (0/0)
{
"target": {
"default": {
"context": ".",
"dockerfile": "Dockerfile"
}
}
}
```
### `target.contexts`
Additional build contexts.
This is the same as the [`--build-context` flag][build-context].
This attribute takes a map, where keys result in named contexts that you can
reference in your builds.
You can specify different types of contexts, such local directories, Git URLs,
and even other Bake targets. Bake automatically determines the type of
a context based on the pattern of the context value.
| Context type | Example |
| --------------- | ----------------------------------------- |
| Container image | `docker-image://alpine@sha256:0123456789` |
| Git URL | `https://github.com/user/proj.git` |
| HTTP URL | `https://example.com/files` |
| Local directory | `../path/to/src` |
| Bake target | `target:base` |
#### Pin an image version
```hcl
# docker-bake.hcl
target "app" {
contexts = {
alpine = "docker-image://alpine:3.13"
}
}
```
```Dockerfile
# Dockerfile
FROM alpine
RUN echo "Hello world"
```
#### Use a local directory
```hcl
# docker-bake.hcl
target "app" {
contexts = {
src = "../path/to/source"
}
}
```
```Dockerfile
# Dockerfile
FROM scratch AS src
FROM golang
COPY --from=src . .
```
#### Use another target as base
> **Note**
>
> You should prefer to use regular multi-stage builds over this option. You can
> Use this feature when you have multiple Dockerfiles that can't be easily
> merged into one.
```hcl
# docker-bake.hcl
target "base" {
dockerfile = "baseapp.Dockerfile"
}
target "app" {
contexts = {
baseapp = "target:base"
}
}
```
```Dockerfile
# Dockerfile
FROM baseapp
RUN echo "Hello world"
```
### `target.dockerfile-inline`
Uses the string value as an inline Dockerfile for the build target.
```hcl
target "default" {
dockerfile-inline = "FROM alpine\nENTRYPOINT [\"echo\", \"hello\"]"
}
```
The `dockerfile-inline` takes precedence over the `dockerfile` attribute.
If you specify both, Bake uses the inline version.
### `target.dockerfile`
Name of the Dockerfile to use for the build.
This is the same as the [`--file` flag][file] for the `docker build` command.
```hcl
target "default" {
dockerfile = "./src/www/Dockerfile"
}
```
Resolves to `"Dockerfile"` by default.
```console
$ docker buildx bake --print -f - <<< 'target "default" {}'
[+] Building 0.0s (0/0)
{
"target": {
"default": {
"context": ".",
"dockerfile": "Dockerfile"
}
}
}
```
### `target.inherits`
A target can inherit attributes from other targets.
Use `inherits` to reference from one target to another.
In the following example,
the `app-dev` target specifies an image name and tag.
The `app-release` target uses `inherits` to reuse the tag name.
```hcl
variable "TAG" {
default = "latest"
}
target "app-dev" {
tags = ["docker.io/username/myapp:${TAG}"]
}
target "app-release" {
inherits = ["app-dev"]
platforms = ["linux/amd64", "linux/arm64"]
}
```
The `inherits` attribute is a list,
meaning you can reuse attributes from multiple other targets.
In the following example, the `app-release` target reuses attributes
from both the `app-dev` and `_release` targets.
```hcl
target "app-dev" {
args = {
GO_VERSION = "1.20"
BUILDX_EXPERIMENTAL = 1
}
tags = ["docker.io/username/myapp"]
dockerfile = "app.Dockerfile"
labels = {
"org.opencontainers.image.source" = "https://github.com/username/myapp"
}
}
target "_release" {
args = {
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
BUILDX_EXPERIMENTAL = 0
}
}
target "app-release" {
inherits = ["app-dev", "_release"]
platforms = ["linux/amd64", "linux/arm64"]
}
```
When inheriting attributes from multiple targets and there's a conflict,
the target that appears last in the `inherits` list takes precedence.
The previous example defines the `BUILDX_EXPERIMENTAL` argument twice for the `app-release` target.
It resolves to `0` because the `_release` target appears last in the inheritance chain:
```console
$ docker buildx bake --print app-release
[+] Building 0.0s (0/0)
{
"group": {
"default": {
"targets": [
"app-release"
]
}
},
"target": {
"app-release": {
"context": ".",
"dockerfile": "app.Dockerfile",
"args": {
"BUILDKIT_CONTEXT_KEEP_GIT_DIR": "1",
"BUILDX_EXPERIMENTAL": "0",
"GO_VERSION": "1.20"
},
"labels": {
"org.opencontainers.image.source": "https://github.com/username/myapp"
},
"tags": [
"docker.io/username/myapp"
],
"platforms": [
"linux/amd64",
"linux/arm64"
]
}
}
}
```
### `target.labels`
Assigns image labels to the build.
This is the same as the `--label` flag for `docker build`.
```hcl
target "default" {
labels = {
"org.opencontainers.image.source" = "https://github.com/username/myapp"
"com.docker.image.source.entrypoint" = "Dockerfile"
}
}
```
It's possible to use a `null` value for labels.
If you do, the builder uses the label value specified in the Dockerfile.
### `target.no-cache-filter`
Don't use build cache for the specified stages.
This is the same as the `--no-cache-filter` flag for `docker build`.
The following example avoids build cache for the `foo` build stage.
```hcl
target "default" {
no-cache-filter = ["foo"]
}
```
### `target.no-cache`
Don't use cache when building the image.
This is the same as the `--no-cache` flag for `docker build`.
```hcl
target "default" {
no-cache = 1
}
```
### `target.output`
Configuration for exporting the build output.
This is the same as the [`--output` flag][output].
The following example configures the target to use a cache-only output,
```hcl
target "default" {
output = ["type=cacheonly"]
}
```
### `target.platforms`
Set target platforms for the build target.
This is the same as the [`--platform` flag][platform].
The following example creates a multi-platform build for three architectures.
```hcl
target "default" {
platforms = ["linux/amd64", "linux/arm64", "linux/arm/v7"]
}
```
### `target.pull`
Configures whether the builder should attempt to pull images when building the target.
This is the same as the `--pull` flag for `docker build`.
The following example forces the builder to always pull all images referenced in the build target.
```hcl
target "default" {
pull = "always"
}
```
### `target.secret`
Defines secrets to expose to the build target.
This is the same as the [`--secret` flag][secret].
```hcl
variable "HOME" {
default = null
}
target "default" {
secret = [
"type=env,id=KUBECONFIG",
"type=file,id=aws,src=${HOME}/.aws/credentials"
]
}
```
This lets you [mount the secret][run_mount_secret] in your Dockerfile.
```dockerfile
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \
aws cloudfront create-invalidation ...
RUN --mount=type=secret,id=KUBECONFIG \
KUBECONFIG=$(cat /run/secrets/KUBECONFIG) helm upgrade --install
```
### `target.ssh`
Defines SSH agent sockets or keys to expose to the build.
This is the same as the [`--ssh` flag][ssh].
This can be useful if you need to access private repositories during a build.
```hcl
target "default" {
ssh = ["default"]
}
```
```dockerfile
FROM alpine
RUN --mount=type=ssh \
apk add git openssh-client \
&& install -m 0700 -d ~/.ssh \
&& ssh-keyscan github.com >> ~/.ssh/known_hosts \
&& git clone git@github.com:user/my-private-repo.git
```
### `target.tags`
Image names and tags to use for the build target.
This is the same as the [`--tag` flag][tag].
```hcl
target "default" {
tags = [
"org/repo:latest",
"myregistry.azurecr.io/team/image:v1"
]
}
```
### `target.target`
Set the target build stage to build.
This is the same as the [`--target` flag][target].
```hcl
target "default" {
target = "binaries"
}
```
## Group
Groups allow you to invoke multiple builds (targets) at once.
```hcl
group "default" {
targets = ["db", "webapp-dev"]
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
}
target "db" {
dockerfile = "Dockerfile.db"
tags = ["docker.io/username/db"]
}
```
Groups take precedence over targets, if both exist with the same name.
The following bake file builds the `default` group.
Bake ignores the `default` target.
```hcl
target "default" {
dockerfile-inline = "FROM ubuntu"
}
group "default" {
targets = ["alpine", "debian"]
}
target "alpine" {
dockerfile-inline = "FROM alpine"
}
target "debian" {
dockerfile-inline = "FROM debian"
}
```
## Variable
The HCL file format supports variable block definitions.
You can use variables as build arguments in your Dockerfile,
or interpolate them in attribute values in your Bake file.
```hcl
variable "TAG" {
default = "latest"
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:${TAG}"]
}
```
You can assign a default value for a variable in the Bake file,
or assign a `null` value to it. If you assign a `null` value,
Buildx uses the default value from the Dockerfile instead.
You can override variable defaults set in the Bake file using environment variables.
The following example sets the `TAG` variable to `dev`,
overriding the default `latest` value shown in the previous example.
```console
$ TAG=dev docker buildx bake webapp-dev
```
### Built-in variables
The following variables are built-ins that you can use with Bake without having
to define them.
| Variable | Description |
| --------------------- | ----------------------------------------------------------------------------------- |
| `BAKE_CMD_CONTEXT` | Holds the main context when building using a remote Bake file. |
| `BAKE_LOCAL_PLATFORM` | Returns the current platforms default platform specification (e.g. `linux/amd64`). |
### Use environment variable as default
You can set a Bake variable to use the value of an environment variable as a default value:
```hcl
variable "HOME" {
default = "$HOME"
}
```
### Interpolate variables into attributes
To interpolate a variable into an attribute string value,
you must use curly brackets.
The following doesn't work:
```hcl
variable "HOME" {
default = "$HOME"
}
target "default" {
ssh = ["default=$HOME/.ssh/id_rsa"]
}
```
Wrap the variable in curly brackets where you want to insert it:
```diff
variable "HOME" {
default = "$HOME"
}
target "default" {
- ssh = ["default=$HOME/.ssh/id_rsa"]
+ ssh = ["default=${HOME}/.ssh/id_rsa"]
}
```
Before you can interpolate a variable into an attribute,
first you must declare it in the bake file,
as demonstrated in the following example.
```console
$ cat docker-bake.hcl
target "default" {
dockerfile-inline = "FROM ${BASE_IMAGE}"
}
$ docker buildx bake
[+] Building 0.0s (0/0)
docker-bake.hcl:2
--------------------
1 | target "default" {
2 | >>> dockerfile-inline = "FROM ${BASE_IMAGE}"
3 | }
4 |
--------------------
ERROR: docker-bake.hcl:2,31-41: Unknown variable; There is no variable named "BASE_IMAGE"., and 1 other diagnostic(s)
$ cat >> docker-bake.hcl
variable "BASE_IMAGE" {
default = "alpine"
}
$ docker buildx bake
[+] Building 0.6s (5/5) FINISHED
```
## Function
A [set of general-purpose functions][bake_stdlib]
provided by [go-cty][go-cty]
are available for use in HCL files:
```hcl
# docker-bake.hcl
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
args = {
buildno = "${add(123, 1)}"
}
}
```
In addition, [user defined functions][userfunc]
are also supported:
```hcl
# docker-bake.hcl
function "increment" {
params = [number]
result = number + 1
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp:latest"]
args = {
buildno = "${increment(123)}"
}
}
```
> **Note**
>
> See [User defined HCL functions][hcl-funcs] page for more details.
<!-- external links -->
[attestations]: https://docs.docker.com/build/attestations/
[bake_stdlib]: https://github.com/docker/buildx/blob/master/bake/hclparser/stdlib.go
[build-arg]: https://docs.docker.com/engine/reference/commandline/build/#build-arg
[build-context]: https://docs.docker.com/engine/reference/commandline/buildx_build/#build-context
[cache-backends]: https://docs.docker.com/build/cache/backends/
[cache-from]: https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-from
[cache-to]: https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-to
[context]: https://docs.docker.com/engine/reference/commandline/buildx_build/#build-context
[file]: https://docs.docker.com/engine/reference/commandline/build/#file
[go-cty]: https://github.com/zclconf/go-cty/tree/main/cty/function/stdlib
[hcl-funcs]: https://docs.docker.com/build/bake/hcl-funcs/
[output]: https://docs.docker.com/engine/reference/commandline/buildx_build/#output
[platform]: https://docs.docker.com/engine/reference/commandline/buildx_build/#platform
[run_mount_secret]: https://docs.docker.com/engine/reference/builder/#run---mounttypesecret
[secret]: https://docs.docker.com/engine/reference/commandline/buildx_build/#secret
[ssh]: https://docs.docker.com/engine/reference/commandline/buildx_build/#ssh
[tag]: https://docs.docker.com/engine/reference/commandline/build/#tag
[target]: https://docs.docker.com/engine/reference/commandline/build/#target
[userfunc]: https://github.com/hashicorp/hcl/tree/main/ext/userfunc

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

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

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

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

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

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

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

@ -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,8 +87,8 @@ 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/)
guide for more details.
See the [Bake file reference](https://docs.docker.com/build/bake/reference/)
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)
```

@ -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,33 @@ 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).
By default, a minimal provenance attestation will be created for the build
result, which will only be attached for images pushed to registries.
For more information, see [here](https://docs.docker.com/build/attestations/slsa-provenance/).
### <a name="allow"></a> Allow extra privileged entitlement (--allow)
```
@ -90,7 +117,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:
@ -139,10 +166,12 @@ COPY --from=project myfile /
#### <a name="source-oci-layout"></a> Source image from OCI layout directory
Source an image from a local [OCI layout compliant directory](https://github.com/opencontainers/image-spec/blob/main/image-layout.md):
Source an image from a local [OCI layout compliant directory](https://github.com/opencontainers/image-spec/blob/main/image-layout.md),
either by tag, or by digest:
```console
$ docker buildx build --build-context foo=oci-layout:///path/to/local/layout@sha256:abcd12345 .
$ docker buildx build --build-context foo=oci-layout:///path/to/local/layout:<tag>
$ docker buildx build --build-context foo=oci-layout:///path/to/local/layout@sha256:<digest>
```
```dockerfile
@ -154,14 +183,8 @@ COPY --from=foo myfile /
FROM foo
```
The OCI layout directory must be compliant with the [OCI layout specification](https://github.com/opencontainers/image-spec/blob/main/image-layout.md). It looks _solely_ for hashes. It does not
do any form of `image:tag` resolution to find the hash of the manifest; that is up to you.
The format of the `--build-context` must be: `<context>=oci-layout://<path-to-local-layout>@sha256:<hash-of-manifest>`, where:
* `context` is the name of the build context as used in the `Dockerfile`.
* `path-to-local-layout` is the path on the local machine, where you are running `docker build`, to the spec-compliant OCI layout.
* `hash-of-manifest` is the hash of the manifest for the image. It can be a single-architecture manifest or a multi-architecture index.
The OCI layout directory must be compliant with the [OCI layout specification](https://github.com/opencontainers/image-spec/blob/main/image-layout.md).
You can reference an image in the layout using either tags, or the exact digest.
### <a name="builder"></a> Override the configured builder instance (--builder)
@ -391,8 +414,13 @@ The `registry` exporter is a shortcut for `type=image,push=true`.
Set the target platform for the build. All `FROM` commands inside the Dockerfile
without their own `--platform` flag will pull base images for this platform and
this value will also be the platform of the resulting image. The default value
will be the current platform of the buildkit daemon.
this value will also be the platform of the resulting image.
The default value is the platform of the BuildKit daemon where the build runs.
The value takes the form of `os/arch` or `os/arch/variant`. For example,
`linux/amd64` or `linux/arm/v7`. Additionally, the `--platform` flag also supports
a special `local` value, which tells BuildKit to use the platform of the BuildKit
client that invokes the build.
When using `docker-container` driver with `buildx`, this flag can accept multiple
values as an input separated by a comma. With multiple values the result will be
@ -455,11 +483,41 @@ $ 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), used to configure
provenance attestations for the build result. For example,
`--provenance=mode=max` can be used as an abbreviation for
`--attest=type=provenance,mode=max`.
Additionally, `--provenance` can be used with boolean values to broadly enable
or disable provenance attestations. For example, `--provenance=false` can be
used to disable all provenance attestations, while `--provenance=true` can be
used to enable all provenance attestations.
By default, a minimal provenance attestation will be created for the build
result, which will only be attached for images pushed to registries.
For more information, see [here](https://docs.docker.com/build/attestations/slsa-provenance/).
### <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), used to configure SBOM
attestations for the build result. For example,
`--sbom=generator=<user>/<generator-image>` can be used as an abbreviation for
`--attest=type=sbom,generator=<user>/<generator-image>`.
Additionally, `--sbom` can be used with boolean values to broadly enable or
disable SBOM attestations. For example, `--sbom=false` can be used to disable
all SBOM attestations.
For more information, see [here](https://docs.docker.com/build/attestations/sbom/).
### <a name="secret"></a> Secret to expose to the build (--secret)
```

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

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

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

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

@ -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-->
@ -72,7 +72,6 @@ unset. Following fields are available:
* `.Name`: provides the reference of the image
* `.Manifest`: provides the manifest or manifest list
* `.Image`: provides the image config
* `.BuildInfo`: provides [build info from image config](https://github.com/moby/buildkit/blob/master/docs/build-repro.md#image-config)
#### `.Name`
@ -122,39 +121,6 @@ Manifests:
Platform: linux/riscv64
```
#### `.BuildInfo`
```console
$ docker buildx imagetools inspect crazymax/buildx:buildinfo --format "{{.BuildInfo}}"
Name: docker.io/crazymax/buildx:buildinfo
Frontend: dockerfile.v0
Attrs:
filename: Dockerfile
source: docker/dockerfile-upstream:master-labs
build-arg:bar: foo
build-arg:foo: bar
Sources:
Type: docker-image
Ref: docker.io/docker/buildx-bin:0.6.1@sha256:a652ced4a4141977c7daaed0a074dcd9844a78d7d2615465b12f433ae6dd29f0
Pin: sha256:a652ced4a4141977c7daaed0a074dcd9844a78d7d2615465b12f433ae6dd29f0
Type: docker-image
Ref: docker.io/library/alpine:3.13
Pin: sha256:026f721af4cf2843e07bba648e158fb35ecc876d822130633cc49f707f0fc88c
Type: docker-image
Ref: docker.io/moby/buildkit:v0.9.0
Pin: sha256:8dc668e7f66db1c044aadbed306020743516a94848793e0f81f94a087ee78cab
Type: docker-image
Ref: docker.io/tonistiigi/xx@sha256:21a61be4744f6531cb5f33b0e6f40ede41fa3a1b8c82d5946178f80cc84bfc04
Pin: sha256:21a61be4744f6531cb5f33b0e6f40ede41fa3a1b8c82d5946178f80cc84bfc04
Type: http
Ref: https://raw.githubusercontent.com/moby/moby/master/README.md
Pin: sha256:419455202b0ef97e480d7f8199b26a721a417818bc0e2d106975f74323f25e6c
```
#### JSON output
A `json` go template func is also available if you want to render fields as
@ -166,7 +132,7 @@ $ docker buildx imagetools inspect crazymax/loop --format "{{json .Manifest}}"
```json
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:08602e7340970e92bde5e0a2e887c1fde4d9ae753d1e05efb4c8ef3b609f97f1",
"digest": "sha256:a9ca35b798e0b198f9be7f3b8b53982e9a6cf96814cb10d78083f40ad8c127f1",
"size": 949
}
```
@ -177,23 +143,23 @@ $ docker buildx imagetools inspect moby/buildkit:master --format "{{json .Manife
```json
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"digest": "sha256:79d97f205e2799d99a3a8ae2a1ef17acb331e11784262c3faada847dc6972c52",
"size": 2010,
"mediaType": "application/vnd.oci.image.index.v1+json",
"digest": "sha256:d895e8fdcf5e2bb39acb5966f97fc4cd87a2d13d27c939c320025eb4aca5440c",
"size": 4654,
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:bd1e78f06de26610fadf4eb9d04b1a45a545799d6342701726e952cc0c11c912",
"size": 1158,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:ac9dd4fbec9e36b562f910618975a2936533f8e411a3fea2858aacc0ac972e1c",
"size": 1054,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:d37dcced63ec0965824fca644f0ac9efad8569434ec15b4c83adfcb3dcfc743b",
"size": 1158,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:0f4dc6797db467372cbf52c7236816203654a839f64a6542c9135d1973c9d744",
"size": 1054,
"platform": {
"architecture": "arm",
"os": "linux",
@ -201,260 +167,356 @@ $ docker buildx imagetools inspect moby/buildkit:master --format "{{json .Manife
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:ce142eb2255e6af46f2809e159fd03081697c7605a3de03b9cbe9a52ddb244bf",
"size": 1158,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:d62bb533d95afe17c4a9caf1e7c57a3b0a7a67409ccfa7af947aeb0f670ffb87",
"size": 1054,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:f59bfb5062fff76ce464bfa4e25ebaaaac887d6818238e119d68613c456d360c",
"size": 1158,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:b4944057e0c68203cdcc3dceff3b2df3c7d9e3dd801724fa977b01081da7771e",
"size": 1054,
"platform": {
"architecture": "s390x",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:cc96426e0c50a78105d5637d31356db5dd6ec594f21b24276e534a32da09645c",
"size": 1159,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:825702a51eb4234904fc9253d8b0bf0a584787ffd8fc3fd6fa374188233ce399",
"size": 1054,
"platform": {
"architecture": "ppc64le",
"os": "linux"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:39f9c1e2878e6c333acb23187d6b205ce82ed934c60da326cb2c698192631478",
"size": 1158,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:dfb27c6acc9b9f3a7c9d47366d137089565062f43c8063c9f5e408d34c87ee4a",
"size": 1054,
"platform": {
"architecture": "riscv64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:f2fe69bccc878e658caf21dfc99eaf726fb20d28f17398c1d66a90e62cc019f9",
"size": 1113,
"annotations": {
"vnd.docker.reference.digest": "sha256:ac9dd4fbec9e36b562f910618975a2936533f8e411a3fea2858aacc0ac972e1c",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:9e112f8d4e383186f36369fba7b454e246d2e9ca5def797f1b84ede265e9f3ca",
"size": 1113,
"annotations": {
"vnd.docker.reference.digest": "sha256:0f4dc6797db467372cbf52c7236816203654a839f64a6542c9135d1973c9d744",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:09d593587f8665269ec6753eaed7fbdb09968f71587dd53e06519502cbc16775",
"size": 1113,
"annotations": {
"vnd.docker.reference.digest": "sha256:d62bb533d95afe17c4a9caf1e7c57a3b0a7a67409ccfa7af947aeb0f670ffb87",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:985a3f4544dfb042db6a8703f5f76438667dd7958aba14cb04bebe3b4cbd9307",
"size": 1113,
"annotations": {
"vnd.docker.reference.digest": "sha256:b4944057e0c68203cdcc3dceff3b2df3c7d9e3dd801724fa977b01081da7771e",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:cfccb6afeede7dc29bf8abef4815d56f2723fa482ea63c9cd519cd991c379294",
"size": 1113,
"annotations": {
"vnd.docker.reference.digest": "sha256:825702a51eb4234904fc9253d8b0bf0a584787ffd8fc3fd6fa374188233ce399",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:2e93733432c6a14cb57db33928b3a17d7ca298b3babe24d9f56dca2754dbde3b",
"size": 1113,
"annotations": {
"vnd.docker.reference.digest": "sha256:dfb27c6acc9b9f3a7c9d47366d137089565062f43c8063c9f5e408d34c87ee4a",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
}
]
}
```
Following command provides [SLSA](https://github.com/moby/buildkit/blob/master/docs/attestations/slsa-provenance.md) JSON output:
```console
$ docker buildx imagetools inspect crazymax/buildx:buildinfo --format "{{json .BuildInfo}}"
$ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .Provenance}}"
```
```json
{
"frontend": "dockerfile.v0",
"attrs": {
"build-arg:bar": "foo",
"build-arg:foo": "bar",
"filename": "Dockerfile",
"source": "crazymax/dockerfile:buildattrs"
},
"sources": [
{
"type": "docker-image",
"ref": "docker.io/docker/buildx-bin:0.6.1@sha256:a652ced4a4141977c7daaed0a074dcd9844a78d7d2615465b12f433ae6dd29f0",
"pin": "sha256:a652ced4a4141977c7daaed0a074dcd9844a78d7d2615465b12f433ae6dd29f0"
},
{
"type": "docker-image",
"ref": "docker.io/library/alpine:3.13@sha256:026f721af4cf2843e07bba648e158fb35ecc876d822130633cc49f707f0fc88c",
"pin": "sha256:026f721af4cf2843e07bba648e158fb35ecc876d822130633cc49f707f0fc88c"
},
{
"type": "docker-image",
"ref": "docker.io/moby/buildkit:v0.9.0@sha256:8dc668e7f66db1c044aadbed306020743516a94848793e0f81f94a087ee78cab",
"pin": "sha256:8dc668e7f66db1c044aadbed306020743516a94848793e0f81f94a087ee78cab"
"SLSA": {
"builder": {
"id": ""
},
{
"type": "docker-image",
"ref": "docker.io/tonistiigi/xx@sha256:21a61be4744f6531cb5f33b0e6f40ede41fa3a1b8c82d5946178f80cc84bfc04",
"pin": "sha256:21a61be4744f6531cb5f33b0e6f40ede41fa3a1b8c82d5946178f80cc84bfc04"
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/docker/buildkit-syft-scanner@stable-1",
"digest": {
"sha256": "b45f1d207e16c3a3a5a10b254ad8ad358d01f7ea090d382b95c6b2ee2b3ef765"
}
},
{
"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"
}
},
{
"type": "http",
"ref": "https://raw.githubusercontent.com/moby/moby/master/README.md",
"pin": "sha256:419455202b0ef97e480d7f8199b26a721a417818bc0e2d106975f74323f25e6c"
"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": {}
}
]
}
}
```
Following command provides [SBOM](https://github.com/moby/buildkit/blob/master/docs/attestations/sbom.md) JSON output:
```console
$ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .SBOM}}"
```
```json
{
"SPDX": {
"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"
}
}
```
```console
$ docker buildx imagetools inspect crazymax/buildx:buildinfo --format "{{json .}}"
$ docker buildx imagetools inspect crazymax/buildkit:attest --format "{{json .}}"
```
```json
{
"name": "crazymax/buildx:buildinfo",
"name": "crazymax/buildkit:attest",
"manifest": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:899d2c7acbc124d406820857bb51d9089717bbe4e22b97eb4bc5789e99f09f83",
"size": 2628
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.index.v1+json",
"digest": "sha256:7007b387ccd52bd42a050f2e8020e56e64622c9269bf7bbe257b326fe99daf19",
"size": 855,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:fbd10fe50b4b174bb9ea273e2eb9827fa8bf5c88edd8635a93dc83e0d1aecb55",
"size": 673,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:a9de632c16998489fd63fbca42a03431df00639cfb2ecb8982bf9984b83c5b2b",
"size": 839,
"annotations": {
"vnd.docker.reference.digest": "sha256:fbd10fe50b4b174bb9ea273e2eb9827fa8bf5c88edd8635a93dc83e0d1aecb55",
"vnd.docker.reference.type": "attestation-manifest"
},
"platform": {
"architecture": "unknown",
"os": "unknown"
}
}
]
},
"image": {
"created": "2022-02-24T12:27:43.627154558Z",
"created": "2022-12-01T11:46:47.713777178Z",
"architecture": "amd64",
"os": "linux",
"config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"DOCKER_TLS_CERTDIR=/certs",
"DOCKER_CLI_EXPERIMENTAL=enabled"
],
"Entrypoint": [
"docker-entrypoint.sh"
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sh"
"/bin/sh"
]
},
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:7fcb75871b2101082203959c83514ac8a9f4ecfee77a0fe9aa73bbe56afdf1b4",
"sha256:d3c0b963ff5684160641f936d6a4aa14efc8ff27b6edac255c07f2d03ff92e82",
"sha256:3f8d78f13fa9b1f35d3bc3f1351d03a027c38018c37baca73f93eecdea17f244",
"sha256:8e6eb1137b182ae0c3f5d40ca46341fda2eaeeeb5fa516a9a2bf96171238e2e0",
"sha256:fde4c869a56b54dd76d7352ddaa813fd96202bda30b9dceb2c2f2ad22fa2e6ce",
"sha256:52025823edb284321af7846419899234b3c66219bf06061692b709875ed0760f",
"sha256:50adb5982dbf6126c7cf279ac3181d1e39fc9116b610b947a3dadae6f7e7c5bc",
"sha256:9801c319e1c66c5d295e78b2d3e80547e73c7e3c63a4b71e97c8ca357224af24",
"sha256:dfbfac44d5d228c49b42194c8a2f470abd6916d072f612a6fb14318e94fde8ae",
"sha256:3dfb74e19dedf61568b917c19b0fd3ee4580870027ca0b6054baf239855d1322",
"sha256:b182e707c23e4f19be73f9022a99d2d1ca7bf1ca8f280d40e4d1c10a6f51550e"
"sha256:ded7a220bb058e28ee3254fbba04ca90b679070424424761a53a043b93b612bf",
"sha256:d85d09ab4b4e921666ccc2db8532e857bf3476b7588e52c9c17741d7af14204f"
]
},
"history": [
{
"created": "2021-11-12T17:19:58.698676655Z",
"created_by": "/bin/sh -c #(nop) ADD file:5a707b9d6cb5fff532e4c2141bc35707593f21da5528c9e71ae2ddb6ba4a4eb6 in / "
"created": "2022-11-22T22:19:28.870801855Z",
"created_by": "/bin/sh -c #(nop) ADD file:587cae71969871d3c6456d844a8795df9b64b12c710c275295a1182b46f630e7 in / "
},
{
"created": "2021-11-12T17:19:58.948920855Z",
"created": "2022-11-22T22:19:29.008562326Z",
"created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]",
"empty_layer": true
},
{
"created": "2022-02-24T12:27:38.285594601Z",
"created_by": "RUN /bin/sh -c apk --update --no-cache add bash ca-certificates openssh-client \u0026\u0026 rm -rf /tmp/* /var/cache/apk/* # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-24T12:27:41.061874167Z",
"created_by": "COPY /opt/docker/ /usr/local/bin/ # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-24T12:27:41.174098947Z",
"created_by": "COPY /usr/bin/buildctl /usr/local/bin/buildctl # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-24T12:27:41.320343683Z",
"created_by": "COPY /usr/bin/buildkit* /usr/local/bin/ # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-24T12:27:41.447149933Z",
"created_by": "COPY /buildx /usr/libexec/docker/cli-plugins/docker-buildx # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-24T12:27:43.057722191Z",
"created_by": "COPY /opt/docker-compose /usr/libexec/docker/cli-plugins/docker-compose # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-24T12:27:43.145224134Z",
"created_by": "ADD https://raw.githubusercontent.com/moby/moby/master/README.md / # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-24T12:27:43.422212427Z",
"created_by": "ENV DOCKER_TLS_CERTDIR=/certs",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2022-02-24T12:27:43.422212427Z",
"created_by": "ENV DOCKER_CLI_EXPERIMENTAL=enabled",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2022-02-24T12:27:43.422212427Z",
"created_by": "RUN /bin/sh -c docker --version \u0026\u0026 buildkitd --version \u0026\u0026 buildctl --version \u0026\u0026 docker buildx version \u0026\u0026 docker compose version \u0026\u0026 mkdir /certs /certs/client \u0026\u0026 chmod 1777 /certs /certs/client # buildkit",
"created": "2022-12-01T11:46:47.713777178Z",
"created_by": "RUN /bin/sh -c apk add curl # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-24T12:27:43.514320155Z",
"created_by": "COPY rootfs/modprobe.sh /usr/local/bin/modprobe # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-24T12:27:43.627154558Z",
"created_by": "COPY rootfs/docker-entrypoint.sh /usr/local/bin/ # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-24T12:27:43.627154558Z",
"created_by": "ENTRYPOINT [\"docker-entrypoint.sh\"]",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2022-02-24T12:27:43.627154558Z",
"created_by": "CMD [\"sh\"]",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
}
]
},
"buildinfo": {
"frontend": "dockerfile.v0",
"attrs": {
"build-arg:bar": "foo",
"build-arg:foo": "bar",
"filename": "Dockerfile",
"source": "docker/dockerfile-upstream:master-labs"
},
"sources": [
{
"type": "docker-image",
"ref": "docker.io/docker/buildx-bin:0.6.1@sha256:a652ced4a4141977c7daaed0a074dcd9844a78d7d2615465b12f433ae6dd29f0",
"pin": "sha256:a652ced4a4141977c7daaed0a074dcd9844a78d7d2615465b12f433ae6dd29f0"
},
{
"type": "docker-image",
"ref": "docker.io/library/alpine:3.13",
"pin": "sha256:026f721af4cf2843e07bba648e158fb35ecc876d822130633cc49f707f0fc88c"
},
{
"type": "docker-image",
"ref": "docker.io/moby/buildkit:v0.9.0",
"pin": "sha256:8dc668e7f66db1c044aadbed306020743516a94848793e0f81f94a087ee78cab"
"Provenance": {
"SLSA": {
"builder": {
"id": ""
},
{
"type": "docker-image",
"ref": "docker.io/tonistiigi/xx@sha256:21a61be4744f6531cb5f33b0e6f40ede41fa3a1b8c82d5946178f80cc84bfc04",
"pin": "sha256:21a61be4744f6531cb5f33b0e6f40ede41fa3a1b8c82d5946178f80cc84bfc04"
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/docker/buildkit-syft-scanner@stable-1",
"digest": {
"sha256": "b45f1d207e16c3a3a5a10b254ad8ad358d01f7ea090d382b95c6b2ee2b3ef765"
}
},
{
"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"
}
},
{
"type": "http",
"ref": "https://raw.githubusercontent.com/moby/moby/master/README.md",
"pin": "sha256:419455202b0ef97e480d7f8199b26a721a417818bc0e2d106975f74323f25e6c"
"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": {
"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"
}
}
}
```
#### Multi-platform
Multi-platform images are supported for `.Image` and `.BuildInfo` fields. If
you want to pick up a specific platform, you can specify it using the `index`
Multi-platform images are supported for `.Image`, `.SLSA` and `.SBOM` fields.
If you want to pick up a specific platform, you can specify it using the `index`
go template function:
```console
@ -462,7 +524,7 @@ $ docker buildx imagetools inspect --format '{{json (index .Image "linux/s390x")
```
```json
{
"created": "2022-02-25T17:13:27.89891722Z",
"created": "2022-11-30T17:42:26.414957336Z",
"architecture": "s390x",
"os": "linux",
"config": {
@ -481,8 +543,8 @@ $ docker buildx imagetools inspect --format '{{json (index .Image "linux/s390x")
"diff_ids": [
"sha256:41048e32d0684349141cf05f629c5fc3c5915d1f3426b66dbb8953a540e01e1e",
"sha256:2651209b9208fff6c053bc3c17353cb07874e50f1a9bc96d6afd03aef63de76a",
"sha256:6741ed7e73039d853fa8902246a4c7e8bf9dd09652fd1b08251bc5f9e8876a7f",
"sha256:92ac046adeeb65c86ae3f0b458dee04ad4a462e417661c04d77642c66494f69b"
"sha256:88577322e65f094ce8ac27435880f1a8a9baadb569258026bb141770451bafcb",
"sha256:de8f9a790e4ed10ff1f1f8ea923c9da4f97246a7e200add2dc6650eba3f10a20"
]
},
"history": [
@ -501,23 +563,23 @@ $ docker buildx imagetools inspect --format '{{json (index .Image "linux/s390x")
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-24T00:34:00.924540012Z",
"created": "2022-08-25T00:39:25.652811078Z",
"created_by": "COPY examples/buildctl-daemonless/buildctl-daemonless.sh /usr/bin/ # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-25T17:13:27.89891722Z",
"created": "2022-11-30T17:42:26.414957336Z",
"created_by": "VOLUME [/var/lib/buildkit]",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
},
{
"created": "2022-02-25T17:13:27.89891722Z",
"created": "2022-11-30T17:42:26.414957336Z",
"created_by": "COPY / /usr/bin/ # buildkit",
"comment": "buildkit.dockerfile.v0"
},
{
"created": "2022-02-25T17:13:27.89891722Z",
"created": "2022-11-30T17:42:26.414957336Z",
"created_by": "ENTRYPOINT [\"buildkitd\"]",
"comment": "buildkit.dockerfile.v0",
"empty_layer": true
@ -541,24 +603,24 @@ $ docker buildx imagetools inspect --raw crazymax/loop | jq
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"digest": "sha256:7ace7d324e79b360b2db8b820d83081863d96d22e734cdf297a8e7fd83f6ceb3",
"size": 2298
"digest": "sha256:a98999183d2c7a8845f6d56496e51099ce6e4359ee7255504174b05430c4b78b",
"size": 2762
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"digest": "sha256:5843afab387455b37944e709ee8c78d7520df80f8d01cf7f861aae63beeddb6b",
"size": 2811478
"digest": "sha256:8663204ce13b2961da55026a2034abb9e5afaaccf6a9cfb44ad71406dcd07c7b",
"size": 2818370
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"digest": "sha256:726d3732a87e1c430d67e8969de6b222a889d45e045ebae1a008a37ba38f3b1f",
"size": 1776812
"digest": "sha256:f0868a92f8e1e5018ed4e60eb845ed4ff0e2229897f4105e5a4735c1d6fd874f",
"size": 1821402
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"digest": "sha256:5d7cf9b33148a8f220c84f27dd2cfae46aca019a3ea3fbf7274f6d6dbfae8f3b",
"size": 382855
"digest": "sha256:d010066dbdfcf7c12fca30cd4b567aa7218eb6762ab53169d043655b7a8d7f2e",
"size": 404457
}
]
}
@ -574,7 +636,7 @@ $ docker buildx imagetools inspect --raw moby/buildkit:master | jq
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:667d28c9fb33820ce686887a717a148e89fa77f9097f9352996bbcce99d352b1",
"digest": "sha256:f9f41c85124686c2afe330a985066748a91d7a5d505777fe274df804ab5e077e",
"size": 1158,
"platform": {
"architecture": "amd64",
@ -583,7 +645,7 @@ $ docker buildx imagetools inspect --raw moby/buildkit:master | jq
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:71789527b64ab3d7b3de01d364b449cd7f7a3da758218fbf73b9c9aae05a6775",
"digest": "sha256:82097c2be19c617aafb3c3e43c88548738d4b2bf3db5c36666283a918b390266",
"size": 1158,
"platform": {
"architecture": "arm",
@ -593,7 +655,7 @@ $ docker buildx imagetools inspect --raw moby/buildkit:master | jq
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:fb64667e1ce6ab0d05478f3a8402af07b27737598dcf9a510fb1d792b13a66be",
"digest": "sha256:b6b91e6c823d7220ded7d3b688e571ba800b13d91bbc904c1d8053593e3ee42c",
"size": 1158,
"platform": {
"architecture": "arm64",
@ -602,7 +664,7 @@ $ docker buildx imagetools inspect --raw moby/buildkit:master | jq
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:1c3ddf95a0788e23f72f25800c05abc4458946685e2b66788c3d978cde6da92b",
"digest": "sha256:797061bcc16778de048b96f769c018ec24da221088050bbe926ea3b8d51d77e8",
"size": 1158,
"platform": {
"architecture": "s390x",
@ -611,7 +673,7 @@ $ docker buildx imagetools inspect --raw moby/buildkit:master | jq
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:05bcde6d460a284e5bc88026cd070277e8380355de3126cbc8fe8a452708c6b1",
"digest": "sha256:b93d3a84d18c4d0b8c279e77343d854d9b5177df7ea55cf468d461aa2523364e",
"size": 1159,
"platform": {
"architecture": "ppc64le",
@ -620,7 +682,7 @@ $ docker buildx imagetools inspect --raw moby/buildkit:master | jq
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:c04c57765304ab84f4f9807fff3e11605c3a60e16435c734b02c723680f6bd6e",
"digest": "sha256:d5c950dd1b270d437c838187112a0cb44c9258248d7a3a8bcb42fae8f717dc01",
"size": 1158,
"platform": {
"architecture": "riscv64",

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

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

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

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

@ -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,21 +6,21 @@ 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.11
github.com/docker/cli v23.0.0-beta.1+incompatible
github.com/docker/cli-docs-tool v0.5.0
github.com/containerd/containerd v1.6.20
github.com/docker/cli v23.0.0-rc.1+incompatible
github.com/docker/cli-docs-tool v0.5.1
github.com/docker/distribution v2.8.1+incompatible
github.com/docker/docker v23.0.0-beta.1+incompatible
github.com/docker/docker v23.0.0-rc.1+incompatible
github.com/docker/go-units v0.5.0
github.com/gofrs/flock v0.8.1
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-rc1.0.20221213193744-862b22d7e7cf
github.com/moby/buildkit v0.11.7-0.20230519102302-348e79dfed17
github.com/moby/sys/mountinfo v0.6.2
github.com/morikuni/aec v1.0.0
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.3-0.20220303224323-02efb9a75ee1
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b
github.com/pelletier/go-toml v1.9.5
github.com/pkg/errors v0.9.1
github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002
@ -74,7 +74,7 @@ require (
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cloudflare/cfssl v0.0.0-20181213083726-b94e044bb51e // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/containerd/ttrpc v1.1.0 // indirect
github.com/containerd/ttrpc v1.1.1 // indirect
github.com/containerd/typeurl v1.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/distribution/distribution/v3 v3.0.0-20220725133111-4bf3547399eb // indirect
@ -123,7 +123,7 @@ require (
github.com/moby/term v0.0.0-20221120202655-abb19827d345 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/opencontainers/runc v1.1.3 // indirect
github.com/opencontainers/runc v1.1.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
@ -132,7 +132,7 @@ require (
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/spf13/viper v1.14.0 // indirect
github.com/theupdateframework/notary v0.6.1 // indirect
github.com/tonistiigi/fsutil v0.0.0-20221114235510-0127568185cf // indirect
github.com/tonistiigi/fsutil v0.0.0-20230105215944-fb433841cbfa // indirect
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect

@ -57,7 +57,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/hcsshim v0.9.5 h1:AbV+VPfTrIVffukazHcpxmz/sRiE6YaMDzHWR9BXZHo=
github.com/Microsoft/hcsshim v0.9.8 h1:lf7xxK2+Ikbj9sVf2QZsouGjRjEp2STj1yDHgoVtU5k=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
@ -140,16 +140,16 @@ 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.11 h1:uIn0uKrRhETIPyAb0lz6WY2xhYBObUOF1bBi5rqZ5x4=
github.com/containerd/containerd v1.6.11/go.mod h1:K4Bw7gjgh4TnkmQY+py/PYQGp4e7xgnHAeg87VeWb3A=
github.com/containerd/containerd v1.6.20 h1:+itjwpdqXpzHB/QAiWc/BZCjjVfcNgw69w/oIeF4Oy0=
github.com/containerd/containerd v1.6.20/go.mod h1:apei1/i5Ux2FzrK6+DM/suEsGuK/MeVOfy8tR2q7Wnw=
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=
github.com/containerd/nydus-snapshotter v0.3.1 h1:b8WahTrPkt3XsabjG2o/leN4fw3HWZYr+qxo/Z8Mfzk=
github.com/containerd/stargz-snapshotter v0.13.0 h1:3zr1/IkW1aEo6cMYTQeZ4L2jSuCN+F4kgGfjnuowe4U=
github.com/containerd/stargz-snapshotter/estargz v0.13.0 h1:fD7AwuVV+B40p0d9qVkH/Au1qhp8hn/HWJHIYjpEcfw=
github.com/containerd/ttrpc v1.1.0 h1:GbtyLRxb0gOLR0TYQWt3O6B0NvT8tMdorEHqIQo/lWI=
github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ=
github.com/containerd/ttrpc v1.1.1 h1:NoRHS/z8UiHhpY1w0xcOqoJDGf2DHyzXrF0H4l5AE8c=
github.com/containerd/ttrpc v1.1.1/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ=
github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY=
github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
@ -163,14 +163,14 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/distribution/distribution/v3 v3.0.0-20220725133111-4bf3547399eb h1:oCCuuU3kMO3sjZH/p7LamvQNW9SWoT4yQuMGcdSxGAE=
github.com/distribution/distribution/v3 v3.0.0-20220725133111-4bf3547399eb/go.mod h1:28YO/VJk9/64+sTGNuYaBjWxrXTPrj0C0XmgTIOjxX4=
github.com/docker/cli v23.0.0-beta.1+incompatible h1:K9CMaN5nHB1eu2f02PURnJhlPhWuFl0s9mL3kildAtE=
github.com/docker/cli v23.0.0-beta.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 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.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-beta.1+incompatible h1:0Xv+AFPWxTbmohdLK57pYRPmefCKthtfRF/qQwXHolg=
github.com/docker/docker v23.0.0-beta.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v23.0.0-rc.1+incompatible h1:Dmn88McWuHc7BSNN1s6RtfhMmt6ZPQAYUEf7FhqpiQI=
github.com/docker/docker v23.0.0-rc.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
@ -345,7 +345,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
github.com/in-toto/in-toto-golang v0.3.4-0.20220709202702-fa494aaa0add h1:DAh7mHiRT7wc6kKepYdCpH16ElPciMPQWJaJ7H3l/ng=
github.com/in-toto/in-toto-golang v0.5.0 h1:hb8bgwr0M2hGdDsLjkJ3ZqJ8JFLL/tgYdAxF/XEFBbY=
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jinzhu/gorm v1.9.2 h1:lCvgEaqe/HVE+tjAR2mt4HbbHAZsQOv3XAZiEZV37iw=
@ -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-rc1.0.20221213193744-862b22d7e7cf h1:X4p2o1QeaKAJ8prPctFx98UrokFHsUgbiC0lDUObpOk=
github.com/moby/buildkit v0.11.0-rc1.0.20221213193744-862b22d7e7cf/go.mod h1:f3jvilDvcG14z+gzPpA2lcWRwIRyFiNTo5bMwHiYDk0=
github.com/moby/buildkit v0.11.7-0.20230519102302-348e79dfed17 h1:asvsqGToDMMsf5LOXiZxjKeHokXLF2FdYHzQVKympL8=
github.com/moby/buildkit v0.11.7-0.20230519102302-348e79dfed17/go.mod h1:GCqKfHhz+pddzfgaR7WmHVEE3nKKZMMDPpK8mh3ZLv4=
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=
@ -443,10 +443,10 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.3-0.20220303224323-02efb9a75ee1 h1:9iFHD5Kt9hkOfeawBNiEeEaV7bmC4/Z5wJp8E9BptMs=
github.com/opencontainers/image-spec v1.0.3-0.20220303224323-02efb9a75ee1/go.mod h1:K/JAU0m27RFhDRX4PcFdIKntROP6y5Ed6O91aZYDQfs=
github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w=
github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8=
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 h1:3snG66yBm59tKhhSPQrQ/0bCrv1LQbKt40LnUPiUxdc=
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
@ -499,7 +499,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
@ -517,6 +516,7 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spdx/tools-golang v0.3.1-0.20230104082527-d6f58551be3f h1:9B623Cfs+mclYK6dsae7gLSwuIBHvlgmEup87qpqsAQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
@ -547,8 +547,8 @@ github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/theupdateframework/notary v0.6.1 h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0=
github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY=
github.com/tonistiigi/fsutil v0.0.0-20221114235510-0127568185cf h1:2n2v98sRhXEG0Kh7+EvctaNIyOim36Ekp4pGDzbuvO8=
github.com/tonistiigi/fsutil v0.0.0-20221114235510-0127568185cf/go.mod h1:AvLEd1LEIl64G2Jpgwo7aVV5lGH0ePcKl0ygGIHNYl8=
github.com/tonistiigi/fsutil v0.0.0-20230105215944-fb433841cbfa h1:XOFp/3aBXlqmOFAg3r6e0qQjPnK5I970LilqX+Is1W8=
github.com/tonistiigi/fsutil v0.0.0-20230105215944-fb433841cbfa/go.mod h1:AvLEd1LEIl64G2Jpgwo7aVV5lGH0ePcKl0ygGIHNYl8=
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0=
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk=
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f h1:DLpt6B5oaaS8jyXHa9VA4rrZloBVPVXeCtrOsrFauxc=

@ -93,6 +93,7 @@ func GetNodeGroup(txn *store.Txn, dockerCli command.Cli, name string) (*store.No
Endpoint: name,
},
},
DockerContext: true,
}
if ng.LastActivity, err = txn.GetLastActivity(ng); err != nil {
return nil, err

@ -3,6 +3,8 @@ package gitutil
import (
"bytes"
"context"
"net/url"
"os"
"os/exec"
"strings"
@ -67,15 +69,23 @@ 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 stripCredentials(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 stripCredentials(ru), nil
}
return "", errors.New("no remote URL found for either origin or upstream")
}
func (c *Git) FullCommit() (string, error) {
return c.clean(c.run("show", "--format=%H", "HEAD", "--quiet"))
return c.clean(c.run("show", "--format=%H", "HEAD", "--quiet", "--"))
}
func (c *Git) ShortCommit() (string, error) {
return c.clean(c.run("show", "--format=%h", "HEAD", "--quiet"))
return c.clean(c.run("show", "--format=%h", "HEAD", "--quiet", "--"))
}
func (c *Git) Tag() (string, error) {
@ -108,6 +118,9 @@ func (c *Git) run(args ...string) (string, error) {
cmd.Dir = c.wd
}
// Override the locale to ensure consistent output
cmd.Env = append(os.Environ(), "LC_ALL=C")
stdout := bytes.Buffer{}
stderr := bytes.Buffer{}
cmd.Stdout = &stdout
@ -126,3 +139,25 @@ func (c *Git) clean(out string, err error) (string, error) {
}
return out, err
}
func IsUnknownRevision(err error) bool {
if err == nil {
return false
}
// https://github.com/git/git/blob/a6a323b31e2bcbac2518bddec71ea7ad558870eb/setup.c#L204
errMsg := strings.ToLower(err.Error())
return strings.Contains(errMsg, "unknown revision or path not in the working tree") || strings.Contains(errMsg, "bad revision")
}
// stripCredentials takes a URL and strips username and password from it.
// e.g. "https://user:password@host.tld/path.git" will be changed to
// "https://host.tld/path.git".
// TODO: remove this function once fix from BuildKit is vendored here
func stripCredentials(s string) string {
ru, err := url.Parse(s)
if err != nil {
return s // string is not a URL, just return it
}
ru.User = nil
return ru.String()
}

@ -46,6 +46,32 @@ func TestGitShortCommit(t *testing.T) {
require.Equal(t, 7, len(out))
}
func TestGitFullCommitErr(t *testing.T) {
Mktmp(t)
c, err := New()
require.NoError(t, err)
GitInit(c, t)
_, err = c.FullCommit()
require.Error(t, err)
require.True(t, IsUnknownRevision(err))
require.False(t, IsAmbiguousArgument(err))
}
func TestGitShortCommitErr(t *testing.T) {
Mktmp(t)
c, err := New()
require.NoError(t, err)
GitInit(c, t)
_, err = c.ShortCommit()
require.Error(t, err)
require.True(t, IsUnknownRevision(err))
require.False(t, IsAmbiguousArgument(err))
}
func TestGitTagsPointsAt(t *testing.T) {
Mktmp(t)
c, err := New()
@ -77,3 +103,131 @@ 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)
})
}
}
func TestStripCredentials(t *testing.T) {
cases := []struct {
name string
url string
want string
}{
{
name: "non-blank Password",
url: "https://user:password@host.tld/this:that",
want: "https://host.tld/this:that",
},
{
name: "blank Password",
url: "https://user@host.tld/this:that",
want: "https://host.tld/this:that",
},
{
name: "blank Username",
url: "https://:password@host.tld/this:that",
want: "https://host.tld/this:that",
},
{
name: "blank Username, blank Password",
url: "https://host.tld/this:that",
want: "https://host.tld/this:that",
},
{
name: "invalid URL",
url: "1https://foo.com",
want: "1https://foo.com",
},
}
for _, tt := range cases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
if g, w := stripCredentials(tt.url), tt.want; g != w {
t.Fatalf("got: %q\nwant: %q", g, w)
}
})
}
}

@ -2,6 +2,7 @@ package gitutil
import (
"os"
"strings"
"testing"
"github.com/stretchr/testify/require"
@ -44,9 +45,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)
}
@ -73,3 +74,11 @@ func fakeGit(c *Git, args ...string) (string, error) {
allArgs = append(allArgs, args...)
return c.clean(c.run(allArgs...))
}
func IsAmbiguousArgument(err error) bool {
if err == nil {
return false
}
errMsg := strings.ToLower(err.Error())
return strings.Contains(errMsg, "use '--' to separate paths from revisions")
}

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

@ -0,0 +1,417 @@
package imagetools
// TODO: replace with go-imageinspect library when public
import (
"context"
"encoding/json"
"sort"
"strings"
"sync"
"github.com/containerd/containerd/content"
"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"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
)
var (
annotationReferences = []string{
"com.docker.reference.digest",
"vnd.docker.reference.digest", // TODO: deprecate/remove after migration to new annotation
}
)
type contentCache interface {
content.Provider
content.Ingester
}
type loader struct {
resolver remotes.Resolver
cache contentCache
}
type manifest struct {
desc ocispec.Descriptor
manifest ocispec.Manifest
}
type index struct {
desc ocispec.Descriptor
index ocispec.Index
}
type asset struct {
config *ocispec.Image
sbom *sbomStub
provenance *provenanceStub
deferredSbom func() (*sbomStub, error)
deferredProvenance func() (*provenanceStub, error)
}
type result struct {
mu sync.Mutex
indexes map[digest.Digest]index
manifests map[digest.Digest]manifest
images map[string]digest.Digest
refs map[digest.Digest][]digest.Digest
platforms []string
assets map[string]asset
}
func newLoader(resolver remotes.Resolver) *loader {
return &loader{
resolver: resolver,
cache: contentutil.NewBuffer(),
}
}
func (l *loader) Load(ctx context.Context, ref string) (*result, error) {
named, err := parseRef(ref)
if err != nil {
return nil, err
}
_, desc, err := l.resolver.Resolve(ctx, named.String())
if err != nil {
return nil, err
}
canonical, err := reference.WithDigest(named, desc.Digest)
if err != nil {
return nil, err
}
fetcher, err := l.resolver.Fetcher(ctx, canonical.String())
if err != nil {
return nil, err
}
r := &result{
indexes: make(map[digest.Digest]index),
manifests: make(map[digest.Digest]manifest),
images: make(map[string]digest.Digest),
refs: make(map[digest.Digest][]digest.Digest),
assets: make(map[string]asset),
}
if err := l.fetch(ctx, fetcher, desc, r); err != nil {
return nil, err
}
for platform, dgst := range r.images {
r.platforms = append(r.platforms, platform)
mfst, ok := r.manifests[dgst]
if !ok {
return nil, errors.Errorf("image %s not found", platform)
}
var a asset
annotations := make(map[string]string, len(mfst.manifest.Annotations)+len(mfst.desc.Annotations))
for k, v := range mfst.desc.Annotations {
annotations[k] = v
}
for k, v := range mfst.manifest.Annotations {
annotations[k] = v
}
if err := l.scanConfig(ctx, fetcher, mfst.manifest.Config, &a); err != nil {
return nil, err
}
refs, ok := r.refs[dgst]
if ok {
if err := l.scanSBOM(ctx, fetcher, r, refs, &a); err != nil {
return nil, err
}
}
if err := l.scanProvenance(ctx, fetcher, r, refs, &a); err != nil {
return nil, err
}
r.assets[platform] = a
}
sort.Strings(r.platforms)
return r, nil
}
func (l *loader) fetch(ctx context.Context, fetcher remotes.Fetcher, desc ocispec.Descriptor, r *result) error {
_, err := remotes.FetchHandler(l.cache, fetcher)(ctx, desc)
if err != nil {
return err
}
switch desc.MediaType {
case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
var mfst ocispec.Manifest
dt, err := content.ReadBlob(ctx, l.cache, desc)
if err != nil {
return err
}
if err := json.Unmarshal(dt, &mfst); err != nil {
return err
}
r.mu.Lock()
r.manifests[desc.Digest] = manifest{
desc: desc,
manifest: mfst,
}
r.mu.Unlock()
found := false
for _, annotationReference := range annotationReferences {
ref, ok := desc.Annotations[annotationReference]
if !ok {
continue
}
refdgst, err := digest.Parse(ref)
if err != nil {
return err
}
r.mu.Lock()
r.refs[refdgst] = append(r.refs[refdgst], desc.Digest)
r.mu.Unlock()
found = true
break
}
if !found {
p := desc.Platform
if p == nil {
p, err = l.readPlatformFromConfig(ctx, fetcher, mfst.Config)
if err != nil {
return err
}
}
r.mu.Lock()
r.images[platforms.Format(platforms.Normalize(*p))] = desc.Digest
r.mu.Unlock()
}
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
var idx ocispec.Index
dt, err := content.ReadBlob(ctx, l.cache, desc)
if err != nil {
return err
}
if err := json.Unmarshal(dt, &idx); err != nil {
return err
}
r.mu.Lock()
r.indexes[desc.Digest] = index{
desc: desc,
index: idx,
}
r.mu.Unlock()
eg, ctx := errgroup.WithContext(ctx)
for _, d := range idx.Manifests {
d := d
eg.Go(func() error {
return l.fetch(ctx, fetcher, d, r)
})
}
if err := eg.Wait(); err != nil {
return err
}
default:
}
return nil
}
func (l *loader) readPlatformFromConfig(ctx context.Context, fetcher remotes.Fetcher, desc ocispec.Descriptor) (*ocispec.Platform, error) {
_, err := remotes.FetchHandler(l.cache, fetcher)(ctx, desc)
if err != nil {
return nil, err
}
dt, err := content.ReadBlob(ctx, l.cache, desc)
if err != nil {
return nil, err
}
var config ocispec.Image
if err := json.Unmarshal(dt, &config); err != nil {
return nil, err
}
return &ocispec.Platform{
OS: config.OS,
Architecture: config.Architecture,
Variant: config.Variant,
}, nil
}
func (l *loader) scanConfig(ctx context.Context, fetcher remotes.Fetcher, desc ocispec.Descriptor, as *asset) error {
_, err := remotes.FetchHandler(l.cache, fetcher)(ctx, desc)
if err != nil {
return err
}
dt, err := content.ReadBlob(ctx, l.cache, desc)
if err != nil {
return err
}
return json.Unmarshal(dt, &as.config)
}
type sbomStub struct {
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")
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 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")
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
}
func (r *result) Configs() map[string]*ocispec.Image {
if len(r.assets) == 0 {
return nil
}
res := make(map[string]*ocispec.Image)
for p, a := range r.assets {
if a.config == nil {
continue
}
res[p] = a.config
}
return res
}
func (r *result) Provenance() (map[string]provenanceStub, error) {
if len(r.assets) == 0 {
return nil, nil
}
res := make(map[string]provenanceStub)
for p, a := range r.assets {
if a.deferredProvenance == nil {
continue
}
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, nil
}
func (r *result) SBOM() (map[string]sbomStub, error) {
if len(r.assets) == 0 {
return nil, nil
}
res := make(map[string]sbomStub)
for p, a := range r.assets {
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, nil
}

@ -6,20 +6,15 @@ import (
"fmt"
"io"
"os"
"sort"
"strings"
"sync"
"text/tabwriter"
"text/template"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/platforms"
"github.com/docker/distribution/reference"
binfotypes "github.com/moby/buildkit/util/buildinfo/types"
"github.com/moby/buildkit/util/imageutil"
"github.com/opencontainers/go-digest"
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
"golang.org/x/sync/errgroup"
)
const defaultPfx = " "
@ -31,11 +26,10 @@ type Printer struct {
name string
format string
raw []byte
ref reference.Named
manifest ocispecs.Descriptor
index ocispecs.Index
platforms []ocispecs.Platform
raw []byte
ref reference.Named
manifest ocispecs.Descriptor
index ocispecs.Index
}
func NewPrinter(ctx context.Context, opt Opt, name string, format string) (*Printer, error) {
@ -46,38 +40,25 @@ func NewPrinter(ctx context.Context, opt Opt, name string, format string) (*Prin
return nil, err
}
dt, manifest, err := resolver.Get(ctx, name)
dt, mfst, err := resolver.Get(ctx, ref.String())
if err != nil {
return nil, err
}
var index ocispecs.Index
if err = json.Unmarshal(dt, &index); err != nil {
var idx ocispecs.Index
if err = json.Unmarshal(dt, &idx); err != nil {
return nil, err
}
var pforms []ocispecs.Platform
switch manifest.MediaType {
case images.MediaTypeDockerSchema2ManifestList, ocispecs.MediaTypeImageIndex:
for _, m := range index.Manifests {
if m.Platform != nil {
pforms = append(pforms, *m.Platform)
}
}
default:
pforms = append(pforms, platforms.DefaultSpec())
}
return &Printer{
ctx: ctx,
resolver: resolver,
name: name,
format: format,
raw: dt,
ref: ref,
manifest: manifest,
index: index,
platforms: pforms,
ctx: ctx,
resolver: resolver,
name: name,
format: format,
raw: dt,
ref: ref,
manifest: mfst,
index: idx,
}, nil
}
@ -102,6 +83,11 @@ func (p *Printer) Print(raw bool, out io.Writer) error {
return nil
}
res, err := newLoader(p.resolver.resolver()).Load(p.ctx, p.name)
if err != nil {
return err
}
tpl, err := template.New("").Funcs(template.FuncMap{
"json": func(v interface{}) string {
b, _ := json.MarshalIndent(v, "", " ")
@ -112,46 +98,15 @@ func (p *Printer) Print(raw bool, out io.Writer) error {
return err
}
imageconfigs := make(map[string]*ocispecs.Image)
imageconfigsMutex := sync.Mutex{}
buildinfos := make(map[string]*binfotypes.BuildInfo)
buildinfosMutex := sync.Mutex{}
eg, _ := errgroup.WithContext(p.ctx)
for _, platform := range p.platforms {
func(platform ocispecs.Platform) {
eg.Go(func() error {
img, dtic, err := p.getImageConfig(&platform)
if err != nil {
return err
} else if img != nil {
imageconfigsMutex.Lock()
imageconfigs[platforms.Format(platform)] = img
imageconfigsMutex.Unlock()
}
if bi, err := imageutil.BuildInfo(dtic); err != nil {
return err
} else if bi != nil {
buildinfosMutex.Lock()
buildinfos[platforms.Format(platform)] = bi
buildinfosMutex.Unlock()
}
return nil
})
}(platform)
}
if err := eg.Wait(); err != nil {
return err
}
imageconfigs := res.Configs()
format := tpl.Root.String()
var manifest interface{}
var mfst interface{}
switch p.manifest.MediaType {
case images.MediaTypeDockerSchema2Manifest, ocispecs.MediaTypeImageManifest:
manifest = p.manifest
mfst = p.manifest
case images.MediaTypeDockerSchema2ManifestList, ocispecs.MediaTypeImageIndex:
manifest = struct {
mfst = struct {
SchemaVersion int `json:"schemaVersion"`
MediaType string `json:"mediaType,omitempty"`
Digest digest.Digest `json:"digest"`
@ -170,10 +125,11 @@ func (p *Printer) Print(raw bool, out io.Writer) error {
switch {
// TODO: print formatted config
case strings.HasPrefix(format, "{{.Manifest"), strings.HasPrefix(format, "{{.BuildInfo"):
case strings.HasPrefix(format, "{{.Manifest"):
w := tabwriter.NewWriter(out, 0, 0, 1, ' ', 0)
_, _ = fmt.Fprintf(w, "Name:\t%s\n", p.ref.String())
if strings.HasPrefix(format, "{{.Manifest") {
switch {
case strings.HasPrefix(format, "{{.Manifest"):
_, _ = fmt.Fprintf(w, "MediaType:\t%s\n", p.manifest.MediaType)
_, _ = fmt.Fprintf(w, "Digest:\t%s\n", p.manifest.Digest)
_ = w.Flush()
@ -181,42 +137,25 @@ func (p *Printer) Print(raw bool, out io.Writer) error {
case images.MediaTypeDockerSchema2ManifestList, ocispecs.MediaTypeImageIndex:
_ = p.printManifestList(out)
}
} else if strings.HasPrefix(format, "{{.BuildInfo") {
_ = w.Flush()
_ = p.printBuildInfos(buildinfos, out)
}
default:
if len(p.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"`
BuildInfo map[string]*binfotypes.BuildInfo `json:"buildinfo,omitempty"`
}{
Name: p.name,
Manifest: manifest,
Image: imageconfigs,
BuildInfo: buildinfos,
if len(res.platforms) > 1 {
return tpl.Execute(out, tplInputs{
Name: p.name,
Manifest: mfst,
Image: imageconfigs,
result: res,
})
}
var ic *ocispecs.Image
for _, v := range imageconfigs {
ic = v
}
var bi *binfotypes.BuildInfo
for _, v := range buildinfos {
bi = v
}
return tpl.Execute(out, struct {
Name string `json:"name,omitempty"`
Manifest interface{} `json:"manifest,omitempty"`
Image *ocispecs.Image `json:"image,omitempty"`
BuildInfo *binfotypes.BuildInfo `json:"buildinfo,omitempty"`
}{
Name: p.name,
Manifest: manifest,
Image: ic,
BuildInfo: bi,
return tpl.Execute(out, tplInput{
Name: p.name,
Manifest: mfst,
Image: ic,
result: res,
})
}
@ -252,6 +191,7 @@ func (p *Printer) printManifestList(out io.Writer) error {
_, _ = fmt.Fprintf(w, "%sURLs:\t%s\n", defaultPfx, strings.Join(m.URLs, ", "))
}
if len(m.Annotations) > 0 {
_, _ = fmt.Fprintf(w, "%sAnnotations:\t\n", defaultPfx)
_ = w.Flush()
w2 := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
for k, v := range m.Annotations {
@ -264,82 +204,48 @@ func (p *Printer) printManifestList(out io.Writer) error {
return w.Flush()
}
func (p *Printer) printBuildInfos(bis map[string]*binfotypes.BuildInfo, out io.Writer) error {
if len(bis) == 0 {
return nil
} else if len(bis) == 1 {
for _, bi := range bis {
return p.printBuildInfo(bi, "", out)
}
}
var pkeys []string
for _, pform := range p.platforms {
pkeys = append(pkeys, platforms.Format(pform))
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
}
sort.Strings(pkeys)
for _, platform := range pkeys {
bi := bis[platform]
w := tabwriter.NewWriter(out, 0, 0, 1, ' ', 0)
_, _ = fmt.Fprintf(w, "\t\nPlatform:\t%s\t\n", platform)
_ = w.Flush()
if err := p.printBuildInfo(bi, "", out); err != nil {
return err
}
for _, v := range sbom {
return v, nil
}
return nil
return sbomStub{}, nil
}
func (p *Printer) printBuildInfo(bi *binfotypes.BuildInfo, pfx string, out io.Writer) error {
w := tabwriter.NewWriter(out, 0, 0, 1, ' ', 0)
_, _ = fmt.Fprintf(w, "%sFrontend:\t%s\n", pfx, bi.Frontend)
if len(bi.Attrs) > 0 {
_, _ = fmt.Fprintf(w, "%sAttrs:\t\n", pfx)
_ = w.Flush()
for k, v := range bi.Attrs {
_, _ = fmt.Fprintf(w, "%s%s:\t%s\n", pfx+defaultPfx, k, *v)
}
func (inp tplInput) Provenance() (provenanceStub, error) {
provenance, err := inp.result.Provenance()
if err != nil {
return provenanceStub{}, nil
}
if len(bi.Sources) > 0 {
_, _ = fmt.Fprintf(w, "%sSources:\t\n", pfx)
_ = w.Flush()
for i, v := range bi.Sources {
if i != 0 {
_, _ = fmt.Fprintf(w, "\t\n")
}
_, _ = fmt.Fprintf(w, "%sType:\t%s\n", pfx+defaultPfx, v.Type)
_, _ = fmt.Fprintf(w, "%sRef:\t%s\n", pfx+defaultPfx, v.Ref)
_, _ = fmt.Fprintf(w, "%sPin:\t%s\n", pfx+defaultPfx, v.Pin)
}
for _, v := range provenance {
return v, nil
}
return provenanceStub{}, nil
}
if len(bi.Deps) > 0 {
_, _ = fmt.Fprintf(w, "%sDeps:\t\n", pfx)
_ = w.Flush()
firstPass := true
for k, v := range bi.Deps {
if !firstPass {
_, _ = fmt.Fprintf(w, "\t\n")
}
_, _ = fmt.Fprintf(w, "%sName:\t%s\n", pfx+defaultPfx, k)
_ = w.Flush()
_ = p.printBuildInfo(&v, pfx+defaultPfx, out)
firstPass = false
}
}
type tplInputs struct {
Name string `json:"name,omitempty"`
Manifest interface{} `json:"manifest,omitempty"`
Image map[string]*ocispecs.Image `json:"image,omitempty"`
return w.Flush()
result *result
}
func (p *Printer) getImageConfig(platform *ocispecs.Platform) (*ocispecs.Image, []byte, error) {
_, dtic, err := p.resolver.ImageConfig(p.ctx, p.name, platform)
if err != nil {
return nil, nil, err
}
var img *ocispecs.Image
if err = json.Unmarshal(dtic, &img); err != nil {
return nil, nil, err
}
return img, dtic, nil
func (inp tplInputs) SBOM() (map[string]sbomStub, error) {
return inp.result.SBOM()
}
func (inp tplInputs) Provenance() (map[string]provenanceStub, error) {
return inp.result.Provenance()
}

@ -299,7 +299,7 @@ type ListContentRequest struct {
// filters. Expanded, containers that match the following will be
// returned:
//
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
//
// If filters is zero-length or nil, all items will be returned.
Filters []string `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"`

@ -141,7 +141,7 @@ message ListContentRequest {
// filters. Expanded, containers that match the following will be
// returned:
//
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
// filters[0] or filters[1] or ... or filters[n-1] or filters[n]
//
// If filters is zero-length or nil, all items will be returned.
repeated string filters = 1;

@ -34,7 +34,7 @@ import (
"github.com/containerd/containerd/log"
"github.com/sirupsen/logrus"
digest "github.com/opencontainers/go-digest"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@ -505,6 +505,7 @@ func (s *store) resumeStatus(ref string, total int64, digester digest.Digester)
return status, fmt.Errorf("provided total differs from status: %v != %v", total, status.Total)
}
//nolint:dupword
// TODO(stevvooe): slow slow slow!!, send to goroutine or use resumable hashes
fp, err := os.Open(data)
if err != nil {

@ -46,10 +46,14 @@ type matchComparer struct {
// Match matches platform with the same windows major, minor
// and build version.
func (m matchComparer) Match(p imagespec.Platform) bool {
if m.defaults.Match(p) {
// TODO(windows): Figure out whether OSVersion is deprecated.
return strings.HasPrefix(p.OSVersion, m.osVersionPrefix)
func (m matchComparer) Match(p specs.Platform) bool {
match := m.defaults.Match(p)
if match && p.OS == "windows" {
if strings.HasPrefix(p.OSVersion, m.osVersionPrefix) {
return true
}
return p.OSVersion == ""
}
return false
}

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

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

@ -24,6 +24,7 @@ import (
"net"
"sync"
"sync/atomic"
"syscall"
"time"
"github.com/sirupsen/logrus"
@ -467,14 +468,12 @@ func (c *serverConn) run(sctx context.Context) {
// branch. Basically, it means that we are no longer receiving
// requests due to a terminal error.
recvErr = nil // connection is now "closing"
if err == io.EOF || err == io.ErrUnexpectedEOF {
if err == io.EOF || err == io.ErrUnexpectedEOF || errors.Is(err, syscall.ECONNRESET) {
// The client went away and we should stop processing
// requests, so that the client connection is closed
return
}
if err != nil {
logrus.WithError(err).Error("error receiving message")
}
logrus.WithError(err).Error("error receiving message")
case <-shutdown:
return
}

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

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

@ -37,7 +37,7 @@ func New(ctx context.Context, cmd string, args ...string) (net.Conn, error) {
c commandConn
err error
)
c.cmd = exec.CommandContext(ctx, cmd, args...)
c.cmd = exec.Command(cmd, args...)
// we assume that args never contains sensitive information
logrus.Debugf("commandconn: starting %s with %v", cmd, args)
c.cmd.Env = os.Environ()

@ -71,8 +71,6 @@ func (o *ClientOptions) InstallFlags(flags *pflag.FlagSet) {
flags.BoolVar(&o.TLS, "tls", dockerTLS, "Use TLS; implied by --tlsverify")
flags.BoolVar(&o.TLSVerify, FlagTLSVerify, dockerTLSVerify, "Use TLS and verify the remote")
// TODO use flag flags.String("identity"}, "i", "", "Path to libtrust key file")
o.TLSOptions = &tlsconfig.Options{
CAFile: filepath.Join(dockerCertPath, DefaultCaFile),
CertFile: filepath.Join(dockerCertPath, DefaultCertFile),

@ -2,14 +2,12 @@ package errdefs // import "github.com/docker/docker/errdefs"
import (
"net/http"
"github.com/sirupsen/logrus"
)
// FromStatusCode creates an errdef error, based on the provided HTTP status-code
func FromStatusCode(err error, statusCode int) error {
if err == nil {
return err
return nil
}
switch statusCode {
case http.StatusNotFound:
@ -33,11 +31,6 @@ func FromStatusCode(err error, statusCode int) error {
err = System(err)
}
default:
logrus.WithError(err).WithFields(logrus.Fields{
"module": "api",
"status_code": statusCode,
}).Debug("FIXME: Got an status-code for which error does not match any expected type!!!")
switch {
case statusCode >= 200 && statusCode < 400:
// it's a client error

@ -13,6 +13,7 @@ import (
_ "github.com/golang/protobuf/ptypes/timestamp"
types "github.com/moby/buildkit/api/types"
pb "github.com/moby/buildkit/solver/pb"
pb1 "github.com/moby/buildkit/sourcepolicy/pb"
github_com_moby_buildkit_util_entitlements "github.com/moby/buildkit/util/entitlements"
github_com_opencontainers_go_digest "github.com/opencontainers/go-digest"
grpc "google.golang.org/grpc"
@ -377,6 +378,7 @@ type SolveRequest struct {
Entitlements []github_com_moby_buildkit_util_entitlements.Entitlement `protobuf:"bytes,9,rep,name=Entitlements,proto3,customtype=github.com/moby/buildkit/util/entitlements.Entitlement" json:"Entitlements,omitempty"`
FrontendInputs map[string]*pb.Definition `protobuf:"bytes,10,rep,name=FrontendInputs,proto3" json:"FrontendInputs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Internal bool `protobuf:"varint,11,opt,name=Internal,proto3" json:"Internal,omitempty"`
SourcePolicy *pb1.Policy `protobuf:"bytes,12,opt,name=SourcePolicy,proto3" json:"SourcePolicy,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -485,6 +487,13 @@ func (m *SolveRequest) GetInternal() bool {
return false
}
func (m *SolveRequest) GetSourcePolicy() *pb1.Policy {
if m != nil {
return m.SourcePolicy
}
return nil
}
type CacheOptions struct {
// ExportRefDeprecated is deprecated in favor or the new Exports since BuildKit v0.4.0.
// When ExportRefDeprecated is set, the solver appends
@ -1496,6 +1505,9 @@ type BuildHistoryRecord struct {
Generation int32 `protobuf:"varint,12,opt,name=Generation,proto3" json:"Generation,omitempty"`
Trace *Descriptor `protobuf:"bytes,13,opt,name=trace,proto3" json:"trace,omitempty"`
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:"-"`
@ -1632,6 +1644,27 @@ func (m *BuildHistoryRecord) GetPinned() bool {
return false
}
func (m *BuildHistoryRecord) GetNumCachedSteps() int32 {
if m != nil {
return m.NumCachedSteps
}
return 0
}
func (m *BuildHistoryRecord) GetNumTotalSteps() int32 {
if m != nil {
return m.NumTotalSteps
}
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"`
@ -1953,143 +1986,149 @@ func init() {
func init() { proto.RegisterFile("control.proto", fileDescriptor_0c5120591600887d) }
var fileDescriptor_0c5120591600887d = []byte{
// 2173 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x39, 0xcd, 0x6f, 0x1b, 0xc7,
0xf5, 0x5e, 0x52, 0xfc, 0x7a, 0xa4, 0x14, 0x79, 0xec, 0x18, 0xfb, 0xdb, 0x9f, 0x23, 0xc9, 0x1b,
0x1b, 0x15, 0x5c, 0x7b, 0xa9, 0xb0, 0x49, 0xed, 0xc8, 0xad, 0x6b, 0x51, 0x64, 0x63, 0xb9, 0x36,
0xec, 0x8c, 0xe4, 0x18, 0x08, 0xe0, 0x16, 0x2b, 0x72, 0x44, 0x2f, 0xb4, 0xdc, 0xdd, 0xce, 0x0c,
0x15, 0x2b, 0x7f, 0x40, 0x81, 0x5c, 0x8a, 0x5e, 0x8a, 0x5e, 0x7a, 0xef, 0xa9, 0xe7, 0x1e, 0x7b,
0x2a, 0xe0, 0x63, 0xcf, 0x39, 0xb8, 0x85, 0xff, 0x80, 0xa2, 0xc7, 0x5e, 0x0a, 0x14, 0xf3, 0xb1,
0xe4, 0x90, 0x5c, 0x4a, 0x94, 0xed, 0x13, 0xe7, 0xcd, 0xbc, 0xf7, 0xf6, 0x7d, 0xcf, 0x7b, 0x43,
0x58, 0xec, 0xc4, 0x11, 0xa7, 0x71, 0xe8, 0x25, 0x34, 0xe6, 0x31, 0x5a, 0xee, 0xc7, 0xfb, 0xc7,
0xde, 0xfe, 0x20, 0x08, 0xbb, 0x87, 0x01, 0xf7, 0x8e, 0x3e, 0x71, 0x6e, 0xf6, 0x02, 0xfe, 0x62,
0xb0, 0xef, 0x75, 0xe2, 0x7e, 0xbd, 0x17, 0xf7, 0xe2, 0xba, 0x44, 0xdc, 0x1f, 0x1c, 0x48, 0x48,
0x02, 0x72, 0xa5, 0x18, 0x38, 0xab, 0xbd, 0x38, 0xee, 0x85, 0x64, 0x84, 0xc5, 0x83, 0x3e, 0x61,
0xdc, 0xef, 0x27, 0x1a, 0xe1, 0x86, 0xc1, 0x4f, 0x7c, 0xac, 0x9e, 0x7e, 0xac, 0xce, 0xe2, 0xf0,
0x88, 0xd0, 0x7a, 0xb2, 0x5f, 0x8f, 0x13, 0xa6, 0xb1, 0xeb, 0x33, 0xb1, 0xfd, 0x24, 0xa8, 0xf3,
0xe3, 0x84, 0xb0, 0xfa, 0x37, 0x31, 0x3d, 0x24, 0x54, 0x13, 0x34, 0x26, 0xc5, 0x55, 0xf2, 0xf8,
0x49, 0xc0, 0xf4, 0xb2, 0x4e, 0x93, 0x4e, 0x9d, 0x71, 0x9f, 0x0f, 0xf4, 0x47, 0xdc, 0xdf, 0x58,
0x50, 0x7b, 0x42, 0x07, 0x11, 0xc1, 0xe4, 0xd7, 0x03, 0xc2, 0x38, 0xba, 0x04, 0xc5, 0x83, 0x20,
0xe4, 0x84, 0xda, 0xd6, 0x5a, 0x7e, 0xbd, 0x82, 0x35, 0x84, 0x96, 0x21, 0xef, 0x87, 0xa1, 0x9d,
0x5b, 0xb3, 0xd6, 0xcb, 0x58, 0x2c, 0xd1, 0x3a, 0xd4, 0x0e, 0x09, 0x49, 0x5a, 0x03, 0xea, 0xf3,
0x20, 0x8e, 0xec, 0xfc, 0x9a, 0xb5, 0x9e, 0x6f, 0x2e, 0xbc, 0x7a, 0xbd, 0x6a, 0xe1, 0xb1, 0x13,
0xe4, 0x42, 0x45, 0xc0, 0xcd, 0x63, 0x4e, 0x98, 0xbd, 0x60, 0xa0, 0x8d, 0xb6, 0xdd, 0xeb, 0xb0,
0xdc, 0x0a, 0xd8, 0xe1, 0x53, 0xe6, 0xf7, 0x4e, 0x93, 0xc5, 0x7d, 0x00, 0xe7, 0x0d, 0x5c, 0x96,
0xc4, 0x11, 0x23, 0xe8, 0x33, 0x28, 0x52, 0xd2, 0x89, 0x69, 0x57, 0x22, 0x57, 0x1b, 0x1f, 0x79,
0x93, 0xfe, 0xf4, 0x34, 0x81, 0x40, 0xc2, 0x1a, 0xd9, 0xfd, 0x43, 0x1e, 0xaa, 0xc6, 0x3e, 0x5a,
0x82, 0xdc, 0x4e, 0xcb, 0xb6, 0xd6, 0xac, 0xf5, 0x0a, 0xce, 0xed, 0xb4, 0x90, 0x0d, 0xa5, 0x47,
0x03, 0xee, 0xef, 0x87, 0x44, 0xeb, 0x9e, 0x82, 0xe8, 0x22, 0x14, 0x76, 0xa2, 0xa7, 0x8c, 0x48,
0xc5, 0xcb, 0x58, 0x01, 0x08, 0xc1, 0xc2, 0x6e, 0xf0, 0x2d, 0x51, 0x6a, 0x62, 0xb9, 0x46, 0x0e,
0x14, 0x9f, 0xf8, 0x94, 0x44, 0xdc, 0x2e, 0x08, 0xbe, 0xcd, 0x9c, 0x6d, 0x61, 0xbd, 0x83, 0x9a,
0x50, 0xd9, 0xa6, 0xc4, 0xe7, 0xa4, 0xbb, 0xc5, 0xed, 0xe2, 0x9a, 0xb5, 0x5e, 0x6d, 0x38, 0x9e,
0xf2, 0x96, 0x97, 0x06, 0x92, 0xb7, 0x97, 0x06, 0x52, 0xb3, 0xfc, 0xea, 0xf5, 0xea, 0xb9, 0xdf,
0xfd, 0x43, 0xd8, 0x6e, 0x48, 0x86, 0xee, 0x01, 0x3c, 0xf4, 0x19, 0x7f, 0xca, 0x24, 0x93, 0xd2,
0xa9, 0x4c, 0x16, 0x24, 0x03, 0x83, 0x06, 0xad, 0x00, 0x48, 0x23, 0x6c, 0xc7, 0x83, 0x88, 0xdb,
0x65, 0x29, 0xbb, 0xb1, 0x83, 0xd6, 0xa0, 0xda, 0x22, 0xac, 0x43, 0x83, 0x44, 0xba, 0xba, 0x22,
0xcd, 0x63, 0x6e, 0x09, 0x0e, 0xca, 0x82, 0x7b, 0xc7, 0x09, 0xb1, 0x41, 0x22, 0x18, 0x3b, 0xc2,
0x97, 0xbb, 0x2f, 0x7c, 0x4a, 0xba, 0x76, 0x55, 0x9a, 0x4b, 0x43, 0xc2, 0xbe, 0xca, 0x12, 0xcc,
0xae, 0x49, 0x27, 0xa7, 0xa0, 0xfb, 0xd7, 0x22, 0xd4, 0x76, 0x45, 0x5e, 0xa4, 0xe1, 0xb0, 0x0c,
0x79, 0x4c, 0x0e, 0xb4, 0x6f, 0xc4, 0x12, 0x79, 0x00, 0x2d, 0x72, 0x10, 0x44, 0x81, 0x94, 0x2a,
0x27, 0x15, 0x5f, 0xf2, 0x92, 0x7d, 0x6f, 0xb4, 0x8b, 0x0d, 0x0c, 0xe4, 0x40, 0xb9, 0xfd, 0x32,
0x89, 0xa9, 0x08, 0xa9, 0xbc, 0x64, 0x33, 0x84, 0xd1, 0x33, 0x58, 0x4c, 0xd7, 0x5b, 0x9c, 0x53,
0x11, 0xa8, 0x22, 0x8c, 0x3e, 0x99, 0x0e, 0x23, 0x53, 0x28, 0x6f, 0x8c, 0xa6, 0x1d, 0x71, 0x7a,
0x8c, 0xc7, 0xf9, 0x08, 0x0d, 0x77, 0x09, 0x63, 0x42, 0x42, 0xe9, 0x7e, 0x9c, 0x82, 0x42, 0x9c,
0x9f, 0xd3, 0x38, 0xe2, 0x24, 0xea, 0x4a, 0xd7, 0x57, 0xf0, 0x10, 0x16, 0xe2, 0xa4, 0x6b, 0x25,
0x4e, 0x69, 0x2e, 0x71, 0xc6, 0x68, 0xb4, 0x38, 0x63, 0x7b, 0x68, 0x13, 0x0a, 0xdb, 0x7e, 0xe7,
0x05, 0x91, 0x5e, 0xae, 0x36, 0x56, 0xa6, 0x19, 0xca, 0xe3, 0xc7, 0xd2, 0xad, 0x4c, 0x26, 0xea,
0x39, 0xac, 0x48, 0xd0, 0x2f, 0xa1, 0xd6, 0x8e, 0x78, 0xc0, 0x43, 0xd2, 0x97, 0x1e, 0xab, 0x08,
0x8f, 0x35, 0x37, 0xbf, 0x7f, 0xbd, 0xfa, 0xe3, 0x99, 0xc5, 0x6a, 0xc0, 0x83, 0xb0, 0x4e, 0x0c,
0x2a, 0xcf, 0x60, 0x81, 0xc7, 0xf8, 0xa1, 0xaf, 0x61, 0x29, 0x15, 0x76, 0x27, 0x4a, 0x06, 0x9c,
0xd9, 0x20, 0xb5, 0x6e, 0xcc, 0xa9, 0xb5, 0x22, 0x52, 0x6a, 0x4f, 0x70, 0x12, 0xc6, 0xde, 0x89,
0x38, 0xa1, 0x91, 0x1f, 0xea, 0x10, 0x1c, 0xc2, 0xce, 0x3d, 0x40, 0xd3, 0x7e, 0x14, 0xf1, 0x76,
0x48, 0x8e, 0xd3, 0x78, 0x3b, 0x24, 0xc7, 0x22, 0xe5, 0x8f, 0xfc, 0x70, 0xa0, 0x4a, 0x41, 0x05,
0x2b, 0x60, 0x33, 0x77, 0xdb, 0x12, 0x1c, 0xa6, 0x4d, 0x7f, 0x26, 0x0e, 0x5f, 0xc2, 0x85, 0x0c,
0x35, 0x32, 0x58, 0x5c, 0x35, 0x59, 0x4c, 0xc7, 0xfb, 0x88, 0xa5, 0xfb, 0xe7, 0x3c, 0xd4, 0x4c,
0x67, 0xa2, 0x0d, 0xb8, 0xa0, 0xf4, 0xc4, 0xe4, 0xa0, 0x45, 0x12, 0x4a, 0x3a, 0xa2, 0x82, 0x68,
0xe6, 0x59, 0x47, 0xa8, 0x01, 0x17, 0x77, 0xfa, 0x7a, 0x9b, 0x19, 0x24, 0x39, 0x99, 0xab, 0x99,
0x67, 0x28, 0x86, 0x0f, 0x15, 0x2b, 0x69, 0x09, 0x83, 0x28, 0x2f, 0x9d, 0xf9, 0xf9, 0xc9, 0x11,
0xe7, 0x65, 0xd2, 0x2a, 0x9f, 0x66, 0xf3, 0x45, 0x3f, 0x85, 0x92, 0x3a, 0x48, 0x93, 0xf6, 0xe3,
0x93, 0x3f, 0xa1, 0x98, 0xa5, 0x34, 0x82, 0x5c, 0xe9, 0xc1, 0xec, 0xc2, 0x19, 0xc8, 0x35, 0x8d,
0x73, 0x1f, 0x9c, 0xd9, 0x22, 0x9f, 0x25, 0x04, 0xdc, 0x3f, 0x59, 0x70, 0x7e, 0xea, 0x43, 0xe2,
0x46, 0x91, 0x35, 0x55, 0xb1, 0x90, 0x6b, 0xd4, 0x82, 0x82, 0xaa, 0x0a, 0x39, 0x29, 0xb0, 0x37,
0x87, 0xc0, 0x9e, 0x51, 0x12, 0x14, 0xb1, 0x73, 0x1b, 0xe0, 0xed, 0x82, 0xd5, 0xfd, 0x8b, 0x05,
0x8b, 0x3a, 0x03, 0xf5, 0xf5, 0xeb, 0xc3, 0x72, 0x9a, 0x42, 0xe9, 0x9e, 0xbe, 0x88, 0x3f, 0x9b,
0x99, 0xbc, 0x0a, 0xcd, 0x9b, 0xa4, 0x53, 0x32, 0x4e, 0xb1, 0x73, 0xb6, 0xd3, 0xb8, 0x9a, 0x40,
0x3d, 0x93, 0xe4, 0x57, 0x60, 0x71, 0x57, 0x36, 0x40, 0x33, 0x6f, 0x15, 0xf7, 0xdf, 0x16, 0x2c,
0xa5, 0x38, 0x5a, 0xbb, 0x4f, 0xa1, 0x7c, 0x44, 0x28, 0x27, 0x2f, 0x09, 0xd3, 0x5a, 0xd9, 0xd3,
0x5a, 0x7d, 0x25, 0x31, 0xf0, 0x10, 0x13, 0x6d, 0x42, 0x59, 0x35, 0x5b, 0x24, 0x75, 0xd4, 0xca,
0x2c, 0x2a, 0xfd, 0xbd, 0x21, 0x3e, 0xaa, 0xc3, 0x42, 0x18, 0xf7, 0x98, 0xce, 0x99, 0xff, 0x9f,
0x45, 0xf7, 0x30, 0xee, 0x61, 0x89, 0x88, 0xee, 0x40, 0xf9, 0x1b, 0x9f, 0x46, 0x41, 0xd4, 0x4b,
0xb3, 0x60, 0x75, 0x16, 0xd1, 0x33, 0x85, 0x87, 0x87, 0x04, 0xa2, 0x0b, 0x2a, 0xaa, 0x33, 0xf4,
0x00, 0x8a, 0xdd, 0xa0, 0x47, 0x18, 0x57, 0x26, 0x69, 0x36, 0xc4, 0x05, 0xf0, 0xfd, 0xeb, 0xd5,
0xeb, 0x46, 0x85, 0x8f, 0x13, 0x12, 0x89, 0xe6, 0xd9, 0x0f, 0x22, 0x42, 0x45, 0x73, 0x79, 0x53,
0x91, 0x78, 0x2d, 0xf9, 0x83, 0x35, 0x07, 0xc1, 0x2b, 0x50, 0x75, 0x5c, 0xd6, 0x8b, 0xb7, 0xe3,
0xa5, 0x38, 0x88, 0x34, 0x88, 0xfc, 0x3e, 0xd1, 0xf7, 0xb6, 0x5c, 0x8b, 0xa6, 0xa2, 0x23, 0xe2,
0xbc, 0x2b, 0xdb, 0xad, 0x32, 0xd6, 0x10, 0xda, 0x84, 0x12, 0xe3, 0x3e, 0x15, 0x35, 0xa7, 0x30,
0x67, 0x37, 0x94, 0x12, 0xa0, 0xbb, 0x50, 0xe9, 0xc4, 0xfd, 0x24, 0x24, 0x82, 0xba, 0x38, 0x27,
0xf5, 0x88, 0x44, 0x84, 0x1e, 0xa1, 0x34, 0xa6, 0xb2, 0x0f, 0xab, 0x60, 0x05, 0xa0, 0x5b, 0xb0,
0x98, 0xd0, 0xb8, 0x47, 0x09, 0x63, 0x5f, 0xd0, 0x78, 0x90, 0xe8, 0xdb, 0xf7, 0xbc, 0x28, 0xde,
0x4f, 0xcc, 0x03, 0x3c, 0x8e, 0xe7, 0xfe, 0x2b, 0x07, 0x35, 0x33, 0x44, 0xa6, 0x1a, 0xd4, 0x07,
0x50, 0x54, 0x01, 0xa7, 0x62, 0xfd, 0xed, 0x6c, 0xac, 0x38, 0x64, 0xda, 0xd8, 0x86, 0x52, 0x67,
0x40, 0x65, 0xf7, 0xaa, 0x7a, 0xda, 0x14, 0x14, 0x9a, 0xf2, 0x98, 0xfb, 0xa1, 0xb4, 0x71, 0x1e,
0x2b, 0x40, 0x34, 0xb4, 0xc3, 0xb9, 0xe7, 0x6c, 0x0d, 0xed, 0x90, 0xcc, 0xf4, 0x5f, 0xe9, 0x9d,
0xfc, 0x57, 0x3e, 0xb3, 0xff, 0xdc, 0xbf, 0x59, 0x50, 0x19, 0xe6, 0x96, 0x61, 0x5d, 0xeb, 0x9d,
0xad, 0x3b, 0x66, 0x99, 0xdc, 0xdb, 0x59, 0xe6, 0x12, 0x14, 0x19, 0xa7, 0xc4, 0xef, 0xab, 0x71,
0x0b, 0x6b, 0x48, 0x54, 0xb1, 0x3e, 0xeb, 0x49, 0x0f, 0xd5, 0xb0, 0x58, 0xba, 0xff, 0xb1, 0x60,
0x71, 0x2c, 0xdd, 0xdf, 0xab, 0x2e, 0x17, 0xa1, 0x10, 0x92, 0x23, 0xa2, 0x06, 0xc2, 0x3c, 0x56,
0x80, 0xd8, 0x65, 0x2f, 0x62, 0xca, 0xa5, 0x70, 0x35, 0xac, 0x00, 0x21, 0x73, 0x97, 0x70, 0x3f,
0x08, 0x65, 0x5d, 0xaa, 0x61, 0x0d, 0x09, 0x99, 0x07, 0x34, 0xd4, 0x4d, 0xb1, 0x58, 0x22, 0x17,
0x16, 0x82, 0xe8, 0x20, 0xd6, 0x61, 0x23, 0x3b, 0x9b, 0xdd, 0x78, 0x40, 0x3b, 0x64, 0x27, 0x3a,
0x88, 0xb1, 0x3c, 0x43, 0x57, 0xa0, 0x48, 0xfd, 0xa8, 0x47, 0xd2, 0x8e, 0xb8, 0x22, 0xb0, 0xb0,
0xd8, 0xc1, 0xfa, 0xc0, 0x75, 0xa1, 0x26, 0x87, 0xca, 0x47, 0x84, 0x89, 0x11, 0x46, 0x84, 0x75,
0xd7, 0xe7, 0xbe, 0x54, 0xbb, 0x86, 0xe5, 0xda, 0xbd, 0x01, 0xe8, 0x61, 0xc0, 0xf8, 0x33, 0x39,
0x40, 0xb3, 0xd3, 0x26, 0xce, 0x5d, 0xb8, 0x30, 0x86, 0xad, 0xaf, 0x85, 0x9f, 0x4c, 0xcc, 0x9c,
0x57, 0xa7, 0x2b, 0xae, 0x9c, 0xd3, 0x3d, 0x45, 0x38, 0x31, 0x7a, 0x2e, 0x42, 0x55, 0xea, 0xa5,
0xbe, 0xed, 0xfa, 0x50, 0x53, 0xa0, 0x66, 0xfe, 0x25, 0x7c, 0x90, 0x32, 0xfa, 0x8a, 0x50, 0x39,
0x3f, 0x58, 0xd2, 0x2e, 0x3f, 0x98, 0xf5, 0x95, 0xe6, 0x38, 0x3a, 0x9e, 0xa4, 0x77, 0x09, 0x5c,
0x90, 0x38, 0xf7, 0x03, 0xc6, 0x63, 0x7a, 0x9c, 0x6a, 0xbd, 0x02, 0xb0, 0xd5, 0xe1, 0xc1, 0x11,
0x79, 0x1c, 0x85, 0xea, 0x1a, 0x2d, 0x63, 0x63, 0x27, 0xbd, 0x22, 0x73, 0xa3, 0xc1, 0xeb, 0x32,
0x54, 0xda, 0x3e, 0x0d, 0x8f, 0xdb, 0x2f, 0x03, 0xae, 0xe7, 0xdf, 0xd1, 0x86, 0xfb, 0x5b, 0x0b,
0xce, 0x9b, 0xdf, 0x69, 0x1f, 0x89, 0x72, 0x71, 0x07, 0x16, 0x78, 0xda, 0xc7, 0x2c, 0x65, 0x29,
0x31, 0x45, 0x22, 0x5a, 0x1d, 0x2c, 0x89, 0x0c, 0x4b, 0xab, 0xc4, 0xb9, 0x7a, 0x32, 0xf9, 0x84,
0xa5, 0xff, 0x5b, 0x02, 0x34, 0x7d, 0x9c, 0x31, 0x50, 0x9a, 0x13, 0x59, 0x6e, 0x62, 0x22, 0x7b,
0x3e, 0x39, 0x91, 0xa9, 0xab, 0xf9, 0xd6, 0x3c, 0x92, 0xcc, 0x31, 0x97, 0xdd, 0x86, 0x4a, 0xda,
0xdd, 0xa4, 0x17, 0xb8, 0x33, 0xcd, 0x7a, 0xd8, 0x00, 0x8d, 0x90, 0xd1, 0x7a, 0x7a, 0xe3, 0xa8,
0xbb, 0x0e, 0xa5, 0x35, 0x85, 0x26, 0x1d, 0x4f, 0xf7, 0x15, 0xfa, 0x16, 0xba, 0x7b, 0xb6, 0xc7,
0x86, 0x85, 0xc9, 0x87, 0x86, 0x26, 0x54, 0xb7, 0xd3, 0x42, 0x79, 0x86, 0x97, 0x06, 0x93, 0x08,
0x6d, 0xe8, 0xc6, 0x46, 0x95, 0xe6, 0xcb, 0xd3, 0x2a, 0xa6, 0xaf, 0x0a, 0x31, 0xd5, 0x9d, 0xcd,
0x41, 0x46, 0x6b, 0x59, 0x91, 0x06, 0xda, 0x9c, 0xcb, 0xf6, 0x73, 0xf6, 0x97, 0xe8, 0x73, 0x28,
0x62, 0xc2, 0x06, 0x21, 0x97, 0xcf, 0x17, 0xd5, 0xc6, 0x95, 0x19, 0xdc, 0x15, 0x92, 0xcc, 0x55,
0x4d, 0x80, 0x7e, 0x01, 0x25, 0xb5, 0x62, 0x76, 0x75, 0xd6, 0x9c, 0x9e, 0x21, 0x99, 0xa6, 0xd1,
0x03, 0x85, 0x86, 0x44, 0x3a, 0x7e, 0x41, 0x22, 0xa2, 0x9f, 0xd5, 0x6a, 0x6b, 0xd6, 0x7a, 0x01,
0x1b, 0x3b, 0xa8, 0x01, 0x05, 0x4e, 0xfd, 0x0e, 0xb1, 0x17, 0xe7, 0x30, 0xa1, 0x42, 0x15, 0x85,
0x2d, 0x09, 0xa2, 0x88, 0x74, 0xed, 0x25, 0xd5, 0x29, 0x29, 0xe8, 0x3d, 0xcc, 0xad, 0xef, 0xa3,
0x2b, 0x77, 0x9e, 0x43, 0xcd, 0xb4, 0x45, 0x06, 0xed, 0xad, 0xf1, 0xa9, 0x77, 0x0e, 0xdf, 0x18,
0x4d, 0xff, 0x73, 0xf8, 0xbf, 0xa7, 0x49, 0xd7, 0xe7, 0x24, 0xab, 0xfa, 0x4d, 0x57, 0x81, 0x4b,
0x50, 0x7c, 0xa2, 0x8c, 0xa5, 0x9e, 0xfc, 0x34, 0x24, 0xf6, 0x5b, 0x44, 0xc4, 0xb1, 0x2e, 0x79,
0x1a, 0x72, 0x2f, 0x83, 0x93, 0xc5, 0x5e, 0x19, 0xc3, 0xfd, 0x63, 0x0e, 0x60, 0xe4, 0x10, 0xf4,
0x11, 0x40, 0x9f, 0x74, 0x03, 0xff, 0x57, 0x7c, 0x34, 0xd4, 0x55, 0xe4, 0x8e, 0x9c, 0xec, 0x46,
0xed, 0x77, 0xee, 0x9d, 0xdb, 0x6f, 0x04, 0x0b, 0x2c, 0xf8, 0x96, 0xe8, 0x56, 0x41, 0xae, 0xd1,
0x63, 0xa8, 0xfa, 0x51, 0x14, 0x73, 0x19, 0x4a, 0xe9, 0xc0, 0x7b, 0xf3, 0xa4, 0x10, 0xf2, 0xb6,
0x46, 0xf8, 0x2a, 0x52, 0x4d, 0x0e, 0xce, 0x5d, 0x58, 0x9e, 0x44, 0x38, 0xd3, 0x40, 0xf6, 0x9d,
0x05, 0x1f, 0x4c, 0xb8, 0x0e, 0x7d, 0x3a, 0xcc, 0x44, 0x6b, 0x8e, 0x10, 0x4f, 0x93, 0xf0, 0x1e,
0xd4, 0xb6, 0x38, 0x17, 0x95, 0x47, 0xe9, 0xa6, 0x46, 0xae, 0x93, 0x69, 0xc7, 0x28, 0xdc, 0xdf,
0x5b, 0xa3, 0x07, 0xc2, 0xcc, 0xb9, 0xfb, 0xce, 0xf8, 0xdc, 0x7d, 0x6d, 0x76, 0x81, 0x7e, 0x9f,
0xe3, 0xf6, 0xf5, 0x9f, 0xc1, 0x87, 0x99, 0x97, 0x23, 0xaa, 0x42, 0x69, 0x77, 0x6f, 0x0b, 0xef,
0xb5, 0x5b, 0xcb, 0xe7, 0x50, 0x0d, 0xca, 0xdb, 0x8f, 0x1f, 0x3d, 0x79, 0xd8, 0xde, 0x6b, 0x2f,
0x5b, 0xe2, 0xa8, 0xd5, 0x16, 0xeb, 0xd6, 0x72, 0xae, 0xf1, 0x5d, 0x11, 0x4a, 0xdb, 0xea, 0xdf,
0x0e, 0xb4, 0x07, 0x95, 0xe1, 0xeb, 0x39, 0x72, 0x33, 0xac, 0x33, 0xf1, 0x0c, 0xef, 0x7c, 0x7c,
0x22, 0x8e, 0x2e, 0x9e, 0xf7, 0xa1, 0x20, 0xff, 0x47, 0x40, 0x19, 0x23, 0xae, 0xf9, 0x07, 0x83,
0x73, 0xf2, 0xbb, 0xfc, 0x86, 0x25, 0x38, 0xc9, 0xf7, 0x81, 0x2c, 0x4e, 0xe6, 0xab, 0x9f, 0xb3,
0x7a, 0xca, 0xc3, 0x02, 0x7a, 0x04, 0x45, 0x3d, 0x34, 0x65, 0xa1, 0x9a, 0xaf, 0x00, 0xce, 0xda,
0x6c, 0x04, 0xc5, 0x6c, 0xc3, 0x42, 0x8f, 0x86, 0x0f, 0xb9, 0x59, 0xa2, 0x99, 0x1d, 0xa7, 0x73,
0xca, 0xf9, 0xba, 0xb5, 0x61, 0xa1, 0xaf, 0xa1, 0x6a, 0xf4, 0x94, 0x28, 0xa3, 0xa3, 0x99, 0x6e,
0x50, 0x9d, 0x6b, 0xa7, 0x60, 0x69, 0xcd, 0xdb, 0xb0, 0x20, 0x13, 0x29, 0xc3, 0xd8, 0x46, 0xcb,
0x99, 0x25, 0xe6, 0x58, 0x0b, 0xba, 0xaf, 0x9a, 0x64, 0x12, 0x99, 0xd1, 0x87, 0xae, 0x9d, 0x76,
0xb7, 0xcd, 0x0c, 0x9b, 0xa9, 0x20, 0xde, 0xb0, 0x50, 0x0c, 0x68, 0xba, 0x78, 0xa2, 0x1f, 0x66,
0x44, 0xc9, 0xac, 0x0a, 0xee, 0xdc, 0x98, 0x0f, 0x59, 0x29, 0xd5, 0xac, 0xbd, 0x7a, 0xb3, 0x62,
0xfd, 0xfd, 0xcd, 0x8a, 0xf5, 0xcf, 0x37, 0x2b, 0xd6, 0x7e, 0x51, 0x76, 0x2d, 0x3f, 0xfa, 0x5f,
0x00, 0x00, 0x00, 0xff, 0xff, 0xea, 0x14, 0x57, 0x80, 0x0d, 0x1c, 0x00, 0x00,
// 2261 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x59, 0xcd, 0x6e, 0x1b, 0xc9,
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.
@ -2853,6 +2892,18 @@ func (m *SolveRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if m.SourcePolicy != nil {
{
size, err := m.SourcePolicy.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintControl(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x62
}
if m.Internal {
i--
if m.Internal {
@ -3339,22 +3390,22 @@ func (m *Vertex) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0x3a
}
if m.Completed != nil {
n7, err7 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Completed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Completed):])
if err7 != nil {
return 0, err7
n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Completed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Completed):])
if err8 != nil {
return 0, err8
}
i -= n7
i = encodeVarintControl(dAtA, i, uint64(n7))
i -= n8
i = encodeVarintControl(dAtA, i, uint64(n8))
i--
dAtA[i] = 0x32
}
if m.Started != nil {
n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Started, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Started):])
if err8 != nil {
return 0, err8
n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Started, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Started):])
if err9 != nil {
return 0, err9
}
i -= n8
i = encodeVarintControl(dAtA, i, uint64(n8))
i -= n9
i = encodeVarintControl(dAtA, i, uint64(n9))
i--
dAtA[i] = 0x2a
}
@ -3419,31 +3470,31 @@ func (m *VertexStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) {
copy(dAtA[i:], m.XXX_unrecognized)
}
if m.Completed != nil {
n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Completed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Completed):])
if err9 != nil {
return 0, err9
n10, err10 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Completed, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Completed):])
if err10 != nil {
return 0, err10
}
i -= n9
i = encodeVarintControl(dAtA, i, uint64(n9))
i -= n10
i = encodeVarintControl(dAtA, i, uint64(n10))
i--
dAtA[i] = 0x42
}
if m.Started != nil {
n10, err10 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Started, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Started):])
if err10 != nil {
return 0, err10
n11, err11 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.Started, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.Started):])
if err11 != nil {
return 0, err11
}
i -= n10
i = encodeVarintControl(dAtA, i, uint64(n10))
i -= n11
i = encodeVarintControl(dAtA, i, uint64(n11))
i--
dAtA[i] = 0x3a
}
n11, err11 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err11 != nil {
return 0, err11
n12, err12 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err12 != nil {
return 0, err12
}
i -= n11
i = encodeVarintControl(dAtA, i, uint64(n11))
i -= n12
i = encodeVarintControl(dAtA, i, uint64(n12))
i--
dAtA[i] = 0x32
if m.Total != 0 {
@ -3516,12 +3567,12 @@ func (m *VertexLog) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x18
}
n12, err12 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err12 != nil {
return 0, err12
n13, err13 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err13 != nil {
return 0, err13
}
i -= n12
i = encodeVarintControl(dAtA, i, uint64(n12))
i -= n13
i = encodeVarintControl(dAtA, i, uint64(n13))
i--
dAtA[i] = 0x12
if len(m.Vertex) > 0 {
@ -3921,6 +3972,25 @@ 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--
dAtA[i] = 0x1
i--
dAtA[i] = 0x80
}
if m.NumCachedSteps != 0 {
i = encodeVarintControl(dAtA, i, uint64(m.NumCachedSteps))
i--
dAtA[i] = 0x78
}
if m.Pinned {
i--
if m.Pinned {
@ -4018,22 +4088,22 @@ func (m *BuildHistoryRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0x42
}
if m.CompletedAt != nil {
n20, err20 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.CompletedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.CompletedAt):])
if err20 != nil {
return 0, err20
n21, err21 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.CompletedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.CompletedAt):])
if err21 != nil {
return 0, err21
}
i -= n20
i = encodeVarintControl(dAtA, i, uint64(n20))
i -= n21
i = encodeVarintControl(dAtA, i, uint64(n21))
i--
dAtA[i] = 0x3a
}
if m.CreatedAt != nil {
n21, err21 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.CreatedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.CreatedAt):])
if err21 != nil {
return 0, err21
n22, err22 := github_com_gogo_protobuf_types.StdTimeMarshalTo(*m.CreatedAt, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(*m.CreatedAt):])
if err22 != nil {
return 0, err22
}
i -= n21
i = encodeVarintControl(dAtA, i, uint64(n21))
i -= n22
i = encodeVarintControl(dAtA, i, uint64(n22))
i--
dAtA[i] = 0x32
}
@ -4546,6 +4616,10 @@ func (m *SolveRequest) Size() (n int) {
if m.Internal {
n += 2
}
if m.SourcePolicy != nil {
l = m.SourcePolicy.Size()
n += 1 + l + sovControl(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@ -5043,6 +5117,15 @@ func (m *BuildHistoryRecord) Size() (n int) {
if m.Pinned {
n += 2
}
if m.NumCachedSteps != 0 {
n += 1 + sovControl(uint64(m.NumCachedSteps))
}
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)
}
@ -6514,6 +6597,42 @@ func (m *SolveRequest) Unmarshal(dAtA []byte) error {
}
}
m.Internal = bool(v != 0)
case 12:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field SourcePolicy", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowControl
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthControl
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthControl
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.SourcePolicy == nil {
m.SourcePolicy = &pb1.Policy{}
}
if err := m.SourcePolicy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipControl(dAtA[iNdEx:])
@ -9925,6 +10044,63 @@ func (m *BuildHistoryRecord) Unmarshal(dAtA []byte) error {
}
}
m.Pinned = bool(v != 0)
case 15:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field NumCachedSteps", wireType)
}
m.NumCachedSteps = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowControl
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.NumCachedSteps |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 16:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field NumTotalSteps", wireType)
}
m.NumTotalSteps = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowControl
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.NumTotalSteps |= int32(b&0x7F) << shift
if b < 0x80 {
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:])

@ -8,6 +8,7 @@ import "github.com/moby/buildkit/solver/pb/ops.proto";
import "github.com/moby/buildkit/api/types/worker.proto";
// import "github.com/containerd/containerd/api/types/descriptor.proto";
import "github.com/gogo/googleapis/google/rpc/status.proto";
import "github.com/moby/buildkit/sourcepolicy/pb/policy.proto";
option (gogoproto.sizer_all) = true;
option (gogoproto.marshaler_all) = true;
@ -68,6 +69,7 @@ message SolveRequest {
repeated string Entitlements = 9 [(gogoproto.customtype) = "github.com/moby/buildkit/util/entitlements.Entitlement" ];
map<string, pb.Definition> FrontendInputs = 10;
bool Internal = 11; // Internal builds are not recorded in build history
moby.buildkit.v1.sourcepolicy.Policy SourcePolicy = 12;
}
message CacheOptions {
@ -202,8 +204,10 @@ message BuildHistoryRecord {
int32 Generation = 12;
Descriptor trace = 13;
bool pinned = 14;
int32 numCachedSteps = 15;
int32 numTotalSteps = 16;
int32 numCompletedSteps = 17;
// TODO: tags
// TODO: steps/cache summary
// TODO: unclipped logs
}
@ -230,4 +234,4 @@ message BuildResultInfo {
message Exporter {
string Type = 1;
map<string, string> Attrs = 2;
}
}

@ -29,6 +29,10 @@ type DefinitionOp struct {
// NewDefinitionOp returns a new operation from a marshalled definition.
func NewDefinitionOp(def *pb.Definition) (*DefinitionOp, error) {
if def == nil {
return nil, errors.New("invalid nil input definition to definition op")
}
ops := make(map[digest.Digest]*pb.Op)
defs := make(map[digest.Digest][]byte)
platforms := make(map[digest.Digest]*ocispecs.Platform)
@ -205,6 +209,7 @@ func (d *DefinitionOp) Inputs() []Output {
dgst: input.Digest,
index: input.Index,
inputCache: d.inputCache,
sources: d.sources,
}
existingIndexes := d.inputCache[input.Digest]
indexDiff := int(input.Index) - len(existingIndexes)

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

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

@ -4,6 +4,7 @@ import (
"encoding/json"
"io"
"os"
"path"
"github.com/gofrs/flock"
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
@ -11,69 +12,86 @@ import (
)
const (
// IndexJSONLockFileSuffix is the suffix of the lock file
IndexJSONLockFileSuffix = ".lock"
// indexFile is the name of the index file
indexFile = "index.json"
// lockFileSuffix is the suffix of the lock file
lockFileSuffix = ".lock"
)
// PutDescToIndex puts desc to index with tag.
// Existing manifests with the same tag will be removed from the index.
func PutDescToIndex(index *ocispecs.Index, desc ocispecs.Descriptor, tag string) error {
if index == nil {
index = &ocispecs.Index{}
type StoreIndex struct {
indexPath string
lockPath string
}
func NewStoreIndex(storePath string) StoreIndex {
indexPath := path.Join(storePath, indexFile)
return StoreIndex{
indexPath: indexPath,
lockPath: indexPath + lockFileSuffix,
}
if index.SchemaVersion == 0 {
index.SchemaVersion = 2
}
func (s StoreIndex) Read() (*ocispecs.Index, error) {
lock := flock.New(s.lockPath)
locked, err := lock.TryRLock()
if err != nil {
return nil, errors.Wrapf(err, "could not lock %s", s.lockPath)
}
if tag != "" {
if desc.Annotations == nil {
desc.Annotations = make(map[string]string)
}
desc.Annotations[ocispecs.AnnotationRefName] = tag
// remove existing manifests with the same tag
var manifests []ocispecs.Descriptor
for _, m := range index.Manifests {
if m.Annotations[ocispecs.AnnotationRefName] != tag {
manifests = append(manifests, m)
}
}
index.Manifests = manifests
if !locked {
return nil, errors.Errorf("could not lock %s", s.lockPath)
}
index.Manifests = append(index.Manifests, desc)
return nil
defer func() {
lock.Unlock()
os.RemoveAll(s.lockPath)
}()
b, err := os.ReadFile(s.indexPath)
if err != nil {
return nil, errors.Wrapf(err, "could not read %s", s.indexPath)
}
var idx ocispecs.Index
if err := json.Unmarshal(b, &idx); err != nil {
return nil, errors.Wrapf(err, "could not unmarshal %s (%q)", s.indexPath, string(b))
}
return &idx, nil
}
func PutDescToIndexJSONFileLocked(indexJSONPath string, desc ocispecs.Descriptor, tag string) error {
lockPath := indexJSONPath + IndexJSONLockFileSuffix
lock := flock.New(lockPath)
func (s StoreIndex) Put(tag string, desc ocispecs.Descriptor) error {
lock := flock.New(s.lockPath)
locked, err := lock.TryLock()
if err != nil {
return errors.Wrapf(err, "could not lock %s", lockPath)
return errors.Wrapf(err, "could not lock %s", s.lockPath)
}
if !locked {
return errors.Errorf("could not lock %s", lockPath)
return errors.Errorf("could not lock %s", s.lockPath)
}
defer func() {
lock.Unlock()
os.RemoveAll(lockPath)
os.RemoveAll(s.lockPath)
}()
f, err := os.OpenFile(indexJSONPath, os.O_RDWR|os.O_CREATE, 0644)
f, err := os.OpenFile(s.indexPath, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
return errors.Wrapf(err, "could not open %s", indexJSONPath)
return errors.Wrapf(err, "could not open %s", s.indexPath)
}
defer f.Close()
var idx ocispecs.Index
b, err := io.ReadAll(f)
if err != nil {
return errors.Wrapf(err, "could not read %s", indexJSONPath)
return errors.Wrapf(err, "could not read %s", s.indexPath)
}
if len(b) > 0 {
if err := json.Unmarshal(b, &idx); err != nil {
return errors.Wrapf(err, "could not unmarshal %s (%q)", indexJSONPath, string(b))
return errors.Wrapf(err, "could not unmarshal %s (%q)", s.indexPath, string(b))
}
}
if err = PutDescToIndex(&idx, desc, tag); err != nil {
if err = insertDesc(&idx, desc, tag); err != nil {
return err
}
b, err = json.Marshal(idx)
if err != nil {
return err
@ -87,27 +105,56 @@ func PutDescToIndexJSONFileLocked(indexJSONPath string, desc ocispecs.Descriptor
return nil
}
func ReadIndexJSONFileLocked(indexJSONPath string) (*ocispecs.Index, error) {
lockPath := indexJSONPath + IndexJSONLockFileSuffix
lock := flock.New(lockPath)
locked, err := lock.TryRLock()
func (s StoreIndex) Get(tag string) (*ocispecs.Descriptor, error) {
idx, err := s.Read()
if err != nil {
return nil, errors.Wrapf(err, "could not lock %s", lockPath)
return nil, err
}
if !locked {
return nil, errors.Errorf("could not lock %s", lockPath)
for _, m := range idx.Manifests {
if t, ok := m.Annotations[ocispecs.AnnotationRefName]; ok && t == tag {
return &m, nil
}
}
defer func() {
lock.Unlock()
os.RemoveAll(lockPath)
}()
b, err := os.ReadFile(indexJSONPath)
return nil, nil
}
func (s StoreIndex) GetSingle() (*ocispecs.Descriptor, error) {
idx, err := s.Read()
if err != nil {
return nil, errors.Wrapf(err, "could not read %s", indexJSONPath)
return nil, err
}
var idx ocispecs.Index
if err := json.Unmarshal(b, &idx); err != nil {
return nil, errors.Wrapf(err, "could not unmarshal %s (%q)", indexJSONPath, string(b))
if len(idx.Manifests) == 1 {
return &idx.Manifests[0], nil
}
return &idx, nil
return nil, nil
}
// insertDesc puts desc to index with tag.
// Existing manifests with the same tag will be removed from the index.
func insertDesc(index *ocispecs.Index, desc ocispecs.Descriptor, tag string) error {
if index == nil {
return nil
}
if index.SchemaVersion == 0 {
index.SchemaVersion = 2
}
if tag != "" {
if desc.Annotations == nil {
desc.Annotations = make(map[string]string)
}
desc.Annotations[ocispecs.AnnotationRefName] = tag
// remove existing manifests with the same tag
var manifests []ocispecs.Descriptor
for _, m := range index.Manifests {
if m.Annotations[ocispecs.AnnotationRefName] != tag {
manifests = append(manifests, m)
}
}
index.Manifests = manifests
}
index.Manifests = append(index.Manifests, desc)
return nil
}

@ -22,6 +22,7 @@ import (
"github.com/moby/buildkit/session/filesync"
"github.com/moby/buildkit/session/grpchijack"
"github.com/moby/buildkit/solver/pb"
spb "github.com/moby/buildkit/sourcepolicy/pb"
"github.com/moby/buildkit/util/bklog"
"github.com/moby/buildkit/util/entitlements"
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
@ -47,6 +48,8 @@ type SolveOpt struct {
SharedSession *session.Session // TODO: refactor to better session syncing
SessionPreInitialized bool // TODO: refactor to better session syncing
Internal bool
SourcePolicy *spb.Policy
Ref string
}
type ExportEntry struct {
@ -93,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())
@ -127,7 +133,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
ex = opt.Exports[0]
}
indicesToUpdate := []string{}
storesToUpdate := []string{}
if !opt.SessionPreInitialized {
if len(syncedDirs) > 0 {
@ -192,7 +198,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
return nil, err
}
contentStores["export"] = cs
indicesToUpdate = append(indicesToUpdate, filepath.Join(ex.OutputDir, "index.json"))
storesToUpdate = append(storesToUpdate, ex.OutputDir)
default:
s.Allow(filesync.NewFSSyncTargetDir(ex.OutputDir))
}
@ -261,6 +267,7 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
Cache: cacheOpt.options,
Entitlements: opt.AllowedEntitlements,
Internal: opt.Internal,
SourcePolicy: opt.SourcePolicy,
})
if err != nil {
return errors.Wrap(err, "failed to solve")
@ -324,8 +331,9 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
if err = json.Unmarshal([]byte(manifestDescJSON), &manifestDesc); err != nil {
return nil, err
}
for indexJSONPath, tag := range cacheOpt.indicesToUpdate {
if err = ociindex.PutDescToIndexJSONFileLocked(indexJSONPath, manifestDesc, tag); err != nil {
for storePath, tag := range cacheOpt.storesToUpdate {
idx := ociindex.NewStoreIndex(storePath)
if err := idx.Put(tag, manifestDesc); err != nil {
return nil, err
}
}
@ -339,12 +347,13 @@ func (c *Client) solve(ctx context.Context, def *llb.Definition, runGateway runG
if err = json.Unmarshal([]byte(manifestDescDt), &manifestDesc); err != nil {
return nil, err
}
for _, indexJSONPath := range indicesToUpdate {
for _, storePath := range storesToUpdate {
tag := "latest"
if t, ok := res.ExporterResponse["image.name"]; ok {
tag = t
}
if err = ociindex.PutDescToIndexJSONFileLocked(indexJSONPath, manifestDesc, tag); err != nil {
idx := ociindex.NewStoreIndex(storePath)
if err := idx.Put(tag, manifestDesc); err != nil {
return nil, err
}
}
@ -403,10 +412,10 @@ func defaultSessionName() string {
}
type cacheOptions struct {
options controlapi.CacheOptions
contentStores map[string]content.Store // key: ID of content store ("local:" + csDir)
indicesToUpdate map[string]string // key: index.JSON file name, value: tag
frontendAttrs map[string]string
options controlapi.CacheOptions
contentStores map[string]content.Store // key: ID of content store ("local:" + csDir)
storesToUpdate map[string]string // key: path to content store, value: tag
frontendAttrs map[string]string
}
func parseCacheOptions(ctx context.Context, isGateway bool, opt SolveOpt) (*cacheOptions, error) {
@ -415,7 +424,7 @@ func parseCacheOptions(ctx context.Context, isGateway bool, opt SolveOpt) (*cach
cacheImports []*controlapi.CacheOptionsEntry
)
contentStores := make(map[string]content.Store)
indicesToUpdate := make(map[string]string) // key: index.JSON file name, value: tag
storesToUpdate := make(map[string]string)
frontendAttrs := make(map[string]string)
for _, ex := range opt.CacheExports {
if ex.Type == "local" {
@ -437,8 +446,7 @@ func parseCacheOptions(ctx context.Context, isGateway bool, opt SolveOpt) (*cach
tag = t
}
// TODO(AkihiroSuda): support custom index JSON path and tag
indexJSONPath := filepath.Join(csDir, "index.json")
indicesToUpdate[indexJSONPath] = tag
storesToUpdate[csDir] = tag
}
if ex.Type == "registry" {
regRef := ex.Attrs["ref"]
@ -462,27 +470,26 @@ func parseCacheOptions(ctx context.Context, isGateway bool, opt SolveOpt) (*cach
bklog.G(ctx).Warning("local cache import at " + csDir + " not found due to err: " + err.Error())
continue
}
// if digest is not specified, load from "latest" tag
// if digest is not specified, attempt to load from tag
if im.Attrs["digest"] == "" {
idx, err := ociindex.ReadIndexJSONFileLocked(filepath.Join(csDir, "index.json"))
tag := "latest"
if t, ok := im.Attrs["tag"]; ok {
tag = t
}
idx := ociindex.NewStoreIndex(csDir)
desc, err := idx.Get(tag)
if err != nil {
bklog.G(ctx).Warning("local cache import at " + csDir + " not found due to err: " + err.Error())
continue
}
for _, m := range idx.Manifests {
tag := "latest"
if t, ok := im.Attrs["tag"]; ok {
tag = t
}
if m.Annotations[ocispecs.AnnotationRefName] == tag {
im.Attrs["digest"] = string(m.Digest)
break
}
}
if im.Attrs["digest"] == "" {
return nil, errors.New("local cache importer requires either explicit digest, \"latest\" tag or custom tag on index.json")
if desc != nil {
im.Attrs["digest"] = desc.Digest.String()
}
}
if im.Attrs["digest"] == "" {
return nil, errors.New("local cache importer requires either explicit digest, \"latest\" tag or custom tag on index.json")
}
contentStores["local:"+csDir] = cs
}
if im.Type == "registry" {
@ -510,9 +517,9 @@ func parseCacheOptions(ctx context.Context, isGateway bool, opt SolveOpt) (*cach
Exports: cacheExports,
Imports: cacheImports,
},
contentStores: contentStores,
indicesToUpdate: indicesToUpdate,
frontendAttrs: frontendAttrs,
contentStores: contentStores,
storesToUpdate: storesToUpdate,
frontendAttrs: frontendAttrs,
}
return &res, nil
}

@ -11,7 +11,7 @@ const (
ExporterImageConfigDigestKey = "containerimage.config.digest"
ExporterImageDescriptorKey = "containerimage.descriptor"
ExporterInlineCache = "containerimage.inlinecache"
ExporterBuildInfo = "containerimage.buildinfo"
ExporterBuildInfo = "containerimage.buildinfo" // Deprecated: Build information is deprecated: https://github.com/moby/buildkit/blob/master/docs/deprecated.md
ExporterPlatformsKey = "refs.platforms"
ExporterEpochKey = "source.date.epoch"
)

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

@ -382,6 +382,7 @@ func (c *grpcClient) Solve(ctx context.Context, creq client.SolveRequest) (res *
AllowResultReturn: true,
AllowResultArrayRef: true,
CacheImports: cacheImports,
SourcePolicies: creq.SourcePolicies,
}
// backwards compatibility with inline return
@ -488,7 +489,15 @@ func (c *grpcClient) ResolveImageConfig(ctx context.Context, ref string, opt llb
OSFeatures: platform.OSFeatures,
}
}
resp, err := c.client.ResolveImageConfig(ctx, &pb.ResolveImageConfigRequest{Ref: ref, Platform: p, ResolveMode: opt.ResolveMode, LogName: opt.LogName, ResolverType: int32(opt.ResolverType), SessionID: opt.SessionID})
resp, err := c.client.ResolveImageConfig(ctx, &pb.ResolveImageConfigRequest{
ResolverType: int32(opt.ResolverType),
Ref: ref,
Platform: p,
ResolveMode: opt.ResolveMode,
LogName: opt.LogName,
SessionID: opt.Store.SessionID,
StoreID: opt.Store.StoreID,
})
if err != nil {
return "", nil, err
}
@ -918,11 +927,11 @@ func (ctr *container) Start(ctx context.Context, req client.StartRequest) (clien
if msg == nil {
// empty message from ctx cancel, so just start shutting down
// input, but continue processing more exit/done messages
// input
closeDoneOnce.Do(func() {
close(done)
})
continue
return ctx.Err()
}
if file := msg.GetFile(); file != nil {

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

@ -8,6 +8,7 @@ import "github.com/moby/buildkit/solver/pb/ops.proto";
import "github.com/moby/buildkit/api/types/worker.proto";
import "github.com/moby/buildkit/util/apicaps/pb/caps.proto";
import "github.com/tonistiigi/fsutil/types/stat.proto";
import "github.com/moby/buildkit/sourcepolicy/pb/policy.proto";
option (gogoproto.sizer_all) = true;
@ -122,6 +123,7 @@ message ResolveImageConfigRequest {
string LogName = 4;
int32 ResolverType = 5;
string SessionID = 6;
string StoreID = 7;
}
message ResolveImageConfigResponse {
@ -148,6 +150,8 @@ message SolveRequest {
map<string, pb.Definition> FrontendInputs = 13;
bool Evaluate = 14;
repeated moby.buildkit.v1.sourcepolicy.Policy SourcePolicies = 15;
}
// CacheOptionsEntry corresponds to the control.CacheOptionsEntry

@ -4,6 +4,7 @@ import (
"context"
"net"
"strings"
"sync"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
"github.com/moby/buildkit/identity"
@ -36,14 +37,16 @@ type Attachable interface {
// Session is a long running connection between client and a daemon
type Session struct {
id string
name string
sharedKey string
ctx context.Context
cancelCtx func()
done chan struct{}
grpcServer *grpc.Server
conn net.Conn
mu sync.Mutex // synchronizes conn run and close
id string
name string
sharedKey string
ctx context.Context
cancelCtx func()
done chan struct{}
grpcServer *grpc.Server
conn net.Conn
closeCalled bool
}
// NewSession returns a new long running session
@ -99,6 +102,11 @@ func (s *Session) ID() string {
// Run activates the session
func (s *Session) Run(ctx context.Context, dialer Dialer) error {
s.mu.Lock()
if s.closeCalled {
s.mu.Unlock()
return nil
}
ctx, cancel := context.WithCancel(ctx)
s.cancelCtx = cancel
s.done = make(chan struct{})
@ -118,15 +126,18 @@ func (s *Session) Run(ctx context.Context, dialer Dialer) error {
}
conn, err := dialer(ctx, "h2c", meta)
if err != nil {
s.mu.Unlock()
return errors.Wrap(err, "failed to dial gRPC")
}
s.conn = conn
s.mu.Unlock()
serve(ctx, s.grpcServer, conn)
return nil
}
// Close closes the session
func (s *Session) Close() error {
s.mu.Lock()
if s.cancelCtx != nil && s.done != nil {
if s.conn != nil {
s.conn.Close()
@ -134,6 +145,8 @@ func (s *Session) Close() error {
s.grpcServer.Stop()
<-s.done
}
s.closeCalled = true
s.mu.Unlock()
return nil
}

@ -14,16 +14,24 @@ type Stream interface {
}
func Copy(ctx context.Context, conn io.ReadWriteCloser, stream Stream, closeStream func() error) error {
defer conn.Close()
g, ctx := errgroup.WithContext(ctx)
g.Go(func() (retErr error) {
p := &BytesMessage{}
for {
if err := stream.RecvMsg(p); err != nil {
conn.Close()
if err == io.EOF {
// indicates client performed CloseSend, but they may still be
// reading data
if conn, ok := conn.(interface {
CloseWrite() error
}); ok {
conn.CloseWrite()
}
return nil
}
conn.Close()
return errors.WithStack(err)
}
select {

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

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

@ -9,12 +9,13 @@ import (
const (
AttestationReasonKey = "reason"
AttestationSBOMCore = "sbom-core"
AttestationInlineOnlyKey = "inline-only"
)
var (
AttestationReasonSBOM = []byte("sbom")
AttestationReasonProvenance = []byte("provenance")
const (
AttestationReasonSBOM = "sbom"
AttestationReasonProvenance = "provenance"
)
type Attestation[T any] struct {

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

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

File diff suppressed because it is too large Load Diff

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

@ -1,3 +1,6 @@
// Package binfotypes implements types for build information.
//
// Deprecated: Build information is deprecated: https://github.com/moby/buildkit/blob/master/docs/deprecated.md
package binfotypes
import (

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

@ -73,22 +73,12 @@ func ParseGitRef(ref string) (*GitRef, error) {
}
}
refSplitBySharp := strings.SplitN(ref, "#", 2)
res.Remote = refSplitBySharp[0]
var fragment string
res.Remote, fragment, _ = strings.Cut(ref, "#")
if len(res.Remote) == 0 {
return res, errdefs.ErrInvalidArgument
}
if len(refSplitBySharp) > 1 {
refSplitBySharpSplitByColon := strings.SplitN(refSplitBySharp[1], ":", 2)
res.Commit = refSplitBySharpSplitByColon[0]
if len(res.Commit) == 0 {
return res, errdefs.ErrInvalidArgument
}
if len(refSplitBySharpSplitByColon) > 1 {
res.SubDir = refSplitBySharpSplitByColon[1]
}
}
res.Commit, res.SubDir, _ = strings.Cut(fragment, ":")
repoSplitBySlash := strings.Split(res.Remote, "/")
res.ShortName = strings.TrimSuffix(repoSplitBySlash[len(repoSplitBySlash)-1], ".git")
return res, nil

@ -9,6 +9,8 @@ import (
)
// BuildInfo returns build info from image config.
//
// Deprecated: Build information is deprecated: https://github.com/moby/buildkit/blob/master/docs/deprecated.md
func BuildInfo(dt []byte) (*binfotypes.BuildInfo, error) {
if len(dt) == 0 {
return nil, nil

@ -14,7 +14,7 @@ var colorError aec.ANSI
func init() {
// As recommended on https://no-color.org/
if _, ok := os.LookupEnv("NO_COLOR"); ok {
if v := os.Getenv("NO_COLOR"); v != "" {
// nil values will result in no ANSI color codes being emitted.
return
} else if runtime.GOOS == "windows" {

@ -73,21 +73,31 @@ func detectExporter() (sdktrace.SpanExporter, error) {
return nil, nil
}
func detect() error {
tp = trace.NewNoopTracerProvider()
func getExporter() (sdktrace.SpanExporter, error) {
exp, err := detectExporter()
if err != nil {
return err
return nil, err
}
if exp != nil {
exp = &threadSafeExporterWrapper{
exporter: exp,
}
}
if Recorder != nil {
Recorder.SpanExporter = exp
exp = Recorder
}
return exp, nil
}
func detect() error {
tp = trace.NewNoopTracerProvider()
if exp == nil {
return nil
exp, err := getExporter()
if err != nil || exp == nil {
return err
}
// enable log with traceID when valid exporter

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

@ -43,10 +43,6 @@ func NewTraceRecorder() *TraceRecorder {
}
func (r *TraceRecorder) Record(traceID trace.TraceID) func() []tracetest.SpanStub {
if r.flush != nil {
r.flush(context.TODO())
}
r.mu.Lock()
defer r.mu.Unlock()
@ -55,6 +51,10 @@ func (r *TraceRecorder) Record(traceID trace.TraceID) func() []tracetest.SpanStu
var spans []tracetest.SpanStub
return func() []tracetest.SpanStub {
once.Do(func() {
if r.flush != nil {
r.flush(context.TODO())
}
r.mu.Lock()
defer r.mu.Unlock()

@ -0,0 +1,26 @@
package detect
import (
"context"
"sync"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
// threadSafeExporterWrapper wraps an OpenTelemetry SpanExporter and makes it thread-safe.
type threadSafeExporterWrapper struct {
mu sync.Mutex
exporter sdktrace.SpanExporter
}
func (tse *threadSafeExporterWrapper) ExportSpans(ctx context.Context, spans []sdktrace.ReadOnlySpan) error {
tse.mu.Lock()
defer tse.mu.Unlock()
return tse.exporter.ExportSpans(ctx, spans)
}
func (tse *threadSafeExporterWrapper) Shutdown(ctx context.Context) error {
tse.mu.Lock()
defer tse.mu.Unlock()
return tse.exporter.Shutdown(ctx)
}

@ -59,4 +59,13 @@ const (
// AnnotationBaseImageName is the annotation key for the image reference of the image's base image.
AnnotationBaseImageName = "org.opencontainers.image.base.name"
// AnnotationArtifactCreated is the annotation key for the date and time on which the artifact was built, conforming to RFC 3339.
AnnotationArtifactCreated = "org.opencontainers.artifact.created"
// AnnotationArtifactDescription is the annotation key for the human readable description for the artifact.
AnnotationArtifactDescription = "org.opencontainers.artifact.description"
// AnnotationReferrersFiltersApplied is the annotation key for the comma separated list of filters applied by the registry in the referrers listing.
AnnotationReferrersFiltersApplied = "org.opencontainers.referrers.filtersApplied"
)

@ -0,0 +1,34 @@
// Copyright 2022 The Linux Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package v1
// Artifact describes an artifact manifest.
// This structure provides `application/vnd.oci.artifact.manifest.v1+json` mediatype when marshalled to JSON.
type Artifact struct {
// MediaType is the media type of the object this schema refers to.
MediaType string `json:"mediaType"`
// ArtifactType is the IANA media type of the artifact this schema refers to.
ArtifactType string `json:"artifactType"`
// Blobs is a collection of blobs referenced by this manifest.
Blobs []Descriptor `json:"blobs,omitempty"`
// Subject (reference) is an optional link from the artifact to another manifest forming an association between the artifact and the other manifest.
Subject *Descriptor `json:"subject,omitempty"`
// Annotations contains arbitrary metadata for the artifact manifest.
Annotations map[string]string `json:"annotations,omitempty"`
}

@ -48,6 +48,15 @@ type ImageConfig struct {
// StopSignal contains the system call signal that will be sent to the container to exit.
StopSignal string `json:"StopSignal,omitempty"`
// ArgsEscaped `[Deprecated]` - This field is present only for legacy
// compatibility with Docker and should not be used by new image builders.
// It is used by Docker for Windows images to indicate that the `Entrypoint`
// or `Cmd` or both, contains only a single element array, that is a
// pre-escaped, and combined into a single string `CommandLine`. If `true`
// the value in `Entrypoint` or `Cmd` should be used as-is to avoid double
// escaping.
ArgsEscaped bool `json:"ArgsEscaped,omitempty"`
}
// RootFS describes a layer content addresses

@ -1,4 +1,4 @@
// Copyright 2016 The Linux Foundation
// Copyright 2016-2022 The Linux Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -44,6 +44,9 @@ type Descriptor struct {
//
// This should only be used when referring to a manifest.
Platform *Platform `json:"platform,omitempty"`
// ArtifactType is the IANA media type of this artifact.
ArtifactType string `json:"artifactType,omitempty"`
}
// Platform describes the platform which the image in the manifest runs on.

@ -1,4 +1,4 @@
// Copyright 2016 The Linux Foundation
// Copyright 2016-2022 The Linux Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -30,6 +30,9 @@ type Manifest struct {
// Layers is an indexed list of layers referenced by the manifest.
Layers []Descriptor `json:"layers"`
// Subject is an optional link from the image manifest to another manifest forming an association between the image manifest and the other manifest.
Subject *Descriptor `json:"subject,omitempty"`
// Annotations contains arbitrary metadata for the image manifest.
Annotations map[string]string `json:"annotations,omitempty"`
}

@ -54,4 +54,7 @@ const (
// MediaTypeImageConfig specifies the media type for the image configuration.
MediaTypeImageConfig = "application/vnd.oci.image.config.v1+json"
// MediaTypeArtifactManifest specifies the media type for a content descriptor.
MediaTypeArtifactManifest = "application/vnd.oci.artifact.manifest.v1+json"
)

@ -20,9 +20,9 @@ const (
// VersionMajor is for an API incompatible changes
VersionMajor = 1
// VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 0
VersionMinor = 1
// VersionPatch is for backwards-compatible bug fixes
VersionPatch = 2
VersionPatch = 0
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = "-dev"

@ -135,7 +135,7 @@ func (s *sender) sendFile(h *sendHandle) error {
defer f.Close()
buf := bufPool.Get().(*[]byte)
defer bufPool.Put(buf)
if _, err := io.CopyBuffer(&fileSender{sender: s, id: h.id}, f, *buf); err != nil {
if _, err := io.CopyBuffer(&fileSender{sender: s, id: h.id}, struct{ io.Reader }{f}, *buf); err != nil {
return err
}
}

21
vendor/modules.txt vendored

@ -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.11
# github.com/containerd/containerd v1.6.20
## explicit; go 1.17
github.com/containerd/containerd/api/services/content/v1
github.com/containerd/containerd/archive/compression
@ -181,7 +181,7 @@ github.com/containerd/containerd/version
## explicit; go 1.17
github.com/containerd/continuity/fs
github.com/containerd/continuity/sysx
# github.com/containerd/ttrpc v1.1.0
# github.com/containerd/ttrpc v1.1.1
## explicit; go 1.13
github.com/containerd/ttrpc
# github.com/containerd/typeurl v1.0.2
@ -194,7 +194,7 @@ github.com/davecgh/go-spew/spew
## explicit; go 1.18
github.com/distribution/distribution/v3/digestset
github.com/distribution/distribution/v3/reference
# github.com/docker/cli v23.0.0-beta.1+incompatible
# github.com/docker/cli v23.0.0-rc.1+incompatible
## explicit
github.com/docker/cli/cli
github.com/docker/cli/cli-plugins/manager
@ -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
@ -241,7 +241,7 @@ github.com/docker/distribution/registry/client/transport
github.com/docker/distribution/registry/storage/cache
github.com/docker/distribution/registry/storage/cache/memory
github.com/docker/distribution/uuid
# github.com/docker/docker v23.0.0-beta.1+incompatible
# github.com/docker/docker v23.0.0-rc.1+incompatible
## explicit
github.com/docker/docker/api
github.com/docker/docker/api/types
@ -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-rc1.0.20221213193744-862b22d7e7cf
# github.com/moby/buildkit v0.11.7-0.20230519102302-348e79dfed17
## explicit; go 1.18
github.com/moby/buildkit/api/services/control
github.com/moby/buildkit/api/types
@ -471,6 +471,7 @@ github.com/moby/buildkit/solver/errdefs
github.com/moby/buildkit/solver/pb
github.com/moby/buildkit/solver/result
github.com/moby/buildkit/source/types
github.com/moby/buildkit/sourcepolicy/pb
github.com/moby/buildkit/util/apicaps
github.com/moby/buildkit/util/apicaps/pb
github.com/moby/buildkit/util/appcontext
@ -535,11 +536,11 @@ github.com/morikuni/aec
# github.com/opencontainers/go-digest v1.0.0
## explicit; go 1.13
github.com/opencontainers/go-digest
# github.com/opencontainers/image-spec v1.0.3-0.20220303224323-02efb9a75ee1
## explicit; go 1.16
# github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b
## explicit; go 1.17
github.com/opencontainers/image-spec/specs-go
github.com/opencontainers/image-spec/specs-go/v1
# github.com/opencontainers/runc v1.1.3
# github.com/opencontainers/runc v1.1.5
## explicit; go 1.16
github.com/opencontainers/runc/libcontainer/user
# github.com/pelletier/go-toml v1.9.5
@ -605,7 +606,7 @@ github.com/theupdateframework/notary/tuf/data
github.com/theupdateframework/notary/tuf/signed
github.com/theupdateframework/notary/tuf/utils
github.com/theupdateframework/notary/tuf/validation
# github.com/tonistiigi/fsutil v0.0.0-20221114235510-0127568185cf
# github.com/tonistiigi/fsutil v0.0.0-20230105215944-fb433841cbfa
## explicit; go 1.18
github.com/tonistiigi/fsutil
github.com/tonistiigi/fsutil/types

Loading…
Cancel
Save