Compare commits

...

1209 Commits

Author SHA1 Message Date
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
2023-03-06 16:25:59 +00:00
CrazyMax
d455c07331 build: strip credentials from remote url on collecting Git provenance info
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-06 17:14:40 +01:00
Tõnis Tiigi
5ac3b4c4b6 Merge pull request #1662 from crazy-max/v0.10.4_picks
[v0.10] cherry-picks for v0.10.4
2023-03-06 14:37:30 +00:00
CrazyMax
b1440b07f2 build: makes git dirty check opt-in
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-03-06 10:56:54 +01:00
David Karlsson
a3286a0ab1 docs: added --platform=local example
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2023-03-06 10:54:42 +01:00
Tõnis Tiigi
b79345c63e Merge pull request #1645 from cpuguy83/0.10_env_no_provenance
[0.10] Add env var to disable default attestations
2023-02-22 10:28:01 -08:00
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>
2023-02-22 18:20:34 +00:00
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
2023-02-16 14:22:20 +01:00
CrazyMax
c960d16da5 ci: update buildx and buildkit to latest
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit f1a5a3ec50)
2023-02-16 14:16:36 +01:00
CrazyMax
b5b9de69d9 Merge pull request #1635 from crazy-max/v0.10_backport_fix-git-ambiguous
[v0.10 backport] build: fix git ambiguous argument
2023-02-16 14:14:11 +01:00
David Gageot
45863c4f16 Remove git warning: buildx/1633
Signed-off-by: David Gageot <david.gageot@docker.com>
(cherry picked from commit d4a4aaf509)
2023-02-16 14:07:28 +01:00
CrazyMax
f2feea8bed Merge pull request #1609 from crazy-max/0.10.3_cherry_picks
[v0.10] cherry-picks for v0.10.3
2023-02-16 13:48:46 +01:00
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)
2023-02-16 13:21:41 +01:00
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)
2023-02-09 22:23:02 +01:00
CrazyMax
661af29d46 build: check reachable git commits
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit fd5884189c)
2023-02-08 14:34:23 +01:00
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)
2023-02-08 14:34:14 +01:00
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)
2023-02-08 14:33:53 +01:00
Justin Chadwell
582cc04be6 build: add docs for boolean attestation flags
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 07548bc898)
2023-02-08 14:33:35 +01:00
CrazyMax
ae278ce450 builder: fix docker context not validated
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 0e544fe835)
2023-02-08 14:31:43 +01:00
Justin Chadwell
b66988c824 bake: fix loop references
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 48357ee0c6)
2023-02-08 14:29:45 +01:00
Tõnis Tiigi
00ed17df6d Merge pull request #1569 from tonistiigi/v0.10.2-picks
[v0.10] cherry-picks for v0.10.2
2023-01-30 11:57:04 -08:00
CrazyMax
cfb71fab97 build: better message output for git provenance
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 6db696748b)
2023-01-30 11:46:51 -08:00
CrazyMax
f62342768b build: silently fail if git remote not found
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
(cherry picked from commit 4789d2219c)
2023-01-30 11:46:42 -08:00
Tonis Tiigi
7776652a4d build: fix multi-node merge to read descriptor from result
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit c33b310b48)
2023-01-30 11:46:12 -08:00
Akihiro Suda
5a4f80f3ce bake: SOURCE_DATE_EPOCH: fix panic: assignment to entry in nil map
Fix issue 1562

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

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

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

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

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

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

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

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

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

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

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

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 01e1c28dd9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-18 20:58:27 +01:00
CrazyMax
bf4b95fc3a Merge pull request #1524 from jedevc/v0.10-docs-reference-attest
[0.10] docs: add reference for new attest family of flags
2023-01-17 16:24:18 +01:00
Justin Chadwell
467586dc8d docs: add reference for new attest family of flags
Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-17 13:48:19 +00:00
Tõnis Tiigi
8764628976 Merge pull request #1501 from tonistiigi/v0.10-picks
[v0.10] cherry-picks
2023-01-09 16:10:12 -08:00
Justin Chadwell
583fe71740 docs: update with new inspect output
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 9818055b0e)
2023-01-09 15:53:42 -08:00
Justin Chadwell
9fb3ff1a27 inspect: change additional spdxs to not have duplicates
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 484823c97d)
2023-01-09 15:53:37 -08:00
Justin Chadwell
9d4f38c5fa inspect: provide access to multiple spdx documents
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 3ce17b01dc)
2023-01-09 15:53:34 -08:00
Justin Chadwell
793082f543 inspect: parse sbom and provenance into json structs
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit e68c566c1c)
2023-01-09 15:53:29 -08:00
Justin Chadwell
fe6f697205 inspect: break after first matching attestation
Signed-off-by: Justin Chadwell <me@jedevc.com>
(cherry picked from commit 19d16aa941)
2023-01-09 15:53:13 -08:00
Tonis Tiigi
fd3fb752d3 github: update CI to buildkit v0.11
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
(cherry picked from commit 571871b084)
2023-01-09 15:52:51 -08:00
CrazyMax
7fcea64eb4 Merge pull request #1496 from thaJeztah/0.10_backport_docs_updates
[0.10 backport] update anchor-links and cli-docs-tool v0.5.1
2023-01-09 15:52:56 +01:00
Sebastiaan van Stijn
05e0ce4953 go.mod: update cli-docs-tool v0.5.1 and re-generate docs
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c97500b117)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-09 13:05:27 +01:00
Sebastiaan van Stijn
f8d9d1e776 docs: update anchor links
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit b8285c17e6)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2023-01-09 13:05:27 +01:00
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>
2023-01-06 16:33:47 -08:00
CrazyMax
e4db8d2a21 imagetools inspect: missing annotations key
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2023-01-06 16:33:47 -08:00
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>
2023-01-06 16:33:46 -08:00
Justin Chadwell
a8be6b576b docs: update oci layout with tag resolution
Signed-off-by: Justin Chadwell <me@jedevc.com>
2023-01-06 16:33:46 -08:00
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>
2023-01-06 16:33:46 -08:00
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>
2023-01-06 16:33:46 -08:00
Tõnis Tiigi
37fce8cc06 Merge pull request #1489 from AkihiroSuda/cherrypick-1482-v0.10
[0.10] Propagate SOURCE_DATE_EPOCH from the client env
2023-01-05 23:45:21 -08:00
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>
2023-01-05 08:48:27 +09:00
Tõnis Tiigi
88852e2330 Merge pull request #1480 from crazy-max/fix-badge
disable buildx experimental in pipeline
2022-12-16 10:28:20 -08:00
CrazyMax
6369c50614 disable buildx experimental in pipeline
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-16 18:53:46 +01:00
CrazyMax
a22d0a35a4 readme: fix status badge
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-16 17:52:30 +01:00
CrazyMax
c93c02df85 Merge pull request #1479 from jedevc/fixup-git-err-check-order
build: check error from toSolveOpt before adding FrontendAttrs
2022-12-16 16:28:17 +01:00
Justin Chadwell
e584c6e1a7 build: check error from toSolveOpt before adding FrontendAttrs
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-16 12:19:33 +00:00
Tõnis Tiigi
64e4c19971 Merge pull request #1477 from crazy-max/git-wsl
build: lookup the right git binary on WSL
2022-12-15 18:00:52 -08:00
Tonis Tiigi
551b8f6785 git: do not show warnings if project does not use git
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-12-15 17:51:46 -08:00
Tõnis Tiigi
fbbe1c1b91 Merge pull request #1472 from crazy-max/ci-attest
ci: opt-in sbom and provenance
2022-12-15 17:38:13 -08:00
Tonis Tiigi
1a85745bf1 github: update buildkit image to v0.11-rc3
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-12-15 16:54:32 -08:00
CrazyMax
0d1fea8134 build: warn if git operation fails
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-15 23:40:19 +01:00
CrazyMax
19417e76e7 build: lookup the right git binary on WSL
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-15 21:16:37 +01:00
Tõnis Tiigi
53d88a79ef Merge pull request #1475 from jedevc/attest-warn-duplicate
buildflags: error on duplicate attest field
2022-12-15 11:07:47 -08:00
Justin Chadwell
4c21b7e680 Merge pull request #1476 from jedevc/dont-filter-attestation-opts
build: forward all build opts everywhere
2022-12-15 19:05:39 +00:00
Justin Chadwell
a8f689c223 build: forward all build opts everywhere
All build options should be passed everywhere - the frontend and the
backend of buildkit should both be able to see all attestations, as well
as all other opts: e.g. epoch settings, and no-cache.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-15 18:19:47 +00:00
CrazyMax
ba8e3f9bc5 ci: generate provenance and sbom for bin image
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-15 19:12:26 +01:00
CrazyMax
477200d1f9 ci: generate provenance and sbom for release binaries
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-15 19:12:25 +01:00
Tõnis Tiigi
662738a7e5 Merge pull request #1474 from crazy-max/fix-ci
ci: fix warnings
2022-12-15 09:29:25 -08:00
Justin Chadwell
f992b77535 buildflags: warn on duplicate attest field
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-15 15:39:19 +00:00
CrazyMax
21b2f135b5 ci: update to ubuntu 22.04
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-15 14:34:03 +01:00
CrazyMax
71e6be5d99 ci: fix deprecated set-output syntax
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-15 14:24:02 +01:00
CrazyMax
df8e7d0a9a Merge pull request #1473 from crazy-max/fix-docs-prerelease
ci: do not publish docs on prerelease
2022-12-15 14:22:07 +01:00
CrazyMax
64422a48d9 Merge pull request #1471 from crazy-max/fix-builder-factory
builder: check endpoint from store when loading factory
2022-12-15 14:19:20 +01:00
CrazyMax
04f9c62772 ci: do not publish docs on prerelease
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-15 14:16:45 +01:00
CrazyMax
2185d07f05 builder: check endpoint from store when loading factory
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-15 13:32:54 +01:00
CrazyMax
a49d28e00e Merge pull request #1460 from crazy-max/docker-load
e2e: load to docker store
2022-12-15 10:35:29 +01:00
Tõnis Tiigi
629128c497 Merge pull request #1449 from crazy-max/bake-var-null
bake: support null arg and label value
2022-12-14 21:03:05 -08:00
Justin Chadwell
b741d26eb5 Merge pull request #1468 from crazy-max/fix-git-vcs-check
build: fix env vars check for vcs details
2022-12-14 12:51:29 +00:00
CrazyMax
cf8fa4a404 build: fix env vars check for vcs details
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-14 09:48:55 +01:00
CrazyMax
fe76a1b179 bake: support null label value
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-14 08:30:58 +01:00
CrazyMax
df4957307f bake: support null arg value
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-14 08:29:27 +01:00
Tõnis Tiigi
e21f56e801 Merge pull request #1434 from jedevc/resource-interpolation
Resource interpolation support
2022-12-13 18:06:51 -08:00
Justin Chadwell
e51b55e03c bake: add tests for block interpolation
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-13 17:27:39 -08:00
Justin Chadwell
296b8249cb bake: support block-based interpolation
This patch adds support for block-based interpolation, so that
properties of blocks can be referenced in the current block and across
other blocks.

Previously, order-of-evaluation did not matter for blocks, and could be
evaluated in any order. However, now that blocks can refer to each
other, we split out this dynamic evaluation order into a separate
resolveBlock function.

Additionally, we need to support partial block evaluations - if block A
refers to property X of block B, when we should only evaluate property
X, and not the entire block. This ensures that we can safely evaluate
blocks that refer to other properties within themselves, and allows
sequences that would otherwise be co-recursive. We take special care in
this logic to ensure that each property is evaluated once *and only*
once - this could otherwise present inconsistencies with stateful
functions, and could risk inconsistent results.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-13 17:27:39 -08:00
Justin Chadwell
7c6b840199 bake: add cty tags to hcl structures
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-13 17:27:36 -08:00
Tõnis Tiigi
2a6ff4cbfc Merge pull request #1462 from crazy-max/attest-vcs
build: set provenance vcs details
2022-12-13 17:23:20 -08:00
CrazyMax
6ad5e2fcf3 build: set provenance vcs details
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-14 00:09:38 +01:00
Tõnis Tiigi
37811320ef Merge pull request #1439 from crazy-max/last-activity
store: set nodegroup last activity
2022-12-13 15:00:47 -08:00
CrazyMax
99ac7f5f9e e2e: load to docker store
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-13 23:32:58 +01:00
Tõnis Tiigi
96aca741a2 Merge pull request #1467 from tonistiigi/update-buildkit-862b22
vendor: update buildkit to 862b22d7
2022-12-13 12:07:42 -08:00
Tonis Tiigi
12ec931237 vendor: update buildkit to 862b22d7
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-12-13 12:00:06 -08:00
Justin Chadwell
0e293a4ec9 Merge pull request #1464 from jedevc/vendor-buildkit-93b40706a007
vendor: update buildkit to 93b40706a007
2022-12-13 11:12:54 +00:00
Justin Chadwell
163712a23b vendor: update buildkit to 93b40706a007
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-13 11:03:53 +00:00
Tõnis Tiigi
5f4d463780 Merge pull request #1435 from thaJeztah/bump_buildkit_v0.11
vendor: github.com/moby/buildkit v0.11.0-rc1.0.20221207183946-5993b526de65
2022-12-08 19:51:10 -08:00
Tõnis Tiigi
abc8121aa8 Merge pull request #1457 from jedevc/add-hosts-length-check
build: don't set add-hosts option if empty
2022-12-08 19:48:09 -08:00
CrazyMax
8c47277141 store: set nodegroup last activity
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-08 19:49:51 +01:00
CrazyMax
36b5cd18e8 store: use constants for directory names
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-08 19:35:55 +01:00
Justin Chadwell
1e72e32ec3 Merge pull request #1412 from jedevc/attestations-cli
Attestations from buildx
2022-12-08 17:30:31 +00:00
Sebastiaan van Stijn
8e5e5a563d vendor: github.com/moby/buildkit v0.11.0-rc1.0.20221207183946-5993b526de65
- drops the replace-rule for github.com/aws/aws-sdk-go-v2/config (as it no longer was replacing anything)
- drops the replace-rules for docker/cli and docker/docker (at least as long as we continue using tagged releases)
- removes the github.com/docker/docker/pkg/stringid package (which was redundant)

full diff: 9624ab4710..5993b526de

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-12-07 23:27:29 +01:00
Justin Chadwell
98049e7eda build: don't set add-hosts option if empty
This looks like an oversight, all of the other options have similar
checks. This can interfere with generated provenance where "add-hosts"
will be marked as an argument to the build, even though it's not
actually being utilized.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-07 19:16:01 +00:00
Justin Chadwell
25aa893bad bake: add attests field
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-07 18:44:21 +00:00
Justin Chadwell
b270a20274 build: add attests flag and sbom/provenance shorthands
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-07 18:44:11 +00:00
Justin Chadwell
f0262dd10e build: add attestations to build options
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-07 18:43:36 +00:00
Justin Chadwell
f8b673eccd build: pass attestation attributes to build request
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-07 16:10:54 +00:00
Justin Chadwell
0c0c9a0030 chore: sort buildOptions alphabetically
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-12-07 16:10:54 +00:00
CrazyMax
d1f79317cf Merge pull request #1455 from crazy-max/nodegroup-exclude-field
store: skip DockerContext field from being saved
2022-12-07 16:07:30 +01:00
CrazyMax
fa58522242 store: skip DockerContext field from being saved
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-07 13:15:18 +01:00
CrazyMax
aa6fd3d888 Merge pull request #1454 from crazy-max/builder-fix-default
builder: fix default docker context behavior
2022-12-07 11:03:06 +01:00
CrazyMax
ebdd8834a9 builder: fix default docker context behavior
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-07 08:52:12 +01:00
CrazyMax
fe8d5627e0 Merge pull request #1433 from crazy-max/makefile-build-opts
hack: mutualize build opts in Makefile and Dockerfile
2022-12-07 05:04:44 +01:00
CrazyMax
b242e3280b Merge pull request #1430 from crazy-max/builder-pkg
Refactor builder and drivers info logic
2022-12-06 12:41:10 +01:00
CrazyMax
cc01caaecb builder: enhance driver factory logic when loading drivers
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-06 12:13:41 +01:00
CrazyMax
e7b5ee7518 mutualize builder logic
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-06 12:13:41 +01:00
CrazyMax
63073b65c0 dockerutil pkg to manage docker api client and context
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-06 12:13:41 +01:00
CrazyMax
47cf72b8ba Merge pull request #1451 from crazy-max/update-buildkit
vendor: update buildkit to master@9624ab4
2022-12-05 17:30:39 +01:00
CrazyMax
af24d72dd8 kubernetes: fix context load test
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-05 17:13:03 +01:00
CrazyMax
f451b455c4 vendor: update buildkit to master@9624ab4
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-05 17:03:47 +01:00
Justin Chadwell
16f4dfafb1 Merge pull request #1450 from crazy-max/fix-hclparser-jsonfunc
hcl: SrcRange not checked when solving JSON func calls
2022-12-05 15:17:23 +00:00
CrazyMax
5b4e8b9d71 hcl: SrcRange not checked when solving JSON func calls
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-05 15:05:17 +01:00
CrazyMax
b06eaffeeb Merge pull request #1442 from crazy-max/hcl-fix-panic
bake: fix panic for unsupported hcl variable type
2022-12-05 14:30:04 +01:00
CrazyMax
3d55540db1 Merge pull request #1445 from dvdksn/docs/move-manuals
docs: moved manual pages to docs repo, added link
2022-12-03 15:41:01 +01:00
Tõnis Tiigi
3c2b9aab96 Merge pull request #1446 from crazy-max/moby-host-gateway
build: skip "host-gateway" validation with moby driver
2022-12-02 20:24:40 -08:00
CrazyMax
49d46e71de build: skip "host-gateway" validation with moby driver
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-02 13:53:13 +01:00
David Karlsson
6c5168e1ec docs: moved manual pages to docs repo, added link
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-12-02 09:49:54 +01:00
Tõnis Tiigi
e91d5326fe Merge pull request #1441 from crazy-max/fix-nil-ref
imagetools: set default repo ref on creation if nil
2022-12-01 09:51:09 -05:00
CrazyMax
48b573e835 bake: fix panic for unsupported hcl variable type
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-12-01 00:52:05 +01:00
CrazyMax
4788eb24ab imagetools: set default repo ref on creation if nil
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-11-30 23:18:43 +01:00
CrazyMax
3ed2783f34 Merge pull request #1436 from thaJeztah/protobuf_extensions_fix
go.mod: golang_protobuf_extensions v1.0.4 - prevent incompat versions
2022-11-30 14:11:33 +01:00
Sebastiaan van Stijn
c0e8a41a6f go.mod: golang_protobuf_extensions v1.0.4 - prevent incompat versions
This module made a whoopsie, and updated to `google.golang.org/protobuf`
in a patch release, but `google.golang.org/protobuf` is not backward
compatible with `github.com/golang/protobuf`.

Updating the minimum version to v1.0.4 which corrects this, to prevent
users of buildx as a module from accidentally pulling in the wrong
version:

- v1.0.3 switched to use `google.golang.org/protobuf`; https://github.com/matttproud/golang_protobuf_extensions/compare/v1.0.2..v1.0.3
- This was reverted in v1.0.4 (which is the same as v1.0.2); https://github.com/matttproud/golang_protobuf_extensions/compare/v1.0.3..v1.0.4
- And a `v2` was created instead; https://github.com/matttproud/golang_protobuf_extensions/releases/tag/v2.0.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-11-30 13:31:42 +01:00
CrazyMax
23b217af24 hack: mutualize build opts in Makefile and Dockerfile
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-11-29 17:05:25 +01:00
CrazyMax
3dab19f933 Merge pull request #1432 from crazy-max/hack-hash-files
hack: improve hash-files script
2022-11-29 13:28:56 +01:00
CrazyMax
05efb6291f hack: improve hash-files script
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-11-29 12:36:34 +01:00
CrazyMax
eba49fdefd Merge pull request #1255 from crazy-max/docker-api
docker api: use helper to parse context docker endpoint metadata
2022-11-29 12:16:52 +01:00
CrazyMax
29f2c49374 Merge pull request #1268 from crazy-max/hack-output
hack: use single output dir
2022-11-29 12:16:38 +01:00
CrazyMax
2245371696 Merge pull request #1420 from jedevc/oci-tar
Support new `tar` option for oci+docker exporters
2022-11-29 11:48:10 +01:00
CrazyMax
74631d5808 Merge pull request #1431 from docker/dependabot/github_actions/peter-evans/create-pull-request-4.2.3
build(deps): Bump peter-evans/create-pull-request from 4.2.2 to 4.2.3
2022-11-28 20:11:01 +01:00
dependabot[bot]
9264b0ca09 build(deps): Bump peter-evans/create-pull-request from 4.2.2 to 4.2.3
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4.2.2 to 4.2.3.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](331d02c7e2...2b011faafd)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-28 18:13:29 +00:00
CrazyMax
a96fb92939 Merge pull request #1429 from crazy-max/update-gh-release
ci: update softprops/action-gh-release to v0.1.15
2022-11-28 14:04:02 +01:00
CrazyMax
ae59e1f72e Merge pull request #1305 from jedevc/progress-group-prefixed-writer
progress: add prefix to vertex progress group
2022-11-28 13:32:27 +01:00
CrazyMax
47167a4e6f ci: update softprops/action-gh-release to v0.1.15
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-11-28 13:29:13 +01:00
CrazyMax
23cabd67fb Merge pull request #1427 from docker/dependabot/github_actions/peter-evans/create-pull-request-4.2.2
build(deps): Bump peter-evans/create-pull-request from 4.2.0 to 4.2.2
2022-11-25 11:27:43 +01:00
CrazyMax
e66410b932 Merge pull request #1313 from jedevc/bake-group-recurse
bake: recursively resolve groups
2022-11-25 11:27:09 +01:00
dependabot[bot]
c3bba05770 build(deps): Bump peter-evans/create-pull-request from 4.2.0 to 4.2.2
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4.2.0 to 4.2.2.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](b4d51739f9...331d02c7e2)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-24 18:07:15 +00:00
Justin Chadwell
69b91f2760 docs: add tar flag to oci+docker exporters
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-11-23 11:35:38 +00:00
Justin Chadwell
e6b09580b4 build: support tar flag for oci+docker exporters
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-11-23 11:35:38 +00:00
Justin Chadwell
36e663edda vendor: update buildkit to master@ae9d0f5
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-11-23 11:35:38 +00:00
Justin Chadwell
60e2029e70 Merge pull request #1419 from jedevc/docs-clarify-support
docs: clarify support for various sets of shared options
2022-11-23 10:25:14 +00:00
Justin Chadwell
5e1db43e34 docs: clarify support for various sets of shared options
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-11-22 11:10:50 +00:00
CrazyMax
6e9b743296 Merge pull request #1417 from accetto/patch-2
Correction in Synopsis.
2022-11-21 09:40:21 +01:00
accetto
ef9710d8e2 Correction in Synopsis.
Correction in Synopsis.

Signed-off-by: accetto <34798830+accetto@users.noreply.github.com>
2022-11-20 13:34:52 +00:00
CrazyMax
468b3b9c8c Merge pull request #1407 from AkihiroSuda/x-crypto-ssh
go.mod: golang.org/x/crypto v0.1.0 (Fix `ssh: parse error in message type 27` with OpenSSH >= 8.9)
2022-11-17 13:27:05 +01:00
CrazyMax
0d8c853917 Merge pull request #1394 from thaJeztah/update_cobra
go.mod: github.com/spf13/cobra v1.6.1
2022-11-17 13:22:29 +01:00
CrazyMax
df3b868fe7 Merge pull request #1414 from crazy-max/move-k8s-config
kubernetes: move context config logic to its own pkg
2022-11-17 11:22:40 +01:00
CrazyMax
3f6a5ab6ba kubernetes: move context config logic to its own pkg
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-11-17 00:34:42 +01:00
Tõnis Tiigi
aa1f4389b1 Merge pull request #1396 from crazy-max/fix-indent
use double spaces with json marshal indent
2022-11-16 14:54:13 -08:00
Justin Chadwell
246cd2aee9 Merge pull request #1411 from jedevc/docker-container-volume-docs
docs: add cache persistence notes for docker-container driver
2022-11-16 12:29:01 +00:00
Justin Chadwell
0b6f8149d1 docs: add cache persistence notes for docker-container driver
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-11-16 11:56:42 +00:00
Akihiro Suda
4dda2ad58b go.mod: golang.org/x/crypto v0.1.0
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2022-11-16 07:43:29 +09:00
Justin Chadwell
15bb14fcf9 Merge pull request #1406 from felixdesouza/fds/fix-concurrent-map-write
Synchronise access to the map when printing.
2022-11-15 15:46:54 +00:00
Felix de Souza
b68114375f Address feedback
Signed-off-by: Felix de Souza <fdesouza@palantir.com>
2022-11-14 18:40:05 +00:00
Felix de Souza
83a09b3cf2 Synchronise access to the map when printing.
Signed-off-by: Felix de Souza <fdesouza@palantir.com>
2022-11-14 15:47:32 +00:00
Justin Chadwell
3690cb12e6 Merge pull request #1397 from markhildreth-gravity/patch-1
Correct documentation on gha scopes
2022-11-10 13:39:11 +00:00
Justin Chadwell
b4de4826c4 Merge pull request #1403 from jedevc/docs-fixups
Docs consistency fixes
2022-11-10 13:29:41 +00:00
Justin Chadwell
b06df637c7 docs: use consistent "Type" header across parameter tables
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-11-10 10:44:17 +00:00
Justin Chadwell
9bb9ae43f9 docs: add env parameter to docker-container driver
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-11-10 10:44:17 +00:00
Mark Hildreth
35e7172b89 Correct documentation on gha scopes
I believe the documentation is misleading in saying that specifying a scope in a gha cache declaration will `ensure each branch gets its own cache`. I believe this should say that each build or each image will get its own cache.

Signed-off-by: Mark Hildreth <mark.hildreth@gravityclimate.com>
2022-11-07 11:06:07 -05:00
CrazyMax
abebf4d955 use double spaces with json marshal indent
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-11-07 16:36:24 +01:00
Sebastiaan van Stijn
1c826d253b go.mod: github.com/spf13/cobra v1.6.1
full diff: https://github.com/spf13/cobra/compare/v1.5.0...v1.6.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-11-06 19:03:52 +01:00
CrazyMax
d1b454232d Merge pull request #1392 from dvdksn/refactor-docs
docs: refactored file and directory structure
2022-11-05 10:07:10 +01:00
David Karlsson
be3b41acc6 docs: refactored file and directory structure
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-11-04 19:57:50 +01:00
Justin Chadwell
2a3e51ebfe Merge pull request #1390 from dvdksn/update-docs-default-branch
docs: update git ref to docs repo
2022-11-04 16:54:44 +00:00
David Karlsson
1382fda1c9 docs: update git ref to docs repo
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-11-04 16:37:46 +01:00
Justin Chadwell
c658096c17 Merge pull request #1385 from jedevc/exporter-docs
Add exporter docs
2022-11-04 15:16:30 +00:00
Justin Chadwell
6097919958 docs: change cache storage links to exporter to docs site
Temporary fix while we update docs upstream.

Co-Authored-By: David Karlsson <david.karlsson@docker.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-11-04 14:57:17 +00:00
Tõnis Tiigi
330bdde0a3 Merge pull request #1383 from jedevc/with-tracer-delegate-panic
driver: don't create tracer delegate opt if tracer is nil
2022-11-02 10:58:58 -07:00
CrazyMax
a55404fa2e Merge pull request #1388 from crazy-max/fix-docs-validate
ci(docs-upstream): fix ref on pull request event
2022-11-02 15:22:29 +01:00
CrazyMax
c8c7c9f376 Merge pull request #1387 from crazy-max/update-compose-go
update github.com/compose-spec/compose-go to v1.6.0
2022-11-02 15:22:12 +01:00
CrazyMax
df34c1ce45 ci(docs-upstream): switch to reusable workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-11-01 19:45:00 +01:00
CrazyMax
da1d66c938 update github.com/compose-spec/compose-go to v1.6.0
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-11-01 16:14:56 +01:00
Justin Chadwell
d32926a7e5 docs: add exporter docs
This patch adds more complete documentation for the various exporters
available to buildx.

Co-Authored-By: David Karlsson <david.karlsson@docker.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-11-01 12:16:45 +00:00
Justin Chadwell
7f008a7d1e driver: don't create tracer delegate opt if tracer is nil
The error handling for the cast to client.TracerDelegate was incorrect,
and previously, a client would unconditionally append an opt.

This results in the scenario that while the ClientOpt was not nil, the
tracer delegate in the ClientOpt was, which isn't an error case
explicitly handled by buildkit.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-10-31 11:19:47 +00:00
Tõnis Tiigi
eab3f704f5 Merge pull request #1371 from jedevc/progress-tty-fail
progress: explicitly fail if tty requested but not available
2022-10-25 11:07:50 -07:00
Justin Chadwell
a50e89c38e progress: explicitly fail if tty requested but not available
The NewPrinter function is mostly borrowed from buildkit. However, at
some point, it seems that the implementations drifted.

This patch updates buildx to be more similar in behavior to it's
buildkit counterpart, specifically, it will explicitly fail if a TTY
output is requested using "--progress=tty", but the output is not
available.

To gracefully fallback to plain progress in this scenario,
"--progress=plain" is required.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-10-25 10:55:36 +01:00
CrazyMax
85723a138f hack: lint scripts
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-24 08:30:35 +02:00
CrazyMax
9c69ba6f6f hack: use single output dir
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-24 08:30:35 +02:00
CrazyMax
e84ed65525 Merge pull request #1356 from thaJeztah/protobuf_extensions_tag
go.mod: matttproud/golang_protobuf_extensions v1.0.2 (use tag)
2022-10-24 08:15:35 +02:00
CrazyMax
4060abd3aa Merge pull request #1363 from docker/dependabot/github_actions/peter-evans/create-pull-request-4.2.0
build(deps): Bump peter-evans/create-pull-request from 4.1.4 to 4.2.0
2022-10-24 08:15:17 +02:00
CrazyMax
c924a0428d Merge pull request #1368 from jedevc/userns-to-driver
Userns to driver
2022-10-24 08:15:01 +02:00
Justin Chadwell
33ef1b3a30 docker-container: move userns detection into driver
This moves the detection of the docker daemon's security options into
the driver from the factory, handling them in a similar way to how we do
cgroups.

Because of recent changes that modify error detection in driver
creation, this attempt to contact the docker daemon during builder
creation meant that a docker-container builder could not be created
without access to the docker socket. This patch resolves this, by
defering the Info call to the driver, when the container is actually
created.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-10-21 13:44:44 +01:00
Justin Chadwell
a6caf4b948 chore: tidy up duplicate dockertypes import
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-10-21 13:40:17 +01:00
Justin Chadwell
cc7e11da99 Merge pull request #1366 from jedevc/remove-structcheck
lint: remove structcheck
2022-10-20 10:22:50 +01:00
Justin Chadwell
a4c3efe783 lint: add nolintlint and fix violations
We should be able to detect nolint comments that point to linters that
are disabled (such as with the removed structcheck).

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-10-20 09:49:51 +01:00
Justin Chadwell
4e22846e95 lint: remove structcheck
structcheck is abandoned, and has been replaced by the unused linter.
See https://golangci-lint.run/usage/linters/#structcheck for more
information.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-10-19 14:19:06 +01:00
dependabot[bot]
ddbd0cd095 build(deps): Bump peter-evans/create-pull-request from 4.1.4 to 4.2.0
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4.1.4 to 4.2.0.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](ad43dccb4d...b4d51739f9)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-18 18:56:21 +00:00
Justin Chadwell
255a3ec82c Merge pull request #1361 from dvdksn/docs-fix-cache-codeblocks
docs: add user sign for console blocks
2022-10-18 11:57:53 +01:00
David Karlsson
167c77baec docs: add user sign for console blocks
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-10-18 12:50:14 +02:00
CrazyMax
ca2718366e Merge pull request #1000 from tonistiigi/docs-named-context
docs: make sure syntax with latest stable dockerfile image is defined
2022-10-18 10:08:06 +02:00
CrazyMax
58d3a643b9 Merge pull request #1345 from crazy-max/bake-print
bake: do not fail printing definition if instance unavailable
2022-10-18 10:05:14 +02:00
CrazyMax
718b8085fa Merge pull request #1354 from dvdksn/fix-cache-cmds
docs: fix cache command examples
2022-10-17 22:32:29 +02:00
CrazyMax
64930d7440 Merge pull request #1359 from jedevc/cache-inline-typo
docs: fix typo in cache docs
2022-10-17 22:31:27 +02:00
CrazyMax
4d2f948869 Merge pull request #1360 from docker/dependabot/github_actions/peter-evans/create-pull-request-4.1.4
build(deps): Bump peter-evans/create-pull-request from 4.1.3 to 4.1.4
2022-10-17 22:30:54 +02:00
dependabot[bot]
19c224cbe1 build(deps): Bump peter-evans/create-pull-request from 4.1.3 to 4.1.4
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4.1.3 to 4.1.4.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](671dc9c9e0...ad43dccb4d)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-17 18:34:07 +00:00
Justin Chadwell
efd1581c01 docs: fix typo in cache docs
We should keep consistency with the rest of the list, and call it
"inline" instead of "inline-cache".

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-10-17 17:06:41 +01:00
Tõnis Tiigi
ac85f590ba Merge pull request #1324 from jedevc/invoke-defaults
invoke: load defaults from image config
2022-10-13 09:01:29 -07:00
Sebastiaan van Stijn
b0d3162875 go.mod: matttproud/golang_protobuf_extensions v1.0.2 (use tag)
it's the same commit: https://github.com/matttproud/golang_protobuf_extensions/compare/v1.0.2...c182affec369

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-10-13 16:12:19 +02:00
David Karlsson
4715a7e9e1 docs: fix cache command examples
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-10-12 17:15:55 +02:00
CrazyMax
c5aec243c9 Merge pull request #1353 from dvdksn/absolute-links-part2
docs: replaced broken relative links
2022-10-11 23:16:10 +02:00
David Karlsson
c76f3d3dba docs: replaced broken relative links
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-10-11 21:35:52 +02:00
Justin Chadwell
7add6e48b6 Merge pull request #1352 from dvdksn/remove-cache-opt-link
remove/update links to satisfy htmlproofer
2022-10-11 13:17:26 +01:00
David Karlsson
1267e0c076 changed from relative to absolute links
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-10-11 13:53:06 +02:00
Justin Chadwell
361c093a35 Merge pull request #1332 from dvdksn/refactor-cache-docs
added tables for cache parameters
2022-10-11 12:19:35 +01:00
CrazyMax
9ad39a29f7 Merge pull request #1334 from dvdksn/driver-docs-review
Driver docs update
2022-10-07 16:17:18 +02:00
David Karlsson
f5a1d8bff9 moved context arg to last
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-10-06 14:04:54 +02:00
CrazyMax
8c86afbd57 Merge pull request #1310 from AkihiroSuda/gcos-rootless
kubernetes: rootless: support Google Container-Optimized OS  (Fix ` Options:[rbind ro]}]: operation not permitted` errors)
2022-10-06 11:05:19 +02:00
David Karlsson
4d6e36df99 review comments, align style with driver docs
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-10-05 20:33:57 +02:00
David Karlsson
f51884e893 address review comments
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-10-05 20:18:42 +02:00
David Karlsson
4afd9ecf16 fix incorrect heading text
Co-authored-by: Justin Chadwell <github@jedevc.com>
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-10-05 20:10:55 +02:00
David Karlsson
ed3b311de4 improve wording on default buildkit image
Co-authored-by: Justin Chadwell <github@jedevc.com>
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-10-05 20:10:50 +02:00
David Karlsson
d030fcc076 updated prose and structure for driver docs
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-10-05 20:10:27 +02:00
CrazyMax
398da1f916 Merge pull request #1343 from dgageot/fix-1342
[1342] Fix assignment to nil map
2022-10-04 17:31:06 +02:00
CrazyMax
3a5741f534 Merge pull request #1341 from dgageot/fix-1340
[1340] Disable git labels if `BUILDX_GIT_LABELS` is not `1` or `full`
2022-10-04 17:04:35 +02:00
CrazyMax
c53b0b8a12 bake: do not fail printing definition if instance unavailable
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-10-04 15:38:45 +02:00
David Gageot
8fd34669ed Fix assignment to nil map
Signed-off-by: David Gageot <david.gageot@docker.com>
2022-10-04 08:30:47 +02:00
David Gageot
be7e91899b Support empty env var when it can't be unset
Signed-off-by: David Gageot <david.gageot@docker.com>
2022-10-03 18:36:06 +02:00
David Karlsson
74a822568e added tables for cache parameters
Signed-off-by: David Karlsson <david.karlsson@docker.com>
2022-09-29 21:40:47 +02:00
CrazyMax
105c214d15 Merge pull request #1333 from docker/dependabot/github_actions/peter-evans/create-pull-request-4.1.3
build(deps): Bump peter-evans/create-pull-request from 4.1.2 to 4.1.3
2022-09-29 17:25:43 +02:00
dependabot[bot]
2b6a51ed34 build(deps): Bump peter-evans/create-pull-request from 4.1.2 to 4.1.3
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4.1.2 to 4.1.3.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](171dd555b9...671dc9c9e0)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-28 18:46:49 +00:00
CrazyMax
e98c252490 Merge pull request #1327 from docker/dependabot/github_actions/peter-evans/create-pull-request-4.1.2
build(deps): Bump peter-evans/create-pull-request from 4.0.4 to 4.1.2
2022-09-22 14:08:32 +02:00
CrazyMax
17f5d6309f Merge pull request #1329 from jedevc/ignore-workflows-on-docs-changes
ci: don't trigger build and e2e workflows on docs-only pull requests
2022-09-22 14:08:09 +02:00
CrazyMax
6a46ea04ab Merge pull request #1316 from jedevc/cache-docs
docs: add cache storage backend docs
2022-09-22 14:07:06 +02:00
CrazyMax
7bd97f6717 Merge pull request #1318 from crazy-max/new-docs-links
docs: update links to new docs
2022-09-22 14:06:47 +02:00
CrazyMax
2a9c98ae40 remove unrelated comment after upgrade
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-09-22 13:53:33 +02:00
Justin Chadwell
1adf80c613 ci: don't trigger build and e2e workflows on docs-only pull requests
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-09-22 11:00:55 +01:00
Justin Chadwell
f823d3c73c docs: final cache storage fixups
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-09-22 10:52:13 +01:00
David Karlsson
91f0ed3fc3 docs: additions from editorial review
- editorial review
- address review comments, rework param sections
- added a common section for parameters
- remove liquid tags for notes

Signed-off-by: David Karlsson <david.karlsson@docker.com>
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-09-22 10:51:16 +01:00
Justin Chadwell
04b56c7331 docs: add cache storage backend docs
This fleshes out the documentation to include information along with
examples and detailed use cases for the cache backends. The general
format and style follows from the style of the build driver docs.

Eventually, these docs will be included on docs.docker.com along with
the rest of the build docs.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-09-22 10:51:16 +01:00
dependabot[bot]
3c1a20097f build(deps): Bump peter-evans/create-pull-request from 4.0.4 to 4.1.2
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 4.0.4 to 4.1.2.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](923ad837f1...171dd555b9)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-21 18:48:36 +00:00
Justin Chadwell
966c4d4e14 invoke: load defaults from image config
If user does not specify image certain container parameters, we can load
them from the exporter metadata.

Additionally, we introduce a new "default" value for the --invoke flag,
that keeps all of the default parameters (since cobra does not have an
easy way of accepting an optional flag argument).

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-09-21 11:43:52 +01:00
CrazyMax
6b8289d68e docs: update links to new docs
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-09-14 13:36:51 +02:00
CrazyMax
294421db9c Merge pull request #1317 from crazy-max/fix-link
docs: fix link in driver guide
2022-09-14 11:33:20 +02:00
CrazyMax
9fdf991c27 docs: update links in driver guide
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-09-13 22:11:47 +02:00
Justin Chadwell
77b33260f8 bake: recursively resolve groups
Groups that contained other groups were not recursively resolved by
ReadTargets, which prevented output from --print from being useable as a
self-contained bake file.

This patch ensures that all groups that are referenced inside the bake
file are actually defined under the groups field. This has required a
substantial refactor, as previously only a single group was returned
from ReadTargets, notably, returning a map of groups, instead of a
slice.

This does introduce a small behavior change to the behavior of --print -
while previously, passing a group name to bake would return all the
targets of that group back as the default group, now only the name of
that group will be inserted into the default group, keeping the original
group intact. The impact of this can be observed in some of the changes
to the bake_test.go file.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-09-12 13:51:34 +01:00
Akihiro Suda
33e5f47c6c kubernetes: rootless: support Google Container-Optimized OS
Tested with GKE Autopilot 1.24.3-gke.200 (kernel 5.10.123+, containerd 1.6.6).

ref: moby/buildkit PR 3097

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2022-09-09 17:16:35 +09:00
CrazyMax
25ceb90678 Merge pull request #1294 from crazy-max/s3-cache
s3 cache client-side support
2022-09-08 14:26:19 +02:00
CrazyMax
27e29055cb Merge pull request #1307 from zhyon404/master
return di.Err when it's not nil
2022-09-08 14:20:14 +02:00
Tõnis Tiigi
810ce31f4b Merge pull request #1297 from cdupuis/git-revision
Add git provenance labels
2022-09-06 10:23:50 -07:00
Christian Dupuis
e3c91c9d29 Add git provenance labels
as per #1290

Signed-off-by: Christian Dupuis <cd@atomist.com>
2022-09-06 19:11:55 +02:00
zhyon404
2f47838ea1 return di.Err when it's not nil
Signed-off-by: zhyon404 <zhyong4@gmail.com>
2022-09-05 18:05:03 +08:00
Justin Chadwell
0566e62995 progress: add prefix to vertex progress group
As buildkit now uses progress groups for the COPY --link instruction
we need to ensure that we additionally prefix the progress group name,
or the target name will be left off in bake commands with more than one
target.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-09-02 16:45:51 +01:00
CrazyMax
aeac42be47 Merge pull request #1299 from thaJeztah/store_cleanup
store: move regex to where it's used
2022-08-31 19:35:05 +02:00
Sebastiaan van Stijn
aa21ff7efd store: move regex to where it's used
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-08-31 19:19:51 +02:00
CrazyMax
57d22a7bd1 s3 cache client-side support
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-30 17:00:15 +02:00
CrazyMax
6804bcbf12 Merge pull request #1298 from nicksieger/compose-go-1.5.0
vendor: bump compose-go to v1.5.0
2022-08-30 15:31:19 +02:00
Nick Sieger
6d34cc0b60 vendor: bump compose-go to v1.5.0
Signed-off-by: Nick Sieger <nick@nicksieger.com>
2022-08-29 10:22:31 -05:00
Tõnis Tiigi
1bb375fe5c Merge pull request #1265 from crazy-max/go-1.19
Dockerfile: update to go 1.19
2022-08-24 21:19:51 -07:00
Tõnis Tiigi
ed00243a0c Merge pull request #1279 from jedevc/inspect-buildkit-version
inspect: add buildkit version information to command output
2022-08-18 09:44:29 -07:00
Tõnis Tiigi
1223e759a4 Merge pull request #1281 from jedevc/fixup-1273
Prevent duplicate "failed to find driver" message
2022-08-18 09:43:09 -07:00
Tõnis Tiigi
4fd3ec1a50 Merge pull request #1277 from crazy-max/fix-compose-merge
bake(compose): fix unskipped services without build context
2022-08-18 09:41:49 -07:00
Justin Chadwell
7f9cad1e4e buildx: prevent duplicate "failed to find driver" message
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-08-18 14:20:47 +01:00
Justin Chadwell
437b8b140f docs: update buildx inspect reference with buildkit version
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-08-18 11:27:38 +01:00
Justin Chadwell
8f0d9bd71f inspect: add buildkit version information to command output
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-08-18 11:03:03 +01:00
CrazyMax
1378c616d6 docs: missing syntax directive
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-18 12:01:20 +02:00
Tonis Tiigi
3b5dfb3fb4 docs: make sure all named context examples use 1.4
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-08-18 11:57:22 +02:00
CrazyMax
9c22be5d9c bake: test compose file validation
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-18 11:34:41 +02:00
CrazyMax
42dea89247 bake: test for unknown extensions
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-18 11:34:40 +02:00
CrazyMax
982a332679 bake(compose): fix unskipped services without build context
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-18 11:34:40 +02:00
Justin Chadwell
441853f189 Merge pull request #1274 from jedevc/consistent-experimental-help
Consistent experimental help
2022-08-18 09:37:47 +01:00
Tõnis Tiigi
611329fc7f Merge pull request #1273 from jedevc/fix-1269
create: improve interface when attempting to create docker driver
2022-08-16 10:50:04 -07:00
Tõnis Tiigi
f3c135e583 Merge pull request #1275 from tonistiigi/update-buildx-220816
vendor: update buildkit to 55ba9d14
2022-08-16 10:47:40 -07:00
Tonis Tiigi
7f84582b37 vendor: update buildkit to 55ba9d14
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-08-16 10:22:36 -07:00
Justin Chadwell
297526c49d docs: add experimental options to build command reference
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-08-16 12:40:46 +01:00
Justin Chadwell
d01d394a2b build: ensure consistent help messages for experimental cli help
Append an [experimental] tag to the end of each experimental command to
highlight that these are experimental options. Square brackets are used
instead of parentheses as parentheses are already in use to highlight
examples and defaults.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-08-16 11:07:36 +01:00
Justin Chadwell
17d4369866 create: improve interface when attempting to create docker driver
Previously, the help information for buildx indicated that users could
create a new instance of the docker driver - which is explicitly
something we don't support, driver of this form are automatically
derived from the available list of docker contexts.

This patch ensures that don't have AllowsInstance set will not appear in
the help text, and additionally provide a new more specific error
message instead of the generic "failed to find driver". This should help
point users in the correct direction.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-08-16 10:58:23 +01:00
Tonis Tiigi
fb5e1393a4 commands: use buildx env for experimental opt-in
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-08-16 10:37:56 +01:00
Tonis Tiigi
18dbde9ed6 build: update outline fallback image
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-08-16 10:25:26 +01:00
CrazyMax
2a13491919 Dockerfile: update golangci-lint to 1.48.0 (go 1.19 support)
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-11 02:10:33 +02:00
CrazyMax
3509a1a7ff Dockerfile: update to go 1.19
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-11 02:10:19 +02:00
Tõnis Tiigi
da1f4b8496 Merge pull request #1100 from tonistiigi/print-outline
Build: Support for printing outline/targets of the current build
2022-08-09 18:34:15 -07:00
Tõnis Tiigi
5b2e1d3ce4 Merge pull request #1261 from crazy-max/bake-env
bake: load .env file from working dir for compose files
2022-08-09 18:31:40 -07:00
CrazyMax
7d8a6bc1d7 bake: load .env file from working dir for compose files
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-10 03:24:38 +02:00
CrazyMax
a378f8095e test: misplaced expected value in assert
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-10 02:18:35 +02:00
Tõnis Tiigi
005bc009e8 Merge pull request #1262 from tonistiigi/docker-driver-features
enable other exporters if docker driver uses containerd
2022-08-09 15:37:41 -07:00
Tonis Tiigi
3bc7d4bec6 enable other exporters if docker driver uses containerd
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-08-09 14:16:30 -07:00
Tõnis Tiigi
96c1b05238 Merge pull request #1257 from tonistiigi/invoke-release
build: fix issues with leaving invoke containers running
2022-08-09 12:29:41 -07:00
CrazyMax
98f9f806f3 Merge pull request #1260 from ndeloof/moby-containerd
detect moby worker supports multiplatform feature through containerd snapshotter
2022-08-09 18:05:50 +02:00
Tonis Tiigi
c834ba1389 add formatting support to print function
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-08-09 08:24:59 -07:00
Tonis Tiigi
cab437adef build: add fallback to outline requests if not supported by frontend
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-08-09 08:24:59 -07:00
Tonis Tiigi
eefa8188e1 build: add experimental support for print flag
Print flag can be used to make additional information
requests about the build and print their results.

Currently Dockerfile supports: outline, targets, subrequests.describe

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-08-09 08:24:52 -07:00
Nicolas De Loof
1d8db8a738 detect moby worker supports multiplatform feature through containerd snapshotter
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
2022-08-09 14:41:08 +02:00
Tonis Tiigi
75ddc5b811 build: fix issues with leaving invoke containers running
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-08-08 23:16:59 -07:00
Tõnis Tiigi
17dc0e1108 Merge pull request #1259 from ktock/invoke-messages
invoke: add messages
2022-08-08 23:16:38 -07:00
Tõnis Tiigi
64ac6c9621 Merge pull request #1256 from crazy-max/x-bake-miss
bake: contexts support with x-bake
2022-08-08 11:43:05 -07:00
CrazyMax
a7753ea781 Merge pull request #1250 from jedevc/prune-all-help
docs: add correct definition of prune --all flag
2022-08-08 14:20:36 +02:00
Justin Chadwell
12a6eb5b22 docs: add correct definition of prune --all flag
The previous definition was the same as the docker images prune command
and referenced dangling images, which isn't what the command does. This
commit brings the command description more inline with the buildctl
definition.

Additionally, add some more description of what the various flags do in
our reference pages.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-08-08 11:31:53 +01:00
CrazyMax
74b21258b6 Merge pull request #1252 from jedevc/prune-filter-until
Fix prune `--filter until=<duration>` option
2022-08-08 12:00:55 +02:00
Kohei Tokunaga
2f9d46ce27 invoke: add messages
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
2022-08-08 17:35:28 +09:00
Tõnis Tiigi
7b660c4e30 Merge pull request #1188 from jedevc/driver-opt-warnings
Introduce new errors for unsupported driver behaviors
2022-08-05 16:58:24 -07:00
Justin Chadwell
406799eb1c prune: cleanup variable names for clarity
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-08-05 17:20:52 +01:00
Justin Chadwell
ef0cbf20f4 buildx: warn on editing nodes
Previously, editing nodes to contain a new set of driver options or
config files was unsupported, and silently dropping them. In this patch,
we update with these, as well as add a new warning message that any new
options may not taken into account until the builder restarts (which
may apply to the flags, platforms and endpoints as well).

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-08-05 17:18:02 +01:00
CrazyMax
7f572eb044 bake: contexts support with x-bake
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-05 15:21:26 +02:00
CrazyMax
0defb614a4 docker api: use helper to parse context docker endpoint metadata
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-04 15:38:04 +02:00
CrazyMax
18023d7f32 Merge pull request #1054 from thaJeztah/test_cli_update
vendor: v20.10.3-0.20220803220330-418ca3b4d46f (v22.06.0-dev)
2022-08-04 11:42:26 +02:00
Sebastiaan van Stijn
4983b98005 vendor: v20.10.3-0.20220803220330-418ca3b4d46f (v22.06.0-dev)
full diff: f1615facb1...418ca3b4d4

relevant changes;

- cli/command: remove unused args from ResolveDefaultContext()
- consider empty DOCKER_HOST and DOCKER_CONTEXT env-vars equivalent to "not set"
- cli: set timeout connection ping on sockets as well

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-08-04 00:45:51 +02:00
Tõnis Tiigi
8675e02cea Merge pull request #1253 from crazy-max/improve-ci
ci: enhanced build workflow
2022-08-03 12:03:48 -07:00
CrazyMax
45fc3bf842 ci: enhanced build workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-03 20:53:01 +02:00
Tõnis Tiigi
cf809aec47 Merge pull request #1218 from crazy-max/validate-docs-upstream
ci: upstream docs conformance validation
2022-08-03 10:53:05 -07:00
CrazyMax
cceb1acca8 docs: fix dead link to color output controls guide
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-02 21:22:09 +02:00
CrazyMax
e620c40a14 ci: upstream docs conformance validation
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-02 21:22:08 +02:00
Tõnis Tiigi
e1590bf68b Merge pull request #1248 from tonistiigi/add-jedevc
add jedevc to maintainers
2022-08-02 08:54:45 -07:00
CrazyMax
bad07943b5 Merge pull request #1247 from crazy-max/docs-pr-on-released
ci: open pr on docs repo only on release
2022-08-02 15:29:09 +02:00
CrazyMax
603595559f Merge pull request #1251 from crazy-max/update-compose
update github.com/compose-spec/compose-go to v1.4.0
2022-08-02 14:11:02 +02:00
Justin Chadwell
febcc25d1a prune: fix filter until option
Previously, when specifying the filter option with the until value, no
cache would be cleaned, preventing users from clearing by time. This bug
arises from passing the until field through into buildkit, where, on
filtering, a non-existent field returns false for a match.

The fix is simple, as we build up our list of filters to pass to
buildkit, we skip over the until key, so create a valid list of filters
for buildkit.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-08-02 12:15:28 +01:00
CrazyMax
e3c0e34b33 update github.com/compose-spec/compose-go to v1.4.0
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-02 13:00:48 +02:00
Justin Chadwell
3f5974b7f9 buildx: forbid mismatched drivers
This patch reorders+refactors the runCreate function to ensure that we
can detect and notify the user in the scenario that the user attempts to
combine multiple drivers in a single builder, which is an unsupported
scenario.

Previously, we would just overwrite the previous builder with the new
driver, potentially invalidating the already existing nodes.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-08-02 11:06:44 +01:00
Justin Chadwell
7ab3dc080b kubernetes: error about unused endpoint argument
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-08-02 11:06:44 +01:00
Tonis Tiigi
0883beac30 add jedevc to maintainers
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-08-01 22:22:47 -07:00
CrazyMax
f9102a3295 ci: open pr on docs repo only on release
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-02 03:03:37 +02:00
Tõnis Tiigi
f360088ae7 Merge pull request #974 from crazy-max/k8s-azure-auth
kubernetes: enable azure auth
2022-08-01 17:16:16 -07:00
CrazyMax
dfc1b361a9 kubernetes: enable azure auth
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-01 16:51:48 -07:00
Tõnis Tiigi
19641ec8ca Merge pull request #1214 from jedevc/timestamp-func
bake: add timestamp function
2022-08-01 16:41:21 -07:00
Tõnis Tiigi
02f7d54aed Merge pull request #1246 from crazy-max/update-compose
update github.com/compose-spec/compose-go to v1.3.0
2022-08-01 16:32:31 -07:00
Tõnis Tiigi
1f6612b118 Merge pull request #1137 from jedevc/imagetools-multiple-repositories
Imagetools multiple repositories
2022-08-01 16:30:53 -07:00
Tõnis Tiigi
c1fbebe73f Merge pull request #1206 from jedevc/init-builder-errors
buildx: log errors in initializing builders
2022-08-01 16:10:18 -07:00
Tõnis Tiigi
30d650862d Merge pull request #1011 from crazy-max/bake-target-name
bake(compose): allow dot in target name
2022-08-01 10:14:58 -07:00
CrazyMax
52fd555bdd update github.com/compose-spec/compose-go to v1.3.0
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-01 14:12:33 +02:00
CrazyMax
7b25e2cffc Merge pull request #1245 from crazy-max/fix-readme
chore: fix readme
2022-08-01 13:30:45 +02:00
CrazyMax
5eb1e40fea chore: fix readme
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-08-01 12:08:28 +02:00
CrazyMax
7ef679d945 bake(compose): allow dot in target name
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-31 16:53:44 +02:00
Tõnis Tiigi
480bf2e123 Merge pull request #1241 from jedevc/docker-driver-docs
docs: add minimal docker driver docs
2022-07-29 13:35:32 -07:00
CrazyMax
0078390934 Merge pull request #1129 from crazy-max/fix-docker-context
check context builder endpoint
2022-07-29 18:16:34 +02:00
Justin Chadwell
06c11ecb61 docs: add minimal docker driver docs
Mostly for completeness, this patch adds basic documentation for the
docker driver.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-29 16:54:01 +01:00
CrazyMax
e27a5966ef check context builder endpoint
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-29 17:39:10 +02:00
Justin Chadwell
f1a9f91323 imagetools: support cross-repo mounting
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-29 14:29:29 +01:00
Justin Chadwell
4ecca34a42 imagetools: give imagetools create a progress bar
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-29 14:29:27 +01:00
Justin Chadwell
37ca8631f9 imagetools: copy manifests between repositories
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-29 14:29:05 +01:00
Justin Chadwell
d3412f1039 imagetools: refactor combining repository logic
This patch modifies the existing combining code in imagetools create to
provide better support for multiple repositories down the road.
Specifically, the code should no longer rely on a single repository
being used for all sources and tags, and should resolve descriptors in
their relevant repositories.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-29 14:21:27 +01:00
CrazyMax
8288ce96cc Merge pull request #1240 from crazy-max/docs-fix-links-2
docs: fix link to docs website
2022-07-29 13:32:10 +02:00
CrazyMax
0222b74ee1 docs: fix link to docs website
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-29 13:26:02 +02:00
CrazyMax
97bccc5ecf Merge pull request #1239 from crazy-max/docs-fix-links
docs: fix link
2022-07-29 12:22:25 +02:00
CrazyMax
47ea0c5b03 docs: fix link
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-29 12:16:56 +02:00
Tõnis Tiigi
766653f7a6 Merge pull request #994 from corhere/local-dockerfile-remote-context
build: allow external Dockerfile on remote context
2022-07-28 22:32:25 -07:00
Tõnis Tiigi
264451ba18 Merge pull request #1233 from jedevc/drivers-guides
Enhanced driver guides
2022-07-28 18:27:21 -07:00
Justin Chadwell
a42eb73043 docs: add further reading section for drivers
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-28 11:21:33 +01:00
Justin Chadwell
f2b504b77d docs: add basic docker-container driver guide
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-28 11:21:33 +01:00
Justin Chadwell
68ef5b9c9b docs: create dedicated drivers section
Create a dedicated folder for information on drivers, and write a new
index.md with content adapted from the README, and a new feature
comparisons table.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-28 11:21:33 +01:00
CrazyMax
07992e66e0 Merge pull request #1236 from crazy-max/docs-experimental-note
docs(bake): set experimental note
2022-07-27 18:43:45 +02:00
CrazyMax
4522331229 docs(bake): set experimental note
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-27 13:48:37 +02:00
CrazyMax
ec1ba14f3e Merge pull request #1215 from crazy-max/docs-fix-bake-fields
docs(bake): fix target fields and show type
2022-07-27 13:42:39 +02:00
CrazyMax
0694efb566 Merge pull request #1235 from crazy-max/update-cli-docs-tool
docs: update cli-docs-tool to v0.5.0
2022-07-27 13:40:26 +02:00
CrazyMax
1324827cd5 docs(bake): fix target fields and show type
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-27 13:13:32 +02:00
Justin Chadwell
86825a95ce buildx: rollback configuration if create fails
This builds on the added warnings from initialized builders, now
erroring the command, and additionally attempting to revert to the
previous configuration.

To preserve the previous configuration, we add a deep Copy() function to
the NodeGroup and Node so that we can easily restore it later if we
encounter a failure.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-27 11:53:47 +01:00
CrazyMax
dd445e5f9b docs: update cli-docs-tool to v0.5.0
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-26 19:39:04 +02:00
Tõnis Tiigi
3075a5a8c1 Merge pull request #1184 from crazy-max/docs-workflow
ci: release workflow to open a PR on docs repo with latest changes
2022-07-26 10:26:20 -07:00
Tõnis Tiigi
9ff5fb0356 Merge pull request #1224 from crazy-max/update-docker-cli
vendor: update docker/cli to f1615fa
2022-07-25 09:10:03 -07:00
CrazyMax
bc19deb5d0 Merge pull request #1232 from crazy-max/docs-remove-frontmatter
docs: remove frontmatter section
2022-07-25 11:25:15 +02:00
CrazyMax
1c7088ee42 docs: remove frontmatter section
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-25 11:01:41 +02:00
CrazyMax
97d3841fbf Merge pull request #1230 from crazy-max/docs-color-ouput
docs(guide): color output controls
2022-07-23 12:29:00 +02:00
CrazyMax
20022fd441 docs(guide): color output controls
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-23 02:57:02 +02:00
Tõnis Tiigi
23455744ac Merge pull request #1226 from spkane/spkane/colorized-buildkit-output
Update buildkit w/ customizable output colors, etc.
2022-07-22 16:55:02 -07:00
Tõnis Tiigi
0ee14fb653 Merge pull request #1229 from crazy-max/docs-update-links
docs: replace links with ones from docs.docker.com
2022-07-22 16:54:21 -07:00
CrazyMax
ff57ae1705 docs: replace links with ones from docs.docker.com
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-22 17:05:07 +02:00
CrazyMax
8da133e34f ci: release workflow to open a PR on docs repo with latest changes
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-22 16:02:15 +02:00
CrazyMax
b0deb8bdd7 vendor: update docker/cli to f1615fa
also needs to update docker/docker to a60b458 (22.06 branch) otherwise
build breaks since docker/cli#3512 with:

    # github.com/docker/cli/cli/flags
    vendor/github.com/docker/cli/cli/flags/common.go:40:37: undefined: client.EnvOverrideCertPath
    vendor/github.com/docker/cli/cli/flags/common.go:41:37: undefined: client.EnvTLSVerify
    vendor/github.com/docker/cli/cli/flags/common.go:89:76: undefined: client.EnvOverrideHost

needs also to update github.com/spf13/cobra to v1.5.0 otherwise
build breaks with:

    # github.com/docker/cli/cli-plugins/plugin
    vendor/github.com/docker/cli/cli-plugins/plugin/plugin.go:130:4: unknown field 'HiddenDefaultCmd' in struct literal of type cobra.CompletionOptions

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-22 10:53:37 +02:00
Sean P. Kane
6583dd3aa2 Update buildkit w/ customizable output colors, etc.
Signed-off-by: Sean P. Kane <spkane00@gmail.com>
2022-07-21 15:45:02 -07:00
CrazyMax
701c548e46 Merge pull request #1223 from crazy-max/update-xx
Update xx to 1.1.2
2022-07-21 14:16:21 +02:00
CrazyMax
0db719af8a Update xx to 1.1.2
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-21 13:17:51 +02:00
Tõnis Tiigi
7eb1235629 Merge pull request #1217 from crazy-max/fix-docs-links
docs(guides): fix links
2022-07-19 11:48:08 -07:00
Tõnis Tiigi
11c1e03e93 Merge pull request #1155 from crazy-max/compose-cacheto
bake: support compose build cache_to
2022-07-19 11:39:28 -07:00
Tõnis Tiigi
bea1ac296c Merge pull request #1173 from deitch/oci-layout-support
add support for oci-layout build-context
2022-07-19 10:13:12 -07:00
CrazyMax
2df799d331 docs(guides): fix links
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-07-19 18:56:41 +02:00
CrazyMax
fecc6958cb Merge pull request #1208 from jedevc/kubernetes-builder-docs
docs: add new kubernetes build driver docs
2022-07-19 18:21:15 +02:00
Avi Deitcher
02bae945c3 add support for oci-layout build-context
Signed-off-by: Avi Deitcher <avi@deitcher.net>
2022-07-18 21:19:03 -04:00
Justin Chadwell
691723f9f9 bake: add timestamp function
Terraform includes a timestamp function to get the current time. go-cty
has imported a number of the timestamp functions to it's standard
library, however, this was one was not included.

This patch simply pulls in the TimestampFunc from Terraform's
internal/lang/funcs/datetime.go to allow easily fetching the current
time in bake.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-18 11:29:35 +01:00
Justin Chadwell
900f356df9 docs: add new kubernetes build driver docs
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-18 09:54:12 +01:00
CrazyMax
724cb29042 Merge pull request #1207 from developer-guy/fix/doc
fix: correct determnistic word
2022-07-12 16:15:41 +02:00
Batuhan Apaydın
f69c62f07a fix: correct determnistic word
Signed-off-by: Batuhan Apaydın <batuhan.apaydin@trendyol.com>
2022-07-12 16:52:55 +03:00
Justin Chadwell
309c49413c buildx: log errors in initializing builders
Previously, errors within the driver config would not be reported to the
user until they tried to use the driver, even though they are easily
accessible from the node group info.

This patch reports these errors (but will not fail because of them,
since the data is already saved) - this should help improve
debuggability of some of the more complex drivers, and prevent error
messages being suppressed.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-12 13:10:05 +01:00
CrazyMax
6824cf4548 Merge pull request #1204 from jedevc/remote-builder-typos
docs: fixup remote builder typos
2022-07-11 09:56:52 +02:00
Justin Chadwell
881b48a3b6 docs: fixup remote builder typos
- Ensure that buildx is always used as a docker subcommand
- Correct invalid buildx ls output

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-08 15:33:35 +01:00
CrazyMax
5b452b72a2 Merge pull request #1198 from jedevc/bump-buildkit-f4eb826
Bump buildkit to master branch
2022-07-06 17:15:00 +02:00
Justin Chadwell
27fcb73c7c bake: add tests for missing attributes in userfuncs
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-06 16:03:41 +01:00
Justin Chadwell
2aa22597f0 bake: forbid empty result and params in userfuncs
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-06 16:03:41 +01:00
Justin Chadwell
d9ef9bec34 kubernetes: add error when no pods available
This prevents the fall-through to the panic from division by zero in the
modulus below, and presents a neater error to the user.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-06 16:02:48 +01:00
Justin Chadwell
3b4780ef19 vendor: bump buildkit to master
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-07-06 09:47:29 +01:00
CrazyMax
12fde33d9b bake: dedup compose main and extension fields values
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-23 21:58:05 +02:00
CrazyMax
a0f92829a7 bake: merge cache-from field from compose and x-bake
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-23 21:58:05 +02:00
CrazyMax
b438032a60 bake: support compose build cache_to
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-23 21:58:04 +02:00
Tõnis Tiigi
3cf549a7f7 Merge pull request #1181 from crazy-max/compose-consistency
bake: fix compose consistency check
2022-06-23 09:51:14 -07:00
CrazyMax
f8884a58e9 Merge pull request #1182 from crazy-max/remove-yamllint
chore: remove yamllint
2022-06-23 13:26:50 +02:00
CrazyMax
5ce3909c48 bake: fix compose consistency check
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-23 13:09:17 +02:00
CrazyMax
45fac6dee3 chore: remove yamllint
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-23 11:15:01 +02:00
Tõnis Tiigi
a8bb25d1b5 Merge pull request #1168 from ktock/invoke
Add `--invoke` option to launch a container from the build result
2022-06-21 08:51:25 -07:00
Kohei Tokunaga
387e1ecca6 Add --invoke option to launch a container from the build result
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
2022-06-21 10:32:07 +09:00
CrazyMax
ad7b077d13 Merge pull request #1167 from crazy-max/refactor-xbake
bake: better handling of compose extension interface
2022-06-16 23:17:52 +02:00
CrazyMax
432c2b2650 bake: better handling of compose extension interface
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-14 23:23:43 +02:00
Tõnis Tiigi
055e85f48f Merge pull request #1166 from crazy-max/ci-concurrency
ci: add concurrency check
2022-06-14 12:49:15 -07:00
Tõnis Tiigi
91fec23f5d Merge pull request #1153 from crazy-max/update-compose-go
bake: support compose build tags and secrets env
2022-06-14 12:45:33 -07:00
Tõnis Tiigi
0295555a5a Merge pull request #1109 from crazy-max/ls-progress
ls: move builder/node status error msg below table
2022-06-14 10:03:22 -07:00
CrazyMax
6cb1b85d7b bake: support compose build tags
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-14 18:45:57 +02:00
CrazyMax
e0350f671a bake: support compose secrets env
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-14 18:45:23 +02:00
CrazyMax
c1adfcb658 ci: add concurrency check
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-14 17:54:10 +02:00
CrazyMax
1343cdfc83 Merge pull request #1140 from crazy-max/bake-docs
docs: bake guides and refactor reference
2022-06-10 09:45:49 +02:00
CrazyMax
f40c2dbb86 docs: rework bake compose file definition
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-09 12:53:01 +02:00
CrazyMax
50c23aa755 update github.com/compose-spec/compose-go to v1.2.7
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-08 22:53:15 +02:00
CrazyMax
ff9517cbf0 docs: rework bake "Configuring builds" page
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-08 16:45:08 +02:00
CrazyMax
824b0268d8 docs: bake specification intro
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-08 16:14:34 +02:00
CrazyMax
77ea999adb docs: guide page to configure bake builds
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-05 18:49:16 +02:00
CrazyMax
1807cfdd26 docs: changes to bake file definition guide
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-05 18:49:16 +02:00
CrazyMax
ebd7d062bf docs: bake guides and refactor reference
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-05 18:48:09 +02:00
CrazyMax
6cb026b766 Merge pull request #1148 from crazy-max/fix-no-output-warn
build: enhance warning message when no output specified
2022-06-05 17:30:46 +02:00
CrazyMax
1cb1ee018b build: enhance warning message when no output specified
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-06-03 19:26:21 +02:00
Tõnis Tiigi
71e4a39ae9 Merge pull request #1134 from jedevc/remote-driver-connhelpers
Remote driver connhelpers
2022-05-31 16:09:55 -07:00
CrazyMax
009730f5fd Merge pull request #1145 from docker/dependabot/github_actions/crazy-max/ghaction-github-runtime-2
build(deps): bump crazy-max/ghaction-github-runtime from 1.0.0 to 2
2022-05-27 07:01:42 +02:00
dependabot[bot]
36466c0744 build(deps): bump crazy-max/ghaction-github-runtime from 1.0.0 to 2
Bumps [crazy-max/ghaction-github-runtime](https://github.com/crazy-max/ghaction-github-runtime) from 1.0.0 to 2.
- [Release notes](https://github.com/crazy-max/ghaction-github-runtime/releases)
- [Changelog](https://github.com/crazy-max/ghaction-github-runtime/blob/master/CHANGELOG.md)
- [Commits](94085cef04...906832f62b)

---
updated-dependencies:
- dependency-name: crazy-max/ghaction-github-runtime
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-26 18:31:58 +00:00
Justin Chadwell
1406ff141b docs: add connhelpers info to remote-builder guide
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-05-25 10:39:16 +01:00
Justin Chadwell
1eff9310f8 remote: add additional connhelpers to buildx
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-05-25 10:39:16 +01:00
Justin Chadwell
22ac3271d2 vendor: update moby/buildkit
Update modules:

  go mod edit -require github.com/moby/buildkit@master
  go mod tidy -compat=1.17 && ./hack/update-vendor

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-05-25 10:20:57 +01:00
CrazyMax
064bd92583 ls: move builder/node status error msg below table
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-24 22:37:08 +02:00
Tõnis Tiigi
1beb3359a6 Merge pull request #1144 from tonistiigi/nil-platform
imagetools: handle manifest with nil platform
2022-05-24 10:05:59 -07:00
Tõnis Tiigi
35f4268081 Merge pull request #1128 from crazy-max/rm
rm: display removed builder and disallow removing context builders
2022-05-24 09:40:26 -07:00
CrazyMax
81ce766501 Merge pull request #1130 from photra/clarify-inspect-docs
Clarify inspect documentation
2022-05-24 14:11:22 +02:00
CrazyMax
66a764f9c1 Merge pull request #1143 from jedevc/revive-linter
Update golint to revive
2022-05-24 09:15:00 +02:00
Tonis Tiigi
e4137b2eea imagetools: handle manifest with nil platform
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-05-23 21:16:00 -07:00
Justin Chadwell
48067735fc Update golint to revive
Resolves the following message in golangci output:

> The linter 'golint' is deprecated (since v1.41.0) due to: The
repository of the linter has been archived by the owner.  Replaced by
revive.

Additionally, fix a minor linting issue discovered by revive.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-05-23 16:54:46 +01:00
CrazyMax
54a2a0c49f cli: uppercase level to match logrus one
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-20 10:59:33 +02:00
CrazyMax
d611bbe609 rm: display name of removed builder
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-20 10:59:33 +02:00
CrazyMax
1e71a3ffa7 rm: disallow removing context builders
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-20 10:59:32 +02:00
Tõnis Tiigi
4a215a943b Merge pull request #1131 from crazy-max/ls-dedup
ls: dedup instances from store and context
2022-05-19 17:30:58 -07:00
CrazyMax
69d95cc847 create: warn if instance name already exists as context builder
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-19 17:17:44 +02:00
Tõnis Tiigi
cdd391e556 Merge pull request #1136 from jedevc/remote-builder-docs-typo
Fix typo in docker-container remote driver instructions
2022-05-18 19:51:55 -07:00
Justin Chadwell
d69fe6140d docs: fix typo in docker-container remote driver instructions
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-05-18 10:35:09 +01:00
Cory Snider
ca3507656d build: allow external Dockerfile on remote context
BuildKit has supported external Dockerfile on remote contexts since
v0.5.0, included in Moby v19.03.0. The client side was the only missing
piece.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2022-05-16 16:47:08 -04:00
CrazyMax
78ae826d74 ls: dedup instances from store and context
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-15 08:30:31 +02:00
Phong Tran
5a8060ea9f Clarify inspect documentation
Signed-off-by: Phong Tran <tran.pho@northeastern.edu>
2022-05-14 23:09:38 -07:00
Tõnis Tiigi
908ce2d206 Merge pull request #1097 from crazy-max/dockerfile-test-stage
dockerfile: enhance test stage
2022-05-13 13:56:11 -07:00
CrazyMax
69824a5d27 Merge pull request #1111 from crazy-max/default-conf
create: load default buildkit config if none specified
2022-05-13 14:23:01 +02:00
CrazyMax
5d38fff729 Merge pull request #1120 from docker/dependabot/github_actions/codecov/codecov-action-3
build(deps): bump codecov/codecov-action from 2 to 3
2022-05-13 13:46:47 +02:00
CrazyMax
31d12c89fa Merge pull request #1123 from crazy-max/update-gha
ci: update gha bundle
2022-05-13 13:45:33 +02:00
CrazyMax
8257a04a7d create: load default buildkit config if none specified
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-13 11:54:16 +02:00
CrazyMax
bdc41dd308 ci: pin external/untrusted github actions
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-12 20:23:33 +02:00
CrazyMax
f6e00a609d ci: bump official actions to latest major
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-12 20:20:51 +02:00
CrazyMax
1845edd647 ci: remove godev workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-12 19:55:00 +02:00
CrazyMax
cab4cfe28f ci: bump docker actions to latest major
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-12 19:54:44 +02:00
dependabot[bot]
815c1dd05c build(deps): bump codecov/codecov-action from 2 to 3
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 2 to 3.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-12 17:26:02 +00:00
Tõnis Tiigi
bbfdaa4161 Merge pull request #1096 from crazy-max/ci-cache
ci: enable cache
2022-05-12 10:25:15 -07:00
Tõnis Tiigi
a9e62dfa83 Merge pull request #1098 from crazy-max/dependabot-gha
chore: dependabot to keep gha up to date
2022-05-12 10:22:39 -07:00
Tõnis Tiigi
b9a408017c Merge pull request #1093 from jedevc/remote-driver-guide
Add remote driver guide
2022-05-12 10:22:11 -07:00
Tõnis Tiigi
062cf29de2 Merge pull request #1103 from jedevc/remote-driver-bootstrap
Use --bootstrap to wait for remote to become active
2022-05-12 10:21:15 -07:00
Justin Chadwell
a2f1de6459 Add remote driver guide
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-05-12 10:44:27 +01:00
Tõnis Tiigi
98439f7f08 Merge pull request #1108 from crazy-max/ls-docs
docs: update ls output example
2022-05-11 11:21:37 -07:00
Tõnis Tiigi
6854eec48d Merge pull request #1057 from thaJeztah/vendor_update
vendor: vendor with -compat=1.17
2022-05-10 13:53:56 -07:00
CrazyMax
1edfb13ba8 docs: update ls output example
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-10 20:54:38 +02:00
Sebastiaan van Stijn
35b238ee82 vendor: vendor with -compat=1.17
This might break compatibility with projects using this module that
are still on go1.16, which is EOL, so probably ok to ignore:

    github.com/docker/buildx/store imports
        github.com/gofrs/flock tested by
        github.com/gofrs/flock.test imports
        gopkg.in/check.v1 loaded from gopkg.in/check.v1@v1.0.0-20200227125254-8fa46927fb4f,
        but go 1.16 would select v1.0.0-20201130134442-10cb98267c6c

    To upgrade to the versions selected by go 1.16:
        go mod tidy -go=1.16 && go mod tidy -go=1.17
    If reproducibility with go 1.16 is not needed:
        go mod tidy -compat=1.17
    For other options, see:
        https://golang.org/doc/modules/pruning

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-05-10 20:33:20 +02:00
Tõnis Tiigi
55b85f5bb2 Merge pull request #998 from crazy-max/ls-buildkit-version
ls: display buildkit version of the nodes
2022-05-10 08:37:38 -07:00
CrazyMax
57156ee95c ls: adds fallback if buildkit version info unimplemented
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-09 16:17:30 +02:00
Justin Chadwell
c245f30a94 remote: use --bootstrap to wait for remote to become active
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-05-09 13:51:07 +01:00
CrazyMax
6e3babc461 ls: display buildkit version of the nodes
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-09 14:12:31 +02:00
CrazyMax
4ee8b14f2a vendor: update buildkit to c78f696
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-09 14:12:31 +02:00
CrazyMax
21b41e580a chore: dependabot to keep gha up to date
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-06 12:51:43 +02:00
CrazyMax
cc90c5ca3c dockerfile: use gobase for test stage
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-06 11:59:43 +02:00
CrazyMax
519aca3672 ci: enable cache
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-06 11:55:54 +02:00
CrazyMax
43968ffa68 Merge pull request #1094 from jedevc/remote-e2e-flake
Attempt to solve some flakiness in the remote driver ci
2022-05-06 10:40:40 +02:00
Justin Chadwell
79ba92b7f8 ci: add check remote buildkitd step in e2e tests
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-05-06 09:19:55 +01:00
CrazyMax
e0cffbdbdf Merge pull request #1095 from crazy-max/fix-checksum-file
release: fix checksum file
2022-05-05 16:15:59 +02:00
CrazyMax
df799b6a0f release: fix checksum file
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-05 14:29:54 +02:00
CrazyMax
27bdbea410 Merge pull request #1087 from crazy-max/fix-guides
docs: fix guides for docs.docker.com
2022-05-05 11:50:06 +02:00
CrazyMax
1e52c2107c Merge pull request #1049 from tonistiigi/update-dockerfile-deps
Dockerfile: update dependencies
2022-05-02 17:49:49 +02:00
CrazyMax
cf298ee01c docs: fix guides for docs.docker.com
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-05-02 13:10:48 +02:00
CrazyMax
e9d6501a4f Merge pull request #1086 from jedevc/remote-driver-docs
Add remote driver documentation
2022-05-02 09:51:32 +02:00
CrazyMax
92009ed03c Merge pull request #1085 from tonistiigi/closeread-ignore
root: ignore SSH CloseRead warning
2022-04-29 17:59:56 +02:00
Justin Chadwell
f2fc0e9eb5 Add remote driver documentation
Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-04-29 16:43:28 +01:00
Tõnis Tiigi
38f1138a45 Merge pull request #1078 from jedevc/remote-driver
Add remote driver
2022-04-29 08:25:25 -07:00
Tonis Tiigi
72758fef22 root: ignore SSH CloseRead warning
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-04-29 08:24:13 -07:00
Tõnis Tiigi
9cdd837f6b Merge pull request #1080 from jedevc/issue-1051
hclparser: strip out blocks for json files
2022-04-28 21:11:02 -07:00
Justin Chadwell
d7e4affe98 Complete remote driver
This patch completes the work started in creating a remote driver:

- Renames the env driver to the remote driver (an alternative suggestion
  that should be more user-friendly)
- Adds support for TLS to encrypt connections with buildkitd
- Fixes outstanding review comments
- Reworks the buildx create command endpoint construction to be clearer
  and include better support for this new driver.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-04-28 11:34:06 +01:00
Batuhan Apaydın
3dc83e5dd8 feat: env driver
Co-authored-by: Furkan Türkal <furkan.turkal@trendyol.com>
Signed-off-by: Batuhan Apaydın <batuhan.apaydin@trendyol.com>
2022-04-28 11:34:06 +01:00
CrazyMax
29f97f6762 Merge pull request #1083 from crazy-max/e2e-workflow
ci: enhance e2e workflow
2022-04-28 12:31:57 +02:00
CrazyMax
88a45cfb24 ci: enhance e2e workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-28 12:03:33 +02:00
Justin Chadwell
03885ec9f1 hclparser: strip out blocks for json files
Body.JustAttributes cannot distinguish between blocks and attributes for
JSON files, so the variable block could be included in the list of
attributes returned.

This patch ensures that JSON and HCL files behave the same way by
removing all known block types first, from the provided config schema
and then from a generated definitions schema.

Fixes #1051

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-04-28 10:22:20 +01:00
Tonis Tiigi
a648d58f63 hack: update linters
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-04-27 17:22:32 -07:00
Tonis Tiigi
0b9d426175 Dockerfile: update to go 1.18
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-04-27 17:22:31 -07:00
Tõnis Tiigi
1c23d1cef5 Merge pull request #1082 from crazy-max/fix-standalone
cli: fix standalone command behavior
2022-04-27 10:51:51 -07:00
CrazyMax
95086cf641 cli: fix standalone command behavior
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-27 17:33:16 +02:00
Tõnis Tiigi
6a702ebe5b Merge pull request #1025 from crazy-max/bake-merge-jsons
bake: merge targets and vars from multiple JSON files
2022-04-25 19:16:05 -07:00
Tõnis Tiigi
a6a1a362ad Merge pull request #1053 from szeber/kubernetes-tolerations-fix
Fix tolerations not parsing its options correctly, update docs regarding quoted driver options
2022-04-21 21:20:26 -07:00
Zsolt
4a226568a0 Fix tolerations not parsing its options correctly, add tests
Signed-off-by: Zsolt <zsolt.szeberenyi@figured.com>
2022-04-22 12:12:05 +12:00
CrazyMax
a2d5bc7cca Merge pull request #1069 from crazy-max/compose-build-secrets
bake: support compose build secrets
2022-04-14 12:05:58 +02:00
Tõnis Tiigi
951201ac1b Merge pull request #1067 from jedevc/fix-imagetools-builder
imagetools: respect --builder flag
2022-04-13 16:40:47 -07:00
CrazyMax
c0f8a8314b bake: support compose build secrets
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-14 01:28:00 +02:00
Tõnis Tiigi
d64428cd2a Merge pull request #1063 from dougborg/custom-rootless-image-fix
Only set default rootless image if it is not already customized
2022-04-13 11:05:43 -07:00
CrazyMax
3a90f99635 update github.com/compose-spec/compose-go to v1.2.4
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-13 16:39:32 +02:00
Justin Chadwell
04b44b3a89 imagetools: respect --builder flag
The --builder flag was being ignored by imagetools because of pointer
problems. Essentially, because the root cmds aren't parsed immediately,
we need to pass a pointer to the builder string so that it can be
updated before the RunE function gets called.

Signed-off-by: Justin Chadwell <me@jedevc.com>
2022-04-13 14:36:48 +01:00
Tõnis Tiigi
b7c4fe5a3a Merge pull request #1066 from crazy-max/fix-inspect
inspect: fix printing of driver options
2022-04-12 18:05:36 -07:00
CrazyMax
082c83b825 inspect: fix printing of driver options
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-12 20:56:57 +02:00
Doug Borg
79de2c5d82 Only set default rootless image if it is not already customized
Only change the image to the default rootless image when using the
--rootless option if the image has not already customized with the
--image option.

Fix #938

Signed-off-by: Doug Borg <dougborg@apple.com>
2022-04-12 10:13:43 -06:00
Tõnis Tiigi
b8bcf1d810 Merge pull request #1052 from AkihiroSuda/update-kube-seccomp
kubernetes: replace deprecated seccomp annotations with securityContext
2022-04-08 20:50:00 -07:00
CrazyMax
28a4363672 Merge pull request #1055 from thaJeztah/update_dockerd_version
Dockerfile: update DOCKERD_VERSION to v20.10.14
2022-04-08 18:26:56 +02:00
CrazyMax
1e98de491d Merge pull request #1056 from thaJeztah/update_xx
Dockerfile: update to tonistiigi/xx:1.1.0
2022-04-08 18:26:36 +02:00
Sebastiaan van Stijn
b54a0aa37c Dockerfile: update to tonistiigi/xx:1.1.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-04-08 17:28:45 +02:00
Sebastiaan van Stijn
e10c385167 Dockerfile: update DOCKERD_VERSION to v20.10.14
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-04-08 17:26:40 +02:00
Akihiro Suda
add4301ed6 kubernetes: replace deprecated seccomp annotations with securityContext
Kubernetes added the official `securityContext.seccompProfile` support in Kubernetes 1.19.
Seccomp is still disabled by default.

The legacy `container.seccomp.security.alpha.kubernetes.io/<PODNAME>` annotation has been deprecated and will be unsupported in Kubernetes 1.25.
https://kubernetes.io/docs/tutorials/security/seccomp/

A test cluster can be created with the following minikube command:
```
minikube start --feature-gates SeccompDefault=true --extra-config kubelet.seccomp-default=true
```

Related to moby/buildkit PR 2782

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2022-04-07 17:23:42 +09:00
Tõnis Tiigi
a60150cbc6 Merge pull request #1045 from szeber/kubernetes-tolerations
feat: add tolerations handling to kubernetes driver
2022-04-06 21:50:17 -07:00
CrazyMax
cad7ed68be bake: merge vars from multiple JSON files
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-06 22:17:23 +02:00
CrazyMax
c317ca1e95 bake: merge targets from multiple JSON files
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-06 22:17:23 +02:00
Zsolt
3f6517747e Add support for defining kubernetes tolerations
Signed-off-by: Zsolt <zsolt.szeberenyi@figured.com>
2022-04-06 17:10:21 +12:00
Tõnis Tiigi
adafbe0e65 Merge pull request #1041 from crazy-max/vendor-buildkit
vendor: update buildkit to 3e38a2d
2022-04-04 11:53:01 -07:00
CrazyMax
a49ad031a5 vendor: update buildkit to 3e38a2d
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-04-03 20:40:33 +02:00
Tõnis Tiigi
c3db06cda0 Merge pull request #970 from crazy-max/nocache-mod-outdated
chore: use no-cache-filter for outdated stage
2022-04-01 16:32:41 -07:00
Akihiro Suda
1201782a11 Merge pull request #1033 from crazy-max/update-compose-go
update github.com/compose-spec/compose-go to v1.2.1
2022-03-30 15:02:24 +09:00
CrazyMax
243b428a58 compose: add test for port mapping
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-30 00:37:55 +02:00
CrazyMax
785dc17f13 update github.com/compose-spec/compose-go to v1.2.1
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-29 21:24:16 +02:00
CrazyMax
cad87f54c5 Merge pull request #1021 from crazy-max/bake-fix-visited-group
bake: fix skipped group when already visited by another one
2022-03-28 21:16:01 +02:00
CrazyMax
0b8dde1071 bake: fix skipped group when already visited by another one
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-23 11:16:10 +01:00
CrazyMax
1ca30a58c2 Merge pull request #1003 from developer-guy/feature/1001
feat: printing driver options
2022-03-17 12:28:36 +01:00
CrazyMax
1246e8da3a Merge pull request #1008 from thaJeztah/bump_distribution
vendor: github.com/docker/distribution v2.8.1
2022-03-17 12:28:20 +01:00
Sebastiaan van Stijn
c0f31349a6 vendor: github.com/docker/distribution v2.8.1
no significant changes to code we use, but the v2.8.0 module was borked

full diff: https://github.com/docker/distribution/compare/v2.8.0...v2.8.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-03-17 11:31:59 +01:00
Tõnis Tiigi
5c2d2f294d Merge pull request #1004 from tonistiigi/update-fsutil-220315
vendor: update fsutil to 9ed61262
2022-03-16 09:40:37 -07:00
Batuhan Apaydın
da4c27e9af feat: printing driver options
Signed-off-by: Batuhan Apaydın <batuhan.apaydin@trendyol.com>
2022-03-16 11:13:19 +03:00
Tonis Tiigi
111ea95629 vendor: update fsutil to 9ed61262
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-03-15 17:09:12 -07:00
Tõnis Tiigi
3adca1c17d Merge pull request #995 from thaJeztah/replace_ioutil
Remove uses of deprecated io/ioutil
2022-03-14 19:13:07 -07:00
Tõnis Tiigi
6ffe22b843 Merge pull request #996 from crazy-max/buildinfo-use-helper
imagetools inspect: use buildinfo helper
2022-03-14 19:12:14 -07:00
CrazyMax
824cb42fe0 dockerfile: update frontend to 1.4
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-10 02:11:19 +01:00
CrazyMax
08bb626304 chore: use no-cache-filter for outdated stage
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-10 02:11:19 +01:00
CrazyMax
38311a35f2 imagetools inspect: use buildinfo helper
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-10 01:52:51 +01:00
Sebastiaan van Stijn
fd62216cbc golangci-lint: prevent io/ioutil from being used
The package has been deprecated since Go 1.16:

https://go.dev/doc/go1.16#ioutil

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-03-10 01:47:41 +01:00
Sebastiaan van Stijn
fc7ba75fd7 Remove uses of deprecated io/ioutil
The package has been deprecated since Go 1.16: https://go.dev/doc/go1.16#ioutil

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2022-03-10 01:46:06 +01:00
Tõnis Tiigi
c8f7c1e93f Merge pull request #993 from tonistiigi/update-buildkit-220308
vendor: update buildkit
2022-03-08 16:59:14 -08:00
Tõnis Tiigi
b78c680207 Merge pull request #989 from crazy-max/moby-imgdgst
build: set remote digest when pushed with docker driver
2022-03-08 10:55:18 -08:00
Tonis Tiigi
d7412c9420 vendor: update buildkit
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-03-08 10:53:06 -08:00
CrazyMax
a7fba7bf3a Merge pull request #992 from tonistiigi/bake-metadata-fix
bake: restore consistent output for metadata
2022-03-08 19:43:48 +01:00
CrazyMax
19ff7cdadc build: set remote digest when pushed with docker driver
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-08 19:31:13 +01:00
Tonis Tiigi
c255c04eed bake: restore consistent output for metadata
Metadata formatting should not depend on the number
of targets.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-03-08 10:06:03 -08:00
Tõnis Tiigi
9fcea76dea Merge pull request #977 from tonistiigi/logs-dupes
progress: avoid double logs when multiple targets build same step
2022-03-04 16:30:53 -08:00
Tõnis Tiigi
1416bc1d83 Merge pull request #972 from crazy-max/imagetools-inspect-order
imagetools inspect: keep platform order
2022-03-04 11:54:15 -08:00
CrazyMax
215a128fc1 imagetools inspect: missing manifest digest for manifest-list (json)
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-04 20:36:14 +01:00
CrazyMax
4e4eea7814 imagetools inspect: deterministic platform order
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-04 20:36:14 +01:00
Tõnis Tiigi
8079bd2841 Merge pull request #980 from crazy-max/imageid
build: return imageID when loading without docker driver
2022-03-04 10:50:53 -08:00
CrazyMax
2d5368cccc Merge pull request #981 from tonistiigi/target-context-remove
build: remove target context if platform specific used
2022-03-04 16:29:20 +01:00
CrazyMax
a1256c6bb2 Merge pull request #985 from tonistiigi/multi-node-platform
build: fix multi-node builds with mixed platforms
2022-03-04 15:35:55 +01:00
CrazyMax
e7863eb664 build: return imageID when loading without docker driver
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-03-04 15:27:09 +01:00
Tonis Tiigi
171c4375a1 build: fix multi-node builds with mixed platforms
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-03-03 13:15:13 -08:00
Tonis Tiigi
45844805ec build: remove target context if platform specific used
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-03-01 21:25:43 -08:00
Tonis Tiigi
b77d7864fa progress: avoid double logs when multiple targets build same step
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-02-28 23:32:54 -08:00
Tõnis Tiigi
6efcee28d5 Merge pull request #973 from crazy-max/vendor-docker-cli
vendor: update docker/cli to 8667ccd
2022-02-27 20:29:34 -08:00
Tõnis Tiigi
3ad24524c4 Merge pull request #971 from crazy-max/fix-docs
docs: small fixes
2022-02-27 20:26:27 -08:00
CrazyMax
971b5d2b73 vendor: update docker/cli to 8667ccd
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-27 00:35:39 +01:00
CrazyMax
94c5dde85a docs: small fixes
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-26 05:39:42 +01:00
Tõnis Tiigi
f62c02329e Merge pull request #969 from tonistiigi/update-buildkit-20220225
vendor: update buildkit to 0692ad79
2022-02-25 12:15:13 -08:00
Tonis Tiigi
d2e53f5e05 vendor: update buildkit to 0692ad79
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-02-25 11:52:45 -08:00
Tõnis Tiigi
7af29802d4 Merge pull request #854 from crazy-max/buildinfo-cmd
imagetools inspect: add --format flag
2022-02-25 11:52:27 -08:00
Tõnis Tiigi
6ac01ec9ac Merge pull request #965 from tonistiigi/bake-context-validation
bake: additional support for named context on remote inputs
2022-02-25 11:36:51 -08:00
CrazyMax
20a55e9184 imagetools inspect: multi-platform support
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-25 20:30:08 +01:00
CrazyMax
6c56109083 imagetools inspect: add --format flag
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-25 17:55:34 +01:00
Tõnis Tiigi
dab3fe71bd Merge pull request #967 from crazy-max/update-clidocstool
docs: update cli-docs-tool to v0.4.0
2022-02-25 08:47:52 -08:00
CrazyMax
9867ca279a docs: update cli-docs-tool to v0.4.0
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-25 15:41:17 +01:00
Tonis Tiigi
91e550b715 bake: add path validation for remote bake invocations
This is a stopgap before proper entitlements support
is implemented.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-02-24 23:19:18 -08:00
Tonis Tiigi
280c008f81 bake: make named contexts relative to remote bake input
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-02-24 23:19:12 -08:00
Tõnis Tiigi
5939a23af6 Merge pull request #963 from tonistiigi/bake-contexts-error
bake: use better error in named contexts not supported
2022-02-24 20:30:55 -08:00
CrazyMax
7f1041164e Merge pull request #964 from tonistiigi/update-buildkit-022322
vendor: update buildkit to b124b0c3
2022-02-23 21:35:09 +01:00
Tonis Tiigi
64ce211ba4 vendor: update buildkit to b124b0c3
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-02-23 12:15:16 -08:00
Tonis Tiigi
b5bf28d722 bake: use better error in named contexts not supported
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-02-22 21:56:52 -08:00
Tõnis Tiigi
10debb577e Merge pull request #959 from tonistiigi/docker-proxy-config
set build-args from docker proxy configuration
2022-02-22 13:56:11 -08:00
CrazyMax
75cdea48e4 Merge pull request #962 from tonistiigi/bake-deps-error
build: fix deadlock on handling deps errors
2022-02-22 10:50:24 +01:00
CrazyMax
d96d7fb2dc Merge pull request #930 from tylerlwsmith/fix-readme-typo
Fix typo in readme
2022-02-21 10:53:05 +01:00
Tyler Smith
e3245a400a Fix typo in readme
Changed "note tha" to "note that"

Signed-off-by: Tyler Smith <tylerlwsmith@gmail.com>
2022-02-18 19:55:05 -08:00
Tõnis Tiigi
e871c39f05 Merge pull request #908 from crazy-max/inline-buildattrs
build: inline buildinfo attrs
2022-02-18 19:36:25 -08:00
Tõnis Tiigi
9c0a23996d Merge pull request #958 from crazy-max/buildinfo-deps
build: send buildinfo dependencies
2022-02-18 19:35:57 -08:00
Tonis Tiigi
3b2aeb2d5b build: fix deadlock on handling deps errors
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-02-18 18:41:52 -08:00
Tonis Tiigi
e98a476dc8 set build-args from docker proxy configuration
For backward compatibility with docker build.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-02-17 22:21:43 -08:00
CrazyMax
7677052cb7 build: send buildinfo dependencies
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-17 21:02:06 +01:00
Tõnis Tiigi
c273e0986c Merge pull request #953 from crazy-max/update-docs
docs: updates and guides
2022-02-17 10:54:31 -08:00
CrazyMax
9ee499ae27 docs: metadata-file usage
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-17 17:52:50 +01:00
CrazyMax
230dfa96a3 docs: built-in build args
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-17 17:52:49 +01:00
CrazyMax
f1a8f54c83 docs: user guides
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-17 17:52:49 +01:00
CrazyMax
2bcf3524e5 docs: ssh usage example
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-16 15:14:45 +01:00
CrazyMax
26918513e3 docs: lint
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-16 15:14:45 +01:00
Tõnis Tiigi
893d505803 Merge pull request #955 from crazy-max/vendor-buildkit
vendor: update buildkit to 1e6032c
2022-02-15 11:32:04 -08:00
CrazyMax
22aaa260e7 vendor: update buildkit to 1e6032c
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-15 19:12:00 +01:00
CrazyMax
1bcc3556fc Merge pull request #949 from docker/dependabot/go_modules/github.com/docker/distribution-2.8.0incompatible
build(deps): bump github.com/docker/distribution from 2.7.1+incompatible to 2.8.0+incompatible
2022-02-14 11:48:21 +01:00
Tõnis Tiigi
eef6deb7c2 Merge pull request #860 from tonistiigi/no-cache-filter
build: add no-cache-filter
2022-02-11 20:09:40 -08:00
dependabot[bot]
542759ea31 build(deps): bump github.com/docker/distribution
Bumps [github.com/docker/distribution](https://github.com/docker/distribution) from 2.7.1+incompatible to 2.8.0+incompatible.
- [Release notes](https://github.com/docker/distribution/releases)
- [Commits](https://github.com/docker/distribution/compare/v2.7.1...v2.8.0)

---
updated-dependencies:
- dependency-name: github.com/docker/distribution
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-11 22:39:59 +00:00
Tõnis Tiigi
e5f590a7fa Merge pull request #946 from crazy-max/metadata-output
build: enhance metadata json output
2022-02-10 23:59:23 -08:00
CrazyMax
ecf215b927 e2e: add bake build and display metadata json
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-11 08:16:47 +01:00
CrazyMax
299fd19c49 build: enhance metadata json output
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-11 08:16:42 +01:00
CrazyMax
4b633c3c7b docs: built-in build args
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-11 07:57:55 +01:00
Tonis Tiigi
eb8057e8e0 forbid setting no-cache and no-cache-filter together
Per review request.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-02-10 22:01:50 -08:00
Tonis Tiigi
32f6358d78 bake: add no-cache-filter
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-02-10 22:01:48 -08:00
Tonis Tiigi
3b47722032 build: add no-cache-filter
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-02-10 22:00:02 -08:00
Tõnis Tiigi
e60f0f2c4f Merge pull request #943 from crazy-max/secret-examples
docs: secret usage examples
2022-02-10 17:36:26 -08:00
CrazyMax
b39ebab666 docs: secret usage examples
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-10 15:37:11 +01:00
Akihiro Suda
f891187d8b Merge pull request #948 from crazy-max/vendor-buildkit
vendor: update buildkit to 2f99651
2022-02-10 12:15:39 +09:00
CrazyMax
307c94e5c7 vendor: update buildkit to 2f99651
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-09 21:53:40 +01:00
Tõnis Tiigi
60a025b227 Merge pull request #928 from tonistiigi/bake-named-contexts
bake: add named contexts keys
2022-02-07 10:52:01 -08:00
Tõnis Tiigi
fec415a8e0 Merge pull request #937 from hinshun/printer-writer
Relax to io.Writer requirement for NewPrinter
2022-02-06 23:24:45 -08:00
Edgar Lee
2d7540fb0a Separate io.Writer from console.File for NewPrinter
Signed-off-by: Edgar Lee <edgarl@netflix.com>
2022-02-06 09:11:47 -08:00
Tõnis Tiigi
595285736c Merge pull request #885 from crazy-max/rm-inactive
cli: add --all-inactive for rm command
2022-02-03 19:25:25 -08:00
CrazyMax
378f0b45c6 cli: add --all-inactive and --force flags for rm command
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-02-03 13:39:53 +01:00
Tonis Tiigi
c3dab802d8 docs: add examples for bake named contexts
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-01-27 18:46:12 -08:00
Tonis Tiigi
fa04611afc bake: connect results between build targets
Build context “target:<name>” will take the contents
from another bake target.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-01-27 18:46:12 -08:00
Tonis Tiigi
ffa062dc95 util: add waitmap for target synchronization
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-01-27 18:46:12 -08:00
Tonis Tiigi
0fc2b5ca85 bake: add named contexts keys
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-01-27 18:46:02 -08:00
Tõnis Tiigi
9a1267cd02 Merge pull request #929 from crazy-max/bake-target-name
bake: restrict target name
2022-01-26 09:06:02 -08:00
CrazyMax
c74b2fe7a4 bake: restrict target name
This fix adds a restriction `[a-zA-Z0-9_-]+`
for target name. This is pretty much the same as the
container name restriction in moby.

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-26 10:29:21 +01:00
Tõnis Tiigi
6c69d970f7 Merge pull request #924 from crazy-max/log
root: filter out useless commandConn.CloseWrite warning message
2022-01-25 08:54:21 -08:00
CrazyMax
d3e56ea9d9 root: simple output format on logrus for parity with cli
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-25 08:54:42 +01:00
Tõnis Tiigi
11b771c789 Merge pull request #904 from tonistiigi/named-contexts
build: support for named contexts(stages)
2022-01-20 19:58:40 -08:00
CrazyMax
278f94a8b6 root: filter out useless commandConn.CloseWrite warning message
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-21 00:36:06 +01:00
Tõnis Tiigi
14b38a9aa8 Merge pull request #914 from crazy-max/fix-target-inherit
bake: keep target inheritance
2022-01-13 18:35:13 -08:00
CrazyMax
0044c28b1f bake: keep target inheritance
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-13 22:23:20 +01:00
Tõnis Tiigi
b568b219bc Merge pull request #920 from crazy-max/update-gocty
bump github.com/zclconf/go-cty from 1.7.1 to 1.10.0
2022-01-13 10:56:54 -08:00
Tõnis Tiigi
aabbe5a56a Merge pull request #919 from crazy-max/mod-outdated-bake
chore: invalidate cache for outdated run stage
2022-01-13 10:56:05 -08:00
Tõnis Tiigi
b038dd063e Merge pull request #921 from crazy-max/readme-install
Update install instructions
2022-01-13 10:55:07 -08:00
CrazyMax
f25d5ff02f Update install instructions
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-13 14:57:25 +01:00
CrazyMax
b67bdedb23 bump github.com/zclconf/go-cty from 1.7.1 to 1.10.0
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-13 14:32:10 +01:00
CrazyMax
3ccb883d95 chore: invalidate cache for outdated run stage
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-13 14:09:47 +01:00
Tõnis Tiigi
785c861233 Merge pull request #915 from crazy-max/ci-buildkit-image
ci: build with stable buildkit image
2022-01-11 22:37:55 -08:00
CrazyMax
1b69919313 ci: build with stable buildkit image
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-12 07:16:58 +01:00
CrazyMax
24db7366ba build: inline buildinfo attrs
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-08 17:53:24 +01:00
Tonis Tiigi
08547827db docs: add docs for -build-context
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-01-07 18:37:25 -08:00
Tonis Tiigi
f37c253ae4 commands: provide more helpful error when —build-context is not supported
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-01-07 18:32:37 -08:00
Tonis Tiigi
d77e2453da commands: rename context flag to build-context
Avoid conflicts with docker context

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-01-07 18:31:32 -08:00
Tõnis Tiigi
2b4d305c58 Merge pull request #905 from crazy-max/compose-go
compose: fix env
2022-01-06 09:02:26 -08:00
CrazyMax
5d715ada96 compose: resolve build args from service environment
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-06 11:59:49 +01:00
CrazyMax
3400fa5628 compose: test env_file
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-06 11:42:16 +01:00
CrazyMax
f04c8c8430 update github.com/compose-spec/compose-go to v1.0.8
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2022-01-06 11:41:45 +01:00
Tonis Tiigi
de6b04d726 build: add support for named contexts
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2022-01-04 22:55:12 -08:00
Tõnis Tiigi
fe9f9bba87 Merge pull request #884 from crazy-max/fix-bake-resgroup
bake: fix group resolution
2022-01-04 10:50:12 -08:00
Tõnis Tiigi
e482ba2c73 Merge pull request #892 from tonistiigi/warnings-summary
Show summary of build warnings.
2022-01-04 10:48:57 -08:00
Tonis Tiigi
038727477c root: filter out useless debug logs from vendored packages
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-12-19 22:33:05 -08:00
Tonis Tiigi
ed4103ef52 commands: build summary of warnings on build
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-12-19 22:32:59 -08:00
Tõnis Tiigi
54286a0117 Merge pull request #889 from tonistiigi/update-buildkit-20211215
vendor: update buildkit to 539be170
2021-12-17 11:58:40 -08:00
Tonis Tiigi
9c3be32bc9 vendor: update buildkit to 539be170
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-12-16 11:42:02 -08:00
Tõnis Tiigi
59533bbb5c Merge pull request #887 from AkihiroSuda/avoid-unneeded-userns-host
docker-container: set UsernsMode only when needed
2021-12-15 21:00:12 -08:00
Akihiro Suda
5f8600f098 docker-container: set UsernsMode only when needed
Set `UsernsMode="host"` only when the daemon is running in userns-remapping mode.

Fix issue 561

The issue will be also fixed in moby/moby PR 43084 (Docker 20.10.13).
This buildx PR helps users of old releases of Docker.

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2021-12-15 18:42:58 +09:00
CrazyMax
d95ebef55c bake: fix group resolution
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-12-14 11:17:37 +01:00
Tõnis Tiigi
33c121df01 Merge pull request #881 from crazy-max/fix-bake-print
bake: fix groups print
2021-12-13 16:09:24 -08:00
Tõnis Tiigi
1dde00c4bc Merge pull request #880 from crazy-max/bake-ignore-field
bake: ignore NetworkMode field for json and hcl
2021-12-13 16:06:41 -08:00
CrazyMax
4466a24f9e bake: fix groups print
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-12-13 19:21:33 +01:00
CrazyMax
ec9daba87e bake: ignore NetworkMode field for json and hcl
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-12-10 19:32:40 +01:00
Sebastiaan van Stijn
202e99695b Merge pull request #823 from crazy-max/docs-git-protoc
docs: fix git protocol
2021-12-09 12:26:17 +01:00
Tõnis Tiigi
7371dda7a2 Merge pull request #863 from zachary-povey/support_host_network_in_compose
Add NetworkMode to bake target
2021-12-04 21:04:05 -08:00
Tõnis Tiigi
62bdf4d85e Merge pull request #868 from crazy-max/discard-containerd-logger
imagetools resolver: discard containerd logger output
2021-12-04 21:03:42 -08:00
Zachary Povey
7f8dbf890d Remove support for network override in bake
Signed-off-by: Zachary Povey <zachary.povey@autotrader.co.uk>
2021-12-01 09:45:32 +00:00
Tõnis Tiigi
bede4ab552 Merge pull request #869 from crazy-max/deprecaded-clientopt
imagetools resolver: fix deprecated client opt
2021-11-30 08:29:40 -08:00
CrazyMax
5c5125f30e imagetools resolver: fix deprecated client opt
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-30 15:34:29 +01:00
CrazyMax
e9cf2cbe32 imagetools resolver: discard containerd logger output
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-30 15:17:56 +01:00
Zachary Povey
4ee7f70400 Remove NetworkMode support for HCL targets
Signed-off-by: Zachary Povey <zachary.povey@autotrader.co.uk>
2021-11-30 11:33:32 +00:00
CrazyMax
0abda783bb Merge pull request #864 from eliottwiener/bake-read-from-stdin
bake: build definition file via stdin
2021-11-30 09:35:03 +01:00
Tõnis Tiigi
aadd118883 Merge pull request #867 from crazy-max/du-last-accessed
disk usage: last accessed not displayed
2021-11-29 09:49:12 -08:00
CrazyMax
9aff9301ce disk usage: last accessed not displayed
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-29 16:21:40 +01:00
CrazyMax
93d6b654ca Merge pull request #866 from Wojciechem/patch-1
add note about variable syntax in json
2021-11-29 09:12:40 +01:00
Wojciech M
42287815b5 add note about variable syntax in json
In addition to HCL, variables can also be defined in json.

Signed-off-by: wojciechem <wmiedzybrodzki@outlook.com>
2021-11-28 22:30:14 +01:00
Eliott Wiener
dcabc22072 bake: build definition file via stdin
closes #833

Accept bake build definition file from stdin with `-f -`.

Signed-off-by: Eliott Wiener <eliottwiener@gmail.com>
2021-11-25 12:43:38 -05:00
Zachary Povey
ae53101e89 Add NetworkMode to bake target
Allows specification of network mode in a bake target.

Fixes #848

Signed-off-by: Zachary Povey <zachary.povey@autotrader.co.uk>
2021-11-25 16:00:42 +00:00
CrazyMax
61627c2ece docs: fix git protocol
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-25 09:07:41 +01:00
Tõnis Tiigi
ab73275f58 Merge pull request #857 from crazy-max/bake-json
bake: fix print output
2021-11-24 15:59:29 -08:00
CrazyMax
316ca972b6 bake: fix print output
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-24 21:54:57 +01:00
CrazyMax
5c2b9bbfc5 Merge pull request #861 from tonistiigi/cleanup
commands: clean up unnecessary code
2021-11-23 09:36:55 +01:00
Tonis Tiigi
cc2a879660 commands: clean up unnecessary code
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-11-22 23:57:42 -08:00
Tõnis Tiigi
89334a88a9 Merge pull request #853 from crazy-max/fix-flags
cli: fix flags usage
2021-11-22 16:21:48 -08:00
Tõnis Tiigi
1927dba42f Merge pull request #852 from DataDog/mayeul/docker-buildx-rm--keep-buildkitd
Add an flag to buildx rm to keep the buildkitd daemon running
2021-11-22 16:21:30 -08:00
Mayeul Blanzat
72dab552b5 Add an option to buildx rm to keep the buildkitd daemon running
Add --keep-daemon to the `rm` command option to preserve the buildkitd daemon after the buildx context is deleted.

Signed-off-by: Mayeul Blanzat <mayeul.blanzat@datadoghq.com>
2021-11-22 13:24:47 +01:00
CrazyMax
a0a7db127c cli: fix flags usage
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-22 10:51:59 +01:00
Tõnis Tiigi
bcfd434829 Merge pull request #839 from crazy-max/xx-update
dockerfile: update xx to 1.0.0
2021-11-13 19:01:51 -08:00
CrazyMax
d1aaed7a77 dockerfile: update xx to 1.0.0
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-13 18:53:01 +01:00
CrazyMax
f0026081a7 Merge pull request #832 from crazy-max/update-compose
update github.com/compose-spec/compose-go to v1.0.5
2021-11-10 11:03:28 +01:00
CrazyMax
a18829f837 update github.com/compose-spec/compose-go to v1.0.5
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-09 10:16:17 +01:00
CrazyMax
da0eb138d0 Merge pull request #829 from crazy-max/typo
fix typo in docs
2021-11-05 09:17:23 +01:00
CrazyMax
a2c7d43e46 fix typo in docs
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-05 08:48:32 +01:00
Akihiro Suda
f7cba04f5e Merge pull request #828 from tonistiigi/strip-binary
Dockerfile: strip binary by default
2021-11-05 14:25:22 +09:00
Tonis Tiigi
12b5db70e2 Dockerfile: strip binary by default
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-11-04 18:11:26 -07:00
Tõnis Tiigi
5c4e3fc860 Merge pull request #818 from crazy-max/fix-builder-flag
cli: fix builder persistent flag
2021-11-04 12:00:43 -07:00
CrazyMax
eab0e6a8fe cli: fix builder persistent flag
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-04 18:52:17 +01:00
CrazyMax
4c938c77ba Merge pull request #825 from tonistiigi/multi-node-registry-conf
allow multi-node push and imagetools to use custom registry config
2021-11-04 18:43:31 +01:00
Tonis Tiigi
1cca41b81a build: support insecure export option for multi-node build
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-11-04 10:02:14 -07:00
Tonis Tiigi
c62472121b allow multi-node push and imagetools to use custom registry config
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-11-04 10:02:12 -07:00
Tonis Tiigi
88d0775692 refactor accessing registry configs via drivers
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-11-04 10:01:23 -07:00
Tõnis Tiigi
8afc82b427 Merge pull request #817 from tonistiigi/project-sharedkey
build: set local sharedkey per project basename
2021-11-04 09:52:51 -07:00
Tõnis Tiigi
d311561a8b Merge pull request #824 from tonistiigi/config-files-store2
store snapshot of config files on create
2021-11-04 09:05:13 -07:00
Tõnis Tiigi
44e180b26e Merge pull request #826 from tonistiigi/multi-node-iidfile 2021-11-04 08:24:33 -07:00
Tonis Tiigi
02d29e0af5 build: fix setting iidfile with multi-node push
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-11-03 23:12:00 -07:00
Tonis Tiigi
40121c671c kubernetes: store config files for k8s
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-11-03 18:24:16 -07:00
Tonis Tiigi
4c1621cccd store snapshot of config files on create
Files can be reused when container needs to be booted again.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-11-03 16:34:43 -07:00
Tõnis Tiigi
7f0e37531c Merge pull request #822 from crazy-max/fix-bake-git-protoc
bake: fix protocol detection
2021-11-02 16:20:22 -07:00
CrazyMax
82b212bddf bake: fix protocol detection
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-11-02 23:12:27 +01:00
Tonis Tiigi
aa52a5a699 build: set local sharedkey per project basename
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-10-29 21:29:04 -07:00
Tõnis Tiigi
49342dd54d Merge pull request #787 from crazy-max/inject-certs
container driver: copy ca and user tls registries certs
2021-10-28 15:11:57 -07:00
CrazyMax
3f716f00fa container driver: copy ca and user tls registries certs
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-28 22:30:11 +02:00
Tõnis Tiigi
5e25191cb6 Merge pull request #814 from crazy-max/cgroup-parent
build: add cgroup-parent support
2021-10-28 10:53:09 -07:00
CrazyMax
dd15969c93 build: add cgroup-parent support
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-28 19:34:47 +02:00
Tõnis Tiigi
81cf2064c4 Merge pull request #815 from tonistiigi/multi-node-push-names
imagetools: fix pushing same image with multiple names
2021-10-28 10:21:30 -07:00
Tonis Tiigi
b497587f21 imagetools: fix pushing same image with multiple names
containerd pusher can’t handle this case atm so we
need to make sure we always create a new resolver
for each name.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-10-27 17:14:49 -07:00
CrazyMax
2890209a11 refactor: lexical order for build opts
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-27 23:42:16 +02:00
Tõnis Tiigi
4690e14c40 Merge pull request #810 from crazy-max/warn-flags-depre
build: warning msg on deprecated flags
2021-10-26 16:25:19 -07:00
CrazyMax
25d2f73858 build: warning on deprecated flags
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-26 21:36:49 +02:00
CrazyMax
36a37a624e refactor: flags lexical order
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-26 13:11:28 +02:00
CrazyMax
e150d7bdd8 add long description to root command
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-26 13:11:28 +02:00
Tõnis Tiigi
be2c8f71fe Merge pull request #812 from cpuguy83/mark_spans_as_error
Mark span status as error when fatal error occurs.
2021-10-25 20:36:35 -07:00
Akihiro Suda
89f5c1ce51 Merge pull request #804 from tonistiigi/http-hijack-session
docker: dial session directly with http hijack
2021-10-22 13:10:26 +09:00
Brian Goff
b6474d43a9 Mark span status as error when fatal error occurs.
Before this only recorded errors instead of setting the span status,
which makes it harder to dig through.
Now an error that bubbles is reflected in the span status.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2021-10-21 22:24:51 +00:00
Tonis Tiigi
2644d56a6d docker: dial session directly with http hijack
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-10-20 18:54:31 -07:00
CrazyMax
084b6c0a95 Merge pull request #790 from crazy-max/shmsize
build: add shm-size support
2021-10-20 06:24:01 +02:00
CrazyMax
8e5595b7c7 build: add shm-size support
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-19 21:06:01 +02:00
CrazyMax
22500c9929 vendor: update buildkit
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-19 21:03:23 +02:00
Tõnis Tiigi
050f4f9219 Merge pull request #801 from crazy-max/bump-go
update go to 1.17.2
2021-10-18 13:26:07 -07:00
CrazyMax
1a56de8e68 update go to 1.17.2
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-16 15:00:31 +02:00
Tõnis Tiigi
868610e0e9 Merge pull request #800 from crazy-max/ulimit
build: add ulimit support
2021-10-15 11:14:49 -07:00
CrazyMax
b89e2f35df build: add ulimit support
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-15 16:03:49 +02:00
CrazyMax
1b3068df7c vendor: update buildkit
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-10-15 15:01:36 +02:00
Tõnis Tiigi
461369748c Merge pull request #782 from djs55/cgroup-parent
docker-container: place build containers in a separate cgroup
2021-09-30 09:06:29 -07:00
David Scott
d5908cdddf docker-container: use /docker/buildx cgroup by default
This allows resource limits to be applied to all builds on a host.
For example to limit the total amount of CPU used by builds:

https://medium.com/@asishrs/docker-limit-resource-utilization-using-cgroup-parent-72a646651f9d

Signed-off-by: David Scott <dave@recoil.org>
2021-09-29 19:58:22 +01:00
David Scott
b5bc754bad docker-container: support --driver-opt cgroup-parent=...
This allows the parent cgroup to be customised, which allows resource
limits to be imposed on build containers separately from "user"
containers.

Signed-off-by: David Scott <dave@recoil.org>
2021-09-29 19:57:46 +01:00
Tõnis Tiigi
dff7673afb Merge pull request #783 from tonistiigi/override-merge
bake: restore previous override merge behavior
2021-09-29 08:59:54 -07:00
Tõnis Tiigi
3e2fde5639 Merge pull request #785 from crazy-max/fix-docs
Fix --driver flag usage markdown output
2021-09-29 08:59:14 -07:00
Tonis Tiigi
7a7b73c043 bake: restore previous override merge behavior
For array fields, overrides are merged together
but override is not merged with the target. If merging
with target is desired we can add support for
overrides with += operator in the future.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-09-29 08:27:27 -07:00
Tõnis Tiigi
e50c9ae7be Merge pull request #784 from crazy-max/fix-e2e
Driver opt not used in e2e tests
2021-09-29 08:18:49 -07:00
CrazyMax
9e62c9f074 Fix --driver flag usage markdown output
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-29 15:33:44 +02:00
CrazyMax
c82dbafaee Driver opt not used in e2e tests
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-29 10:42:27 +02:00
Tonis Tiigi
0e4d7aa7a9 bake: add test for merging overrides
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-09-28 23:21:07 -07:00
Tõnis Tiigi
c05a6eb2c1 Merge pull request #781 from crazy-max/vendor-buildkit
vendor: update buildkit
2021-09-27 19:01:49 -07:00
CrazyMax
eec1693f30 vendor: update buildkit
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-27 21:54:35 +02:00
CrazyMax
c643c2ca95 Merge pull request #775 from crazy-max/vendor-buildkit
vendor: update buildkit
2021-09-25 18:48:36 +02:00
Tõnis Tiigi
761e22e395 Merge pull request #774 from crazy-max/driver-e2e
Driver e2e tests
2021-09-23 16:49:55 -07:00
CrazyMax
ef8c936b27 Driver e2e tests
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-23 10:49:30 +02:00
Tõnis Tiigi
0cea838344 Merge pull request #773 from tonistiigi/bake-push-fix
bake: fix using push override with output definition
2021-09-21 17:53:45 -07:00
Akihiro Suda
2b18a9b4a5 Merge pull request #761 from morlay/kubeconfig-enhance
util: support load Colon-separated KUBECONFIG
2021-09-21 16:45:55 +09:00
CrazyMax
45e4550c36 vendor: update buildkit
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-21 07:49:45 +02:00
Tonis Tiigi
6fc906532b bake: fix using push override with output definition
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-09-20 16:22:27 -07:00
Tõnis Tiigi
06541ebd0f Merge pull request #765 from thaJeztah/fix_broken_anchors
docs: fix some broken anchors
2021-09-15 16:00:21 -07:00
Sebastiaan van Stijn
773fac9a73 docs: fix some broken anchors
- ./_site/engine/reference/commandline/buildx_build/index.html
      *  linking to internal hash #--buildkitd-flags-flags that does not exist (line 904)
         <a href="/engine/reference/commandline/buildx_create/#--buildkitd-flags-flags"></a>
    - ./_site/engine/reference/commandline/buildx_create/index.html
      *  linking to internal hash #--buildkitd-flags-flags that does not exist (line 350)
         <a href="#--buildkitd-flags-flags"></a>
      *  linking to internal hash #--config-file that does not exist (line 336)
         <a href="#--config-file"></a>
      *  linking to internal hash #--config-file that does not exist (line 336)
         <a href="/engine/reference/commandline/buildx_build/#--load"></a>
      *  linking to internal hash #--load that does not exist (line 369)
         <a href="/engine/reference/commandline/buildx_build/#--load"></a>

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-09-13 17:06:18 +02:00
CrazyMax
7f0e05dfac Merge pull request #762 from crazy-max/remove-yaml
Remove generated YAML docs
2021-09-09 13:39:53 +02:00
CrazyMax
e59aecf034 Remove YAML docs from the repo
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-09 10:29:13 +02:00
CrazyMax
ac9a1612d2 Merge pull request #758 from crazy-max/mod-outdated
Mod outdated
2021-09-08 13:33:26 +02:00
Morlay
c83812144c util: support load Colon-separated KUBECONFIG
Signed-off-by: Morlay <morlay.null@gmail.com>
2021-09-08 17:51:56 +08:00
CrazyMax
df521e4e96 Mod outdated
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-04 18:57:48 +02:00
Tõnis Tiigi
00cb53d0ef Merge pull request #746 from crazy-max/bake-workflow
Bake workflow
2021-09-03 14:11:54 -07:00
CrazyMax
6cfef7fa36 Bake workflow
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-03 22:50:05 +02:00
Tõnis Tiigi
b05c313204 Merge pull request #740 from bossmc/support-quiet
Implement `--quiet` support
2021-09-03 11:00:26 -07:00
CrazyMax
3e8bbbc286 Merge pull request #757 from crazy-max/bump-clidocstool
Fix flags usage markdown output
2021-09-03 14:25:21 +02:00
CrazyMax
8a12884814 Fix flags usage markdown output
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-03 11:52:49 +02:00
Tõnis Tiigi
6cf9fa8261 Merge pull request #739 from crazy-max/go117
Go 1.17
2021-09-02 16:01:45 -07:00
Tõnis Tiigi
fd94fc5fdf Merge pull request #748 from crazy-max/platform-func
Built-in variable `BAKE_LOCAL_PLATFORM`
2021-09-02 16:01:26 -07:00
CrazyMax
45c678ad26 Go 1.17
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-02 23:11:10 +02:00
CrazyMax
55a3ce606f Built-in variable BAKE_LOCAL_PLATFORM
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-09-02 23:06:05 +02:00
CrazyMax
c1c414e4c9 Merge pull request #747 from crazy-max/yaml-docs
Generate YAML doc
2021-09-02 20:16:56 +02:00
Tõnis Tiigi
610601cec0 Merge pull request #753 from tonistiigi/ci-branches
github: fix running ci in version branches
2021-08-28 10:08:06 -07:00
Tonis Tiigi
9833420a03 github: fix running ci in version branches
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-08-27 21:19:11 -07:00
Tõnis Tiigi
7f322caa79 Merge pull request #751 from thaJeztah/fix_mount_path
container-driver: fix volume destination for cache
2021-08-27 21:02:09 -07:00
Sebastiaan van Stijn
93867d02f0 container-driver: fix volume destination for cache
The container-driver creates a Linux container (as there currently isn't a
Windows version of buildkitd). However, the defaults are platform specific.

Buildx was using the defaults from the buildkit `util/appdefault' package,
which resulted in Buildx running on a Windows client to create a Linux
container that used the Windows location, which causes it to fail:

    invalid mount config for type "volume": invalid mount path: 'C:/ProgramData/buildkitd/.buildstate' mount path must be absolute

This patch hard-codes the destination to the default Linux path.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-08-27 09:48:31 +02:00
CrazyMax
b8a602821c Generate YAML doc
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-08-25 19:10:03 +02:00
Tõnis Tiigi
a8a3b1738e Merge pull request #741 from tonistiigi/client-ctx
use long-running context for client initialization
2021-08-20 09:01:53 -07:00
Andy Caldwell
ef3e46fd62 Move printing to stdout up to the command itself
Signed-off-by: Andy Caldwell <andrew.caldwell@metaswitch.com>
2021-08-20 15:13:23 +01:00
Andy Caldwell
3ab0b6953a Regenerate docs now that --quiet is unmasked
Signed-off-by: Andy Caldwell <andrew.caldwell@metaswitch.com>
2021-08-20 15:13:19 +01:00
Andy Caldwell
c19c018a4c Implement --quiet support
Signed-off-by: Andy Caldwell <andrew.caldwell@metaswitch.com>
2021-08-20 15:13:13 +01:00
Tonis Tiigi
422ba60b04 use long-running context for client initialization
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-08-19 20:36:24 -07:00
Tõnis Tiigi
2d3763990c Merge pull request #731 from crazy-max/dockerfile-13
Update Dockerfile references to use 1.3
2021-08-18 09:05:53 -07:00
CrazyMax
dc6ada9b50 Update Dockerfile references to use 1.3
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-08-17 08:41:15 +02:00
Tõnis Tiigi
cb185f095f Merge pull request #721 from crazy-max/compose-ext
bake: `x-bake` extension field with compose
2021-08-13 07:51:23 -07:00
CrazyMax
89e126fa60 bake: x-bake extension field with compose
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-08-13 09:15:15 +02:00
Tõnis Tiigi
04bac63745 Merge pull request #692 from crazy-max/boostrap-cmd
Allow booting builder after creation
2021-08-12 10:35:33 -07:00
Tõnis Tiigi
3594851128 Merge pull request #720 from crazy-max/default-group
bake: print default group
2021-08-12 10:31:16 -07:00
Tõnis Tiigi
58e5a73389 Merge pull request #707 from crazy-max/update-readme
Enhance readme
2021-08-12 10:30:10 -07:00
CrazyMax
c685e46609 bake: print default group
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-08-12 09:02:36 +02:00
CrazyMax
e3283e6169 Enhance readme
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-08-12 08:57:09 +02:00
CrazyMax
5d50bd7b43 Allow booting builder after creation
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-08-12 08:45:55 +02:00
Tõnis Tiigi
3dfbe2c184 Merge pull request #674 from crazy-max/checksum
Create checksums for artifacts
2021-08-10 13:16:13 -07:00
Tõnis Tiigi
06367a120b Merge pull request #682 from morlay/k8s-enhance
[kubernetes] Support --config to mount buildkit.toml and -driver-opt=qemu.install=true,qemu.image=tonistiigi/binfmt:latest for qemu installing
2021-08-10 13:15:32 -07:00
CrazyMax
6149507c7e Merge pull request #670 from crazy-max/cache-gha-doc
Example with gha cache
2021-08-09 13:39:59 +02:00
Morlay
c76b5eac03 feat(driver/kubernetes): support mount buildkit.toml and qemu installing
Signed-off-by: Morlay <morlay.null@gmail.com>
2021-08-04 21:32:27 +08:00
CrazyMax
cd133cee25 Merge pull request #700 from crazy-max/bake-docs
Update bake docs
2021-08-03 14:53:43 +02:00
CrazyMax
eeab638476 Merge pull request #710 from crazy-max/update-ctnd
bump github.com/containerd/containerd from 1.5.4 to 1.5.5
2021-08-02 14:32:44 +02:00
CrazyMax
19b9b86af8 bump github.com/containerd/containerd from 1.5.4 to 1.5.5
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-08-02 13:47:27 +02:00
CrazyMax
0101c96532 Update cache docs
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-08-02 11:05:42 +02:00
CrazyMax
85dedf1aea Create checksums for artifacts
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-08-02 03:37:36 +02:00
CrazyMax
5f05bd9a2b Update bake docs
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-08-01 03:21:20 +02:00
CrazyMax
260d07a9a1 Merge pull request #704 from crazy-max/use-compose-config-file
Set `ConfigFile` to parse compose files with bake
2021-07-30 18:35:00 +02:00
CrazyMax
9aa8f09f14 Set ConfigFile to parse compose files with bake
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-07-30 17:56:40 +02:00
CrazyMax
0363b676bc Merge pull request #697 from docker/dependabot/go_modules/github.com/containerd/containerd-1.5.4
build(deps): bump github.com/containerd/containerd from 1.5.2 to 1.5.4
2021-07-28 14:09:33 +02:00
dependabot[bot]
a10045e8cb build(deps): bump github.com/containerd/containerd from 1.5.2 to 1.5.4
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.5.2 to 1.5.4.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](https://github.com/containerd/containerd/compare/v1.5.2...v1.5.4)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 21:37:28 +00:00
CrazyMax
0afcca221d Merge pull request #694 from crazy-max/codecov
Bump to codecov/codecov-action v2
2021-07-26 10:22:00 +02:00
CrazyMax
5daf176722 Merge pull request #693 from crazy-max/buildkit-progress
Duplicated progress env var
2021-07-25 22:18:29 +02:00
CrazyMax
3d1ab82dc6 Duplicated progress env var
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-07-25 12:40:13 +02:00
CrazyMax
872430d2d3 Bump to codecov/codecov-action v2
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-07-24 23:24:12 +02:00
CrazyMax
7d312eaa0a Merge pull request #686 from morlay/nil-client-fix
fix: should ignore nil client
2021-07-23 20:12:32 +02:00
CrazyMax
a6bc4ed21e Merge pull request #679 from akvadrako/patch-1
Fix link to generally useful functions
2021-07-23 08:19:53 +02:00
Morlay
3768ab268b fix: should ignore nil client
Signed-off-by: Morlay <morlay.null@gmail.com>
2021-07-21 15:47:55 +08:00
Devin Bayer
4c2daeb852 Fix link to generally useful functions
Signed-off-by: Devin Bayer <dev@doubly.so>
2021-07-20 18:09:53 +02:00
Tõnis Tiigi
d9ee3b134c Merge pull request #676 from tonistiigi/vol-delete
don't error on deleting old build containers without state volume
2021-07-16 12:37:37 -07:00
Tonis Tiigi
0b6ba1cd32 don't error on deleting old build containers without state volume
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-07-16 12:00:27 -07:00
Tõnis Tiigi
65a6955db8 Merge pull request #672 from crazy-max/keep-buildkit-state
Keep BuildKit state in a volume
2021-07-13 10:21:51 -07:00
CrazyMax
258d12b2e7 Keep BuildKit state in a volume
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-07-13 18:09:35 +02:00
Tõnis Tiigi
6e3a319a9d Merge pull request #671 from tonistiigi/remote-context
bake: allow BAKE_CMD_CONTEXT builtin var
2021-07-13 08:50:27 -07:00
Tonis Tiigi
1bb425a882 bake: allow BAKE_CMD_CONTEXT builtin var
Allows accessing the main context for bake command from bake
file that has been imported remotely.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-07-12 21:01:41 -07:00
Tõnis Tiigi
5f6ad50df4 Merge pull request #635 from tonistiigi/otel
OpenTelemetry support
2021-07-12 14:27:32 -07:00
Tonis Tiigi
9d88450118 enable opentelemetry support
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-07-12 13:42:52 -07:00
Tonis Tiigi
334c93fbbe vendor: update buildkit to opentelemetry support
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-07-12 13:42:45 -07:00
Tõnis Tiigi
6ba080d337 Merge pull request #669 from crazy-max/compose-spec
Use compose-spec parser
2021-07-12 09:46:13 -07:00
CrazyMax
ba443811e4 Use compose-spec parser
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-07-12 11:21:04 +02:00
CrazyMax
67bd6f4dc8 Merge pull request #659 from crazy-max/release-out
Ignore release-out folder
2021-07-02 11:12:46 +02:00
CrazyMax
9f50eccbd7 Ignore release-out folder
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-07-02 07:18:18 +02:00
Tõnis Tiigi
12db50748b Merge pull request #645 from tonistiigi/new-bake-parser
New bake parser
2021-07-01 17:09:45 -07:00
CrazyMax
9b4937f062 Merge pull request #656 from crazy-max/buildx-image
Create buildx image
2021-06-30 20:22:38 +02:00
CrazyMax
3d48359e95 Create buildx image
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-06-30 16:01:28 +02:00
CrazyMax
70002ebbc7 Merge pull request #657 from crazy-max/moby-ioutils
Use `ioutils.AtomicWriteFile` from moby
2021-06-30 09:20:38 +02:00
CrazyMax
ef95f8135b Use ioutils.AtomicWriteFile from moby
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-06-30 08:34:45 +02:00
CrazyMax
9215fc56a3 Merge pull request #605 from crazy-max/bake-iidfile
Add `metadata-file` flag
2021-06-30 08:25:33 +02:00
CrazyMax
1253020b3d Add metadata-file flag
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-06-30 07:41:26 +02:00
Tõnis Tiigi
621c55066c Merge pull request #654 from tonistiigi/enable-win-arm64
Dockerfile: enable windows/arm64
2021-06-29 10:52:29 -07:00
Tonis Tiigi
77632ac15f Dockerfile: enable windows/arm64
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-06-29 08:55:05 -07:00
Tõnis Tiigi
db6aa34252 Merge pull request #653 from tonistiigi/xx-v2
Dockerfile: update xx
2021-06-29 08:53:25 -07:00
CrazyMax
7ecfd3d298 Merge pull request #652 from tonistiigi/enable-riscv64
enable linux/riscv64 builds
2021-06-29 09:52:44 +02:00
Tonis Tiigi
9a8c287629 Dockerfile: update xx
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-06-28 18:30:57 -07:00
Tonis Tiigi
591099a4b8 enable linux/riscv64 builds
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-06-28 18:16:53 -07:00
Tõnis Tiigi
31309b9205 Merge pull request #582 from rumpl/feat-fail-fast
Fail fast on multi platform build with load
2021-06-28 09:29:12 -07:00
CrazyMax
8c0cefcd89 Merge pull request #649 from admackin/patch-3
note that buildx not in all distros
2021-06-28 03:45:27 +02:00
Andy MacKinlay
a07f5cdf42 note that buildx not in all distros
Signed-off-by: Andy MacKinlay <admackin@gmail.com>
2021-06-28 09:41:19 +10:00
Djordje Lukic
a1d899d400 Fail fast on multi platform build with load
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
2021-06-27 16:18:08 +02:00
CrazyMax
886e1a378c Merge pull request #639 from eitsupi/fix-link
Minor fix to links in the document
2021-06-25 14:51:31 +02:00
SHIMA Tatsuya
47b7ba4e79 change the default branch name of the linked repo
Signed-off-by: SHIMA Tatsuya <ts1s1andn@gmail.com>
2021-06-25 19:17:40 +09:00
Tonis Tiigi
79433cef7a bake: fix target merge between compose and hcl
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-06-24 22:40:32 -07:00
Tonis Tiigi
c5eb8f58b4 bake: new hclparser package
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-06-24 22:40:25 -07:00
Tõnis Tiigi
03b7128b60 Merge pull request #575 from tonistiigi/user-func-vars
bake: allow user functions in variables and vice-versa
2021-06-23 11:08:56 -07:00
Tõnis Tiigi
15b358bec6 Merge pull request #618 from MichalAugustyn/handle-resources
feat: add resources handling to kubernetes driver
2021-05-29 22:25:40 -07:00
Michal Augustyn
a53e392afb feat: add resources handling to kubernetes driver
Signed-off-by: Michal Augustyn <michal.augustyn@mail.com>
2021-05-29 13:45:52 +02:00
Akihiro Suda
4fec647b9d Merge pull request #613 from tonistiigi/docs-update
readme: update installation instructions
2021-05-19 15:50:28 +09:00
Tonis Tiigi
d7b28fb4d3 docs: update bake notes
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-05-17 22:53:56 -07:00
Tonis Tiigi
9bc9291fc9 readme: update installation instructions
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-05-17 22:33:08 -07:00
Tonis Tiigi
df7a318ec0 bake: allow user functions in variables and vice-versa
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-05-05 22:08:31 -07:00
Tõnis Tiigi
908a856079 Merge pull request #590 from AkihiroSuda/split-flagparser
build: split buildflags package
2021-04-22 11:50:57 -07:00
Akihiro Suda
8d64b6484f Merge pull request #592 from tonistiigi/descriptor-merge
imagetools: fix merging JSON descriptor with old one
2021-04-15 21:23:56 +09:00
Akihiro Suda
399df854ea build: split buildflags package
Planned to be imported by nerdctl in future.

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2021-04-12 14:36:56 +09:00
Tonis Tiigi
328441cdc6 imagetools: fix merging JSON descriptor with old one
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-04-09 11:02:16 -07:00
Tõnis Tiigi
5ca0cbff8e Merge pull request #535 from tonistiigi/github-actions-cache
allow exporting to github cache backend
2021-04-09 10:30:46 -07:00
Tõnis Tiigi
ab09846df7 Merge pull request #583 from thaJeztah/docs_fixes
docs: address some review comments from the docs repository
2021-04-07 08:07:49 -07:00
Sebastiaan van Stijn
cd3a9ad38d docs: address some review comments from the docs repository
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-04-07 16:04:11 +02:00
Tõnis Tiigi
adc5f35237 Merge pull request #581 from alexcb/use-default-ssh-when-missing-v2
include default ssh socket when given an ssh-based git url
2021-04-01 19:32:18 -07:00
Alex Couture-Beil
0b984e429b Update buildkit
- updated buildkit to current code in master via:

  go mod edit -require github.com/moby/buildkit@master && go mod tidy && ./hack/update-vendor

Signed-off-by: Alex Couture-Beil <alex@earthly.dev>
2021-04-01 16:38:16 -07:00
Alex Couture-Beil
eec843a325 include default ssh socket when given an ssh-based git url
Signed-off-by: Alex Couture-Beil <alex@earthly.dev>
2021-04-01 11:25:18 -07:00
Tonis Tiigi
83868a48b7 temp local copy of userfunc
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-03-26 17:06:38 -07:00
Tõnis Tiigi
98d337af21 Merge pull request #541 from tonistiigi/json-vars-attrs
bake: allow attributes in global scope
2021-03-26 17:06:19 -07:00
Tõnis Tiigi
b2c7dc00cc Merge pull request #570 from thaJeztah/fix_trailing_whitespace
remove trailing whitespace in command descriptions
2021-03-26 16:47:29 -07:00
Sebastiaan van Stijn
44ddc5a02b remove trailing whitespace in command descriptions
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-25 23:19:15 +01:00
Tonis Tiigi
f036bba48c bake: add test for json vars and attributes
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-03-25 11:00:17 -07:00
Tonis Tiigi
0fe2ce7fac bake: allow attributes in global scope
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-03-25 11:00:17 -07:00
Tõnis Tiigi
0147b92230 Merge pull request #506 from thaJeztah/split_docs
Split docs to separate files
2021-03-24 22:14:43 -07:00
Tonis Tiigi
4047bccf6c docs: add external docs links support
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-03-25 00:44:29 +01:00
Tonis Tiigi
363c0fdf4b hack: add docs generation/validation
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-03-25 00:44:26 +01:00
Tonis Tiigi
c46407b2d3 docs: reference docs updates
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-25 00:44:17 +01:00
Tonis Tiigi
ca0f5dabea docs: add md generation
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-03-25 00:38:04 +01:00
Sebastiaan van Stijn
17d4106e1b docs: fix markdown formatting and highlighting
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-25 00:38:02 +01:00
Sebastiaan van Stijn
442d38080e docs: use "examples" section, and rephrase headings
Put the flag descriptions/examples under an "examples"
section (used at docs.docker.com), and rephrase the
headings to be more consistent with other pages in the
docker documentation.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-25 00:38:01 +01:00
Sebastiaan van Stijn
87ec3af5bb docs: add stubs for all commands
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-25 00:37:59 +01:00
Sebastiaan van Stijn
1a8af33ff6 docs: standardize format for usage
Use the usage output of `--help` for each subcommand, to make
sure all flags/options are included on the page, and to make
it easier to keep docs in sync.

Note that the usage output is only used when reading these
docs on GitHub; docs.docker.com only consumes the "description"
and "example" sections (when present), and generates flag information
and usage output from source

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-25 00:37:57 +01:00
Sebastiaan van Stijn
ff749d8863 docs: split reference docs to separate files
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-25 00:37:53 +01:00
Tõnis Tiigi
2d86ddd37f Merge pull request #569 from thaJeztah/dont_discard_manifest_errors
imagetools inspect: don't discard errors from PrintManifestList
2021-03-24 09:23:43 -07:00
Sebastiaan van Stijn
e1bbb9d8de imagetools inspect: don't discard errors from PrintManifestList
Looks like this function may return an error, which we currently discard.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-03-24 15:54:32 +01:00
Tonis Tiigi
d7964be29c gha cache caps detection
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-03-23 08:58:50 -07:00
Tonis Tiigi
3fef64f584 allow exporting to github cache backend
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-03-23 08:58:50 -07:00
Akihiro Suda
319b6503a5 Merge pull request #565 from tonistiigi/buildkit-update-0322
vendor: update buildkit to 8effd45b
2021-03-23 18:32:30 +09:00
Tonis Tiigi
d40a6082fa vendor: update buildkit to 8effd45b
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-03-22 15:54:07 -07:00
Akihiro Suda
28809b82a2 Merge pull request #539 from tonistiigi/vars-cross-refs
bake: allow variables to reference each other
2021-03-19 18:34:29 +09:00
Tõnis Tiigi
c9f02c32d4 Merge pull request #558 from ulyssessouza/add-quiet-mode-to-progress-printer
Add quiet mode to progress printer
2021-03-09 13:07:48 -08:00
Ulysses Souza
55d5b80dfe Add quiet mode to progress printer
Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
2021-03-09 17:12:46 -03:00
Tonis Tiigi
33f25acb08 bake: allow variables to reference each other
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-03-07 21:27:30 -08:00
Tonis Tiigi
0e9066f6ed bake: fix hcl tests layout
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-03-01 12:08:09 -08:00
Akihiro Suda
7d2e30096b Merge pull request #538 from tonistiigi/vars-multi-file 2021-02-27 18:11:36 +09:00
Tonis Tiigi
0e9d6460db bake: allow variables across files
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-02-25 16:30:27 -08:00
Tõnis Tiigi
927163bf13 Merge pull request #481 from fauust/patch-1
Update README.md
2021-02-25 16:05:16 -08:00
Tibor Vass
8ac1cf6e45 Merge pull request #545 from tonistiigi/update-go116
update to go1.16
2021-02-23 08:41:34 -08:00
Tonis Tiigi
dba79ba223 update lint to go1.16/golangci
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-02-16 23:43:06 -08:00
Tonis Tiigi
905be6431b Dockerfile: update to go1.16
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-02-16 23:42:59 -08:00
Tõnis Tiigi
ad95d6ba04 Merge pull request #532 from tonistiigi/vars-in-func
bake: allow variables in user functions
2021-02-10 10:06:13 -08:00
Tõnis Tiigi
b77690a373 Merge pull request #540 from tonistiigi/maintainers-update
add akihiro and crazy-max to maintainers
2021-02-10 09:52:50 -08:00
Akihiro Suda
84a734dc87 Merge pull request #531 from tonistiigi/net-none 2021-02-11 02:34:46 +09:00
Akihiro Suda
5079b64ab5 Merge pull request #536 from tonistiigi/hcl-update 2021-02-11 02:32:09 +09:00
Tonis Tiigi
6a343488d2 add akihiro and crazy-max to maintainers
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-02-10 09:18:05 -08:00
Tonis Tiigi
98c3ef60e6 vendor: update hcl
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-02-08 10:18:14 -08:00
faust
73fa351b1c Update README.md
typo

Signed-off-by: Faustin Lammler <faustin@fala.red>
2021-02-08 12:26:18 +01:00
Tibor Vass
c88f7fc307 Merge pull request #529 from tonistiigi/darwin-arm-ci
ci: enable building darwin/arm64 in CI
2021-02-05 08:54:06 -08:00
Tõnis Tiigi
55b8712268 Merge pull request #530 from HollowMan6/patch-1
Fix typos in README.md
2021-02-05 00:51:02 -08:00
Tonis Tiigi
7878f0c514 bake: allow variables in user functions
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-02-04 23:27:09 -08:00
Tonis Tiigi
0f09e2ecfe don't require entitlement for network none
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-02-04 22:45:20 -08:00
Hollow Man
bea3acd4b6 Fix typos
defintion -> definition
avaialble -> available
registed -> registered

Signed-off-by: Hollow Man <hollowman@hollowman.ml>
2021-02-05 14:26:26 +08:00
Tonis Tiigi
fb9004d6b2 ci: enable building darwin/arm64 in CI
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-02-04 19:00:41 -08:00
Tibor Vass
42b7e7bc56 Merge pull request #526 from tonistiigi/darwin-arm64
Dockerfile: add darwin/arm64 support
2021-02-04 17:07:07 -08:00
Tibor Vass
4b2ddd5b6e Merge pull request #527 from tonistiigi/avoid-cp
avoid cp in install target
2021-02-04 17:04:23 -08:00
Tonis Tiigi
b3006221f1 avoid cp in install target
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-02-04 13:29:16 -08:00
Tonis Tiigi
e57108e7c9 Dockerfile: add darwin/arm64 support
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2021-02-04 12:23:23 -08:00
Tõnis Tiigi
6b3dc6687b Merge pull request #517 from tiborvass/execabs
Use golang.org/x/sys/execabs
2021-01-28 15:47:19 -08:00
Tibor Vass
92f6f9f973 Use golang.org/x/sys/execabs
Signed-off-by: Tibor Vass <tibor@docker.com>
2021-01-27 21:09:53 +00:00
Tõnis Tiigi
a56a4c00dd Merge pull request #503 from felipecrs/patch-1
Add setproduct function to the bake HCL
2021-01-19 16:54:35 -08:00
Tõnis Tiigi
ee4a115d4c Merge pull request #505 from thaJeztah/bump_cobra
vendor: github.com/spf13/cobra v1.1.1
2021-01-19 16:53:11 -08:00
Sebastiaan van Stijn
976a58c918 vendor: github.com/spf13/cobra v1.1.1
v1.1.1:

- Fix: yaml.v2 2.3.0 contained a unintended breaking change. This release reverts
  to yaml.v2 v2.2.8 which has recent critical CVE fixes, but does not have the
  breaking changes.
- Fix: correct internal formatting for go-md2man v2 (which caused man page
  generation to be broken).

v1.1.0:

- Extend Go completions and revamp zsh comp
- Add completion for help command
- Complete subcommands when TraverseChildren is set
- Fix stderr printing functions
- fix: fish output redirection

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2021-01-13 11:18:25 +01:00
Tõnis Tiigi
db82aa1b77 Merge pull request #504 from crazy-max/default-progress
Allow to set default progress through env var
2021-01-11 09:33:33 -08:00
CrazyMax
d05504c50f Allow to set default progress through env var
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2021-01-11 01:41:44 +01:00
Felipe Santos
f1f464e364 Add setproduct function to the bake HCL
As explained in the following link, it's a very useful function.

https://www.terraform.io/docs/configuration/functions/setproduct.html#finding-combinations-for-for_each
Signed-off-by: Felipe Santos <felipecassiors@gmail.com>
2021-01-10 06:11:14 +00:00
Tõnis Tiigi
57b875a955 Merge pull request #491 from crazy-max/hcl2-funcs
Extend hcl2 support with more functions
2021-01-04 10:44:23 -08:00
Tõnis Tiigi
ea5d32ddff Merge pull request #488 from crazy-max/secrets-env
Allow secrets with env
2021-01-04 10:40:09 -08:00
Tõnis Tiigi
da8c8ccaf5 Merge pull request #497 from morlay/k8s-driver-configuration-bind
feat: store kube config file to make buildx builder switchable
2021-01-04 10:39:14 -08:00
Tõnis Tiigi
dcbe4b3e1a Merge pull request #477 from morlay/master
should list real pod nodes when all drivers are kubernetes
2021-01-04 10:37:55 -08:00
Wang
68cebffe13 feat: store kube config file to make buildx builder switchable
Signed-off-by: Wang <morlay.null@gmail.com>
2020-12-30 17:28:14 +08:00
CrazyMax
96e7f3224a Extend hcl2 support with more functions
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2020-12-23 12:33:55 +01:00
CrazyMax
f6d83c97bb Allow secrets with env
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2020-12-19 04:18:51 +01:00
Tõnis Tiigi
74f76cf4e9 Merge pull request #480 from AkihiroSuda/bkimage-rootless
set DefaultRootlessImage to "moby/buildkit:buildx-stable-1-rootless"
2020-12-16 11:59:56 -08:00
Akihiro Suda
8b8725d1fd set DefaultRootlessImage to "moby/buildkit:buildx-stable-1-rootless"
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2020-12-16 17:35:38 +09:00
Tõnis Tiigi
20494f799d Merge pull request #470 from tonistiigi/dockerfile-1.2
update Dockerfile to v1.2
2020-12-15 10:35:55 -08:00
Wang Jinglei
dd13e16bc7 should list real pod nodes when all drivers are kubernetes
Signed-off-by: Wang <morlay.null@gmail.com>
2020-12-15 17:09:03 +08:00
Tõnis Tiigi
11057da373 Merge pull request #475 from tiborvass/fix_create_platform_regression
driver: do not insert "platform" as driver-opt
2020-12-14 23:37:22 -08:00
Tibor Vass
381dc8fb43 driver: do not insert "platform" as driver-opt
Addresses https://github.com/docker/setup-buildx-action/issues/45

Simple repro:
```
$ buildx create --platform linux/amd64 --use
$ buildx build - <<EOF
from scratch
EOF
```

Since https://github.com/docker/buildx/pull/370 a `platform` driver-opt was automatically inserted with the value specified by `--platform` flag on regardless of the type of driver, even though it was only used in the kubernetes driver. However, because the docker-container driver is pedantic about the options being passed, it errored out.

Another side-effect I suspect is that with the kubernetes driver it was now possible to specify the platforms in two different ways: `--driver-opt platform=...` and `--platform`.

This patch reverts completely the `platform` driver-opt and instead ensures the platforms information is passed onto the kubernetes driver via variables.

Signed-off-by: Tibor Vass <tibor@docker.com>
2020-12-15 07:09:46 +00:00
Tõnis Tiigi
780fad46f2 Merge pull request #471 from crazy-max/remove-travis
Remove travis support and unused buildmode
2020-12-09 20:40:15 -08:00
CrazyMax
2ca5ffa06a Remove travis support and unused buildmode
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2020-12-09 07:51:32 +01:00
Tonis Tiigi
f349ba8750 update Dockerfile to v1.2
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-12-08 15:44:08 -08:00
Tõnis Tiigi
33e3ca524e Merge pull request #442 from tonistiigi/moby-push
build: add push support to docker driver
2020-12-08 15:01:37 -08:00
Tõnis Tiigi
ea1a71dc07 Merge pull request #467 from cpuguy83/deterministic_output
Get multi-platform buildkit frontend opt from args
2020-12-08 15:00:57 -08:00
Tõnis Tiigi
ae820293a2 Merge pull request #468 from crazy-max/ghactions-release
GitHub Actions release
2020-12-08 13:57:38 -08:00
Tonis Tiigi
f68f42cb11 build: add push support to docker driver
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-12-08 13:54:41 -08:00
Brian Goff
7f58ad45fa Get multi-platform buildkit frontend opt from args
This allows builders to opt into determnistic output regardless of
multi-platform output or not.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2020-12-08 13:18:56 -08:00
Tõnis Tiigi
aa7c17989b Merge pull request #469 from tonistiigi/buildkit-update-1207
vendor: update buildkit to v0.8
2020-12-08 13:10:07 -08:00
Tonis Tiigi
6b6afc4077 build: add logger for auth
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-12-07 23:43:28 -08:00
Tonis Tiigi
69a1419ab1 vendor: update buildkit to v0.8
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-12-07 23:16:06 -08:00
Tõnis Tiigi
080e9981c7 Merge pull request #398 from tonistiigi/remote-bake
bake: remote inputs support
2020-12-07 23:07:24 -08:00
CrazyMax
8cc00ab486 GitHub Actions release
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2020-12-08 07:20:41 +01:00
Tonis Tiigi
40fad4bbb5 progress: make sure all channels have written before returning
Possible write on closed channel on cancellation before.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-12-07 22:02:51 -08:00
Tonis Tiigi
232af9aa0d move moby check to driver interface
Driver caching masked the method detection

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-12-07 22:02:51 -08:00
Tonis Tiigi
5bf2ff98c9 bake: support filenames without suffix
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-12-07 22:02:51 -08:00
Tonis Tiigi
570e733a51 bake: support inline dockerfile
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-12-07 22:02:51 -08:00
Tonis Tiigi
cffcd57edb bake: support for remote files
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-12-07 22:02:51 -08:00
Tonis Tiigi
1496ac9b55 util: simplify progress syncronization
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-12-07 22:02:51 -08:00
Tonis Tiigi
290e25917c build: allow dockerfile from URL
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-12-07 22:02:51 -08:00
Tõnis Tiigi
0360668cc1 Merge pull request #428 from zanven42/master
fixes #427: Handle empty strings in elements enabling conditional logic
2020-12-07 21:59:43 -08:00
Tõnis Tiigi
343a4753c7 Merge pull request #460 from morlay/master
fix: buildx in k8s pod with kube client config in cluster
2020-12-07 21:59:23 -08:00
Wang
d827f42d38 fix: buildx in k8s pod with kube client config in cluster
Signed-off-by: Wang <morlay.null@gmail.com>
2020-12-08 13:17:23 +08:00
Tonis Tiigi
5843e67a90 fix indentations in example
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-12-07 21:02:48 -08:00
Tõnis Tiigi
517df133e3 Merge pull request #403 from jygastaud/master
fixes #401 : Replace error generated by `quiet` option by a warning.
2020-12-07 20:57:09 -08:00
Tõnis Tiigi
621114fbe1 Merge pull request #465 from crazy-max/update-vendor
Update vendor and binaries script
2020-12-07 20:55:32 -08:00
Tõnis Tiigi
2066051d3a Merge pull request #466 from crazy-max/ghactions-cross
GitHub Actions cross
2020-12-07 20:53:09 -08:00
CrazyMax
d94cbd870c GitHub Actions cross
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2020-12-07 17:29:35 +01:00
CrazyMax
48f15dcf3d Update vendor and binaries script
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2020-12-07 17:14:45 +01:00
Tõnis Tiigi
35a60b8e04 Merge pull request #441 from tonistiigi/buildkit-pull-creds2
refactor driver auth for easier passing
2020-12-05 00:02:38 -08:00
CrazyMax
4b3df09155 Merge pull request #463 from crazy-max/ghactions-test
GitHub Actions for test
2020-12-05 08:13:41 +01:00
CrazyMax
b1215c2ce2 GitHub Actions for test
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2020-12-05 04:18:28 +01:00
Tõnis Tiigi
99ac03f9f3 Merge pull request #451 from docker/ghactions-validate
Refactor validate for GitHub Actions
2020-12-04 15:19:37 -08:00
Tõnis Tiigi
a0aa45a4a7 Merge pull request #462 from zencargo/userns
Disable user namespace remapping in docker-container driver
2020-12-03 20:03:32 -08:00
Tõnis Tiigi
aab3a92890 Merge pull request #444 from tonistiigi/lowercase-dockerfile
build: handle lowercase Dockerfile name as a fallback
2020-12-03 17:54:47 -08:00
Andrew Haines
37020dc8da Disable user namespace remapping in docker-container driver
Signed-off-by: Andrew Haines <andrew.haines@zencargo.com>
2020-12-03 10:50:00 +00:00
CrazyMax
d66d3a2d09 Refactor validate for GitHub Actions
Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
2020-11-30 08:14:28 +01:00
Tonis Tiigi
f057195a4f build: handle lowercase Dockerfile name as a fallback
This was supported by the legacy builder: moby#10858

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-11-18 22:11:35 -08:00
Tonis Tiigi
378bf70d4b refactor driver auth for easier passing
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-11-15 20:49:58 -08:00
Tõnis Tiigi
1ccf0bd7d8 Merge pull request #433 from tonistiigi/buildkit-pull-creds
docker-container: ensure credentials are passed when pulling buildkit
2020-11-15 20:13:27 -08:00
Tõnis Tiigi
ddbfddce88 Merge pull request #425 from tonistiigi/default-builder
allow builder flag to switch to default instance
2020-11-12 11:07:37 -08:00
Tonis Tiigi
ea19cf9d8d inspect: make sure to show boot error from driver
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-11-04 14:39:54 -08:00
Tonis Tiigi
3b69482a2f docker-container: ensure credentials are passed when pulling buildkit image
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-11-04 13:04:04 -08:00
Tõnis Tiigi
778fbb4669 Merge pull request #390 from tonistiigi/fix-warn
build: avoid warn on empty config value
2020-11-02 19:36:20 -08:00
Tõnis Tiigi
13533e359a Merge pull request #432 from thaJeztah/bump_console_v1.0.1
vendor: containerd/console v1.0.1, and remove golang.org/x/sys replace
2020-11-02 19:35:34 -08:00
Sebastiaan van Stijn
3c2d0aa667 vendor: containerd/console v1.0.1, and remove golang.org/x/sys replace
this removes the replace rule that was added in 3c94621142,
to fix compile failures for macOS.

containerd/console v1.0.1 fixes those issues, which allows us to remove the
replace rule again.

full diff: https://github.com/containerd/console/compare/v1.0.0...v1.0.1

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-10-31 14:18:57 +01:00
Sebastiaan van Stijn
5551de4b8a go.mod: reformat file
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-10-31 13:50:45 +01:00
Sebastiaan van Stijn
fa51b90094 vendor: fix docker/docker vendoring (update to 9f28837c1d93
commit c41b006be1 updated the version of
docker/docker in go.mod, but possibly overlooked that there was still a
replace rule present. As a result the version was not actually updated.

This patch removes the replace rule, updating docker/docker to 9f28837c1d93

full diff: 4634ce647c...9f28837c1d

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-10-31 13:50:34 +01:00
Anthony Poschen
bfd1ea3877 Added doco for conditonal tags in bake file.
Signed-off-by: Anthony Poschen <zanven42@gmail.com>
2020-10-26 16:37:28 +11:00
Anthony Poschen
abfb2c064d Add support for empty strings in target elements and compact func.
Signed-off-by: Anthony Poschen <zanven42@gmail.com>
2020-10-26 15:56:18 +11:00
Tonis Tiigi
4f7517115c allow builder flag to switch to default instance
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-10-21 23:19:28 -07:00
Tonis Tiigi
1621b9bad0 build: avoid warn on empty config value
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-10-16 23:05:37 -07:00
Tibor Vass
d2bf42f8b4 Merge pull request #397 from tonistiigi/update-buildkit-20200919
vendor: update buildkit to 2943a0838
2020-10-14 01:03:56 -07:00
Tõnis Tiigi
d1a46faf84 Merge pull request #404 from thaJeztah/remove_annotations
Remove "version" annotations from du and prune commands
2020-09-29 14:35:05 -07:00
Sebastiaan van Stijn
39f1d99dcc Remove "version" annotations from du and prune commands
These annotations were picked up by the YAML docs generator, and shows up as
"minimum API version". I couldn't find a reference to these annotations in the
PR that added them, so thought it would be ok to remove

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-09-29 23:13:53 +02:00
Jean-Yves Gastaud
1f04ec9575 fixes #401
Replace error generated by `quiet` option by a warning.

Signed-off-by: Jean-Yves Gastaud <jygastaud@gmail.com>
2020-09-28 11:24:14 +02:00
Tõnis Tiigi
ac2e081528 Merge pull request #391 from tonistiigi/hcl-errors
bake: format hcl errors with source definition
2020-09-19 23:19:41 -07:00
Tonis Tiigi
95ac9ebb8a bake: format hcl errors with source definition
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-09-19 22:50:47 -07:00
Tonis Tiigi
c41b006be1 vendor: update buildkit to 2943a0838
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-09-19 22:49:12 -07:00
Sebastiaan van Stijn
92fb995505 Merge pull request #389 from tonistiigi/buildkit-update-20200913
vendor: update buildkit with typed errors support
2020-09-17 12:40:34 +02:00
Tonis Tiigi
3c94621142 vendor: downgrade sys unix
containerd and moby packages do not build in darwin anymore

6fcdbc0bbc

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-09-14 20:50:09 -07:00
Tonis Tiigi
2d720a1e0b vendor: update buildkit with typed errors support
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-09-13 21:28:20 -07:00
Tõnis Tiigi
0269388aa7 Merge pull request #385 from errordeveloper/fix-308
Allow users to have separate store paths
2020-09-10 10:24:05 -07:00
Ilya Dmitrichenko
4b2aab09b5 Allow users to have separate store paths
- decouple store path from `$DOCKER_CONFIG`
- improve containerised build setup
- introduce new `$BUILDX_CONFIG` environment variable

Signed-off-by: Ilya Dmitrichenko <errordeveloper@gmail.com>
2020-09-10 17:14:41 +01:00
Tõnis Tiigi
1c7434a8f0 Merge pull request #372 from thaJeztah/arch_detect
hack/util: take other arches into account on Darwin
2020-09-02 08:30:22 -07:00
Sebastiaan van Stijn
20f8f67928 hack/util: take other arches into account on Darwin
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-08-31 11:40:10 +02:00
Tõnis Tiigi
159535261d Merge pull request #370 from morlay/kubernetes-driver-enhancement
feat: enhance kubernetes driver
2020-08-30 19:35:13 -07:00
Tõnis Tiigi
a840e891fe Merge pull request #371 from tonistiigi/update-travis-image
travis: update base image
2020-08-30 19:33:34 -07:00
Wang Jinglei
a7c704c39d feat: enhance kubernetes driver
Signed-off-by: Wang Jinglei <morlay.null@gmail.com>
2020-08-31 09:20:49 +08:00
Tonis Tiigi
e1c0eb2187 travis: update base image
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-08-30 17:26:20 -07:00
Sebastiaan van Stijn
aa8ab9fcca hack/util: fix mixed tab/spaces for indentation
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-08-30 13:00:37 +02:00
Sebastiaan van Stijn
a746959fc1 hack: fix SC2069 : to redirect stdout+stderr, 2>&1 must be last
See https://github.com/koalaman/shellcheck/wiki/SC2069

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-08-30 12:57:19 +02:00
Tõnis Tiigi
ee34eb2180 Merge pull request #368 from morlay/master
feat: use k8s cluster config when buildx used in k8s cluster
2020-08-29 12:15:17 -07:00
Wang Jinglei
844b901005 feat: use k8s cluster config when buildx used in k8s cluster
Signed-off-by: Wang Jinglei <morlay.null@gmail.com>
2020-08-28 17:51:18 +08:00
Tõnis Tiigi
83ebc13a37 Merge pull request #297 from AkihiroSuda/doc-linuxkit-binfmt
README.md: add usage of tonistiigi/binfmt
2020-08-26 16:49:01 -07:00
Akihiro Suda
82c8f2d8f0 README.md: add usage of tonistiigi/binfmt
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2020-08-26 13:52:26 +09:00
Tõnis Tiigi
a11cc8840e Merge pull request #360 from kotaroooo0/fix-error-message-for-push-option
build: fix error message for --push option
2020-08-25 15:59:14 -07:00
Tõnis Tiigi
35ee6ce62d Merge pull request #363 from thaJeztah/bump_deps
Update dependencies
2020-08-25 11:37:26 -07:00
Sebastiaan van Stijn
37861cb99f vendor: hashicorp/hcl v2.6.0
full diff: https://github.com/hashicorp/hcl/compare/v2.4.0...v2.6.0

v2.6.0
-------------------------

Enhancements:

- hcldec: Add a new Spec, ValidateSpec, which allows custom validation of values at decode-time.

Bugs Fixed:

- hclsyntax: Fix panic with combination of sequences and null arguments
- hclsyntax: Fix handling of unknown values and sequences

v2.5.1
-------------------------

- hclwrite: handle legacy dot access of numeric indexes. (#369)
- hclwrite: Fix panic for dotted full splat (foo.*)

v2.5.0
-------------------------

- hclwrite: Generate multi-line objects and maps.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-08-24 11:04:40 +02:00
Sebastiaan van Stijn
a178d05023 vendor: github.com/gofrs/flock v0.7.3
full diff: https://github.com/gofrs/flock/compare/v0.7.0...v0.7.3

v0.7.3
-------------------------

- Fix issues in the license file, update year.

v0.7.2
-------------------------

- Ensure we release file handle if we failed to take an exclusive lock

v0.7.1
-------------------------

- Fix linting issues and add goreportcard badge

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-08-24 11:02:16 +02:00
Sebastiaan van Stijn
ee9ccfe2e3 vendor: buildkit v0.7.2
v0.7.2
----------------

Fixes:

- solver: gracefully handle cache loading errors
- remotecache: only visit each item once when walking results
- cache: avoid possible nil dereference on error handling
- contenthash: allow security.capability in cache checksum
- contenthash: treat unix sockets as regular files
- push: fix race condition on pushing the same layers in parallel
- inline cache: fix handling of duplicate blobs in same image
- gateway: fix metadata getting lost on subsolve in external frontend
- filesync: avoid ignoring close error
- runc: update runc binary to v1.0.0-rc91
- buildctl-daemonless: allow max retries on socket connect for buildctl
- buildctl-daemonless: fix shell args expansion
- buildctl-daemonless: show log on startup timeout

v0.7.1
----------------

Fixes:

- git: use --force flag on fetch
- tar exporter: handle symlinks properly
- resolver: disable http2 for pushing

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-08-24 10:30:00 +02:00
Sebastiaan van Stijn
c6c4b4a871 vendor: sirupsen/logrus v1.6.0
1.6.0
--------------------------

Fixes:
  * end of line cleanup
  * revert the entry concurrency bug fix whic leads to deadlock under some circumstances
  * update dependency on go-windows-terminal-sequences to fix a crash with go 1.14

Features:
  * add an option to the `TextFormatter` to completely disable fields quoting

1.5.0
--------------------------

Code quality:
  * add golangci linter run on travis

Fixes:
  * add mutex for hooks concurrent access on `Entry` data
  * caller function field for go1.14
  * fix build issue for gopherjs target

Feature:
  * add an hooks/writer sub-package whose goal is to split output on different stream depending on the trace level
  * add a `DisableHTMLEscape` option in the `JSONFormatter`
  * add `ForceQuote` and `PadLevelText` options in the `TextFormatter`

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-08-24 10:26:07 +02:00
Sebastiaan van Stijn
273c6a75a2 vendor: update Cobra v1.0.0
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-08-24 10:20:59 +02:00
Kotaro Adachi
1384bf02f9 error message for --push option
Signed-off-by: Kotaro Adachi <k33asby@gmail.com>
2020-08-23 00:03:13 +09:00
Tõnis Tiigi
fb7b670b76 Merge pull request #338 from tonistiigi/load-no-warn
build: avoid warning if default load disabled
2020-08-21 19:36:07 -07:00
Tõnis Tiigi
9ac5b075cf Merge pull request #323 from saulshanabrook/patch-1
Increase ls and inspect timeouts
2020-08-21 12:44:33 -07:00
Tonis Tiigi
0124b6b9c9 build: avoid warning if default load disabled
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-08-21 12:43:49 -07:00
Tõnis Tiigi
691a1479fc Merge pull request #351 from tonistiigi/multi-iidfile
build: remove warning for multi-platform iidfile
2020-08-21 12:29:47 -07:00
Tonis Tiigi
c9d69b082b build: remove warning for multi-platform iidfile
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-08-17 22:34:45 -07:00
Tõnis Tiigi
e24e04be57 Merge pull request #332 from tonistiigi/bootstrap-logs
docker-container: show logs on bootstrap error
2020-07-29 19:33:08 -07:00
Tõnis Tiigi
38f9241316 Merge pull request #337 from tonistiigi/cacheonly-exporter
build: support cacheonly exporter
2020-07-29 19:32:54 -07:00
Tonis Tiigi
3862ff269b build: add opt-out from default load behavior
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-07-27 22:38:06 -07:00
Tonis Tiigi
9e5321eab8 build: support cacheonly exporter
cacheonly is supported by moby so add support for buildx
as well so same flags can be used

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-07-27 22:33:44 -07:00
Tibor Vass
f2cf7cf281 Merge pull request #333 from tonistiigi/dockerd-log
demo-env: correct dockerd logging
2020-07-27 17:44:06 +02:00
Tonis Tiigi
8961d3573e hack: correct dockerd logging
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-07-26 00:13:02 -07:00
Tonis Tiigi
26570d05c1 docker-container: increase bootstrap timeout
Previous value was only 2 sec

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-07-26 00:11:33 -07:00
Tonis Tiigi
8627f668f2 docker-container: show logs on bootstrap error
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-07-26 00:11:27 -07:00
Tõnis Tiigi
d8ca46066d Merge pull request #321 from errordeveloper/fix-320
bake: ensure `--builder` is wired from root options
2020-07-19 15:58:33 -07:00
Saul Shanabrook
c00c5a89e5 Increase inspect timeout from 5 to 20 seconds
Signed-off-by: Saul Shanabrook <s.shanabrook@gmail.com>
2020-07-16 11:56:40 -04:00
Saul Shanabrook
14b7936c3b Increase ls timeout from 7 to 20 seconds
Signed-off-by: Saul Shanabrook <s.shanabrook@gmail.com>
2020-07-16 11:56:40 -04:00
Ilya Dmitrichenko
40b41ac6e4 bake: ensure --builder is wired from root options
Signed-off-by: Ilya Dmitrichenko <errordeveloper@gmail.com>
2020-07-08 12:03:15 +01:00
Tõnis Tiigi
fd6de6b6ae Merge pull request #281 from tonistiigi/load-fix
build: improve error checking on load
2020-07-07 09:06:34 -07:00
Tõnis Tiigi
f3111bcbef Merge pull request #312 from donhui/master
README.md: update the content which not display in markdown
2020-06-20 17:41:31 -07:00
Donghui Wang
e6be472831 update the content which not display in markdown
Signed-off-by: Donghui Wang <977675308@qq.com>
2020-06-19 17:30:49 +08:00
Tibor Vass
e5217f26e2 Merge pull request #296 from tonistiigi/seed-fix
cmd: seed math rand
2020-05-18 12:03:57 -07:00
Tonis Tiigi
7f7acf7837 cmd: seed math rand
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-05-17 16:21:11 -07:00
Tonis Tiigi
baae4b2e71 build: improve error checking on load
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-05-08 17:46:28 -07:00
Tõnis Tiigi
42448c5f37 Merge pull request #280 from vanstee/hcl-json-support
Support parsing json config with hcl v2
2020-05-08 09:25:25 -07:00
Tõnis Tiigi
fc7875675c Merge pull request #277 from cpuguy83/moar_hcl_stdlib_funcs
Update go-cty to pull in more stdlib funcs.
2020-05-08 09:23:47 -07:00
Patrick Van Stee
355261e49e Parse bake config as hcl falling back to json
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
2020-05-07 23:53:49 -04:00
Patrick Van Stee
44c840b31d Add test of parsing a json bake config
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
2020-05-07 23:53:49 -04:00
Patrick Van Stee
1bc068a583 Fix json keys for groups and targets
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
2020-05-07 23:53:49 -04:00
Patrick Van Stee
340686a383 Support parsing json config with hcl v2
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
2020-05-07 23:53:49 -04:00
Brian Goff
1ad87c6ba6 Update go-cty to pull in more stdlib funcs.
I needed "split" specifically so I can do something like:

```hcl
variable PLATFORMS {
  default = "linux/amd64"
}

target foo {
  platforms = split(",", "${PLATFORMS}")
  # other stuff
}
```

Where the existing "csvdecode" does not work for this because it parses
the string into a list of objects instead of a list of strings.

I went ahead and just added all the available new functions.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2020-05-07 16:05:17 -07:00
Tõnis Tiigi
eadf5eddbc Merge pull request #270 from thaJeztah/prune_force_shorthand
Add -f shorthand flag for prune --force
2020-05-07 11:41:32 -07:00
Sebastiaan van Stijn
f4f58003fb Add -f shorthand flag for prune --force
The docker builder prune command has a shorthand `-f` flag for `--force`:

    docker builder prune --help

    Usage:	docker builder prune

    Remove build cache

    Options:
      -a, --all                  Remove all unused build cache, not just dangling ones
          --filter filter        Provide filter values (e.g. 'until=24h')
      -f, --force                Do not prompt for confirmation
          --keep-storage bytes   Amount of disk space to keep for cache

Given that `buildx` can be used as a drop-in replacement for the native build
commands, it should match the UI, and also have a shorthand flag.

This patch also updates the flag's description to be in line with the docker commandline

With this patch applied;

    buildx prune --help
    Remove build cache

    Usage:
      buildx prune [flags]

    Flags:
      -a, --all                  Remove all unused images, not just dangling ones
          --filter filter        Provide filter values (e.g. 'until=24h')
      -f, --force                Do not prompt for confirmation
      -h, --help                 help for prune
          --keep-storage bytes   Amount of disk space to keep for cache
          --verbose              Provide a more verbose output

    Global Flags:
          --builder string   Override the configured builder instance

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-05-02 21:29:23 +02:00
Tõnis Tiigi
bda4882a65 Merge pull request #268 from tiborvass/fix-tristate
Fix --pull and --no-cache behavior
2020-04-30 15:08:21 -07:00
Tibor Vass
77ddee9314 bake: fix pull and no-cache overrides
Signed-off-by: Tibor Vass <tibor@docker.com>
2020-04-30 14:05:21 -07:00
Tonis Tiigi
c9676c79d1 bake: fix hcl tags
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-04-30 13:41:49 -07:00
Tonis Tiigi
18095ee87b bake: reset no-cache and pull if not set
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-04-30 13:01:45 -07:00
Tibor Vass
c4d07f67e3 commands: check if flag is set instead of using flagutil.Tristate
Fixes --pull and --no-cache without argument

Signed-off-by: Tibor Vass <tibor@docker.com>
2020-04-30 12:25:41 -07:00
Tõnis Tiigi
205165bec5 Merge pull request #192 from vanstee/hcl2-with-interpolation
Upgrade to hcl2 to support variables and functions
2020-04-29 10:55:53 -07:00
Patrick Van Stee
870b38837b Allow for user defined functions
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
2020-04-29 08:52:48 -04:00
Patrick Van Stee
10d4b7a878 Add example of interpolation to the README
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
2020-04-29 08:52:20 -04:00
Patrick Van Stee
abed97cf33 Include test cases of different hcl files
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
2020-04-29 08:51:26 -04:00
Patrick Van Stee
f10d8dab5e Define variables as blocks with defaults
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
2020-04-29 08:51:26 -04:00
Patrick Van Stee
5185d534bc Include go-cty stdlib functions in HCL file scope
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
2020-04-29 08:51:26 -04:00
Patrick Van Stee
a520de447e Provide current env as variables in eval context
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
2020-04-29 08:51:26 -04:00
Patrick Van Stee
4121ae50b5 Modify parsing functions and config structs to accept hcl changes
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
2020-04-29 08:51:26 -04:00
Patrick Van Stee
87c4bf1df9 Upgrade hcl to v2
Signed-off-by: Patrick Van Stee <patrick@vanstee.me>
2020-04-28 22:07:52 -04:00
Tibor Vass
09339bf500 Merge pull request #263 from tonistiigi/platforms-print
separate manual and automatically detected platforms
2020-04-28 17:46:09 -07:00
Tõnis Tiigi
af9edb6ba4 Merge pull request #246 from cpuguy83/override_instance
Add option to build/bake to override instance
2020-04-28 17:38:38 -07:00
Brian Goff
b2ec1d331c Add builder as a global flag.
This allows all subcommands to use this flag.
Additionally reads the default value for the flag from the
`BUILDX_BUILDER` env var.

Precedence is:

CLI ARG > flag > env var > config file

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2020-04-27 14:37:17 -07:00
Brian Goff
213d3af3b0 Add option to build/bake to override instance
This helps prevent race conditions with concurrent build invocations.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2020-04-27 11:12:31 -07:00
Tonis Tiigi
4804824c78 separate manual and automatically detected platforms
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-04-24 20:08:43 -07:00
Tõnis Tiigi
d89e3f3014 Merge pull request #249 from tonistiigi/prune
add prune and du commands
2020-04-23 12:17:49 -07:00
Tõnis Tiigi
9ab9b852c2 Merge pull request #165 from tiborvass/pertarget-nocache
bake: allow overriding no-cache and pull per target via --set
2020-04-23 12:17:30 -07:00
Tibor Vass
2a257a8252 bake: allow overriding no-cache and pull per target via --set
Signed-off-by: Tibor Vass <tibor@docker.com>
2020-04-23 18:11:22 +00:00
Tõnis Tiigi
0e1f0e3c73 Merge pull request #164 from tiborvass/multitarget-set
bake: allow pattern matching for target names in --set
2020-04-23 09:23:12 -07:00
Tibor Vass
078b65905a bake: add test cases for pattern matching
Signed-off-by: Tibor Vass <tibor@docker.com>
2020-04-23 05:54:11 +00:00
Tibor Vass
417f52e001 bake: add --load and --push shorthands for --set
Signed-off-by: Tibor Vass <tibor@docker.com>
2020-04-23 05:54:11 +00:00
Tibor Vass
2bca8fa677 bake: allow pattern matching for target names in --set
Although bake is for running multiple targets, --set required a single
target name for overriding a property. This change allows matching
multiple targets for overrides.

Signed-off-by: Tibor Vass <tibor@docker.com>
2020-04-23 05:54:11 +00:00
Tõnis Tiigi
721b63f3a0 Merge pull request #259 from tiborvass/fix-inherits-override
bake: fix override bug with inheritance
2020-04-22 22:24:12 -07:00
Tibor Vass
14e65ff3b4 bake: fix override+inheritance bug
Signed-off-by: Tibor Vass <tibor@docker.com>
2020-04-21 22:42:03 +00:00
Tibor Vass
3282dae09b bake: add tests for override+inheritance bug
Signed-off-by: Tibor Vass <tibor@docker.com>
2020-04-21 22:38:06 +00:00
Sebastiaan van Stijn
7b297eb895 Merge pull request #251 from philips/patch-1
README: add mkdir for .docker/cli-plugins
2020-04-14 18:06:04 +02:00
Brandon Philips
bae6b1cec8 README: add mkdir for .docker/cli-plugins
this dir doesn't exist by default so add a mkdir
2020-04-11 08:54:09 -07:00
Tibor Vass
f4ac640252 Merge pull request #250 from tonistiigi/buildkit-bump
vendor: update buildkit to v0.7.0
2020-04-10 13:43:09 -07:00
Tonis Tiigi
7c627da986 vendor: update buildkit to v0.7.0
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-04-09 22:37:06 -07:00
Tonis Tiigi
d52f5db6ba commands: add du command
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-04-06 19:32:21 -07:00
Tonis Tiigi
66672b4052 commands: add prune command
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2020-04-06 18:03:30 -07:00
Tõnis Tiigi
ed6be92de4 Merge pull request #245 from developer-guy/master
i added kubernetes driver information to drivers section
2020-03-30 15:07:50 -07:00
Batuhan Apaydın
2def02ea74 added kubernetes driver information 2020-03-30 18:34:22 +03:00
Tibor Vass
52b0ea328f Merge pull request #233 from silvin-lubecki/go-1.13
bump to Go 1.13
2020-03-04 12:19:16 -08:00
Silvin Lubecki
960107d00f Bump golang to 1.13 in Dockerfiles
Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
2020-03-04 18:37:46 +01:00
Silvin Lubecki
bbc902b4d6 Bump buildkit to master and fix versions incompatible with go mod 1.13
Bump github.com/gogo/googleapis to v1.3.2
Bump github.com/docker/cli to master

Signed-off-by: Silvin Lubecki <silvin.lubecki@docker.com>
2020-03-04 18:37:42 +01:00
Sebastiaan van Stijn
54549235da Merge pull request #234 from thaJeztah/remove_fossa_scan
Remove FOSSA checks from Jenkins CI
2020-03-04 13:38:47 +01:00
Sebastiaan van Stijn
231f983600 Revert "Add FOSSA checks to Jenkins CI"
This reverts commit 5f4d4a87f7.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2020-03-04 13:01:41 +01:00
Tõnis Tiigi
891d355679 Merge pull request #225 from cpuguy83/k8s_priority
Make k8s driver priority lower
2020-02-16 11:11:40 -08:00
Brian Goff
87fbc406f5 Make k8s driver priority lower
Otherwise it ends up being default and it's probably not the normal
case.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2020-02-12 16:26:53 -08:00
Tõnis Tiigi
08b5a52ccd Merge pull request #219 from ArturKlauser/patch-1
Explain binfmt_misc requirements
2020-01-13 09:38:16 -08:00
Artur Klauser
14a28d7fc3 Update README.md 2020-01-12 10:01:13 +01:00
Tõnis Tiigi
5a79b401b0 Merge pull request #221 from cpuguy83/build_args_env
build: only use env for args if set
2020-01-08 15:30:01 -08:00
Brian Goff
5e4444823c build: only use env for args if set
When following this pattern:

  buildx build --arg FOO

Where we want to pull `FOO` from env, currently we always set `FOO`
regardless if the `FOO` env var is even set.

This change makes it so that `FOO` would only be set if it has been set
in the env (even if it is set to empty).

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2020-01-06 12:02:06 -08:00
Artur Klauser
5ff7635447 Explain binfmt_misc requirements
Getting the QEMU interpreters to work transparently inside containers seems to be a bit of a sticking point, with major distributions still on kernels and/or binfmt-support package versions that don't support the fix_binary flag yet. Give the reader a little more guidance what to look out for.
2020-01-04 00:00:40 +01:00
Tõnis Tiigi
709ef36b4f Merge pull request #207 from ulyssessouza/use-file-interface
Bump containerd/console to use console.File instead of os.File
2019-12-11 17:03:00 -08:00
ulyssessouza
7f0b59dc37 Remove replace for docker/docker and restore prefix on docker/cli
Signed-off-by: ulyssessouza <ulyssessouza@gmail.com>
2019-12-12 01:27:56 +01:00
ulyssessouza
9e8c532e61 Bump docker/cli to 06f34ba50786ec67761745c818e87baecc2ba139
Signed-off-by: ulyssessouza <ulyssessouza@gmail.com>
2019-12-11 14:55:53 +01:00
ulyssessouza
f2be09f4e4 Bump microsoft/hcsshim to v0.8.7
Signed-off-by: ulyssessouza <ulyssessouza@gmail.com>
2019-12-11 14:35:32 +01:00
ulyssessouza
3ff9abca3a Bump moby/buildkit
Signed-off-by: ulyssessouza <ulyssessouza@gmail.com>
2019-12-11 14:13:56 +01:00
ulyssessouza
3d630c6f7f Replace usage of *os.File by console.File interface on printer
Signed-off-by: ulyssessouza <ulyssessouza@gmail.com>
2019-12-10 23:37:42 +01:00
ulyssessouza
9f4f945d4f Bump docker/docker and containerd/console
Signed-off-by: ulyssessouza <ulyssessouza@gmail.com>
2019-12-10 23:37:11 +01:00
Tõnis Tiigi
a0490a8720 Merge pull request #204 from tiborvass/remove-fossa
Revert "ADDED .fossa file for fossa scans"
2019-12-10 10:13:04 -08:00
Tibor Vass
aba962c12c Revert "ADDED .fossa file for fossa scans"
This reverts commit 6e1fd0eab6.
2019-12-10 09:11:39 -08:00
Tõnis Tiigi
aa21e3c731 Merge pull request #200 from jingxiaolu/inspect_image
docker-container: check local image store if pulling image failed
2019-12-08 18:00:55 -08:00
l00397676
5b9d88b3ad docker-container: check local image store if pulling image failed
When booting `docker-container` driver, it will pull and run image
`moby/buildkit:buildx-stable-1`.
If current node cannot connect to dockerhub, driver `docker-container`
will always booting failure.
But user may already load the image manually or pull it from a priviate
registry.
Buildx should check local docker image store after pull failed.

Fixes: #199 issuecomment-561996661

Signed-off-by: Lu Jingxiao <lujingxiao@huawei.com>
2019-12-09 09:29:56 +08:00
Tibor Vass
8bce430f4d Merge pull request #167 from AkihiroSuda/kube
new driver: kubernetes
2019-11-21 09:46:00 -08:00
Akihiro Suda
c6f8de90aa kubernetes: show Kubernetes Pods as buildx "Nodes" in docker buildx inspect
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2019-11-21 10:30:39 +09:00
Akihiro Suda
6b65b0c982 new driver: kubernetes
Tested with `kind` and GKE.

Note: "nodes" shown in `docker buildx ls` are unrelated to Kubernetes "nodes".
Probably buildx should come up with an alternative term.

Usage:

  $ kind create cluster
  $ export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"

  $ docker buildx create --driver kubernetes --driver-opt replicas=3 --use
  $ docker buildx build -t foo --load .

`--load` loads the image into the local Docker.

Driver opts:

  - `image=IMAGE` - Sets the container image to be used for running buildkit.
  - `namespace=NS` - Sets the Kubernetes namespace. Defaults to the current namespace.
  - `replicas=N` - Sets the number of `Pod` replicas. Defaults to 1.
  - `rootless=(true|false)` - Run the container as a non-root user without `securityContext.privileged`. Defaults to false.
  - `loadbalance=(sticky|random)` - Load-balancing strategy. If set to "sticky", the pod is chosen using the hash of the context path. Defaults to "sticky"

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2019-11-21 10:30:39 +09:00
Tõnis Tiigi
f5c2673878 Merge pull request #184 from cpuguy83/bake_args_from_env
Support reading from env on bake --set <t>.args
2019-11-20 10:32:12 -08:00
Tõnis Tiigi
8e92bfc8f0 Merge pull request #188 from shykes/patch-1
Clarify documentation structure
2019-11-07 10:50:04 -08:00
Solomon Hykes
d7adb9ef6e Clarify documentation structure
Move a paragraph in README to clarify where it fits in the structure.

- Before the move, the paragraph seems to apply to the `--output=local` section when in fact it applies to the entire `--output` section. This is especially confusing for the sentence "if just the path is specified as a value, `buildx` will use the local exporter with this path as the destination".

- After the move, it is clear that the paragraph applies to `--output`
2019-11-06 16:42:12 -08:00
Brian Goff
6634f1e75c Support reading from env on bake --set <t>.args
This works just like the `build` command where if you have `--build-arg
FOO`, it will read the variable from env and only set a value if the
variable is defined.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2019-10-30 15:31:38 -07:00
Tõnis Tiigi
6aba19193a Merge pull request #182 from tonistiigi/raw-newline
imagetools: avoid printing newline on raw mode
2019-10-28 16:37:53 -07:00
Tonis Tiigi
eb1aabe9e3 imagetools: avoid printing newline on raw mode
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-10-28 16:14:35 -07:00
Tõnis Tiigi
714f181d81 Merge pull request #170 from sirlatrom/169-docker-container-driver-envs
Support environment variables in docker-container driver
2019-10-28 15:05:58 -07:00
Sune Keller
fd44accc79 Support environment variables in docker-container driver
Fixes #169

Signed-off-by: Sune Keller <absukl@almbrand.dk>
2019-10-28 21:56:14 +01:00
Tõnis Tiigi
43edd6b77e Merge pull request #162 from daixiang0/patch-1
Update README.md
2019-10-25 21:58:27 -07:00
Xiang Dai
427c19d65c Update README.md
Comment that with docker 19.03-, can not use buildx as docker plugin.
2019-10-26 11:07:27 +08:00
Tõnis Tiigi
6db68d0295 Merge pull request #155 from tiborvass/vendor-buildkit
vendor: update buildkit to docker-19.03 (ae10b292)
2019-09-27 10:36:16 -07:00
Tibor Vass
abe8ba769e vendor: update buildkit to docker-19.03 (ae10b292)
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-09-27 17:18:25 +00:00
Tõnis Tiigi
96fb17b711 Merge pull request #154 from tiborvass/fix-149
build: fix scoping issue in closure inside loop
2019-09-26 11:32:04 -07:00
Tibor Vass
63e5633d62 build: fix scoping issue in closure inside loop
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-09-26 18:01:29 +00:00
Tibor Vass
299d41660b Merge pull request #153 from tonistiigi/stdin-dockerfile
build: fix stdin dockerfile filename
2019-09-26 10:53:28 -07:00
Tibor Vass
1ec87b7beb Merge pull request #152 from tonistiigi/stream-input
build: use correct in-memory input
2019-09-26 10:45:55 -07:00
Tonis Tiigi
0475107882 build: fix stdin dockerfile filename
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-09-26 09:17:04 -07:00
Tonis Tiigi
75f8d7ebb5 build: use correct in-memory input
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-09-26 09:10:39 -07:00
Tibor Vass
7c97854b6f Merge pull request #144 from droopy4096/master
Add FOSSA checks to Jenkins CI
2019-09-17 14:56:00 -07:00
Dmytro Makovey
5f4d4a87f7 Add FOSSA checks to Jenkins CI
Signed-off-by: Dmytro Makovey <dmytro.makovey@docker.com>
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-09-17 21:27:29 +00:00
Tõnis Tiigi
c1ce7300d5 Merge pull request #146 from gfrancesco/master
README typo
2019-09-17 10:19:34 -07:00
gfrancesco
e118c4d8e9 UPD: Readme typo 2019-09-17 18:13:16 +02:00
Tibor Vass
5fe779703d Merge pull request #134 from tonistiigi/group-merge
bake: merge targets on same groups
2019-09-05 17:15:01 -07:00
Tonis Tiigi
15a5a42eb1 bake: merge targets on same groups
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-08-19 15:48:42 -07:00
Tõnis Tiigi
5b974158f9 Merge pull request #131 from gracenoah/patch-1
Fix some quotes in the readme
2019-08-14 12:16:13 -07:00
gracenoah
1c0a7f14e8 Fix some quotes in the readme 2019-08-13 14:27:10 +02:00
Tibor Vass
7ec8912591 Merge pull request #125 from tiborvass/docs-allow
Document build --allow
2019-08-01 18:18:00 -07:00
Tibor Vass
83da6a3378 docs: crosslink buildkitd-flags and config flags in create
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-08-01 17:56:05 -07:00
Tibor Vass
cad02a4681 docs: document build --allow
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-08-01 17:56:05 -07:00
Tõnis Tiigi
c967f1d570 Merge pull request #124 from tiborvass/update-docs
Update docs
2019-08-01 16:41:26 -07:00
Tibor Vass
be3efc979b docs: add documentation for --buildkitd-flags, --config, --driver-opt on create
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-08-01 16:15:11 -07:00
Tibor Vass
5c5f54c6d6 docs: Update install instructions with Docker CE 19.03
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-08-01 15:23:02 -07:00
Tibor Vass
6f8f04e1f8 Merge pull request #122 from tonistiigi/custom-image
driver: allow setting driver opts
2019-08-01 11:41:49 -07:00
Tonis Tiigi
afd821010d docker-container: allow setting custom buildkit image
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-07-31 22:46:37 -07:00
Tonis Tiigi
bcc882cbf1 docker-container: allow using host network
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-07-31 17:42:49 -07:00
Tonis Tiigi
75b80c277f driver: allow setting driver opts
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-07-31 17:25:25 -07:00
Tibor Vass
096d1befc9 Merge pull request #104 from tonistiigi/entitlements
build: add allowed entitlements
2019-07-31 15:36:13 -07:00
Tibor Vass
2bf6187a88 Merge pull request #121 from tonistiigi/config
driver: allow setting buildkit config file
2019-07-31 15:21:17 -07:00
Tonis Tiigi
8ed8795268 driver: allow setting buildkit config file
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Co-Authored-By: Tibor Vass <tiborvass@users.noreply.github.com>
2019-07-31 15:08:26 -07:00
Tõnis Tiigi
6e32ea3418 Merge pull request #118 from tiborvass/bake-no-cache-pull
bake: honor --no-cache and --pull
2019-07-31 10:59:59 -07:00
Tibor Vass
8b2171f78a bake: honor --no-cache and --pull
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-07-30 19:39:01 -07:00
Tibor Vass
92f1234aaa Merge pull request #116 from tonistiigi/build-arg-default
build: load default build args from env
2019-07-30 19:20:09 -07:00
Tibor Vass
73645c8348 Merge pull request #117 from tonistiigi/compose-env
bake: replace env in compose files
2019-07-30 19:14:21 -07:00
Tonis Tiigi
662c0768cb bake: replace env in compose files
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-07-30 16:44:05 -07:00
Tonis Tiigi
43150ef849 build: load default build args from env
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-07-30 16:32:36 -07:00
Tibor Vass
3f18b659a0 Merge pull request #102 from tonistiigi/buildkitd-flags
driver: allow configuring buildkitd flags
2019-07-09 17:27:17 -07:00
Tonis Tiigi
6b81b0bed6 build: add allowed entitlements
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-07-08 15:59:53 -07:00
Tonis Tiigi
f0af89a204 driver: allow configuring buildkitd flags
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-07-08 15:29:43 -07:00
Tõnis Tiigi
550c2b9042 Merge pull request #100 from FernandoMiguel/patch-1
add chmod
2019-07-06 12:38:08 -07:00
Fernando Miguel
c8cda08209 add chmod 2019-07-05 12:14:40 +01:00
Tõnis Tiigi
2b03339235 Merge pull request #93 from zelahi/enable-fossa-scan
[TAR-853] ADDED .fossa file for fossa scans
2019-06-17 09:21:16 -07:00
zelahi
6e1fd0eab6 ADDED .fossa file for fossa scans 2019-06-14 10:49:12 -07:00
Tõnis Tiigi
5336e74bd4 Merge pull request #89 from khs1994/master
Fix Dockerfile format
2019-06-05 13:56:29 -07:00
Tõnis Tiigi
afeaed790f Merge pull request #86 from AkihiroSuda/driver-ls
Put driver names to create --help
2019-06-05 13:55:44 -07:00
khs1994
aed531a8a9 Fix Dockerfile format
Signed-off-by: Kang HuaiShuai <khs1994@khs1994.com>
2019-06-04 17:43:39 +08:00
Akihiro Suda
eee78c6c10 Put driver names to create --help
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2019-06-02 00:02:20 +09:00
Tõnis Tiigi
ab5fe3dec5 Merge pull request #87 from tiborvass/no-build-field
[Carry #79] Change compose file handling to require valid service specifications
2019-05-29 19:22:22 -07:00
Tibor Vass
b741350afd bake: compose parser should only error if there are neither build nor image fields
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-05-29 18:12:30 -07:00
Tõnis Tiigi
8b6dfbd9c8 Merge pull request #85 from tiborvass/license-contributing
Add project files (LICENSE, AUTHORS, MAINTAINERS, Code of Conduct, CONTRIBUTING)
2019-05-24 18:39:53 -07:00
Jack Laxson
4b2666b9d6 Change compose file handling to require valid service specifications
Added the checks and some tests
One of the tests wasn't valid docker-compose.yml, that's been changed.
Bad config throws an error and has a test

Signed-off-by: Jack Laxson <jackjrabbit@gmail.com>
2019-05-24 17:41:48 -07:00
Sebastiaan van Stijn
854f704a2f Add LICENSE file
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-05-24 17:35:34 -07:00
Sebastiaan van Stijn
138b2e7415 Add contributing, code of conduct
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-05-24 17:34:06 -07:00
Sebastiaan van Stijn
e1f54de9ac Add maintainers and authors
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2019-05-24 17:33:28 -07:00
Tibor Vass
61a6fdd767 Merge pull request #84 from tiborvass/platform-local
Update README to use --platform=local with Docker 19.03
2019-05-24 17:16:03 -07:00
Tibor Vass
77c23dd85f Update README to use --platform=local with Docker 19.03
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-05-24 23:29:14 +00:00
Tibor Vass
0eb2df54ce Merge pull request #83 from tonistiigi/relative-dockerfile-path
bake: make dockerfile relative to context
2019-05-24 16:18:50 -07:00
Tonis Tiigi
f1fd9a274b bake: make dockerfile relative to context
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-05-24 16:04:01 -07:00
Tibor Vass
4e61674ac8 Merge pull request #81 from tiborvass/experimental
Allow Docker to ship buildx guarded by the experimental flag
2019-05-23 14:42:28 -07:00
Tibor Vass
695034153a cmd/buildx: add empty by default experimental variable
To guard this Docker CLI plugin with docker's experimental CLI config,
buildx needs to be built with `go build -ldflags "-X main.experimental=1"`

Signed-off-by: Tibor Vass <tibor@docker.com>
2019-05-23 21:21:27 +00:00
Tibor Vass
fb9cf7720a Merge pull request #82 from tiborvass/vendor-cli
vendor: update docker/cli (ab688a9a79a1) and docker/docker (3998dffb806f)
2019-05-23 14:20:40 -07:00
Tibor Vass
03ae6f8e54 vendor: update docker/cli (ab688a9a79a1) and docker/docker (3998dffb806f)
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-05-23 20:43:16 +00:00
Tibor Vass
715d38ff96 Merge pull request #75 from tonistiigi/update-buildkit
vendor: update buildkit to f238f1e
2019-05-15 10:39:55 -07:00
Tibor Vass
3045eb1b10 Merge pull request #76 from tonistiigi/build-flags
build: add missing flags
2019-05-15 10:39:05 -07:00
Tonis Tiigi
717a4afae0 build: add missing flags
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-05-14 18:06:42 -07:00
Tonis Tiigi
b68b005f68 vendor: update buildkit to f238f1e
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-05-14 17:59:01 -07:00
Tõnis Tiigi
cb83df7a69 Merge pull request #71 from cpuguy83/docker_bake_file_help
Correct help output for default bake file.
2019-05-08 10:56:37 -07:00
Brian Goff
e23e4a6bdc Correct help output for default bake file.
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2019-05-08 08:54:00 -07:00
Tõnis Tiigi
84f7e9d02d Merge pull request #70 from tonistiigi/local-platform
platformutil: add local platform
2019-05-06 17:24:41 -07:00
Tõnis Tiigi
dcd8ca9308 Merge pull request #69 from tonistiigi/progress-env
progress: add env config
2019-05-06 17:24:31 -07:00
Tibor Vass
b3fe1a333d Merge pull request #68 from tonistiigi/arm-variant
imagetools: keep arm variant
2019-05-06 17:11:49 -07:00
Tibor Vass
f38dfd2032 Merge pull request #67 from tonistiigi/unfork-cli
dockerfile: unfork cli
2019-05-06 17:07:49 -07:00
Tibor Vass
250558eb3a Merge pull request #66 from tonistiigi/df-update
dockerfile: update to 1.1
2019-05-06 17:05:58 -07:00
Tibor Vass
5d0db8be7f Merge pull request #64 from tonistiigi/skip-target
readme: simplify install instructions
2019-05-06 17:05:10 -07:00
Tonis Tiigi
13b74e0d80 platformutil: add local platform
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-05-06 16:55:36 -07:00
Tonis Tiigi
9b57f9e872 imagetools: keep arm variant
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-05-06 16:50:42 -07:00
Tonis Tiigi
f8e8f17f4e progress: add env config
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-05-06 16:39:09 -07:00
Tõnis Tiigi
361f52ab6c Merge pull request #65 from tiborvass/load-multiarch
Explain single-platform limitation of docker export type
2019-05-06 16:14:05 -07:00
Tonis Tiigi
bffca0b271 dockerfile: unfork cli
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-05-06 16:12:09 -07:00
Tonis Tiigi
9bc85fc3d8 dockerfile: update to 1.1
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-05-06 16:04:23 -07:00
Tibor Vass
707e17d05c Explain single-platform limitation of docker export type
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-05-06 15:33:17 -07:00
Tõnis Tiigi
0066fcc9db Merge pull request #60 from tiborvass/linux-install
Add Linux Nightly Docker install instructions
2019-05-06 14:40:16 -07:00
Tibor Vass
c222726c15 Add Linux Docker install instructions
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-05-06 14:24:22 -07:00
Tonis Tiigi
25ae122153 readme: simplify install instructions
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-05-06 14:20:41 -07:00
Tibor Vass
7339f85248 Merge pull request #61 from northtyphoon/bindu/readme
fix the typo in --cache-to example
2019-05-06 14:15:25 -07:00
Bin Du
c5a19f754f fix the typo in --cache-to example
Signed-off-by: Bin Du <bindu@microsoft.com>
2019-05-05 23:38:39 -07:00
Tibor Vass
bbbbc2ca4b Merge pull request #58 from tiborvass/readme-install
Update install instructions in README
2019-05-01 10:16:49 -07:00
Tibor Vass
93d21f1a86 Update install instructions in README
Signed-off-by: Tibor Vass <tibor@docker.com>
2019-05-01 10:01:45 -07:00
Tõnis Tiigi
509c4b6bd4 Merge pull request #54 from tonistiigi/readme-update
readme: more guide content
2019-04-25 23:48:54 -07:00
Tonis Tiigi
9e4a609346 readme: more guide content
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-04-25 23:27:27 -07:00
Tõnis Tiigi
4c84819a32 Merge pull request #53 from tonistiigi/compose-target
bake: fix parsing target from compose files
2019-04-25 22:53:49 -07:00
Tonis Tiigi
43356bbbbe bake: fix parsing target from compose files
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-04-25 21:36:28 -07:00
Tõnis Tiigi
d5a84b1593 Merge pull request #52 from tonistiigi/title-format
readme: better title formatting
2019-04-25 09:16:01 -07:00
Tonis Tiigi
1c35bc7d91 readme: better title formatting
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
2019-04-24 21:35:54 -07:00
5577 changed files with 924811 additions and 337649 deletions

View File

@@ -1,2 +1 @@
bin/
cross-out/

4
.github/CODE_OF_CONDUCT.md vendored Normal file
View File

@@ -0,0 +1,4 @@
# Code of conduct
- [Moby community guidelines](https://github.com/moby/moby/blob/master/CONTRIBUTING.md#moby-community-guidelines)
- [Docker Code of Conduct](https://github.com/docker/code-of-conduct)

292
.github/CONTRIBUTING.md vendored Normal file
View File

@@ -0,0 +1,292 @@
# Contribute to the Buildx project
This page contains information about reporting issues as well as some tips and
guidelines useful to experienced open source contributors.
## Reporting security issues
The project maintainers take security seriously. If you discover a security
issue, please bring it to their attention right away!
**Please _DO NOT_ file a public issue**, instead send your report privately to
[security@docker.com](mailto:security@docker.com).
Security reports are greatly appreciated and we will publicly thank you for it.
We also like to send gifts&mdash;if you're into schwag, make sure to let
us know. We currently do not offer a paid security bounty program, but are not
ruling it out in the future.
## Reporting other issues
A great way to contribute to the project is to send a detailed report when you
encounter an issue. We always appreciate a well-written, thorough bug report,
and will thank you for it!
Check that [our issue database](https://github.com/docker/buildx/issues)
doesn't already include that problem or suggestion before submitting an issue.
If you find a match, you can use the "subscribe" button to get notified on
updates. Do *not* leave random "+1" or "I have this too" comments, as they
only clutter the discussion, and don't help resolving it. However, if you
have ways to reproduce the issue or have additional information that may help
resolving the issue, please leave a comment.
Include the steps required to reproduce the problem if possible and applicable.
This information will help us review and fix your issue faster. When sending
lengthy log-files, consider posting them as an attachment, instead of posting
inline.
**Do not forget to remove sensitive data from your logfiles before submitting**
(you can replace those parts with "REDACTED").
### Pull requests are always welcome
Not sure if that typo is worth a pull request? Found a bug and know how to fix
it? Do it! We will appreciate it.
If your pull request is not accepted on the first try, don't be discouraged! If
there's a problem with the implementation, hopefully you received feedback on
what to improve.
We're trying very hard to keep Buildx lean and focused. We don't want it to
do everything for everybody. This means that we might decide against
incorporating a new feature. However, there might be a way to implement that
feature *on top of* Buildx.
### Design and cleanup proposals
You can propose new designs for existing features. You can also design
entirely new features. We really appreciate contributors who want to refactor or
otherwise cleanup our project.
### Sign your work
The sign-off is a simple line at the end of the explanation for the patch. Your
signature certifies that you wrote the patch or otherwise have the right to pass
it on as an open-source patch. The rules are pretty simple: if you can certify
the below (from [developercertificate.org](http://developercertificate.org/)):
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```
Then you just add a line to every git commit message:
Signed-off-by: Joe Smith <joe.smith@email.com>
**Use your real name** (sorry, no pseudonyms or anonymous contributions.)
If you set your `user.name` and `user.email` git configs, you can sign your
commit automatically with `git commit -s`.
### Run the unit- and integration-tests
To enter a demo container environment and experiment, you may run:
```
$ make shell
```
To validate PRs before submitting them you should run:
```
$ make validate-all
```
To generate new vendored files with go modules run:
```
$ make vendor
```
### Conventions
- Fork the repository and make changes on your fork in a feature branch
- Submit tests for your changes. See [run the unit- and integration-tests](#run-the-unit--and-integration-tests)
for details.
- [Sign your work](#sign-your-work)
Write clean code. Universally formatted code promotes ease of writing, reading,
and maintenance. Always run `gofmt -s -w file.go` on each changed file before
committing your changes. Most editors have plug-ins that do this automatically.
Pull request descriptions should be as clear as possible and include a
reference to all the issues that they address. Be sure that the [commit
messages](#commit-messages) also contain the relevant information.
### Successful Changes
Before contributing large or high impact changes, make the effort to coordinate
with the maintainers of the project before submitting a pull request. This
prevents you from doing extra work that may or may not be merged.
Large PRs that are just submitted without any prior communication are unlikely
to be successful.
While pull requests are the methodology for submitting changes to code, changes
are much more likely to be accepted if they are accompanied by additional
engineering work. While we don't define this explicitly, most of these goals
are accomplished through communication of the design goals and subsequent
solutions. Often times, it helps to first state the problem before presenting
solutions.
Typically, the best methods of accomplishing this are to submit an issue,
stating the problem. This issue can include a problem statement and a
checklist with requirements. If solutions are proposed, alternatives should be
listed and eliminated. Even if the criteria for elimination of a solution is
frivolous, say so.
Larger changes typically work best with design documents. These are focused on
providing context to the design at the time the feature was conceived and can
inform future documentation contributions.
### Commit Messages
Commit messages must start with a capitalized and short summary (max. 50 chars)
written in the imperative, followed by an optional, more detailed explanatory
text which is separated from the summary by an empty line.
Commit messages should follow best practices, including explaining the context
of the problem and how it was solved, including in caveats or follow up changes
required. They should tell the story of the change and provide readers
understanding of what led to it.
If you're lost about what this even means, please see [How to Write a Git
Commit Message](http://chris.beams.io/posts/git-commit/) for a start.
In practice, the best approach to maintaining a nice commit message is to
leverage a `git add -p` and `git commit --amend` to formulate a solid
changeset. This allows one to piece together a change, as information becomes
available.
If you squash a series of commits, don't just submit that. Re-write the commit
message, as if the series of commits was a single stroke of brilliance.
That said, there is no requirement to have a single commit for a PR, as long as
each commit tells the story. For example, if there is a feature that requires a
package, it might make sense to have the package in a separate commit then have
a subsequent commit that uses it.
Remember, you're telling part of the story with the commit message. Don't make
your chapter weird.
### Review
Code review comments may be added to your pull request. Discuss, then make the
suggested modifications and push additional commits to your feature branch. Post
a comment after pushing. New commits show up in the pull request automatically,
but the reviewers are notified only when you comment.
Pull requests must be cleanly rebased on top of master without multiple branches
mixed into the PR.
> **Git tip**: If your PR no longer merges cleanly, use `rebase master` in your
> feature branch to update your pull request rather than `merge master`.
Before you make a pull request, squash your commits into logical units of work
using `git rebase -i` and `git push -f`. A logical unit of work is a consistent
set of patches that should be reviewed together: for example, upgrading the
version of a vendored dependency and taking advantage of its now available new
feature constitute two separate units of work. Implementing a new function and
calling it in another file constitute a single logical unit of work. The very
high majority of submissions should have a single commit, so if in doubt: squash
down to one.
- After every commit, [make sure the test suite passes](#run-the-unit--and-integration-tests).
Include documentation changes in the same pull request so that a revert would
remove all traces of the feature or fix.
- Include an issue reference like `closes #XXXX` or `fixes #XXXX` in the PR
description that close an issue. Including references automatically closes
the issue on a merge.
- Do not add yourself to the `AUTHORS` file, as it is regenerated regularly
from the Git history.
- See the [Coding Style](#coding-style) for further guidelines.
### Merge approval
Project maintainers use LGTM (Looks Good To Me) in comments on the code review to
indicate acceptance, or use the Github review approval feature.
## Coding Style
Unless explicitly stated, we follow all coding guidelines from the Go
community. While some of these standards may seem arbitrary, they somehow seem
to result in a solid, consistent codebase.
It is possible that the code base does not currently comply with these
guidelines. We are not looking for a massive PR that fixes this, since that
goes against the spirit of the guidelines. All new contributions should make a
best effort to clean up and make the code base better than they left it.
Obviously, apply your best judgement. Remember, the goal here is to make the
code base easier for humans to navigate and understand. Always keep that in
mind when nudging others to comply.
The rules:
1. All code should be formatted with `gofmt -s`.
2. All code should pass the default levels of
[`golint`](https://github.com/golang/lint).
3. All code should follow the guidelines covered in [Effective
Go](http://golang.org/doc/effective_go.html) and [Go Code Review
Comments](https://github.com/golang/go/wiki/CodeReviewComments).
4. Comment the code. Tell us the why, the history and the context.
5. Document _all_ declarations and methods, even private ones. Declare
expectations, caveats and anything else that may be important. If a type
gets exported, having the comments already there will ensure it's ready.
6. Variable name length should be proportional to its context and no longer.
`noCommaALongVariableNameLikeThisIsNotMoreClearWhenASimpleCommentWouldDo`.
In practice, short methods will have short variable names and globals will
have longer names.
7. No underscores in package names. If you need a compound name, step back,
and re-examine why you need a compound name. If you still think you need a
compound name, lose the underscore.
8. No utils or helpers packages. If a function is not general enough to
warrant its own package, it has not been written generally enough to be a
part of a util package. Just leave it unexported and well-documented.
9. All tests should run with `go test` and outside tooling should not be
required. No, we don't need another unit testing framework. Assertion
packages are acceptable if they provide _real_ incremental value.
10. Even though we call these "rules" above, they are actually just
guidelines. Since you've read all the rules, you now know that.
If you are having trouble getting into the mood of idiomatic Go, we recommend
reading through [Effective Go](https://golang.org/doc/effective_go.html). The
[Go Blog](https://blog.golang.org) is also a great resource.

10
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: "github-actions"
open-pull-requests-limit: 10
directory: "/"
schedule:
interval: "daily"
labels:
- "dependencies"
- "bot"

226
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,226 @@
name: build
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
push:
branches:
- 'master'
- 'v[0-9]*'
tags:
- 'v*'
pull_request:
branches:
- 'master'
- 'v[0-9]*'
paths-ignore:
- 'README.md'
- 'docs/**'
env:
BUILDX_VERSION: "latest"
BUILDKIT_IMAGE: "moby/buildkit:latest"
REPO_SLUG: "docker/buildx-bin"
DESTDIR: "./bin"
jobs:
test:
runs-on: ubuntu-22.04
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: ${{ env.BUILDX_VERSION }}
driver-opts: image=${{ env.BUILDKIT_IMAGE }}
buildkitd-flags: --debug
-
name: Test
uses: docker/bake-action@v2
with:
targets: test
set: |
*.cache-from=type=gha,scope=test
*.cache-to=type=gha,scope=test
-
name: Upload coverage
uses: codecov/codecov-action@v3
with:
directory: ${{ env.DESTDIR }}/coverage
prepare:
runs-on: ubuntu-22.04
outputs:
matrix: ${{ steps.platforms.outputs.matrix }}
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Create matrix
id: platforms
run: |
echo "matrix=$(docker buildx bake binaries-cross --print | jq -cr '.target."binaries-cross".platforms')" >>${GITHUB_OUTPUT}
-
name: Show matrix
run: |
echo ${{ steps.platforms.outputs.matrix }}
binaries:
runs-on: ubuntu-22.04
needs:
- prepare
strategy:
fail-fast: false
matrix:
platform: ${{ fromJson(needs.prepare.outputs.matrix) }}
steps:
-
name: Prepare
run: |
platform=${{ matrix.platform }}
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: ${{ env.BUILDX_VERSION }}
driver-opts: image=${{ env.BUILDKIT_IMAGE }}
buildkitd-flags: --debug
-
name: Build
run: |
make release
env:
PLATFORMS: ${{ matrix.platform }}
CACHE_FROM: type=gha,scope=binaries-${{ env.PLATFORM_PAIR }}
CACHE_TO: type=gha,scope=binaries-${{ env.PLATFORM_PAIR }},mode=max
-
name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: buildx
path: ${{ env.DESTDIR }}/*
if-no-files-found: error
bin-image:
runs-on: ubuntu-22.04
if: ${{ github.event_name != 'pull_request' }}
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: ${{ env.BUILDX_VERSION }}
driver-opts: image=${{ env.BUILDKIT_IMAGE }}
buildkitd-flags: --debug
-
name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: |
${{ env.REPO_SLUG }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
bake-target: meta-helper
-
name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push image
uses: docker/bake-action@v2
with:
files: |
./docker-bake.hcl
${{ steps.meta.outputs.bake-file }}
targets: image-cross
push: ${{ github.event_name != 'pull_request' }}
set: |
*.cache-from=type=gha,scope=bin-image
*.cache-to=type=gha,scope=bin-image,mode=max
*.attest=type=sbom
*.attest=type=provenance,mode=max,builder-id=https://github.com/${{ env.GITHUB_REPOSITORY }}/actions/runs/${{ env.GITHUB_RUN_ID }}
release:
runs-on: ubuntu-22.04
needs:
- binaries
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Download binaries
uses: actions/download-artifact@v3
with:
name: buildx
path: ${{ env.DESTDIR }}
-
name: Create checksums
run: ./hack/hash-files
-
name: List artifacts
run: |
tree -nh ${{ env.DESTDIR }}
-
name: Check artifacts
run: |
find ${{ env.DESTDIR }} -type f -exec file -e ascii -- {} +
-
name: GitHub Release
if: startsWith(github.ref, 'refs/tags/v')
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
draft: true
files: ${{ env.DESTDIR }}/*
buildkit-edge:
runs-on: ubuntu-22.04
continue-on-error: true
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: ${{ env.BUILDX_VERSION }}
driver-opts: image=moby/buildkit:master
buildkitd-flags: --debug
-
# Just run a bake target to check eveything runs fine
name: Build
uses: docker/bake-action@v2
with:
targets: binaries

58
.github/workflows/docs-release.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
name: docs-release
on:
release:
types:
- released
jobs:
open-pr:
runs-on: ubuntu-22.04
if: "!github.event.release.prerelease"
steps:
-
name: Checkout docs repo
uses: actions/checkout@v3
with:
token: ${{ secrets.GHPAT_DOCS_DISPATCH }}
repository: docker/docs
ref: main
-
name: Prepare
run: |
rm -rf ./_data/buildx/*
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build docs
uses: docker/bake-action@v2
with:
source: ${{ github.server_url }}/${{ github.repository }}.git#${{ github.event.release.name }}
targets: update-docs
set: |
*.output=/tmp/buildx-docs
env:
DOCS_FORMATS: yaml
-
name: Copy files
run: |
cp /tmp/buildx-docs/out/reference/*.yaml ./_data/buildx/
-
name: Commit changes
run: |
git add -A .
-
name: Create PR on docs repo
uses: peter-evans/create-pull-request@2b011faafdcbc9ceb11414d64d0573f37c774b04
with:
token: ${{ secrets.GHPAT_DOCS_DISPATCH }}
push-to-fork: docker-tools-robot/docker.github.io
commit-message: "build: update buildx reference to ${{ github.event.release.name }}"
signoff: true
branch: dispatch/buildx-ref-${{ github.event.release.name }}
delete-branch: true
title: Update buildx reference to ${{ github.event.release.name }}
body: |
Update the buildx reference documentation to keep in sync with the latest release `${{ github.event.release.name }}`
draft: false

61
.github/workflows/docs-upstream.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
# this workflow runs the remote validate bake target from docker/docker.github.io
# to check if yaml reference docs and markdown files used in this repo are still valid
# https://github.com/docker/docker.github.io/blob/98c7c9535063ae4cd2cd0a31478a21d16d2f07a3/docker-bake.hcl#L34-L36
name: docs-upstream
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches:
- 'master'
- 'v[0-9]*'
paths:
- '.github/workflows/docs-upstream.yml'
- 'docs/**'
pull_request:
paths:
- '.github/workflows/docs-upstream.yml'
- 'docs/**'
jobs:
docs-yaml:
runs-on: ubuntu-22.04
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: latest
-
name: Build reference YAML docs
uses: docker/bake-action@v2
with:
targets: update-docs
set: |
*.output=/tmp/buildx-docs
*.cache-from=type=gha,scope=docs-yaml
*.cache-to=type=gha,scope=docs-yaml,mode=max
env:
DOCS_FORMATS: yaml
-
name: Upload reference YAML docs
uses: actions/upload-artifact@v3
with:
name: docs-yaml
path: /tmp/buildx-docs/out/reference
retention-days: 1
validate:
uses: docker/docs/.github/workflows/validate-upstream.yml@main
needs:
- docs-yaml
with:
repo: https://github.com/${{ github.repository }}
data-files-id: docs-yaml
data-files-folder: buildx

218
.github/workflows/e2e.yml vendored Normal file
View File

@@ -0,0 +1,218 @@
name: e2e
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
push:
branches:
- 'master'
- 'v[0-9]*'
pull_request:
branches:
- 'master'
- 'v[0-9]*'
paths-ignore:
- 'README.md'
- 'docs/**'
env:
DESTDIR: "./bin"
K3S_VERSION: "v1.21.2-k3s1"
jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: latest
-
name: Build
uses: docker/bake-action@v2
with:
targets: binaries
set: |
*.cache-from=type=gha,scope=release
*.cache-from=type=gha,scope=binaries
*.cache-to=type=gha,scope=binaries
-
name: Rename binary
run: |
mv ${{ env.DESTDIR }}/build/buildx ${{ env.DESTDIR }}/build/docker-buildx
-
name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: binary
path: ${{ env.DESTDIR }}/build
if-no-files-found: error
retention-days: 7
driver:
runs-on: ubuntu-20.04
needs:
- build
strategy:
fail-fast: false
matrix:
driver:
- docker
- docker-container
- kubernetes
- remote
buildkit:
- moby/buildkit:buildx-stable-1
- moby/buildkit:master
buildkit-cfg:
- bkcfg-false
- bkcfg-true
multi-node:
- mnode-false
- mnode-true
platforms:
- linux/amd64
- linux/amd64,linux/arm64
include:
- driver: kubernetes
driver-opt: qemu.install=true
- driver: remote
endpoint: tcp://localhost:1234
exclude:
- driver: docker
multi-node: mnode-true
- driver: docker
buildkit-cfg: bkcfg-true
- driver: docker-container
multi-node: mnode-true
- driver: remote
multi-node: mnode-true
- driver: remote
buildkit-cfg: bkcfg-true
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
if: matrix.driver == 'docker' || matrix.driver == 'docker-container'
-
name: Install buildx
uses: actions/download-artifact@v3
with:
name: binary
path: /home/runner/.docker/cli-plugins
-
name: Fix perms and check
run: |
chmod +x /home/runner/.docker/cli-plugins/docker-buildx
docker buildx version
-
name: Init env vars
run: |
# BuildKit cfg
if [ "${{ matrix.buildkit-cfg }}" = "bkcfg-true" ]; then
cat > "/tmp/buildkitd.toml" <<EOL
[worker.oci]
max-parallelism = 2
EOL
echo "BUILDKIT_CFG=/tmp/buildkitd.toml" >> $GITHUB_ENV
fi
# Multi node
if [ "${{ matrix.multi-node }}" = "mnode-true" ]; then
echo "MULTI_NODE=1" >> $GITHUB_ENV
else
echo "MULTI_NODE=0" >> $GITHUB_ENV
fi
-
name: Install k3s
if: matrix.driver == 'kubernetes'
uses: actions/github-script@v6
with:
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: Print KUBECONFIG
if: matrix.driver == 'kubernetes'
run: |
yq ${{ env.KUBECONFIG }}
-
name: Launch remote buildkitd
if: matrix.driver == 'remote'
run: |
docker run -d \
--privileged \
--name=remote-buildkit \
-p 1234:1234 \
${{ matrix.buildkit }} \
--addr unix:///run/buildkit/buildkitd.sock \
--addr tcp://0.0.0.0:1234
-
name: Test
run: |
make test-driver
env:
BUILDKIT_IMAGE: ${{ matrix.buildkit }}
DRIVER: ${{ matrix.driver }}
DRIVER_OPT: ${{ matrix.driver-opt }}
ENDPOINT: ${{ matrix.endpoint }}
PLATFORMS: ${{ matrix.platforms }}

42
.github/workflows/validate.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: validate
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
workflow_dispatch:
push:
branches:
- 'master'
- 'v[0-9]*'
tags:
- 'v*'
pull_request:
branches:
- 'master'
- 'v[0-9]*'
jobs:
validate:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
target:
- lint
- validate-vendor
- validate-docs
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
version: latest
-
name: Run
run: |
make ${{ matrix.target }}

3
.gitignore vendored
View File

@@ -1,2 +1 @@
bin
cross-out
/bin

40
.golangci.yml Normal file
View File

@@ -0,0 +1,40 @@
run:
timeout: 10m
skip-files:
- ".*\\.pb\\.go$"
modules-download-mode: vendor
build-tags:
linters:
enable:
- gofmt
- govet
- deadcode
- depguard
- goimports
- ineffassign
- misspell
- unused
- varcheck
- revive
- staticcheck
- typecheck
- nolintlint
disable-all: true
linters-settings:
depguard:
list-type: blacklist
include-go-root: true
packages:
# The io/ioutil package has been deprecated.
# https://go.dev/doc/go1.16#ioutil
- io/ioutil
issues:
exclude-rules:
- linters:
- revive
text: "stutters"

13
.mailmap Normal file
View File

@@ -0,0 +1,13 @@
# This file lists all individuals having contributed content to the repository.
# For how it is generated, see hack/dockerfiles/authors.Dockerfile.
CrazyMax <github@crazymax.dev>
CrazyMax <github@crazymax.dev> <1951866+crazy-max@users.noreply.github.com>
CrazyMax <github@crazymax.dev> <crazy-max@users.noreply.github.com>
Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn <github@gone.nl> <thaJeztah@users.noreply.github.com>
Tibor Vass <tibor@docker.com>
Tibor Vass <tibor@docker.com> <tiborvass@users.noreply.github.com>
Tõnis Tiigi <tonistiigi@gmail.com>
Ulysses Souza <ulyssessouza@gmail.com>
Wang Jinglei <morlay.null@gmail.com>

View File

@@ -1,35 +0,0 @@
dist: trusty
sudo: required
install:
- docker run --name buildkit --rm -d --privileged -p 1234:1234 $REPO_SLUG_ORIGIN --addr tcp://0.0.0.0:1234
- sudo docker cp buildkit:/usr/bin/buildctl /usr/bin/
- export BUILDKIT_HOST=tcp://0.0.0.0:1234
env:
global:
- PLATFORMS="linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x,linux/ppc64le"
- CROSS_PLATFORMS="${PLATFORMS},darwin/amd64,windows/amd64"
- PREFER_BUILDCTL="1"
script:
- make binaries validate-all && TARGETPLATFORM="${CROSS_PLATFORMS}" ./hack/cross
deploy:
- provider: script
script: PLATFORMS="${CROSS_PLATFORMS}" ./hack/release $TRAVIS_TAG release-out
on:
repo: docker/buildx
tags: true
condition: $TRAVIS_TAG =~ ^v[0-9]
- provider: releases
api_key:
secure: "VKVL+tyS3BfqjM4VMGHoHJbcKY4mqq4AGrclVEvBnt0gm1LkGeKxSheCZgF1EC4oSV8rCy6dkoRWL0PLkl895MIl20Z4v53o1NOQ4Fn0A+eptnrld8jYUkL5PcD+kdEqv2GkBn7vO6E/fwYY/wH9FYlE+fXUa0c/YQGqNGS+XVDtgkftqBV+F2EzaIwk+D+QClFBRmKvIbXrUQASi1K6K2eT3gvzR4zh679TSdI2nbnTKtE06xG1PBFVmb1Ux3/Jz4yHFvf2d3M1mOyqIBsozKoyxisiFQxnm3FjhPrdlZJ9oy/nsQM3ahQKJ3DF8hiLI1LxcxRa6wo//t3uu2eJSYl/c5nu0T7gVw4sChQNy52fUhEGoDTDwYoAxsLSDXcpj1jevRsKvxt/dh2e2De1a9HYj5oM+z2O+pcyiY98cKDbhe2miUqUdiYMBy24xUunB46zVcJF3pIqCYtw5ts8ES6Ixn3u+4OGV/hMDrVdiG2bOZtNVkdbKMEkOEBGa3parPJ69jh6og639kdAD3DFxyZn3YKYuJlcNShn3tj6iPokBYhlLwwf8vuEV7gK7G0rDS9yxuF03jgkwpBBF2wy+u1AbJv241T7v2ZB8H8VlYyHA0E5pnoWbw+lIOTy4IAc8gIesMvDuFFi4r1okhiAt/24U0p4aAohjh1nPuU3spY="
file: release-out/**/*
skip_cleanup: true
file_glob: true
on:
repo: docker/buildx
tags: true
condition: $TRAVIS_TAG =~ ^v[0-9]

45
AUTHORS Normal file
View File

@@ -0,0 +1,45 @@
# This file lists all individuals having contributed content to the repository.
# For how it is generated, see hack/dockerfiles/authors.Dockerfile.
Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
Alex Couture-Beil <alex@earthly.dev>
Andrew Haines <andrew.haines@zencargo.com>
Andy MacKinlay <admackin@users.noreply.github.com>
Anthony Poschen <zanven42@gmail.com>
Artur Klauser <Artur.Klauser@computer.org>
Batuhan Apaydın <developerguy2@gmail.com>
Bin Du <bindu@microsoft.com>
Brandon Philips <brandon@ifup.org>
Brian Goff <cpuguy83@gmail.com>
CrazyMax <github@crazymax.dev>
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Devin Bayer <dev@doubly.so>
Djordje Lukic <djordje.lukic@docker.com>
Dmytro Makovey <dmytro.makovey@docker.com>
Donghui Wang <977675308@qq.com>
faust <faustin@fala.red>
Felipe Santos <felipecassiors@gmail.com>
Fernando Miguel <github@FernandoMiguel.net>
gfrancesco <gfrancesco@users.noreply.github.com>
gracenoah <gracenoahgh@gmail.com>
Hollow Man <hollowman@hollowman.ml>
Ilya Dmitrichenko <errordeveloper@gmail.com>
Jack Laxson <jackjrabbit@gmail.com>
Jean-Yves Gastaud <jygastaud@gmail.com>
khs1994 <khs1994@khs1994.com>
Kotaro Adachi <k33asby@gmail.com>
l00397676 <lujingxiao@huawei.com>
Michal Augustyn <michal.augustyn@mail.com>
Patrick Van Stee <patrick@vanstee.me>
Saul Shanabrook <s.shanabrook@gmail.com>
Sebastiaan van Stijn <github@gone.nl>
SHIMA Tatsuya <ts1s1andn@gmail.com>
Silvin Lubecki <silvin.lubecki@docker.com>
Solomon Hykes <sh.github.6811@hykes.org>
Sune Keller <absukl@almbrand.dk>
Tibor Vass <tibor@docker.com>
Tõnis Tiigi <tonistiigi@gmail.com>
Ulysses Souza <ulyssessouza@gmail.com>
Wang Jinglei <morlay.null@gmail.com>
Xiang Dai <764524258@qq.com>
zelahi <elahi.zuhayr@gmail.com>

View File

@@ -1,80 +1,92 @@
# syntax=docker/dockerfile:1.0-experimental
# syntax=docker/dockerfile-upstream:1.5.0
ARG DOCKERD_VERSION=19.03-rc
ARG CLI_VERSION=19.03
ARG GO_VERSION=1.19
ARG XX_VERSION=1.1.2
ARG DOCKERD_VERSION=20.10.14
FROM docker:$DOCKERD_VERSION AS dockerd-release
# xgo is a helper for golang cross-compilation
FROM --platform=$BUILDPLATFORM tonistiigi/xx:golang@sha256:6f7d999551dd471b58f70716754290495690efa8421e0a1fcf18eb11d0c0a537 AS xgo
# xx is a helper for cross-compilation
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
FROM --platform=$BUILDPLATFORM golang:1.12-alpine AS gobase
COPY --from=xgo / /
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS golatest
FROM golatest AS gobase
COPY --from=xx / /
RUN apk add --no-cache file git
ENV GOFLAGS=-mod=vendor
ENV CGO_ENABLED=0
WORKDIR /src
FROM gobase AS buildx-version
RUN --mount=target=. \
PKG=github.com/docker/buildx VERSION=$(git describe --match 'v[0-9]*' --dirty='.m' --always --tags) REVISION=$(git rev-parse HEAD)$(if ! git diff --no-ext-diff --quiet --exit-code; then echo .m; fi); \
echo "-X ${PKG}/version.Version=${VERSION} -X ${PKG}/version.Revision=${REVISION} -X ${PKG}/version.Package=${PKG}" | tee /tmp/.ldflags; \
echo -n "${VERSION}" | tee /tmp/.version;
RUN --mount=type=bind,target=. <<EOT
set -e
mkdir /buildx-version
echo -n "$(./hack/git-meta version)" | tee /buildx-version/version
echo -n "$(./hack/git-meta revision)" | tee /buildx-version/revision
EOT
FROM gobase AS buildx-build
ENV CGO_ENABLED=0
ARG TARGETPLATFORM
RUN --mount=target=. --mount=target=/root/.cache,type=cache \
--mount=target=/go/pkg/mod,type=cache \
--mount=source=/tmp/.ldflags,target=/tmp/.ldflags,from=buildx-version \
set -x; go build -ldflags "$(cat /tmp/.ldflags)" -o /usr/bin/buildx ./cmd/buildx && \
file /usr/bin/buildx && file /usr/bin/buildx | egrep "statically linked|Mach-O|Windows"
RUN --mount=type=bind,target=. \
--mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=bind,from=buildx-version,source=/buildx-version,target=/buildx-version <<EOT
set -e
xx-go --wrap
DESTDIR=/usr/bin VERSION=$(cat /buildx-version/version) REVISION=$(cat /buildx-version/revision) GO_EXTRA_LDFLAGS="-s -w" ./hack/build
xx-verify --static /usr/bin/docker-buildx
EOT
FROM buildx-build AS integration-tests
COPY . .
FROM gobase AS test
RUN --mount=type=bind,target=. \
--mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/go/pkg/mod \
go test -v -coverprofile=/tmp/coverage.txt -covermode=atomic ./... && \
go tool cover -func=/tmp/coverage.txt
FROM golang:1.12-alpine AS docker-cli-build
RUN apk add -U git bash coreutils gcc musl-dev
ENV CGO_ENABLED=0
ARG REPO=github.com/tiborvass/cli
ARG BRANCH=cli-plugin-aliases
ARG CLI_VERSION
WORKDIR /go/src/github.com/docker/cli
RUN git clone git://$REPO . && git checkout $BRANCH
RUN ./scripts/build/binary
FROM scratch AS test-coverage
COPY --from=test /tmp/coverage.txt /coverage.txt
FROM scratch AS binaries-unix
COPY --from=buildx-build /usr/bin/buildx /
COPY --link --from=buildx-build /usr/bin/docker-buildx /buildx
FROM binaries-unix AS binaries-darwin
FROM binaries-unix AS binaries-linux
FROM scratch AS binaries-windows
COPY --from=buildx-build /usr/bin/buildx /buildx.exe
COPY --link --from=buildx-build /usr/bin/docker-buildx /buildx.exe
FROM binaries-$TARGETOS AS binaries
# enable scanning for this stage
ARG BUILDKIT_SBOM_SCAN_STAGE=true
# Release
FROM --platform=$BUILDPLATFORM alpine AS releaser
WORKDIR /work
ARG TARGETPLATFORM
RUN --mount=from=binaries \
--mount=source=/tmp/.version,target=/tmp/.version,from=buildx-version \
mkdir -p /out && cp buildx* "/out/buildx-$(cat /tmp/.version).$(echo $TARGETPLATFORM | sed 's/\//-/g')$(ls buildx* | sed -e 's/^buildx//')"
--mount=type=bind,from=buildx-version,source=/buildx-version,target=/buildx-version <<EOT
set -e
mkdir -p /out
cp buildx* "/out/buildx-$(cat /buildx-version/version).$(echo $TARGETPLATFORM | sed 's/\//-/g')$(ls buildx* | sed -e 's/^buildx//')"
EOT
FROM scratch AS release
COPY --from=releaser /out/ /
FROM alpine AS demo-env
# Shell
FROM docker:$DOCKERD_VERSION AS dockerd-release
FROM alpine AS shell
RUN apk add --no-cache iptables tmux git vim less openssh
RUN mkdir -p /usr/local/lib/docker/cli-plugins && ln -s /usr/local/bin/buildx /usr/local/lib/docker/cli-plugins/docker-buildx
COPY ./hack/demo-env/entrypoint.sh /usr/local/bin
COPY ./hack/demo-env/tmux.conf /root/.tmux.conf
COPY --from=dockerd-release /usr/local/bin /usr/local/bin
COPY --from=docker-cli-build /go/src/github.com/docker/cli/build/docker /usr/local/bin
WORKDIR /work
COPY ./hack/demo-env/examples .
COPY --from=binaries / /usr/local/bin/
VOLUME /var/lib/docker
ENTRYPOINT ["entrypoint.sh"]
FROM binaries
FROM binaries

210
MAINTAINERS Normal file
View File

@@ -0,0 +1,210 @@
# Buildx maintainers file
#
# This file describes the maintainer groups within the project.
# More detail on Moby project governance is available in the
# https://github.com/moby/moby/blob/master/project/GOVERNANCE.md file.
#
# It is structured to be consumable by both humans and programs.
# To extract its contents programmatically, use any TOML-compliant
# parser.
#
[Rules]
[Rules.maintainers]
title = "What is a maintainer?"
text = """
There are different types of maintainers, with different
responsibilities, but all maintainers have 3 things in common:
1) They share responsibility in the project's success.
2) They have made a long-term, recurring time investment to improve
the project.
3) They spend that time doing whatever needs to be done, not
necessarily what is the most interesting or fun.
Maintainers are often under-appreciated, because their work is harder
to appreciate. It's easy to appreciate a really cool and technically
advanced feature. It's harder to appreciate the absence of bugs, the
slow but steady improvement in stability, or the reliability of a
release process. But those things distinguish a good project from a
great one.
"""
[Rules.adding-maintainers]
title = "How are maintainers added?"
text = """
Maintainers are first and foremost contributors that have shown they
are committed to the long term success of a project. Contributors
wanting to become maintainers are expected to be deeply involved in
contributing code, pull request review, and triage of issues in the
project for more than three months.
Just contributing does not make you a maintainer, it is about building
trust with the current maintainers of the project and being a person
that they can depend on and trust to make decisions in the best
interest of the project.
Periodically, the existing maintainers curate a list of contributors
that have shown regular activity on the project over the prior
months. From this list, maintainer candidates are selected.
After a candidate has been announced, the existing maintainers are
given five business days to discuss the candidate, raise objections
and cast their vote. Candidates must be approved by at least 66% of
the current maintainers by adding their vote on the slack
channel. Only maintainers of the repository that the candidate is
proposed for are allowed to vote.
If a candidate is approved, a maintainer will contact the candidate to
invite the candidate to open a pull request that adds the contributor
to the MAINTAINERS file. The candidate becomes a maintainer once the
pull request is merged.
"""
[Rules.stepping-down-policy]
title = "Stepping down policy"
text = """
Life priorities, interests, and passions can change. If you're a
maintainer but feel you must remove yourself from the list, inform
other maintainers that you intend to step down, and if possible, help
find someone to pick up your work. At the very least, ensure your
work can be continued where you left off.
After you've informed other maintainers, create a pull request to
remove yourself from the MAINTAINERS file.
"""
[Rules.inactive-maintainers]
title = "Removal of inactive maintainers"
text = """
Similar to the procedure for adding new maintainers, existing
maintainers can be removed from the list if they do not show
significant activity on the project. Periodically, the maintainers
review the list of maintainers and their activity over the last three
months.
If a maintainer has shown insufficient activity over this period, a
neutral person will contact the maintainer to ask if they want to
continue being a maintainer. If the maintainer decides to step down as
a maintainer, they open a pull request to be removed from the
MAINTAINERS file.
If the maintainer wants to remain a maintainer, but is unable to
perform the required duties they can be removed with a vote of at
least 66% of the current maintainers. The voting period is five
business days. Issues related to a maintainer's performance should be
discussed with them among the other maintainers so that they are not
surprised by a pull request removing them.
"""
[Rules.DCO]
title = "Helping contributors with the DCO"
text = """
The [DCO or `Sign your work`](
https://github.com/moby/buildkit/blob/master/CONTRIBUTING.md#sign-your-work)
requirement is not intended as a roadblock or speed bump.
Some BuildKit contributors are not as familiar with `git`, or have
used a web based editor, and thus asking them to `git commit --amend
-s` is not the best way forward.
In this case, maintainers can update the commits based on clause (c)
of the DCO. The most trivial way for a contributor to allow the
maintainer to do this, is to add a DCO signature in a pull requests's
comment, or a maintainer can simply note that the change is
sufficiently trivial that it does not substantially change the
existing contribution - i.e., a spelling change.
When you add someone's DCO, please also add your own to keep a log.
"""
[Rules."no direct push"]
title = "I'm a maintainer. Should I make pull requests too?"
text = """
Yes. Nobody should ever push to master directly. All changes should be
made through a pull request.
"""
[Rules.meta]
title = "How is this process changed?"
text = "Just like everything else: by making a pull request :)"
[Org]
[Org.Maintainers]
people = [
"akihirosuda",
"crazy-max",
"jedevc",
"tiborvass",
"tonistiigi",
]
[Org.Curators]
# The curators help ensure that incoming issues and pull requests are properly triaged and
# that our various contribution and reviewing processes are respected. With their knowledge of
# the repository activity, they can also guide contributors to relevant material or
# discussions.
#
# They are neither code nor docs reviewers, so they are never expected to merge. They can
# however:
# - close an issue or pull request when it's an exact duplicate
# - close an issue or pull request when it's inappropriate or off-topic
people = [
"thajeztah",
]
[people]
# A reference list of all people associated with the project.
# All other sections should refer to people by their canonical key
# in the people section.
[people.akihirosuda]
Name = "Akihiro Suda"
Email = "akihiro.suda.cz@hco.ntt.co.jp"
GitHub = "AkihiroSuda"
[people.crazy-max]
Name = "Kevin Alvarez"
Email = "contact@crazymax.dev"
GitHub = "crazy-max"
[people.jedevc]
Name = "Justin Chadwell"
Email = "me@jedevc.com"
GitHub = "jedevc"
[people.thajeztah]
Name = "Sebastiaan van Stijn"
Email = "github@gone.nl"
GitHub = "thaJeztah"
[people.tiborvass]
Name = "Tibor Vass"
Email = "tibor@docker.com"
GitHub = "tiborvass"
[people.tonistiigi]
Name = "Tõnis Tiigi"
Email = "tonis@docker.com"
GitHub = "tonistiigi"

View File

@@ -1,28 +1,80 @@
ifneq (, $(BUILDX_BIN))
export BUILDX_CMD = $(BUILDX_BIN)
else ifneq (, $(shell docker buildx version))
export BUILDX_CMD = docker buildx
else ifneq (, $(shell which buildx))
export BUILDX_CMD = $(which buildx)
endif
export BUILDX_CMD ?= docker buildx
.PHONY: all
all: binaries
.PHONY: build
build:
./hack/build
.PHONY: shell
shell:
./hack/shell
.PHONY: binaries
binaries:
./hack/binaries
$(BUILDX_CMD) bake binaries
.PHONY: binaries-cross
binaries-cross:
EXPORT_LOCAL=cross-out ./hack/cross
$(BUILDX_CMD) bake binaries-cross
.PHONY: install
install: binaries
mkdir -p ~/.docker/cli-plugins
cp bin/buildx ~/.docker/cli-plugins/docker-buildx
install bin/build/buildx ~/.docker/cli-plugins/docker-buildx
.PHONY: release
release:
./hack/release
.PHONY: validate-all
validate-all: lint test validate-vendor validate-docs
.PHONY: lint
lint:
./hack/lint
$(BUILDX_CMD) bake lint
.PHONY: test
test:
./hack/test
$(BUILDX_CMD) bake test
.PHONY: validate-vendor
validate-vendor:
./hack/validate-vendor
validate-all: lint test validate-vendor
$(BUILDX_CMD) bake validate-vendor
.PHONY: validate-docs
validate-docs:
$(BUILDX_CMD) bake validate-docs
.PHONY: validate-authors
validate-authors:
$(BUILDX_CMD) bake validate-authors
.PHONY: test-driver
test-driver:
./hack/test-driver
.PHONY: vendor
vendor:
./hack/update-vendor
.PHONY: vendor lint shell binaries install binaries-cross validate-all
.PHONY: docs
docs:
./hack/update-docs
.PHONY: authors
authors:
$(BUILDX_CMD) bake update-authors
.PHONY: mod-outdated
mod-outdated:
$(BUILDX_CMD) bake mod-outdated

769
README.md
View File

@@ -1,569 +1,324 @@
# buildx - Docker CLI plugin for extended build capabilities with BuildKit
# buildx
## buildx is Tech Preview
[![GitHub release](https://img.shields.io/github/release/docker/buildx.svg?style=flat-square)](https://github.com/docker/buildx/releases/latest)
[![PkgGoDev](https://img.shields.io/badge/go.dev-docs-007d9c?style=flat-square&logo=go&logoColor=white)](https://pkg.go.dev/github.com/docker/buildx)
[![Build Status](https://img.shields.io/github/actions/workflow/status/docker/buildx/build.yml?branch=master&label=build&logo=github&style=flat-square)](https://github.com/docker/buildx/actions?query=workflow%3Abuild)
[![Go Report Card](https://goreportcard.com/badge/github.com/docker/buildx?style=flat-square)](https://goreportcard.com/report/github.com/docker/buildx)
[![codecov](https://img.shields.io/codecov/c/github/docker/buildx?logo=codecov&style=flat-square)](https://codecov.io/gh/docker/buildx)
### TL;DR
`buildx` is a Docker CLI plugin for extended build capabilities with
[BuildKit](https://github.com/moby/buildkit).
Key features:
- Familiar UI from `docker build`
- Full BuildKit capabilities with container driver
- Multiple builder instance support
- Multi-node builds for cross-platform images
- Compose build support
- WIP: High-level build constructs (`bake`)
- TODO: In-container driver support
- High-level build constructs (`bake`)
- In-container driver support (both Docker and Kubernetes)
# Table of Contents
- [Installing](#installing)
- [Windows and macOS](#windows-and-macos)
- [Linux packages](#linux-packages)
- [Manual download](#manual-download)
- [Dockerfile](#dockerfile)
- [Set buildx as the default builder](#set-buildx-as-the-default-builder)
- [Building](#building)
+ [with Docker 18.09+](#with-docker-1809)
+ [with buildx or Docker 19.03](#with-buildx-or-docker-1903)
- [Documentation](#documentation)
+ [`buildx build [OPTIONS] PATH | URL | -`](#buildx-build-options-path--url---)
+ [`buildx create [OPTIONS] [CONTEXT|ENDPOINT]`](#buildx-create-options-contextendpoint)
+ [`buildx use NAME`](#buildx-use-name)
+ [`buildx inspect [NAME]`](#buildx-inspect-name)
+ [`buildx ls`](#buildx-ls)
+ [`buildx stop [NAME]`](#buildx-stop-name)
+ [`buildx rm [NAME]`](#buildx-rm-name)
+ [`buildx bake [OPTIONS] [TARGET...]`](#buildx-bake-options-target)
+ [`buildx imagetools create [OPTIONS] [SOURCE] [SOURCE...]`](#buildx-imagetools-create-options-source-source)
+ [`buildx imagetools inspect NAME`](#buildx-imagetools-inspect-name)
- [Setting buildx as default builder in Docker 19.03+](#setting-buildx-as-default-builder-in-docker-1903)
- [Getting started](#getting-started)
- [Building with buildx](#building-with-buildx)
- [Working with builder instances](#working-with-builder-instances)
- [Building multi-platform images](#building-multi-platform-images)
- [Manuals](docs/manuals)
- [High-level build options with Bake](docs/manuals/bake/index.md)
- [Drivers](docs/manuals/drivers/index.md)
- [Exporters](docs/manuals/exporters/index.md)
- [Cache backends](docs/manuals/cache/backends/index.md)
- [Guides](docs/guides)
- [CI/CD](docs/guides/cicd.md)
- [CNI networking](docs/guides/cni-networking.md)
- [Using a custom network](docs/guides/custom-network.md)
- [Using a custom registry configuration](docs/guides/custom-registry-config.md)
- [OpenTelemetry support](docs/guides/opentelemetry.md)
- [Registry mirror](docs/guides/registry-mirror.md)
- [Resource limiting](docs/guides/resource-limiting.md)
- [Reference](docs/reference/buildx.md)
- [`buildx bake`](docs/reference/buildx_bake.md)
- [`buildx build`](docs/reference/buildx_build.md)
- [`buildx create`](docs/reference/buildx_create.md)
- [`buildx du`](docs/reference/buildx_du.md)
- [`buildx imagetools`](docs/reference/buildx_imagetools.md)
- [`buildx imagetools create`](docs/reference/buildx_imagetools_create.md)
- [`buildx imagetools inspect`](docs/reference/buildx_imagetools_inspect.md)
- [`buildx inspect`](docs/reference/buildx_inspect.md)
- [`buildx install`](docs/reference/buildx_install.md)
- [`buildx ls`](docs/reference/buildx_ls.md)
- [`buildx prune`](docs/reference/buildx_prune.md)
- [`buildx rm`](docs/reference/buildx_rm.md)
- [`buildx stop`](docs/reference/buildx_stop.md)
- [`buildx uninstall`](docs/reference/buildx_uninstall.md)
- [`buildx use`](docs/reference/buildx_use.md)
- [`buildx version`](docs/reference/buildx_version.md)
- [Contributing](#contributing)
# Installing
Using `buildx` as a docker CLI plugin requires using Docker 19.03.0 beta. A limited set of functionality works with older versions of Docker when invoking the binary directly.
Using `buildx` as a docker CLI plugin requires using Docker 19.03 or newer.
A limited set of functionality works with older versions of Docker when
invoking the binary directly.
<!---
## Windows and macOS
### Docker Desktop (Edge)
Docker Buildx is included in [Docker Desktop](https://docs.docker.com/desktop/)
for Windows and macOS.
`buildx` is included with Docker Desktop edge builds since 19.03.0-beta3.
## Linux packages
For more information see https://docs.docker.com/docker-for-mac/edge-release-notes/
Docker Linux packages also include Docker Buildx when installed using the
[DEB or RPM packages](https://docs.docker.com/engine/install/).
### Docker CE nightly builds
## Manual download
`buildx` comes bundled with the Docker CE nightly builds.
https://download.docker.com/linux/static/nightly/
https://download.docker.com/mac/static/nightly/
> **Important**
>
> This section is for unattended installation of the buildx component. These
> instructions are mostly suitable for testing purposes. We do not recommend
> installing buildx using manual download in production environments as they
> will not be updated automatically with security updates.
>
> On Windows and macOS, we recommend that you install [Docker Desktop](https://docs.docker.com/desktop/)
> instead. For Linux, we recommend that you follow the [instructions specific for your distribution](#linux-packages).
-->
You can also download the latest binary from the [GitHub releases page](https://github.com/docker/buildx/releases/latest).
### Binary release
Rename the relevant binary and copy it to the destination matching your OS:
Download the latest binary release from https://github.com/docker/buildx/releases/latest and copy it to `~/.docker/cli-plugins` folder with name `docker-buildx`.
| OS | Binary name | Destination folder |
| -------- | -------------------- | -----------------------------------------|
| Linux | `docker-buildx` | `$HOME/.docker/cli-plugins` |
| macOS | `docker-buildx` | `$HOME/.docker/cli-plugins` |
| Windows | `docker-buildx.exe` | `%USERPROFILE%\.docker\cli-plugins` |
Or copy it into one of these folders for installing it system-wide.
After installing you can run `docker buildx` to see the new commands.
On Unix environments:
* `/usr/local/lib/docker/cli-plugins` OR `/usr/local/libexec/docker/cli-plugins`
* `/usr/lib/docker/cli-plugins` OR `/usr/libexec/docker/cli-plugins`
On Windows:
* `C:\ProgramData\Docker\cli-plugins`
* `C:\Program Files\Docker\cli-plugins`
> **Note**
>
> On Unix environments, it may also be necessary to make it executable with `chmod +x`:
> ```shell
> $ chmod +x ~/.docker/cli-plugins/docker-buildx
> ```
## Dockerfile
Here is how to install and use Buildx inside a Dockerfile through the
[`docker/buildx-bin`](https://hub.docker.com/r/docker/buildx-bin) image:
```dockerfile
# syntax=docker/dockerfile:1
FROM docker
COPY --from=docker/buildx-bin /buildx /usr/libexec/docker/cli-plugins/docker-buildx
RUN docker buildx version
```
# Set buildx as the default builder
Running the command [`docker buildx install`](docs/reference/buildx_install.md)
sets up docker builder command as an alias to `docker buildx build`. This
results in the ability to have `docker build` use the current buildx builder.
To remove this alias, run [`docker buildx uninstall`](docs/reference/buildx_uninstall.md).
# Building
### with Docker 18.09+
```
$ git clone git://github.com/docker/buildx && cd buildx
```console
# Buildx 0.6+
$ docker buildx bake "https://github.com/docker/buildx.git"
$ mkdir -p ~/.docker/cli-plugins
$ 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"
$ mkdir -p ~/.docker/cli-plugins
$ mv buildx ~/.docker/cli-plugins/docker-buildx
# Local
$ git clone https://github.com/docker/buildx.git && cd buildx
$ make install
```
### with buildx or Docker 19.03
```
$ export DOCKER_BUILDKIT=1
$ # choose a platform that matches your architecture
$ docker build --target=binaries --platform=[darwin,windows,linux,linux/arm64] -o . git://github.com/docker/buildx
$ mv buildx ~/.docker/cli-plugins/docker-buildx
# Getting started
## Building with buildx
Buildx is a Docker CLI plugin that extends the `docker build` command with the
full support of the features provided by [Moby BuildKit](https://github.com/moby/buildkit)
builder toolkit. It provides the same user experience as `docker build` with
many new features like creating scoped builder instances and building against
multiple nodes concurrently.
After installation, buildx can be accessed through the `docker buildx` command
with Docker 19.03. `docker buildx build` is the command for starting a new
build. With Docker versions older than 19.03 buildx binary can be called
directly to access the `docker buildx` subcommands.
```console
$ docker buildx build .
[+] Building 8.4s (23/32)
=> ...
```
# Documentation
Buildx will always build using the BuildKit engine and does not require
`DOCKER_BUILDKIT=1` environment variable for starting builds.
### `buildx build [OPTIONS] PATH | URL | -`
The `docker buildx build` command supports features available for `docker build`,
including features such as outputs configuration, inline build caching, and
specifying target platform. In addition, Buildx also supports new features that
are not yet available for regular `docker build` like building manifest lists,
distributed caching, and exporting build results to OCI image tarballs.
The `buildx build` command starts a build using BuildKit. This command is similar to the UI of `docker build` command and takes the same flags and arguments.
Buildx is flexible and can be run in different configurations that are exposed
through various "drivers". Each driver defines how and where a build should
run, and have different feature sets.
Options:
We currently support the following drivers:
- The `docker` driver ([guide](docs/manuals/drivers/docker.md), [reference](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver))
- The `docker-container` driver ([guide](docs/manuals/drivers/docker-container.md), [reference](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver))
- The `kubernetes` driver ([guide](docs/manuals/drivers/kubernetes.md), [reference](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver))
- The `remote` driver ([guide](docs/manuals/drivers/remote.md))
| Flag | Description |
| --- | --- |
| --add-host [] | Add a custom host-to-IP mapping (host:ip)
| --build-arg [] | Set build-time variables
| --cache-from [] | External cache sources (eg. user/app:cache, type=local,src=path/to/dir)
| --cache-to [] | Cache export destinations (eg. user/app:cache, type=local,dest=path/to/dir)
| --file string | Name of the Dockerfile (Default is 'PATH/Dockerfile')
| --iidfile string | Write the image ID to the file
| --label [] | Set metadata for an image
| --load | Shorthand for --output=type=docker
| --network string | Set the networking mode for the RUN instructions during build (default "default")
| --no-cache | Do not use cache when building the image
| --output [] | Output destination (format: type=local,dest=path)
| --platform [] | Set target platform for build
| --progress string | Set type of progress output (auto, plain, tty). Use plain to show container output (default "auto")
| --pull | Always attempt to pull a newer version of the image
| --push | Shorthand for --output=type=registry
| --secret [] | Secret file to expose to the build: id=mysecret,src=/local/secret
| --ssh [] | SSH agent socket or keys to expose to the build (format: default|<id>[=<socket>|<key>[,<key>]])
| --tag [] | Name and optionally a tag in the 'name:tag' format
| --target string | Set the target build stage to build.
For more information on drivers, see the [drivers guide](docs/manuals/drivers/index.md).
For documentation on most of these flags refer to `docker build` documentation in https://docs.docker.com/engine/reference/commandline/build/ . In here well document a subset of the new flags.
## Working with builder instances
#### ` --platform=value[,value]`
By default, buildx will initially use the `docker` driver if it is supported,
providing a very similar user experience to the native `docker build`. Note that
you must use a local shared daemon to build your applications.
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.
Buildx allows you to create new instances of isolated builders. This can be
used for getting a scoped environment for your CI builds that does not change
the state of the shared daemon or for isolating the builds for different
projects. You can create a new instance for a set of remote nodes, forming a
build farm, and quickly switch between them.
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 built for all of the specified platforms and joined together into a single manifest list.
You can create new instances using the [`docker buildx create`](docs/reference/buildx_create.md)
command. This creates a new builder instance with a single node based on your
current configuration.
If the`Dockerfile` needs to invoke the `RUN` command, the builder needs runtime support for the specified platform. In a clean setup, you can only execute `RUN` commands for your system architecture. If your kernel supports binfmt_misc https://en.wikipedia.org/wiki/Binfmt_misc launchers for secondary architectures buildx will pick them up automatically. Docker desktop releases come with binfmt_misc automatically configured for `arm64` and `arm` architectures. You can see what runtime platforms your current builder instance supports by running `docker buildx inspect --bootstrap`.
To use a remote node you can specify the `DOCKER_HOST` or the remote context name
while creating the new builder. After creating a new instance, you can manage its
lifecycle using the [`docker buildx inspect`](docs/reference/buildx_inspect.md),
[`docker buildx stop`](docs/reference/buildx_stop.md), and
[`docker buildx rm`](docs/reference/buildx_rm.md) commands. To list all
available builders, use [`buildx ls`](docs/reference/buildx_ls.md). After
creating a new builder you can also append new nodes to it.
Inside a `Dockerfile`, you can access the current platform value through `TARGETPLATFORM` build argument. Please refer to `docker build` documentation for the full description of automatic platform argument variants https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope .
To switch between different builders, use [`docker buildx use <name>`](docs/reference/buildx_use.md).
After running this command, the build commands will automatically use this
builder.
The formatting for the platform specifier is defined in https://github.com/containerd/containerd/blob/v1.2.6/platforms/platforms.go#L63 .
Docker also features a [`docker context`](https://docs.docker.com/engine/reference/commandline/context/)
command that can be used for giving names for remote Docker API endpoints.
Buildx integrates with `docker context` so that all of your contexts
automatically get a default builder instance. While creating a new builder
instance or when adding a node to it you can also set the context name as the
target.
Examples:
```
docker buildx build --platform=linux/arm64 .
docker buildx build --platform=linux/amd64,linux/arm64,linux/arm/v7 .
docker buildx build --platform=darwin .
## Building multi-platform images
BuildKit is designed to work well for building for multiple platforms and not
only for the architecture and operating system that the user invoking the build
happens to run.
When you invoke a build, you can set the `--platform` flag to specify the target
platform for the build output, (for example, `linux/amd64`, `linux/arm64`, or
`darwin/amd64`).
When the current builder instance is backed by the `docker-container` or
`kubernetes` driver, you can specify multiple platforms together. In this case,
it builds a manifest list which contains images for all specified architectures.
When you use this image in [`docker run`](https://docs.docker.com/engine/reference/commandline/run/)
or [`docker service`](https://docs.docker.com/engine/reference/commandline/service/),
Docker picks the correct image based on the node's platform.
You can build multi-platform images using three different strategies that are
supported by Buildx and Dockerfiles:
1. Using the QEMU emulation support in the kernel
2. Building on multiple native nodes using the same builder instance
3. Using a stage in Dockerfile to cross-compile to different architectures
QEMU is the easiest way to get started if your node already supports it (for
example. if you are using Docker Desktop). It requires no changes to your
Dockerfile and BuildKit automatically detects the secondary architectures that
are available. When BuildKit needs to run a binary for a different architecture,
it automatically loads it through a binary registered in the `binfmt_misc`
handler.
For QEMU binaries registered with `binfmt_misc` on the host OS to work
transparently inside containers they must be registered with the `fix_binary`
flag. This requires a kernel >= 4.8 and binfmt-support >= 2.1.7. You can check
for proper registration by checking if `F` is among the flags in
`/proc/sys/fs/binfmt_misc/qemu-*`. While Docker Desktop comes preconfigured
with `binfmt_misc` support for additional platforms, for other installations
it likely needs to be installed using [`tonistiigi/binfmt`](https://github.com/tonistiigi/binfmt)
image.
```console
$ docker run --privileged --rm tonistiigi/binfmt --install all
```
#### `-o, --output=[PATH,-,type=TYPE[,KEY=VALUE]`
Using multiple native nodes provide better support for more complicated cases
that are not handled by QEMU and generally have better performance. You can
add additional nodes to the builder instance using the `--append` flag.
Sets the export action for the build result. In `docker build` all builds finish by creating a container image and exporting it to `docker images`. `buildx` makes this step configurable allowing results to be exported directly to the client, oci image tarballs, registry etc.
Assuming contexts `node-amd64` and `node-arm64` exist in `docker context ls`;
Supported exported types are:
##### `local`
The `local` export type writes all result files to a directory on the client. The new files will be owned by the current user. On multi-platform builds, all results will be put in subdirectories by their platform.
Attribute key:
- `dest` - destination directory where files will be written
##### `tar`
The `tar` export type writes all result files as a single tarball on the client. On multi-platform builds all results will be put in subdirectories by their platform.
Attribute key:
- `dest` - destination path where tarball will be written. “-” writes to stdout.
##### `oci`
The `oci` export type writes the result image or manifest list as an OCI image layout tarball https://github.com/opencontainers/image-spec/blob/master/image-layout.md on the client.
Attribute key:
- `dest` - destination path where tarball will be written. “-” writes to stdout.
##### `docker`
The `docker` export type writes the result image as an Docker image specification tarball https://github.com/moby/moby/blob/master/image/spec/v1.2.md on the client. Tarballs created by this exporter are also OCI compatible.
Attribute keys:
- `dest` - destination path where tarball will be written. If not specified the tar will be loaded automatically to the current docker instance.
- `context` - name for the docker context where to import the result
##### `image`
The `image` exporter writes the build result as an image or a manifest list. When using `docker` driver the image will appear in `docker images`. Optionally image can be automatically pushed to a registry by specifying attributes.
Attribute keys:
- `name` - name (references) for the new image.
- `push` - boolean to automatically push the image.
##### `registry`
The `registry` exporter is a shortcut for `type=image,push=true`.
Buildx with `docker` driver currently only supports local, tarball exporter and image exporter. `docker-container` driver supports all the exporters.
If just the path is specified as a value, `buildx` will use the local exporter with this path as the destination. If the value is “-”, `buildx` will use `tar` exporter and write to `stdout`.
Examples:
```
docker buildx build -o . .
docker buildx build -o outdir .
docker buildx build -o - - > out.tar
docker buildx build -o type=docker .
docker buildx build -o type=docker,dest=- . > myimage.tar
docker buildx build -t tonistiigi/foo -o type=registry
````
#### `--push`
Shorthand for `--output=type=registry` . Will automatically push the build result to registry.
#### `--load`
Shorthand for `--output=type=docker` . Will automatically load the build result to `docker images`.
#### `--cache-from=[NAME|type=TYPE[,KEY=VALUE]]`
Use an external cache source for a build. Supported types are `registry` and `local`. The `registry` source can import cache from a cache manifest or (special) image configuration on the registry. The `local` source can export cache from local files previously exported with `--cache-to`.
If no type is specified, `registry` exporter is used with a specified reference.
`docker` driver currently only supports importing build cache from the registry.
Examples:
```
docker buildx build --cache-from=user/app:cache .
docker buildx build --cache-from=user/app .
docker buildx build --cache-from=type=registry,ref=user/app .
docker buildx build --cache-from=type=local,src=path/to/cache .
```console
$ docker buildx create --use --name mybuild node-amd64
mybuild
$ docker buildx create --append --name mybuild node-arm64
$ docker buildx build --platform linux/amd64,linux/arm64 .
```
#### `--cache-to=[NAME|type=TYPE[,KEY=VALUE]]`
Finally, depending on your project, the language that you use may have good
support for cross-compilation. In that case, multi-stage builds in Dockerfiles
can be effectively used to build binaries for the platform specified with
`--platform` using the native architecture of the build node. A list of build
arguments like `BUILDPLATFORM` and `TARGETPLATFORM` is available automatically
inside your Dockerfile and can be leveraged by the processes running as part
of your build.
Export build cache to an external cache destination. Supported types are `registry`, `local` and `inline`. Registry exports build cache to a cache manifest in the registry, local exports cache to a local directory on the client and inline writes the cache metadata into the image configuration.
`docker` driver currently only supports exporting inline cache metadata to image configuration. Alternatively, `--build-arg BUILDKIT_INLINE_CACHE=1` can be used to trigger inline cache exporter.
Attribute key:
- `mode` - Specifies how many layers are exported with the cache. “min” on only exports layers already in the final build build stage, “max” exports layers for all stages. Metadata is always exported for the whole build.
Examples:
```
docker buildx build --cache-to=user/app:cache .
docker buildx build --cache-to=type=inline .
docker buildx build --cache-to=type=registry,ref=user/app .
docker buildx build --cache-to=type=local,src=path/to/cache .
```dockerfile
# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM golang:alpine AS build
ARG TARGETPLATFORM
ARG BUILDPLATFORM
RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log
FROM alpine
COPY --from=build /log /log
```
You can also use [`tonistiigi/xx`](https://github.com/tonistiigi/xx) Dockerfile
cross-compilation helpers for more advanced use-cases.
### `buildx create [OPTIONS] [CONTEXT|ENDPOINT]`
Create makes a new builder instance pointing to a docker context or endpoint, where context is the name of a context from `docker context ls` and endpoint is the address for docker socket (eg. `DOCKER_HOST` value).
By default, the current docker configuration is used for determining the context/endpoint value.
Builder instances are isolated environments where builds can be invoked. All docker contexts also get the default builder instance.
Options:
| Flag | Description |
| --- | --- |
| --append | Append a node to builder instead of changing it
| --driver string | Driver to use (eg. docker-container)
| --leave | Remove a node from builder instead of changing it
| --name string | Builder instance name
| --node string | Create/modify node with given name
| --platform stringArray | Fixed platforms for current node
| --use | Set the current builder instance
#### `--driver DRIVER`
Sets the builder driver to be used. There are two available drivers, each have their own specificities.
- `docker` - Uses the builder that is built into the docker daemon. With this driver, the `--load` flag is implied by default on `buildx build`. However, building multi-platform images or exporting cache is not currently supported.
- `docker-container` - Uses a buildkit container that will be spawned via docker. With this driver, both building multi-platform images and exporting cache are supported. However, images built will not automatically appear in `docker images` (see [`build --load`](#--load)).
#### `--append`
Changes the action of the command to appends a new node to an existing builder specified by `--name`. Buildx will choose an appropriate node for a build based on the platforms it supports.
Example:
```
$ docker buildx create mycontext1
eager_beaver
$ docker buildx create --name eager_beaver --append mycontext2
eager_beaver
```
#### `--leave`
Changes the action of the command to removes a node from a builder. The builder needs to be specified with `--name` and node that is removed is set with `--node`.
Example:
```
docker buildx create --name mybuilder --node mybuilder0 --leave
```
#### `--name NAME`
Specifies the name of the builder to be created or modified. If none is specified, one will be automatically generated.
#### `--node NODE`
Specifies the name of the node to be created or modified. If none is specified, it is the name of the builder it belongs to, with an index number suffix.
#### `--platform PLATFORMS`
Sets the platforms supported by the node. It expects a comma-separated list of platforms of the form OS/architecture/variant. The node will also automatically detect the platforms it supports, but manual values take priority over the detected ones and can be used when multiple nodes support building for the same platform.
Example:
```
docker buildx create --platform linux/amd64
docker buildx create --platform linux/arm64,linux/arm/v8
```
#### `--use`
Automatically switches the current builder to the newly created one. Equivalent to running `docker buildx use $(docker buildx create ...)`.
### `buildx use NAME`
Switches the current builder instance. Build commands invoked after this command will run on a specified builder. Alternatively, a context name can be used to switch to the default builder of that context.
### `buildx inspect [NAME]`
Shows information about the current or specified builder.
Example:
```
Name: elated_tesla
Driver: docker-container
Nodes:
Name: elated_tesla0
Endpoint: unix:///var/run/docker.sock
Status: running
Platforms: linux/amd64
Name: elated_tesla1
Endpoint: ssh://ubuntu@1.2.3.4
Status: running
Platforms: linux/arm64, linux/arm/v7, linux/arm/v6
```
#### `--bootstrap`
Ensures that the builder is running before inspecting it. If the driver is `docker-container`, then `--bootstrap` starts the buildkit container and waits until it is operational. Bootstrapping is automatically done during build, it is thus not necessary. The same BuildKit container is used during the lifetime of the associated builder node (as displayed in `buildx ls`).
### `buildx ls`
Lists all builder instances and the nodes for each instance
Example:
```
docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS
elated_tesla * docker-container
elated_tesla0 unix:///var/run/docker.sock running linux/amd64
elated_tesla1 ssh://ubuntu@1.2.3.4 running linux/arm64, linux/arm/v7, linux/arm/v6
default docker
default default running linux/amd64
```
Each builder has one or more nodes associated with it. The current builders name is marked with a `*`.
### `buildx stop [NAME]`
Stops the specified or current builder. This will not prevent buildx build to restart the builder. The implementation of stop depends on the driver.
### `buildx rm [NAME]`
Removes the specified or current builder. It is a no-op attempting to remove the default builder.
### `buildx bake [OPTIONS] [TARGET...]`
Bake is a high-level build command.
Each specified target will run in parallel as part of the build.
Options:
| Flag | Description |
| --- | --- |
| -f, --file stringArray | Build definition file
| --no-cache | Do not use cache when building the image
| --print | Print the options without building
| --progress string | Set type of progress output (auto, plain, tty). Use plain to show container output (default "auto")
| --pull | Always attempt to pull a newer version of the image
| --set stringArray | Override target value (eg: target.key=value)
#### `-f, --file FILE`
Specifies the bake definition file. The file can be a Docker Compose, JSON or HCL file. If multiple files are specified they are all read and configurations are combined. By default, if no files are specified, the following are parsed:
docker-compose.yml
docker-compose.yaml
docker-bake.json
docker-bake.override.json
docker-bake.hcl
docker-bake.override.hcl
#### `--no-cache`
Same as `build --no-cache`. Do not use cache when building the image.
#### `--print`
Prints the resulting options of the targets desired to be built, in a JSON format, without starting a build.
```
$ docker buildx bake -f docker-bake.hcl --print db
{
"target": {
"db": {
"context": "./",
"dockerfile": "Dockerfile",
"tags": [
"docker.io/tiborvass/db"
]
}
}
}
```
#### `--progress`
Same as `build --progress`. Set type of progress output (auto, plain, tty). Use plain to show container output (default "auto").
#### `--pull`
Same as `build --pull`.
#### `--set target.key[.subkey]=value`
Override target configurations from command line.
Example:
```
docker buildx bake --set target.args.mybuildarg=value
docker buildx bake --set target.platform=linux/arm64
```
#### File definition
In addition to compose files, bake supports a JSON and an equivalent HCL file format for defining build groups and targets.
A target reflects a single docker build invocation with the same options that you would specify for `docker build`. A group is a grouping of targets.
Multiple files can include the same target and final build options will be determined by merging them together.
In the case of compose files, each service corresponds to a target.
A group can specify its list of targets with the `targets` option. A target can inherit build options by setting the `inherits` option to the list of targets or groups to inherit from.
Note: Design of bake command is work in progress, the user experience may change based on feedback.
Example HCL defintion:
```
group “default” {
targets = [“db”, “webapp-dev”]
}
target “webapp-dev” {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp"]
}
target “webapp-release” {
inherits = [“webapp-dev”]
platforms = [“linux/amd64”, “linux/arm64”]
}
target “db” {
dockerfile = "Dockerfile.db"
tags = [“docker.io/username/db”]
}
```
### `buildx imagetools create [OPTIONS] [SOURCE] [SOURCE...]`
Imagetools contains commands for working with manifest lists in the registry. These commands are useful for inspecting multi-platform build results.
Create creates a new manifest list based on source manifests. The source manifests can be manifest lists or single platform distribution manifests and must already exist in the registry where the new manifest is created. If only one source is specified create performs a carbon copy.
Options:
| Flag | Description |
| --- | --- |
| --append | Append to existing manifest
| --dry-run | Show final image instead of pushing
| -f, --file stringArray | Read source descriptor from file
| -t, --tag stringArray | Set reference for new image
#### `--append`
Append appends the new sources to an existing manifest list in the destination.
#### `--dry-run`
Do not push the image, just show it.
#### `-f, --file FILE`
Reads source from files. A source can be a manifest digest, manifest reference or a JSON of OCI descriptor object.
#### `-t, --tag IMAGE`
Name of the image to be created.
Examples:
```
docker buildx imagetools create --dry-run alpine@sha256:5c40b3c27b9f13c873fefb2139765c56ce97fd50230f1f2d5c91e55dec171907 sha256:c4ba6347b0e4258ce6a6de2401619316f982b7bcc529f73d2a410d0097730204
docker buildx imagetools create -t tonistiigi/myapp -f image1 -f image2
```
### `buildx imagetools inspect NAME`
Show details of image in the registry.
Example:
```
$ docker buildx imagetools inspect alpine
Name: docker.io/library/alpine:latest
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest: sha256:28ef97b8686a0b5399129e9b763d5b7e5ff03576aa5580d6f4182a49c5fe1913
Manifests:
Name: docker.io/library/alpine:latest@sha256:5c40b3c27b9f13c873fefb2139765c56ce97fd50230f1f2d5c91e55dec171907
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/amd64
Name: docker.io/library/alpine:latest@sha256:c4ba6347b0e4258ce6a6de2401619316f982b7bcc529f73d2a410d0097730204
MediaType: application/vnd.docker.distribution.manifest.v2+json
Platform: linux/arm/v6
...
```
#### `--raw`
Raw prints the original JSON bytes instead of the formatted output.
# Setting buildx as default builder in Docker 19.03+
Running `docker buildx install` sets up `docker builder` command as an alias to `docker buildx`. This results in the ability to have `docker build` use the current buildx builder.
To remove this alias, you can run `docker buildx uninstall`.
## High-level build options
See [`docs/manuals/bake/index.md`](docs/manuals/bake/index.md) for more details.
# Contributing
To enter a demo container environment and experiment, you may run:
```
$ make shell
```
To validate PRs before submitting them you should run:
```
$ make validate-all
```
To generate new vendored files with go modules run:
```
$ make vendor
```
Want to contribute to Buildx? Awesome! You can find information about
contributing to this project in the [CONTRIBUTING.md](/.github/CONTRIBUTING.md)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,39 +1,60 @@
package bake
import (
"github.com/docker/cli/cli/compose/loader"
composetypes "github.com/docker/cli/cli/compose/types"
"os"
"path/filepath"
"strings"
"github.com/compose-spec/compose-go/dotenv"
"github.com/compose-spec/compose-go/loader"
compose "github.com/compose-spec/compose-go/types"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
)
func parseCompose(dt []byte) (*composetypes.Config, error) {
parsed, err := loader.ParseYAML([]byte(dt))
func ParseComposeFiles(fs []File) (*Config, error) {
envs, err := composeEnv()
if err != nil {
return nil, err
}
return loader.Load(composetypes.ConfigDetails{
ConfigFiles: []composetypes.ConfigFile{
{
Config: parsed,
},
},
})
var cfgs []compose.ConfigFile
for _, f := range fs {
cfgs = append(cfgs, compose.ConfigFile{
Filename: f.Name,
Content: f.Data,
})
}
return ParseCompose(cfgs, envs)
}
func ParseCompose(dt []byte) (*Config, error) {
cfg, err := parseCompose(dt)
func ParseCompose(cfgs []compose.ConfigFile, envs map[string]string) (*Config, error) {
cfg, err := loader.Load(compose.ConfigDetails{
ConfigFiles: cfgs,
Environment: envs,
}, func(options *loader.Options) {
options.SkipNormalization = true
})
if err != nil {
return nil, err
}
var c Config
if len(cfg.Services) > 0 {
c.Group = map[string]Group{}
c.Target = map[string]Target{}
c.Groups = []*Group{}
c.Targets = []*Target{}
var g Group
g := &Group{Name: "default"}
for _, s := range cfg.Services {
g.Targets = append(g.Targets, s.Name)
if s.Build == nil {
continue
}
targetName := sanitizeTargetName(s.Name)
if err = validateTargetName(targetName); err != nil {
return nil, errors.Wrapf(err, "invalid service name %q", targetName)
}
var contextPathP *string
if s.Build.Context != "" {
contextPath := s.Build.Context
@@ -44,35 +65,260 @@ func ParseCompose(dt []byte) (*Config, error) {
dockerfilePath := s.Build.Dockerfile
dockerfilePathP = &dockerfilePath
}
t := Target{
var secrets []string
for _, bs := range s.Build.Secrets {
secret, err := composeToBuildkitSecret(bs, cfg.Secrets[bs.Source])
if err != nil {
return nil, err
}
secrets = append(secrets, secret)
}
// compose does not support nil values for labels
labels := map[string]*string{}
for k, v := range s.Build.Labels {
v := v
labels[k] = &v
}
g.Targets = append(g.Targets, targetName)
t := &Target{
Name: targetName,
Context: contextPathP,
Dockerfile: dockerfilePathP,
Labels: s.Build.Labels,
Args: toMap(s.Build.Args),
CacheFrom: s.Build.CacheFrom,
// TODO: add platforms
Tags: s.Build.Tags,
Labels: labels,
Args: flatten(s.Build.Args.Resolve(func(val string) (string, bool) {
if val, ok := s.Environment[val]; ok && val != nil {
return *val, true
}
val, ok := cfg.Environment[val]
return val, ok
})),
CacheFrom: s.Build.CacheFrom,
CacheTo: s.Build.CacheTo,
NetworkMode: &s.Build.Network,
Secrets: secrets,
}
if err = t.composeExtTarget(s.Build.Extensions); err != nil {
return nil, err
}
if s.Build.Target != "" {
t.Target = &s.Build.Target
target := s.Build.Target
t.Target = &target
}
if s.Image != "" {
if len(t.Tags) == 0 && s.Image != "" {
t.Tags = []string{s.Image}
}
c.Target[s.Name] = t
c.Targets = append(c.Targets, t)
}
c.Group["default"] = g
c.Groups = append(c.Groups, g)
}
return &c, nil
}
func toMap(in composetypes.MappingWithEquals) map[string]string {
m := map[string]string{}
for k, v := range in {
if v != nil {
m[k] = *v
func validateComposeFile(dt []byte, fn string) (bool, error) {
envs, err := composeEnv()
if err != nil {
return true, err
}
fnl := strings.ToLower(fn)
if strings.HasSuffix(fnl, ".yml") || strings.HasSuffix(fnl, ".yaml") {
return true, validateCompose(dt, envs)
}
if strings.HasSuffix(fnl, ".json") || strings.HasSuffix(fnl, ".hcl") {
return false, nil
}
err = validateCompose(dt, envs)
return err == nil, err
}
func validateCompose(dt []byte, envs map[string]string) error {
_, err := loader.Load(compose.ConfigDetails{
ConfigFiles: []compose.ConfigFile{
{
Content: dt,
},
},
Environment: envs,
}, func(options *loader.Options) {
options.SkipNormalization = true
// consistency is checked later in ParseCompose to ensure multiple
// compose files can be merged together
options.SkipConsistencyCheck = true
})
return err
}
func composeEnv() (map[string]string, error) {
envs := sliceToMap(os.Environ())
if wd, err := os.Getwd(); err == nil {
envs, err = loadDotEnv(envs, wd)
if err != nil {
return nil, err
}
}
return m
return envs, nil
}
func loadDotEnv(curenv map[string]string, workingDir string) (map[string]string, error) {
if curenv == nil {
curenv = make(map[string]string)
}
ef, err := filepath.Abs(filepath.Join(workingDir, ".env"))
if err != nil {
return nil, err
}
if _, err = os.Stat(ef); os.IsNotExist(err) {
return curenv, nil
} else if err != nil {
return nil, err
}
dt, err := os.ReadFile(ef)
if err != nil {
return nil, err
}
envs, err := dotenv.UnmarshalBytes(dt)
if err != nil {
return nil, err
}
for k, v := range envs {
if _, set := curenv[k]; set {
continue
}
curenv[k] = v
}
return curenv, nil
}
func flatten(in compose.MappingWithEquals) map[string]*string {
if len(in) == 0 {
return nil
}
out := map[string]*string{}
for k, v := range in {
if v == nil {
continue
}
out[k] = v
}
return out
}
// xbake Compose build extension provides fields not (yet) available in
// Compose build specification: https://github.com/compose-spec/compose-spec/blob/master/build.md
type xbake struct {
Tags stringArray `yaml:"tags,omitempty"`
CacheFrom stringArray `yaml:"cache-from,omitempty"`
CacheTo stringArray `yaml:"cache-to,omitempty"`
Secrets stringArray `yaml:"secret,omitempty"`
SSH stringArray `yaml:"ssh,omitempty"`
Platforms stringArray `yaml:"platforms,omitempty"`
Outputs stringArray `yaml:"output,omitempty"`
Pull *bool `yaml:"pull,omitempty"`
NoCache *bool `yaml:"no-cache,omitempty"`
NoCacheFilter stringArray `yaml:"no-cache-filter,omitempty"`
Contexts stringMap `yaml:"contexts,omitempty"`
// don't forget to update documentation if you add a new field:
// docs/manuals/bake/compose-file.md#extension-field-with-x-bake
}
type stringMap map[string]string
type stringArray []string
func (sa *stringArray) UnmarshalYAML(unmarshal func(interface{}) error) error {
var multi []string
err := unmarshal(&multi)
if err != nil {
var single string
if err := unmarshal(&single); err != nil {
return err
}
*sa = strings.Fields(single)
} else {
*sa = multi
}
return nil
}
// composeExtTarget converts Compose build extension x-bake to bake Target
// https://github.com/compose-spec/compose-spec/blob/master/spec.md#extension
func (t *Target) composeExtTarget(exts map[string]interface{}) error {
var xb xbake
ext, ok := exts["x-bake"]
if !ok || ext == nil {
return nil
}
yb, _ := yaml.Marshal(ext)
if err := yaml.Unmarshal(yb, &xb); err != nil {
return err
}
if len(xb.Tags) > 0 {
t.Tags = dedupSlice(append(t.Tags, xb.Tags...))
}
if len(xb.CacheFrom) > 0 {
t.CacheFrom = dedupSlice(append(t.CacheFrom, xb.CacheFrom...))
}
if len(xb.CacheTo) > 0 {
t.CacheTo = dedupSlice(append(t.CacheTo, xb.CacheTo...))
}
if len(xb.Secrets) > 0 {
t.Secrets = dedupSlice(append(t.Secrets, xb.Secrets...))
}
if len(xb.SSH) > 0 {
t.SSH = dedupSlice(append(t.SSH, xb.SSH...))
}
if len(xb.Platforms) > 0 {
t.Platforms = dedupSlice(append(t.Platforms, xb.Platforms...))
}
if len(xb.Outputs) > 0 {
t.Outputs = dedupSlice(append(t.Outputs, xb.Outputs...))
}
if xb.Pull != nil {
t.Pull = xb.Pull
}
if xb.NoCache != nil {
t.NoCache = xb.NoCache
}
if len(xb.NoCacheFilter) > 0 {
t.NoCacheFilter = dedupSlice(append(t.NoCacheFilter, xb.NoCacheFilter...))
}
if len(xb.Contexts) > 0 {
t.Contexts = dedupMap(t.Contexts, xb.Contexts)
}
return nil
}
// composeToBuildkitSecret converts secret from compose format to buildkit's
// csv format.
func composeToBuildkitSecret(inp compose.ServiceSecretConfig, psecret compose.SecretConfig) (string, error) {
if psecret.External.External {
return "", errors.Errorf("unsupported external secret %s", psecret.Name)
}
var bkattrs []string
if inp.Source != "" {
bkattrs = append(bkattrs, "id="+inp.Source)
}
if psecret.File != "" {
bkattrs = append(bkattrs, "src="+psecret.File)
}
if psecret.Environment != "" {
bkattrs = append(bkattrs, "env="+psecret.Environment)
}
return strings.Join(bkattrs, ","), nil
}

View File

@@ -1,16 +1,18 @@
package bake
import (
"os"
"path/filepath"
"sort"
"testing"
compose "github.com/compose-spec/compose-go/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestParseCompose(t *testing.T) {
var dt = []byte(`
version: "3"
services:
db:
build: ./db
@@ -20,22 +22,640 @@ services:
build:
context: ./dir
dockerfile: Dockerfile-alternate
network:
none
args:
buildno: 123
cache_from:
- type=local,src=path/to/cache
cache_to:
- type=local,dest=path/to/cache
secrets:
- token
- aws
secrets:
token:
environment: ENV_TOKEN
aws:
file: /root/.aws/credentials
`)
c, err := ParseCompose(dt)
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Group))
sort.Strings(c.Group["default"].Targets)
require.Equal(t, []string{"db", "webapp"}, c.Group["default"].Targets)
require.Equal(t, 1, len(c.Groups))
require.Equal(t, "default", c.Groups[0].Name)
sort.Strings(c.Groups[0].Targets)
require.Equal(t, []string{"db", "webapp"}, c.Groups[0].Targets)
require.Equal(t, 2, len(c.Target))
require.Equal(t, "./db", *c.Target["db"].Context)
require.Equal(t, 2, len(c.Targets))
sort.Slice(c.Targets, func(i, j int) bool {
return c.Targets[i].Name < c.Targets[j].Name
})
require.Equal(t, "db", c.Targets[0].Name)
require.Equal(t, "./db", *c.Targets[0].Context)
require.Equal(t, []string{"docker.io/tonistiigi/db"}, c.Targets[0].Tags)
require.Equal(t, "./dir", *c.Target["webapp"].Context)
require.Equal(t, "Dockerfile-alternate", *c.Target["webapp"].Dockerfile)
require.Equal(t, 1, len(c.Target["webapp"].Args))
require.Equal(t, "123", c.Target["webapp"].Args["buildno"])
require.Equal(t, "webapp", c.Targets[1].Name)
require.Equal(t, "./dir", *c.Targets[1].Context)
require.Equal(t, "Dockerfile-alternate", *c.Targets[1].Dockerfile)
require.Equal(t, 1, len(c.Targets[1].Args))
require.Equal(t, ptrstr("123"), c.Targets[1].Args["buildno"])
require.Equal(t, []string{"type=local,src=path/to/cache"}, c.Targets[1].CacheFrom)
require.Equal(t, []string{"type=local,dest=path/to/cache"}, c.Targets[1].CacheTo)
require.Equal(t, "none", *c.Targets[1].NetworkMode)
require.Equal(t, []string{
"id=token,env=ENV_TOKEN",
"id=aws,src=/root/.aws/credentials",
}, c.Targets[1].Secrets)
}
func TestNoBuildOutOfTreeService(t *testing.T) {
var dt = []byte(`
services:
external:
image: "verycooldb:1337"
webapp:
build: ./db
`)
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Groups))
require.Equal(t, 1, len(c.Targets))
}
func TestParseComposeTarget(t *testing.T) {
var dt = []byte(`
services:
db:
build:
context: ./db
target: db
webapp:
build:
context: .
target: webapp
`)
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
require.Equal(t, 2, len(c.Targets))
sort.Slice(c.Targets, func(i, j int) bool {
return c.Targets[i].Name < c.Targets[j].Name
})
require.Equal(t, "db", c.Targets[0].Name)
require.Equal(t, "db", *c.Targets[0].Target)
require.Equal(t, "webapp", c.Targets[1].Name)
require.Equal(t, "webapp", *c.Targets[1].Target)
}
func TestComposeBuildWithoutContext(t *testing.T) {
var dt = []byte(`
services:
db:
build:
target: db
webapp:
build:
context: .
target: webapp
`)
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
require.Equal(t, 2, len(c.Targets))
sort.Slice(c.Targets, func(i, j int) bool {
return c.Targets[i].Name < c.Targets[j].Name
})
require.Equal(t, "db", c.Targets[0].Name)
require.Equal(t, "db", *c.Targets[0].Target)
require.Equal(t, "webapp", c.Targets[1].Name)
require.Equal(t, "webapp", *c.Targets[1].Target)
}
func TestBuildArgEnvCompose(t *testing.T) {
var dt = []byte(`
version: "3.8"
services:
example:
image: example
build:
context: .
dockerfile: Dockerfile
args:
FOO:
BAR: $ZZZ_BAR
BRB: FOO
`)
t.Setenv("FOO", "bar")
t.Setenv("BAR", "foo")
t.Setenv("ZZZ_BAR", "zzz_foo")
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, sliceToMap(os.Environ()))
require.NoError(t, err)
require.Equal(t, ptrstr("bar"), c.Targets[0].Args["FOO"])
require.Equal(t, ptrstr("zzz_foo"), c.Targets[0].Args["BAR"])
require.Equal(t, ptrstr("FOO"), c.Targets[0].Args["BRB"])
}
func TestInconsistentComposeFile(t *testing.T) {
var dt = []byte(`
services:
webapp:
entrypoint: echo 1
`)
_, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.Error(t, err)
}
func TestAdvancedNetwork(t *testing.T) {
var dt = []byte(`
services:
db:
networks:
- example.com
build:
context: ./db
target: db
networks:
example.com:
name: example.com
driver: bridge
ipam:
config:
- subnet: 10.5.0.0/24
ip_range: 10.5.0.0/24
gateway: 10.5.0.254
`)
_, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
}
func TestTags(t *testing.T) {
var dt = []byte(`
services:
example:
image: example
build:
context: .
dockerfile: Dockerfile
tags:
- foo
- bar
`)
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
require.Equal(t, []string{"foo", "bar"}, c.Targets[0].Tags)
}
func TestDependsOnList(t *testing.T) {
var dt = []byte(`
version: "3.8"
services:
example-container:
image: example/fails:latest
build:
context: .
dockerfile: Dockerfile
depends_on:
other-container:
condition: service_healthy
networks:
default:
aliases:
- integration-tests
other-container:
image: example/other:latest
healthcheck:
test: ["CMD", "echo", "success"]
retries: 5
interval: 5s
timeout: 10s
start_period: 5s
networks:
default:
name: test-net
`)
_, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
}
func TestComposeExt(t *testing.T) {
var dt = []byte(`
services:
addon:
image: ct-addon:bar
build:
context: .
dockerfile: ./Dockerfile
cache_from:
- user/app:cache
cache_to:
- user/app:cache
tags:
- ct-addon:baz
args:
CT_ECR: foo
CT_TAG: bar
x-bake:
contexts:
alpine: docker-image://alpine:3.13
tags:
- ct-addon:foo
- ct-addon:alp
platforms:
- linux/amd64
- linux/arm64
cache-from:
- type=local,src=path/to/cache
cache-to:
- type=local,dest=path/to/cache
pull: true
aws:
image: ct-fake-aws:bar
build:
dockerfile: ./aws.Dockerfile
args:
CT_ECR: foo
CT_TAG: bar
x-bake:
secret:
- id=mysecret,src=/local/secret
- id=mysecret2,src=/local/secret2
ssh: default
platforms: linux/arm64
output: type=docker
no-cache: true
`)
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
require.Equal(t, 2, len(c.Targets))
sort.Slice(c.Targets, func(i, j int) bool {
return c.Targets[i].Name < c.Targets[j].Name
})
require.Equal(t, map[string]*string{"CT_ECR": ptrstr("foo"), "CT_TAG": ptrstr("bar")}, c.Targets[0].Args)
require.Equal(t, []string{"ct-addon:baz", "ct-addon:foo", "ct-addon:alp"}, c.Targets[0].Tags)
require.Equal(t, []string{"linux/amd64", "linux/arm64"}, c.Targets[0].Platforms)
require.Equal(t, []string{"user/app:cache", "type=local,src=path/to/cache"}, c.Targets[0].CacheFrom)
require.Equal(t, []string{"user/app:cache", "type=local,dest=path/to/cache"}, c.Targets[0].CacheTo)
require.Equal(t, newBool(true), c.Targets[0].Pull)
require.Equal(t, map[string]string{"alpine": "docker-image://alpine:3.13"}, c.Targets[0].Contexts)
require.Equal(t, []string{"ct-fake-aws:bar"}, c.Targets[1].Tags)
require.Equal(t, []string{"id=mysecret,src=/local/secret", "id=mysecret2,src=/local/secret2"}, c.Targets[1].Secrets)
require.Equal(t, []string{"default"}, c.Targets[1].SSH)
require.Equal(t, []string{"linux/arm64"}, c.Targets[1].Platforms)
require.Equal(t, []string{"type=docker"}, c.Targets[1].Outputs)
require.Equal(t, newBool(true), c.Targets[1].NoCache)
}
func TestComposeExtDedup(t *testing.T) {
var dt = []byte(`
services:
webapp:
image: app:bar
build:
cache_from:
- user/app:cache
cache_to:
- user/app:cache
tags:
- ct-addon:foo
x-bake:
tags:
- ct-addon:foo
- ct-addon:baz
cache-from:
- user/app:cache
- type=local,src=path/to/cache
cache-to:
- type=local,dest=path/to/cache
`)
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, []string{"ct-addon:foo", "ct-addon:baz"}, c.Targets[0].Tags)
require.Equal(t, []string{"user/app:cache", "type=local,src=path/to/cache"}, c.Targets[0].CacheFrom)
require.Equal(t, []string{"user/app:cache", "type=local,dest=path/to/cache"}, c.Targets[0].CacheTo)
}
func TestEnv(t *testing.T) {
envf, err := os.CreateTemp("", "env")
require.NoError(t, err)
defer os.Remove(envf.Name())
_, err = envf.WriteString("FOO=bsdf -csdf\n")
require.NoError(t, err)
var dt = []byte(`
services:
scratch:
build:
context: .
args:
CT_ECR: foo
FOO:
NODE_ENV:
environment:
- NODE_ENV=test
- AWS_ACCESS_KEY_ID=dummy
- AWS_SECRET_ACCESS_KEY=dummy
env_file:
- ` + envf.Name() + `
`)
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
require.Equal(t, map[string]*string{"CT_ECR": ptrstr("foo"), "FOO": ptrstr("bsdf -csdf"), "NODE_ENV": ptrstr("test")}, c.Targets[0].Args)
}
func TestDotEnv(t *testing.T) {
tmpdir := t.TempDir()
err := os.WriteFile(filepath.Join(tmpdir, ".env"), []byte("FOO=bar"), 0644)
require.NoError(t, err)
var dt = []byte(`
services:
scratch:
build:
context: .
args:
FOO:
`)
chdir(t, tmpdir)
c, err := ParseComposeFiles([]File{{
Name: "docker-compose.yml",
Data: dt,
}})
require.NoError(t, err)
require.Equal(t, map[string]*string{"FOO": ptrstr("bar")}, c.Targets[0].Args)
}
func TestPorts(t *testing.T) {
var dt = []byte(`
services:
foo:
build:
context: .
ports:
- 3306:3306
bar:
build:
context: .
ports:
- mode: ingress
target: 3306
published: "3306"
protocol: tcp
`)
_, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
}
func newBool(val bool) *bool {
b := val
return &b
}
func TestServiceName(t *testing.T) {
cases := []struct {
svc string
wantErr bool
}{
{
svc: "a",
wantErr: false,
},
{
svc: "abc",
wantErr: false,
},
{
svc: "a.b",
wantErr: false,
},
{
svc: "_a",
wantErr: false,
},
{
svc: "a_b",
wantErr: false,
},
{
svc: "AbC",
wantErr: false,
},
{
svc: "AbC-0123",
wantErr: false,
},
}
for _, tt := range cases {
tt := tt
t.Run(tt.svc, func(t *testing.T) {
_, err := ParseCompose([]compose.ConfigFile{{Content: []byte(`
services:
` + tt.svc + `:
build:
context: .
`)}}, nil)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateComposeSecret(t *testing.T) {
cases := []struct {
name string
dt []byte
wantErr bool
}{
{
name: "secret set by file",
dt: []byte(`
secrets:
foo:
file: .secret
`),
wantErr: false,
},
{
name: "secret set by environment",
dt: []byte(`
secrets:
foo:
environment: TOKEN
`),
wantErr: false,
},
{
name: "external secret",
dt: []byte(`
secrets:
foo:
external: true
`),
wantErr: false,
},
{
name: "unset secret",
dt: []byte(`
secrets:
foo: {}
`),
wantErr: true,
},
{
name: "undefined secret",
dt: []byte(`
services:
foo:
build:
secrets:
- token
`),
wantErr: true,
},
}
for _, tt := range cases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
_, err := ParseCompose([]compose.ConfigFile{{Content: tt.dt}}, nil)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestValidateComposeFile(t *testing.T) {
cases := []struct {
name string
fn string
dt []byte
isCompose bool
wantErr bool
}{
{
name: "empty service",
fn: "docker-compose.yml",
dt: []byte(`
services:
foo:
`),
isCompose: true,
wantErr: true,
},
{
name: "build",
fn: "docker-compose.yml",
dt: []byte(`
services:
foo:
build: .
`),
isCompose: true,
wantErr: false,
},
{
name: "image",
fn: "docker-compose.yml",
dt: []byte(`
services:
simple:
image: nginx
`),
isCompose: true,
wantErr: false,
},
{
name: "unknown ext",
fn: "docker-compose.foo",
dt: []byte(`
services:
simple:
image: nginx
`),
isCompose: true,
wantErr: false,
},
{
name: "hcl",
fn: "docker-bake.hcl",
dt: []byte(`
target "default" {
dockerfile = "test"
}
`),
isCompose: false,
wantErr: false,
},
}
for _, tt := range cases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
isCompose, err := validateComposeFile(tt.dt, tt.fn)
assert.Equal(t, tt.isCompose, isCompose)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
func TestComposeNullArgs(t *testing.T) {
var dt = []byte(`
services:
scratch:
build:
context: .
args:
FOO: null
bar: "baz"
`)
c, err := ParseCompose([]compose.ConfigFile{{Content: dt}}, nil)
require.NoError(t, err)
require.Equal(t, map[string]*string{"bar": ptrstr("baz")}, c.Targets[0].Args)
}
// chdir changes the current working directory to the named directory,
// and then restore the original working directory at the end of the test.
func chdir(t *testing.T, dir string) {
olddir, err := os.Getwd()
if err != nil {
t.Fatalf("chdir: %v", err)
}
if err := os.Chdir(dir); err != nil {
t.Fatalf("chdir %s: %v", dir, err)
}
t.Cleanup(func() {
if err := os.Chdir(olddir); err != nil {
t.Errorf("chdir to original working directory %s: %v", olddir, err)
os.Exit(1)
}
})
}

View File

@@ -1,11 +1,78 @@
package bake
import "github.com/hashicorp/hcl"
import (
"strings"
func ParseHCL(dt []byte) (*Config, error) {
var c Config
if err := hcl.Unmarshal(dt, &c); err != nil {
return nil, err
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclparse"
"github.com/moby/buildkit/solver/errdefs"
"github.com/moby/buildkit/solver/pb"
)
func ParseHCLFile(dt []byte, fn string) (*hcl.File, bool, error) {
var err error
if strings.HasSuffix(fn, ".json") {
f, diags := hclparse.NewParser().ParseJSON(dt, fn)
if diags.HasErrors() {
err = diags
}
return f, true, err
}
if strings.HasSuffix(fn, ".hcl") {
f, diags := hclparse.NewParser().ParseHCL(dt, fn)
if diags.HasErrors() {
err = diags
}
return f, true, err
}
f, diags := hclparse.NewParser().ParseHCL(dt, fn+".hcl")
if diags.HasErrors() {
f, diags2 := hclparse.NewParser().ParseJSON(dt, fn+".json")
if !diags2.HasErrors() {
return f, true, nil
}
return nil, false, diags
}
return f, true, nil
}
func formatHCLError(err error, files []File) error {
if err == nil {
return nil
}
diags, ok := err.(hcl.Diagnostics)
if !ok {
return err
}
for _, d := range diags {
if d.Severity != hcl.DiagError {
continue
}
if d.Subject != nil {
var dt []byte
for _, f := range files {
if d.Subject.Filename == f.Name {
dt = f.Data
break
}
}
src := errdefs.Source{
Info: &pb.SourceInfo{
Filename: d.Subject.Filename,
Data: dt,
},
Ranges: []*pb.Range{toErrRange(d.Subject)},
}
err = errdefs.WithSource(err, src)
break
}
}
return err
}
func toErrRange(in *hcl.Range) *pb.Range {
return &pb.Range{
Start: pb.Position{Line: int32(in.Start.Line), Character: int32(in.Start.Column)},
End: pb.Position{Line: int32(in.End.Line), Character: int32(in.End.Column)},
}
return &c, nil
}

View File

@@ -1,57 +1,955 @@
package bake
import (
"reflect"
"testing"
"github.com/stretchr/testify/require"
)
func TestParseHCL(t *testing.T) {
var dt = []byte(`
group "default" {
targets = ["db", "webapp"]
}
target "db" {
context = "./db"
tags = ["docker.io/tonistiigi/db"]
}
target "webapp" {
context = "./dir"
dockerfile = "Dockerfile-alternate"
args = {
buildno = "123"
func TestHCLBasic(t *testing.T) {
t.Parallel()
dt := []byte(`
group "default" {
targets = ["db", "webapp"]
}
}
target "cross" {
platforms = [
"linux/amd64",
"linux/arm64"
]
}
target "webapp-plus" {
inherits = ["webapp", "cross"]
args = {
IAMCROSS = "true"
target "db" {
context = "./db"
tags = ["docker.io/tonistiigi/db"]
}
}
`)
c, err := ParseHCL(dt)
target "webapp" {
context = "./dir"
dockerfile = "Dockerfile-alternate"
args = {
buildno = "123"
}
}
target "cross" {
platforms = [
"linux/amd64",
"linux/arm64"
]
}
target "webapp-plus" {
inherits = ["webapp", "cross"]
args = {
IAMCROSS = "true"
}
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Groups))
require.Equal(t, "default", c.Groups[0].Name)
require.Equal(t, []string{"db", "webapp"}, c.Groups[0].Targets)
require.Equal(t, 4, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "db")
require.Equal(t, "./db", *c.Targets[0].Context)
require.Equal(t, c.Targets[1].Name, "webapp")
require.Equal(t, 1, len(c.Targets[1].Args))
require.Equal(t, ptrstr("123"), c.Targets[1].Args["buildno"])
require.Equal(t, c.Targets[2].Name, "cross")
require.Equal(t, 2, len(c.Targets[2].Platforms))
require.Equal(t, []string{"linux/amd64", "linux/arm64"}, c.Targets[2].Platforms)
require.Equal(t, c.Targets[3].Name, "webapp-plus")
require.Equal(t, 1, len(c.Targets[3].Args))
require.Equal(t, map[string]*string{"IAMCROSS": ptrstr("true")}, c.Targets[3].Args)
}
func TestHCLBasicInJSON(t *testing.T) {
dt := []byte(`
{
"group": {
"default": {
"targets": ["db", "webapp"]
}
},
"target": {
"db": {
"context": "./db",
"tags": ["docker.io/tonistiigi/db"]
},
"webapp": {
"context": "./dir",
"dockerfile": "Dockerfile-alternate",
"args": {
"buildno": "123"
}
},
"cross": {
"platforms": [
"linux/amd64",
"linux/arm64"
]
},
"webapp-plus": {
"inherits": ["webapp", "cross"],
"args": {
"IAMCROSS": "true"
}
}
}
}
`)
c, err := ParseFile(dt, "docker-bake.json")
require.NoError(t, err)
require.Equal(t, 1, len(c.Group))
require.Equal(t, []string{"db", "webapp"}, c.Group["default"].Targets)
require.Equal(t, 1, len(c.Groups))
require.Equal(t, "default", c.Groups[0].Name)
require.Equal(t, []string{"db", "webapp"}, c.Groups[0].Targets)
require.Equal(t, 4, len(c.Target))
require.Equal(t, "./db", *c.Target["db"].Context)
require.Equal(t, 4, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "db")
require.Equal(t, "./db", *c.Targets[0].Context)
require.Equal(t, 1, len(c.Target["webapp"].Args))
require.Equal(t, "123", c.Target["webapp"].Args["buildno"])
require.Equal(t, c.Targets[1].Name, "webapp")
require.Equal(t, 1, len(c.Targets[1].Args))
require.Equal(t, ptrstr("123"), c.Targets[1].Args["buildno"])
require.Equal(t, 2, len(c.Target["cross"].Platforms))
require.Equal(t, []string{"linux/amd64", "linux/arm64"}, c.Target["cross"].Platforms)
require.Equal(t, c.Targets[2].Name, "cross")
require.Equal(t, 2, len(c.Targets[2].Platforms))
require.Equal(t, []string{"linux/amd64", "linux/arm64"}, c.Targets[2].Platforms)
require.Equal(t, c.Targets[3].Name, "webapp-plus")
require.Equal(t, 1, len(c.Targets[3].Args))
require.Equal(t, map[string]*string{"IAMCROSS": ptrstr("true")}, c.Targets[3].Args)
}
func TestHCLWithFunctions(t *testing.T) {
dt := []byte(`
group "default" {
targets = ["webapp"]
}
target "webapp" {
args = {
buildno = "${add(123, 1)}"
}
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Groups))
require.Equal(t, "default", c.Groups[0].Name)
require.Equal(t, []string{"webapp"}, c.Groups[0].Targets)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "webapp")
require.Equal(t, ptrstr("124"), c.Targets[0].Args["buildno"])
}
func TestHCLWithUserDefinedFunctions(t *testing.T) {
dt := []byte(`
function "increment" {
params = [number]
result = number + 1
}
group "default" {
targets = ["webapp"]
}
target "webapp" {
args = {
buildno = "${increment(123)}"
}
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Groups))
require.Equal(t, "default", c.Groups[0].Name)
require.Equal(t, []string{"webapp"}, c.Groups[0].Targets)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "webapp")
require.Equal(t, ptrstr("124"), c.Targets[0].Args["buildno"])
}
func TestHCLWithVariables(t *testing.T) {
dt := []byte(`
variable "BUILD_NUMBER" {
default = "123"
}
group "default" {
targets = ["webapp"]
}
target "webapp" {
args = {
buildno = "${BUILD_NUMBER}"
}
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Groups))
require.Equal(t, "default", c.Groups[0].Name)
require.Equal(t, []string{"webapp"}, c.Groups[0].Targets)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "webapp")
require.Equal(t, ptrstr("123"), c.Targets[0].Args["buildno"])
t.Setenv("BUILD_NUMBER", "456")
c, err = ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Groups))
require.Equal(t, "default", c.Groups[0].Name)
require.Equal(t, []string{"webapp"}, c.Groups[0].Targets)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "webapp")
require.Equal(t, ptrstr("456"), c.Targets[0].Args["buildno"])
}
func TestHCLWithVariablesInFunctions(t *testing.T) {
dt := []byte(`
variable "REPO" {
default = "user/repo"
}
function "tag" {
params = [tag]
result = ["${REPO}:${tag}"]
}
target "webapp" {
tags = tag("v1")
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "webapp")
require.Equal(t, []string{"user/repo:v1"}, c.Targets[0].Tags)
t.Setenv("REPO", "docker/buildx")
c, err = ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "webapp")
require.Equal(t, []string{"docker/buildx:v1"}, c.Targets[0].Tags)
}
func TestHCLMultiFileSharedVariables(t *testing.T) {
dt := []byte(`
variable "FOO" {
default = "abc"
}
target "app" {
args = {
v1 = "pre-${FOO}"
}
}
`)
dt2 := []byte(`
target "app" {
args = {
v2 = "${FOO}-post"
}
}
`)
c, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr("pre-abc"), c.Targets[0].Args["v1"])
require.Equal(t, ptrstr("abc-post"), c.Targets[0].Args["v2"])
t.Setenv("FOO", "def")
c, err = ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr("pre-def"), c.Targets[0].Args["v1"])
require.Equal(t, ptrstr("def-post"), c.Targets[0].Args["v2"])
}
func TestHCLVarsWithVars(t *testing.T) {
dt := []byte(`
variable "FOO" {
default = upper("${BASE}def")
}
variable "BAR" {
default = "-${FOO}-"
}
target "app" {
args = {
v1 = "pre-${BAR}"
}
}
`)
dt2 := []byte(`
variable "BASE" {
default = "abc"
}
target "app" {
args = {
v2 = "${FOO}-post"
}
}
`)
c, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr("pre--ABCDEF-"), c.Targets[0].Args["v1"])
require.Equal(t, ptrstr("ABCDEF-post"), c.Targets[0].Args["v2"])
t.Setenv("BASE", "new")
c, err = ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr("pre--NEWDEF-"), c.Targets[0].Args["v1"])
require.Equal(t, ptrstr("NEWDEF-post"), c.Targets[0].Args["v2"])
}
func TestHCLTypedVariables(t *testing.T) {
dt := []byte(`
variable "FOO" {
default = 3
}
variable "IS_FOO" {
default = true
}
target "app" {
args = {
v1 = FOO > 5 ? "higher" : "lower"
v2 = IS_FOO ? "yes" : "no"
}
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr("lower"), c.Targets[0].Args["v1"])
require.Equal(t, ptrstr("yes"), c.Targets[0].Args["v2"])
t.Setenv("FOO", "5.1")
t.Setenv("IS_FOO", "0")
c, err = ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr("higher"), c.Targets[0].Args["v1"])
require.Equal(t, ptrstr("no"), c.Targets[0].Args["v2"])
t.Setenv("FOO", "NaN")
_, err = ParseFile(dt, "docker-bake.hcl")
require.Error(t, err)
require.Contains(t, err.Error(), "failed to parse FOO as number")
t.Setenv("FOO", "0")
t.Setenv("IS_FOO", "maybe")
_, err = ParseFile(dt, "docker-bake.hcl")
require.Error(t, err)
require.Contains(t, err.Error(), "failed to parse IS_FOO as bool")
}
func TestHCLNullVariables(t *testing.T) {
dt := []byte(`
variable "FOO" {
default = null
}
target "default" {
args = {
foo = FOO
}
}`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, ptrstr(nil), c.Targets[0].Args["foo"])
t.Setenv("FOO", "bar")
c, err = ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, ptrstr("bar"), c.Targets[0].Args["foo"])
}
func TestJSONNullVariables(t *testing.T) {
dt := []byte(`{
"variable": {
"FOO": {
"default": null
}
},
"target": {
"default": {
"args": {
"foo": "${FOO}"
}
}
}
}`)
c, err := ParseFile(dt, "docker-bake.json")
require.NoError(t, err)
require.Equal(t, ptrstr(nil), c.Targets[0].Args["foo"])
t.Setenv("FOO", "bar")
c, err = ParseFile(dt, "docker-bake.json")
require.NoError(t, err)
require.Equal(t, ptrstr("bar"), c.Targets[0].Args["foo"])
}
func TestHCLVariableCycle(t *testing.T) {
dt := []byte(`
variable "FOO" {
default = BAR
}
variable "FOO2" {
default = FOO
}
variable "BAR" {
default = FOO
}
target "app" {}
`)
_, err := ParseFile(dt, "docker-bake.hcl")
require.Error(t, err)
require.Contains(t, err.Error(), "variable cycle not allowed")
}
func TestHCLAttrs(t *testing.T) {
dt := []byte(`
FOO="abc"
BAR="attr-${FOO}def"
target "app" {
args = {
"v1": BAR
}
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr("attr-abcdef"), c.Targets[0].Args["v1"])
// env does not apply if no variable
t.Setenv("FOO", "bar")
c, err = ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr("attr-abcdef"), c.Targets[0].Args["v1"])
// attr-multifile
}
func TestHCLTargetAttrs(t *testing.T) {
dt := []byte(`
target "foo" {
dockerfile = "xxx"
context = target.bar.context
target = target.foo.dockerfile
}
target "bar" {
dockerfile = target.foo.dockerfile
context = "yyy"
target = target.bar.context
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 2, len(c.Targets))
require.Equal(t, "foo", c.Targets[0].Name)
require.Equal(t, "bar", c.Targets[1].Name)
require.Equal(t, "xxx", *c.Targets[0].Dockerfile)
require.Equal(t, "yyy", *c.Targets[0].Context)
require.Equal(t, "xxx", *c.Targets[0].Target)
require.Equal(t, "xxx", *c.Targets[1].Dockerfile)
require.Equal(t, "yyy", *c.Targets[1].Context)
require.Equal(t, "yyy", *c.Targets[1].Target)
}
func TestHCLTargetGlobal(t *testing.T) {
dt := []byte(`
target "foo" {
dockerfile = "x"
}
x = target.foo.dockerfile
y = x
target "bar" {
dockerfile = y
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 2, len(c.Targets))
require.Equal(t, "foo", c.Targets[0].Name)
require.Equal(t, "bar", c.Targets[1].Name)
require.Equal(t, "x", *c.Targets[0].Dockerfile)
require.Equal(t, "x", *c.Targets[1].Dockerfile)
}
func TestHCLTargetAttrName(t *testing.T) {
dt := []byte(`
target "foo" {
dockerfile = target.foo.name
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, "foo", c.Targets[0].Name)
require.Equal(t, "foo", *c.Targets[0].Dockerfile)
}
func TestHCLTargetAttrEmptyChain(t *testing.T) {
dt := []byte(`
target "foo" {
# dockerfile = Dockerfile
context = target.foo.dockerfile
target = target.foo.context
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, "foo", c.Targets[0].Name)
require.Nil(t, c.Targets[0].Dockerfile)
require.Nil(t, c.Targets[0].Context)
require.Nil(t, c.Targets[0].Target)
}
func TestHCLAttrsCustomType(t *testing.T) {
dt := []byte(`
platforms=["linux/arm64", "linux/amd64"]
target "app" {
platforms = platforms
args = {
"v1": platforms[0]
}
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, []string{"linux/arm64", "linux/amd64"}, c.Targets[0].Platforms)
require.Equal(t, ptrstr("linux/arm64"), c.Targets[0].Args["v1"])
}
func TestHCLMultiFileAttrs(t *testing.T) {
dt := []byte(`
variable "FOO" {
default = "abc"
}
target "app" {
args = {
v1 = "pre-${FOO}"
}
}
`)
dt2 := []byte(`
FOO="def"
`)
c, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr("pre-def"), c.Targets[0].Args["v1"])
t.Setenv("FOO", "ghi")
c, err = ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.hcl"},
}, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr("pre-ghi"), c.Targets[0].Args["v1"])
}
func TestJSONAttributes(t *testing.T) {
dt := []byte(`{"FOO": "abc", "variable": {"BAR": {"default": "def"}}, "target": { "app": { "args": {"v1": "pre-${FOO}-${BAR}"}} } }`)
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("pre-abc-def"), c.Targets[0].Args["v1"])
}
func TestJSONFunctions(t *testing.T) {
dt := []byte(`{
"FOO": "abc",
"function": {
"myfunc": {
"params": ["inp"],
"result": "<${upper(inp)}-${FOO}>"
}
},
"target": {
"app": {
"args": {
"v1": "pre-${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("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" {
params = [inp]
result = "[${inp}]"
}
function "myupper" {
params = [val]
result = "${upper(val)} <> ${brace(v2)}"
}
v1=myupper("foo")
v2=lower("BAZ")
target "app" {
args = {
"v1": v1
}
}
`)
c, err := ParseFile(dt, "docker-bake.hcl")
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr("FOO <> [baz]"), c.Targets[0].Args["v1"])
}
func TestHCLCombineCompose(t *testing.T) {
dt := []byte(`
target "app" {
context = "dir"
args = {
v1 = "foo"
}
}
`)
dt2 := []byte(`
version: "3"
services:
app:
build:
dockerfile: Dockerfile-alternate
args:
v2: "bar"
`)
c, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
{Data: dt2, Name: "c2.yml"},
}, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, ptrstr("foo"), c.Targets[0].Args["v1"])
require.Equal(t, ptrstr("bar"), c.Targets[0].Args["v2"])
require.Equal(t, "dir", *c.Targets[0].Context)
require.Equal(t, "Dockerfile-alternate", *c.Targets[0].Dockerfile)
}
func TestHCLBuiltinVars(t *testing.T) {
dt := []byte(`
target "app" {
context = BAKE_CMD_CONTEXT
dockerfile = "test"
}
`)
c, err := ParseFiles([]File{
{Data: dt, Name: "c1.hcl"},
}, map[string]string{
"BAKE_CMD_CONTEXT": "foo",
})
require.NoError(t, err)
require.Equal(t, 1, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "app")
require.Equal(t, "foo", *c.Targets[0].Context)
require.Equal(t, "test", *c.Targets[0].Dockerfile)
}
func TestCombineHCLAndJSONTargets(t *testing.T) {
c, err := ParseFiles([]File{
{
Name: "docker-bake.hcl",
Data: []byte(`
group "default" {
targets = ["a"]
}
target "metadata-a" {}
target "metadata-b" {}
target "a" {
inherits = ["metadata-a"]
context = "."
target = "a"
}
target "b" {
inherits = ["metadata-b"]
context = "."
target = "b"
}`),
},
{
Name: "metadata-a.json",
Data: []byte(`
{
"target": [{
"metadata-a": [{
"tags": [
"app/a:1.0.0",
"app/a:latest"
]
}]
}]
}`),
},
{
Name: "metadata-b.json",
Data: []byte(`
{
"target": [{
"metadata-b": [{
"tags": [
"app/b:1.0.0",
"app/b:latest"
]
}]
}]
}`),
},
}, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Groups))
require.Equal(t, "default", c.Groups[0].Name)
require.Equal(t, []string{"a"}, c.Groups[0].Targets)
require.Equal(t, 4, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "metadata-a")
require.Equal(t, []string{"app/a:1.0.0", "app/a:latest"}, c.Targets[0].Tags)
require.Equal(t, c.Targets[1].Name, "metadata-b")
require.Equal(t, []string{"app/b:1.0.0", "app/b:latest"}, c.Targets[1].Tags)
require.Equal(t, c.Targets[2].Name, "a")
require.Equal(t, ".", *c.Targets[2].Context)
require.Equal(t, "a", *c.Targets[2].Target)
require.Equal(t, c.Targets[3].Name, "b")
require.Equal(t, ".", *c.Targets[3].Context)
require.Equal(t, "b", *c.Targets[3].Target)
}
func TestCombineHCLAndJSONVars(t *testing.T) {
c, err := ParseFiles([]File{
{
Name: "docker-bake.hcl",
Data: []byte(`
variable "ABC" {
default = "foo"
}
variable "DEF" {
default = ""
}
group "default" {
targets = ["one"]
}
target "one" {
args = {
a = "pre-${ABC}"
}
}
target "two" {
args = {
b = "pre-${DEF}"
}
}`),
},
{
Name: "foo.json",
Data: []byte(`{"variable": {"DEF": {"default": "bar"}}, "target": { "one": { "args": {"a": "pre-${ABC}-${DEF}"}} } }`),
},
{
Name: "bar.json",
Data: []byte(`{"ABC": "ghi", "DEF": "jkl"}`),
},
}, nil)
require.NoError(t, err)
require.Equal(t, 1, len(c.Groups))
require.Equal(t, "default", c.Groups[0].Name)
require.Equal(t, []string{"one"}, c.Groups[0].Targets)
require.Equal(t, 2, len(c.Targets))
require.Equal(t, c.Targets[0].Name, "one")
require.Equal(t, map[string]*string{"a": ptrstr("pre-ghi-jkl")}, c.Targets[0].Args)
require.Equal(t, c.Targets[1].Name, "two")
require.Equal(t, map[string]*string{"b": ptrstr("pre-jkl")}, c.Targets[1].Args)
}
func TestEmptyVariableJSON(t *testing.T) {
dt := []byte(`{
"variable": {
"VAR": {}
}
}`)
_, err := ParseFile(dt, "docker-bake.json")
require.NoError(t, err)
}
func TestFunctionNoParams(t *testing.T) {
dt := []byte(`
function "foo" {
result = "bar"
}
target "foo_target" {
args = {
test = foo()
}
}
`)
_, err := ParseFile(dt, "docker-bake.hcl")
require.Error(t, err)
}
func TestFunctionNoResult(t *testing.T) {
dt := []byte(`
function "foo" {
params = ["a"]
}
`)
_, err := ParseFile(dt, "docker-bake.hcl")
require.Error(t, err)
}
func TestVarUnsupportedType(t *testing.T) {
dt := []byte(`
variable "FOO" {
default = []
}
target "default" {}`)
t.Setenv("FOO", "bar")
_, err := ParseFile(dt, "docker-bake.hcl")
require.Error(t, err)
}
func ptrstr(s interface{}) *string {
var n *string = nil
if reflect.ValueOf(s).Kind() == reflect.String {
ss := s.(string)
n = &ss
}
return n
}

103
bake/hclparser/body.go Normal file
View File

@@ -0,0 +1,103 @@
package hclparser
import (
"github.com/hashicorp/hcl/v2"
)
type filterBody struct {
body hcl.Body
schema *hcl.BodySchema
exclude bool
}
func FilterIncludeBody(body hcl.Body, schema *hcl.BodySchema) hcl.Body {
return &filterBody{
body: body,
schema: schema,
}
}
func FilterExcludeBody(body hcl.Body, schema *hcl.BodySchema) hcl.Body {
return &filterBody{
body: body,
schema: schema,
exclude: true,
}
}
func (b *filterBody) Content(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Diagnostics) {
if b.exclude {
schema = subtractSchemas(schema, b.schema)
} else {
schema = intersectSchemas(schema, b.schema)
}
content, _, diag := b.body.PartialContent(schema)
return content, diag
}
func (b *filterBody) PartialContent(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Body, hcl.Diagnostics) {
if b.exclude {
schema = subtractSchemas(schema, b.schema)
} else {
schema = intersectSchemas(schema, b.schema)
}
return b.body.PartialContent(schema)
}
func (b *filterBody) JustAttributes() (hcl.Attributes, hcl.Diagnostics) {
return b.body.JustAttributes()
}
func (b *filterBody) MissingItemRange() hcl.Range {
return b.body.MissingItemRange()
}
func intersectSchemas(a, b *hcl.BodySchema) *hcl.BodySchema {
result := &hcl.BodySchema{}
for _, blockA := range a.Blocks {
for _, blockB := range b.Blocks {
if blockA.Type == blockB.Type {
result.Blocks = append(result.Blocks, blockA)
break
}
}
}
for _, attrA := range a.Attributes {
for _, attrB := range b.Attributes {
if attrA.Name == attrB.Name {
result.Attributes = append(result.Attributes, attrA)
break
}
}
}
return result
}
func subtractSchemas(a, b *hcl.BodySchema) *hcl.BodySchema {
result := &hcl.BodySchema{}
for _, blockA := range a.Blocks {
found := false
for _, blockB := range b.Blocks {
if blockA.Type == blockB.Type {
found = true
break
}
}
if !found {
result.Blocks = append(result.Blocks, blockA)
}
}
for _, attrA := range a.Attributes {
found := false
for _, attrB := range b.Attributes {
if attrA.Name == attrB.Name {
found = true
break
}
}
if !found {
result.Attributes = append(result.Attributes, attrA)
}
}
return result
}

145
bake/hclparser/expr.go Normal file
View File

@@ -0,0 +1,145 @@
package hclparser
import (
"reflect"
"unsafe"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/pkg/errors"
)
func funcCalls(exp hcl.Expression) ([]string, hcl.Diagnostics) {
node, ok := exp.(hclsyntax.Node)
if !ok {
fns, err := jsonFuncCallsRecursive(exp)
if err != nil {
return nil, wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
}
return fns, nil
}
var funcnames []string
hcldiags := hclsyntax.VisitAll(node, func(n hclsyntax.Node) hcl.Diagnostics {
if fe, ok := n.(*hclsyntax.FunctionCallExpr); ok {
funcnames = append(funcnames, fe.Name)
}
return nil
})
if hcldiags.HasErrors() {
return nil, hcldiags
}
return funcnames, nil
}
func jsonFuncCallsRecursive(exp hcl.Expression) ([]string, error) {
je, ok := exp.(jsonExp)
if !ok {
return nil, errors.Errorf("invalid expression type %T", exp)
}
m := map[string]struct{}{}
for _, e := range elementExpressions(je, exp) {
if err := appendJSONFuncCalls(e, m); err != nil {
return nil, err
}
}
arr := make([]string, 0, len(m))
for n := range m {
arr = append(arr, n)
}
return arr, nil
}
func appendJSONFuncCalls(exp hcl.Expression, m map[string]struct{}) error {
v := reflect.ValueOf(exp)
if v.Kind() != reflect.Ptr || v.IsNil() {
return errors.Errorf("invalid json expression kind %T %v", exp, v.Kind())
}
src := v.Elem().FieldByName("src")
if src.IsZero() {
return errors.Errorf("%v has no property src", v.Elem().Type())
}
if src.Kind() != reflect.Interface {
return errors.Errorf("%v src is not interface: %v", src.Type(), src.Kind())
}
src = src.Elem()
if src.IsNil() {
return nil
}
if src.Kind() == reflect.Ptr {
src = src.Elem()
}
if src.Kind() != reflect.Struct {
return errors.Errorf("%v is not struct: %v", src.Type(), src.Kind())
}
// hcl/v2/json/ast#stringVal
val := src.FieldByName("Value")
if !val.IsValid() || val.IsZero() {
return nil
}
rng := src.FieldByName("SrcRange")
if rng.IsZero() {
return nil
}
var stringVal struct {
Value string
SrcRange hcl.Range
}
if !val.Type().AssignableTo(reflect.ValueOf(stringVal.Value).Type()) {
return nil
}
if !rng.Type().AssignableTo(reflect.ValueOf(stringVal.SrcRange).Type()) {
return nil
}
// reflect.Set does not work for unexported fields
stringVal.Value = *(*string)(unsafe.Pointer(val.UnsafeAddr()))
stringVal.SrcRange = *(*hcl.Range)(unsafe.Pointer(rng.UnsafeAddr()))
expr, diags := hclsyntax.ParseExpression([]byte(stringVal.Value), stringVal.SrcRange.Filename, stringVal.SrcRange.Start)
if diags.HasErrors() {
return nil
}
fns, err := funcCalls(expr)
if err != nil {
return err
}
for _, fn := range fns {
m[fn] = struct{}{}
}
return nil
}
type jsonExp interface {
ExprList() []hcl.Expression
ExprMap() []hcl.KeyValuePair
}
func elementExpressions(je jsonExp, exp hcl.Expression) []hcl.Expression {
list := je.ExprList()
if len(list) != 0 {
exp := make([]hcl.Expression, 0, len(list))
for _, e := range list {
if je, ok := e.(jsonExp); ok {
exp = append(exp, elementExpressions(je, e)...)
}
}
return exp
}
kvlist := je.ExprMap()
if len(kvlist) != 0 {
exp := make([]hcl.Expression, 0, len(kvlist)*2)
for _, p := range kvlist {
exp = append(exp, p.Key)
if je, ok := p.Value.(jsonExp); ok {
exp = append(exp, elementExpressions(je, p.Value)...)
}
}
return exp
}
return []hcl.Expression{exp}
}

755
bake/hclparser/hclparser.go Normal file
View File

@@ -0,0 +1,755 @@
package hclparser
import (
"fmt"
"math"
"math/big"
"reflect"
"strconv"
"strings"
"github.com/docker/buildx/util/userfunc"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/gohcl"
"github.com/pkg/errors"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/gocty"
)
type Opt struct {
LookupVar func(string) (string, bool)
Vars map[string]string
ValidateLabel func(string) error
}
type variable struct {
Name string `json:"-" hcl:"name,label"`
Default *hcl.Attribute `json:"default,omitempty" hcl:"default,optional"`
Body hcl.Body `json:"-" hcl:",body"`
}
type functionDef struct {
Name string `json:"-" hcl:"name,label"`
Params *hcl.Attribute `json:"params,omitempty" hcl:"params"`
Variadic *hcl.Attribute `json:"variadic_param,omitempty" hcl:"variadic_params"`
Result *hcl.Attribute `json:"result,omitempty" hcl:"result"`
}
type inputs struct {
Variables []*variable `hcl:"variable,block"`
Functions []*functionDef `hcl:"function,block"`
Remain hcl.Body `json:"-" hcl:",remain"`
}
type parser struct {
opt Opt
vars map[string]*variable
attrs map[string]*hcl.Attribute
funcs map[string]*functionDef
blocks map[string]map[string][]*hcl.Block
blockValues map[*hcl.Block]reflect.Value
blockTypes map[string]reflect.Type
ectx *hcl.EvalContext
progress map[string]struct{}
progressF map[string]struct{}
progressB map[*hcl.Block]map[string]struct{}
doneF map[string]struct{}
doneB map[*hcl.Block]map[string]struct{}
}
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
}
for _, fn := range fns {
if err := p.resolveFunction(fn); err != nil {
if allowMissing && errors.Is(err, errUndefined) {
continue
}
return wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
}
}
for _, v := range exp.Variables() {
if _, ok := exclude[v.RootName()]; ok {
continue
}
if _, ok := p.blockTypes[v.RootName()]; ok {
blockType := v.RootName()
split := v.SimpleSplit().Rel
if len(split) == 0 {
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid expression",
Detail: fmt.Sprintf("cannot access %s as a variable", blockType),
Subject: exp.Range().Ptr(),
Context: exp.Range().Ptr(),
},
}
}
blockName, ok := split[0].(hcl.TraverseAttr)
if !ok {
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid expression",
Detail: fmt.Sprintf("cannot traverse %s without attribute", blockType),
Subject: exp.Range().Ptr(),
Context: exp.Range().Ptr(),
},
}
}
blocks := p.blocks[blockType][blockName.Name]
if len(blocks) == 0 {
continue
}
var target *hcl.BodySchema
if len(split) > 1 {
if attr, ok := split[1].(hcl.TraverseAttr); ok {
target = &hcl.BodySchema{
Attributes: []hcl.AttributeSchema{{Name: attr.Name}},
Blocks: []hcl.BlockHeaderSchema{{Type: attr.Name}},
}
}
}
if err := p.resolveBlock(blocks[0], target); err != nil {
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 {
if allowMissing && errors.Is(err, errUndefined) {
continue
}
return wrapErrorDiagnostic("Invalid expression", err, exp.Range().Ptr(), exp.Range().Ptr())
}
}
}
return nil
}
// resolveFunction forces evaluation of a function, storing the result into the
// parser.
func (p *parser) resolveFunction(name string) error {
if _, ok := p.doneF[name]; ok {
return nil
}
f, ok := p.funcs[name]
if !ok {
if _, ok := p.ectx.Functions[name]; ok {
return nil
}
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)
}
p.progressF[name] = struct{}{}
if f.Result == nil {
return errors.Errorf("empty result not allowed for %s", name)
}
if f.Params == nil {
return errors.Errorf("empty params not allowed for %s", name)
}
paramExprs, paramsDiags := hcl.ExprList(f.Params.Expr)
if paramsDiags.HasErrors() {
return paramsDiags
}
var diags hcl.Diagnostics
params := map[string]struct{}{}
for _, paramExpr := range paramExprs {
param := hcl.ExprAsKeyword(paramExpr)
if param == "" {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid param element",
Detail: "Each parameter name must be an identifier.",
Subject: paramExpr.Range().Ptr(),
})
}
params[param] = struct{}{}
}
var variadic hcl.Expression
if f.Variadic != nil {
variadic = f.Variadic.Expr
param := hcl.ExprAsKeyword(variadic)
if param == "" {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid param element",
Detail: "Each parameter name must be an identifier.",
Subject: f.Variadic.Range.Ptr(),
})
}
params[param] = struct{}{}
}
if diags.HasErrors() {
return diags
}
if diags := p.loadDeps(f.Result.Expr, params, false); diags.HasErrors() {
return diags
}
v, diags := userfunc.NewFunction(f.Params.Expr, variadic, f.Result.Expr, func() *hcl.EvalContext {
return p.ectx
})
if diags.HasErrors() {
return diags
}
p.doneF[name] = struct{}{}
p.ectx.Functions[name] = v
return nil
}
// resolveValue forces evaluation of a named value, storing the result into the
// parser.
func (p *parser) resolveValue(name string) (err error) {
if _, ok := p.ectx.Variables[name]; ok {
return nil
}
if _, ok := p.progress[name]; ok {
return errors.Errorf("variable cycle not allowed for %s", name)
}
p.progress[name] = struct{}{}
var v *cty.Value
defer func() {
if v != nil {
p.ectx.Variables[name] = *v
}
}()
def, ok := p.attrs[name]
if _, builtin := p.opt.Vars[name]; !ok && !builtin {
vr, ok := p.vars[name]
if !ok {
return errors.Wrapf(errUndefined, "variable %q does not exit", name)
}
def = vr.Default
}
if def == nil {
val, ok := p.opt.Vars[name]
if !ok {
val, _ = p.opt.LookupVar(name)
}
vv := cty.StringVal(val)
v = &vv
return
}
if diags := p.loadDeps(def.Expr, nil, true); diags.HasErrors() {
return diags
}
vv, diags := def.Expr.Value(p.ectx)
if diags.HasErrors() {
return diags
}
_, isVar := p.vars[name]
if envv, ok := p.opt.LookupVar(name); ok && isVar {
switch {
case vv.Type().Equals(cty.Bool):
b, err := strconv.ParseBool(envv)
if err != nil {
return errors.Wrapf(err, "failed to parse %s as bool", name)
}
vv = cty.BoolVal(b)
case vv.Type().Equals(cty.String), vv.Type().Equals(cty.DynamicPseudoType):
vv = cty.StringVal(envv)
case vv.Type().Equals(cty.Number):
n, err := strconv.ParseFloat(envv, 64)
if err == nil && (math.IsNaN(n) || math.IsInf(n, 0)) {
err = errors.Errorf("invalid number value")
}
if err != nil {
return errors.Wrapf(err, "failed to parse %s as number", name)
}
vv = cty.NumberVal(big.NewFloat(n))
default:
// TODO: support lists with csv values
return errors.Errorf("unsupported type %s for variable %s", vv.Type().FriendlyName(), name)
}
}
v = &vv
return nil
}
// resolveBlock force evaluates a block, storing the result in the parser. If a
// target schema is provided, only the attributes and blocks present in the
// schema will be evaluated.
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 wrapErrorDiagnostic("Invalid name", err, &block.LabelRanges[0], &block.LabelRanges[0])
}
if _, ok := p.doneB[block]; !ok {
p.doneB[block] = map[string]struct{}{}
}
if _, ok := p.progressB[block]; !ok {
p.progressB[block] = map[string]struct{}{}
}
if target != nil {
// filter out attributes and blocks that are already evaluated
original := target
target = &hcl.BodySchema{}
for _, a := range original.Attributes {
if _, ok := p.doneB[block][a.Name]; !ok {
target.Attributes = append(target.Attributes, a)
}
}
for _, b := range original.Blocks {
if _, ok := p.doneB[block][b.Type]; !ok {
target.Blocks = append(target.Blocks, b)
}
}
if len(target.Attributes) == 0 && len(target.Blocks) == 0 {
return nil
}
}
if target != nil {
// detect reference cycles
for _, a := range target.Attributes {
if _, ok := p.progressB[block][a.Name]; ok {
return errors.Errorf("reference cycle not allowed for %s.%s.%s", block.Type, name, a.Name)
}
}
for _, b := range target.Blocks {
if _, ok := p.progressB[block][b.Type]; ok {
return errors.Errorf("reference cycle not allowed for %s.%s.%s", block.Type, name, b.Type)
}
}
for _, a := range target.Attributes {
p.progressB[block][a.Name] = struct{}{}
}
for _, b := range target.Blocks {
p.progressB[block][b.Type] = struct{}{}
}
}
// create a filtered body that contains only the target properties
body := func() hcl.Body {
if target != nil {
return FilterIncludeBody(block.Body, target)
}
filter := &hcl.BodySchema{}
for k := range p.doneB[block] {
filter.Attributes = append(filter.Attributes, hcl.AttributeSchema{Name: k})
filter.Blocks = append(filter.Blocks, hcl.BlockHeaderSchema{Type: k})
}
return FilterExcludeBody(block.Body, filter)
}
// load dependencies from all targeted properties
t, ok := p.blockTypes[block.Type]
if !ok {
return nil
}
schema, _ := gohcl.ImpliedBodySchema(reflect.New(t).Interface())
content, _, diag := body().PartialContent(schema)
if diag.HasErrors() {
return diag
}
for _, a := range content.Attributes {
diag := p.loadDeps(a.Expr, nil, true)
if diag.HasErrors() {
return diag
}
}
for _, b := range content.Blocks {
err := p.resolveBlock(b, nil)
if err != nil {
return err
}
}
// decode!
var output reflect.Value
if prev, ok := p.blockValues[block]; ok {
output = prev
} else {
output = reflect.New(t)
setLabel(output, block.Labels[0]) // early attach labels, so we can reference them
}
diag = gohcl.DecodeBody(body(), p.ectx, output.Interface())
if diag.HasErrors() {
return diag
}
p.blockValues[block] = output
// mark all targeted properties as done
for _, a := range content.Attributes {
p.doneB[block][a.Name] = struct{}{}
}
for _, b := range content.Blocks {
p.doneB[block][b.Type] = struct{}{}
}
if target != nil {
for _, a := range target.Attributes {
p.doneB[block][a.Name] = struct{}{}
}
for _, b := range target.Blocks {
p.doneB[block][b.Type] = struct{}{}
}
}
// store the result into the evaluation context (so if can be referenced)
outputType, err := gocty.ImpliedType(output.Interface())
if err != nil {
return err
}
outputValue, err := gocty.ToCtyValue(output.Interface(), outputType)
if err != nil {
return err
}
var m map[string]cty.Value
if m2, ok := p.ectx.Variables[block.Type]; ok {
m = m2.AsValueMap()
}
if m == nil {
m = map[string]cty.Value{}
}
m[name] = outputValue
p.ectx.Variables[block.Type] = cty.MapVal(m)
return nil
}
func Parse(b hcl.Body, opt Opt, val interface{}) hcl.Diagnostics {
reserved := map[string]struct{}{}
schema, _ := gohcl.ImpliedBodySchema(val)
for _, bs := range schema.Blocks {
reserved[bs.Type] = struct{}{}
}
for k := range opt.Vars {
reserved[k] = struct{}{}
}
var defs inputs
if err := gohcl.DecodeBody(b, nil, &defs); err != nil {
return err
}
defsSchema, _ := gohcl.ImpliedBodySchema(defs)
if opt.LookupVar == nil {
opt.LookupVar = func(string) (string, bool) {
return "", false
}
}
if opt.ValidateLabel == nil {
opt.ValidateLabel = func(string) error {
return nil
}
}
p := &parser{
opt: opt,
vars: map[string]*variable{},
attrs: map[string]*hcl.Attribute{},
funcs: map[string]*functionDef{},
blocks: map[string]map[string][]*hcl.Block{},
blockValues: map[*hcl.Block]reflect.Value{},
blockTypes: map[string]reflect.Type{},
progress: map[string]struct{}{},
progressF: map[string]struct{}{},
progressB: map[*hcl.Block]map[string]struct{}{},
doneF: map[string]struct{}{},
doneB: map[*hcl.Block]map[string]struct{}{},
ectx: &hcl.EvalContext{
Variables: map[string]cty.Value{},
Functions: stdlibFunctions,
},
}
for _, v := range defs.Variables {
// TODO: validate name
if _, ok := reserved[v.Name]; ok {
continue
}
p.vars[v.Name] = v
}
for _, v := range defs.Functions {
// TODO: validate name
if _, ok := reserved[v.Name]; ok {
continue
}
p.funcs[v.Name] = v
}
content, b, diags := b.PartialContent(schema)
if diags.HasErrors() {
return diags
}
blocks, b, diags := b.PartialContent(defsSchema)
if diags.HasErrors() {
return diags
}
attrs, diags := b.JustAttributes()
if diags.HasErrors() {
if d := removeAttributesDiags(diags, reserved, p.vars); len(d) > 0 {
return d
}
}
for _, v := range attrs {
if _, ok := reserved[v.Name]; ok {
continue
}
p.attrs[v.Name] = v
}
delete(p.attrs, "function")
for k := range p.opt.Vars {
_ = p.resolveValue(k)
}
for _, a := range content.Attributes {
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid attribute",
Detail: "global attributes currently not supported",
Subject: &a.Range,
Context: &a.Range,
},
}
}
for k := range p.vars {
if err := p.resolveValue(k); err != nil {
if diags, ok := err.(hcl.Diagnostics); ok {
return diags
}
r := p.vars[k].Body.MissingItemRange()
return wrapErrorDiagnostic("Invalid value", err, &r, &r)
}
}
for k := range p.funcs {
if err := p.resolveFunction(k); err != nil {
if diags, ok := err.(hcl.Diagnostics); ok {
return diags
}
var subject *hcl.Range
var context *hcl.Range
if p.funcs[k].Params != nil {
subject = &p.funcs[k].Params.Range
context = subject
} else {
for _, block := range blocks.Blocks {
if block.Type == "function" && len(block.Labels) == 1 && block.Labels[0] == k {
subject = &block.LabelRanges[0]
context = &block.DefRange
break
}
}
}
return wrapErrorDiagnostic("Invalid function", err, subject, context)
}
}
for _, b := range content.Blocks {
if len(b.Labels) == 0 || len(b.Labels) > 1 {
return hcl.Diagnostics{
&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid block",
Detail: fmt.Sprintf("invalid block label: %v", b.Labels),
Subject: &b.LabelRanges[0],
Context: &b.LabelRanges[0],
},
}
}
bm, ok := p.blocks[b.Type]
if !ok {
bm = map[string][]*hcl.Block{}
p.blocks[b.Type] = bm
}
lbl := b.Labels[0]
bm[lbl] = append(bm[lbl], b)
}
type value struct {
reflect.Value
idx int
}
type field struct {
idx int
typ reflect.Type
values map[string]value
}
types := map[string]field{}
vt := reflect.ValueOf(val).Elem().Type()
for i := 0; i < vt.NumField(); i++ {
tags := strings.Split(vt.Field(i).Tag.Get("hcl"), ",")
p.blockTypes[tags[0]] = vt.Field(i).Type.Elem().Elem()
types[tags[0]] = field{
idx: i,
typ: vt.Field(i).Type,
values: make(map[string]value),
}
}
diags = hcl.Diagnostics{}
for _, b := range content.Blocks {
v := reflect.ValueOf(val)
err := p.resolveBlock(b, nil)
if err != nil {
if diag, ok := err.(hcl.Diagnostics); ok {
if diag.HasErrors() {
diags = append(diags, diag...)
continue
}
} else {
return wrapErrorDiagnostic("Invalid block", err, &b.LabelRanges[0], &b.DefRange)
}
}
vv := p.blockValues[b]
t := types[b.Type]
lblIndex := setLabel(vv, b.Labels[0])
oldValue, exists := t.values[b.Labels[0]]
if !exists && lblIndex != -1 {
if v.Elem().Field(t.idx).Type().Kind() == reflect.Slice {
for i := 0; i < v.Elem().Field(t.idx).Len(); i++ {
if b.Labels[0] == v.Elem().Field(t.idx).Index(i).Elem().Field(lblIndex).String() {
exists = true
oldValue = value{Value: v.Elem().Field(t.idx).Index(i), idx: i}
break
}
}
}
}
if exists {
if m := oldValue.Value.MethodByName("Merge"); m.IsValid() {
m.Call([]reflect.Value{vv})
} else {
v.Elem().Field(t.idx).Index(oldValue.idx).Set(vv)
}
} else {
slice := v.Elem().Field(t.idx)
if slice.IsNil() {
slice = reflect.New(t.typ).Elem()
}
t.values[b.Labels[0]] = value{Value: vv, idx: slice.Len()}
v.Elem().Field(t.idx).Set(reflect.Append(slice, vv))
}
}
if diags.HasErrors() {
return diags
}
for k := range p.attrs {
if err := p.resolveValue(k); err != nil {
if diags, ok := err.(hcl.Diagnostics); ok {
return diags
}
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()
for i := 0; i < numFields; i++ {
for _, t := range strings.Split(v.Elem().Type().Field(i).Tag.Get("hcl"), ",") {
if t == "label" {
v.Elem().Field(i).Set(reflect.ValueOf(lbl))
return i
}
}
}
return -1
}
func removeAttributesDiags(diags hcl.Diagnostics, reserved map[string]struct{}, vars map[string]*variable) hcl.Diagnostics {
var fdiags hcl.Diagnostics
for _, d := range diags {
if fout := func(d *hcl.Diagnostic) bool {
// https://github.com/docker/buildx/pull/541
if d.Detail == "Blocks are not allowed here." {
return true
}
for r := range reserved {
// JSON body objects don't handle repeated blocks like HCL but
// reserved name attributes should be allowed when multi bodies are merged.
// https://github.com/hashicorp/hcl/blob/main/json/spec.md#blocks
if strings.HasPrefix(d.Detail, fmt.Sprintf(`Argument "%s" was already set at `, r)) {
return true
}
}
for v := range vars {
// Do the same for global variables
if strings.HasPrefix(d.Detail, fmt.Sprintf(`Argument "%s" was already set at `, v)) {
return true
}
}
return false
}(d); !fout {
fdiags = append(fdiags, d)
}
}
return fdiags
}

126
bake/hclparser/stdlib.go Normal file
View File

@@ -0,0 +1,126 @@
package hclparser
import (
"time"
"github.com/hashicorp/go-cty-funcs/cidr"
"github.com/hashicorp/go-cty-funcs/crypto"
"github.com/hashicorp/go-cty-funcs/encoding"
"github.com/hashicorp/go-cty-funcs/uuid"
"github.com/hashicorp/hcl/v2/ext/tryfunc"
"github.com/hashicorp/hcl/v2/ext/typeexpr"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/function"
"github.com/zclconf/go-cty/cty/function/stdlib"
)
var stdlibFunctions = map[string]function.Function{
"absolute": stdlib.AbsoluteFunc,
"add": stdlib.AddFunc,
"and": stdlib.AndFunc,
"base64decode": encoding.Base64DecodeFunc,
"base64encode": encoding.Base64EncodeFunc,
"bcrypt": crypto.BcryptFunc,
"byteslen": stdlib.BytesLenFunc,
"bytesslice": stdlib.BytesSliceFunc,
"can": tryfunc.CanFunc,
"ceil": stdlib.CeilFunc,
"chomp": stdlib.ChompFunc,
"chunklist": stdlib.ChunklistFunc,
"cidrhost": cidr.HostFunc,
"cidrnetmask": cidr.NetmaskFunc,
"cidrsubnet": cidr.SubnetFunc,
"cidrsubnets": cidr.SubnetsFunc,
"csvdecode": stdlib.CSVDecodeFunc,
"coalesce": stdlib.CoalesceFunc,
"coalescelist": stdlib.CoalesceListFunc,
"compact": stdlib.CompactFunc,
"concat": stdlib.ConcatFunc,
"contains": stdlib.ContainsFunc,
"convert": typeexpr.ConvertFunc,
"distinct": stdlib.DistinctFunc,
"divide": stdlib.DivideFunc,
"element": stdlib.ElementFunc,
"equal": stdlib.EqualFunc,
"flatten": stdlib.FlattenFunc,
"floor": stdlib.FloorFunc,
"formatdate": stdlib.FormatDateFunc,
"format": stdlib.FormatFunc,
"formatlist": stdlib.FormatListFunc,
"greaterthan": stdlib.GreaterThanFunc,
"greaterthanorequalto": stdlib.GreaterThanOrEqualToFunc,
"hasindex": stdlib.HasIndexFunc,
"indent": stdlib.IndentFunc,
"index": stdlib.IndexFunc,
"int": stdlib.IntFunc,
"jsondecode": stdlib.JSONDecodeFunc,
"jsonencode": stdlib.JSONEncodeFunc,
"keys": stdlib.KeysFunc,
"join": stdlib.JoinFunc,
"length": stdlib.LengthFunc,
"lessthan": stdlib.LessThanFunc,
"lessthanorequalto": stdlib.LessThanOrEqualToFunc,
"log": stdlib.LogFunc,
"lookup": stdlib.LookupFunc,
"lower": stdlib.LowerFunc,
"max": stdlib.MaxFunc,
"md5": crypto.Md5Func,
"merge": stdlib.MergeFunc,
"min": stdlib.MinFunc,
"modulo": stdlib.ModuloFunc,
"multiply": stdlib.MultiplyFunc,
"negate": stdlib.NegateFunc,
"notequal": stdlib.NotEqualFunc,
"not": stdlib.NotFunc,
"or": stdlib.OrFunc,
"parseint": stdlib.ParseIntFunc,
"pow": stdlib.PowFunc,
"range": stdlib.RangeFunc,
"regexall": stdlib.RegexAllFunc,
"regex": stdlib.RegexFunc,
"regex_replace": stdlib.RegexReplaceFunc,
"reverse": stdlib.ReverseFunc,
"reverselist": stdlib.ReverseListFunc,
"rsadecrypt": crypto.RsaDecryptFunc,
"sethaselement": stdlib.SetHasElementFunc,
"setintersection": stdlib.SetIntersectionFunc,
"setproduct": stdlib.SetProductFunc,
"setsubtract": stdlib.SetSubtractFunc,
"setsymmetricdifference": stdlib.SetSymmetricDifferenceFunc,
"setunion": stdlib.SetUnionFunc,
"sha1": crypto.Sha1Func,
"sha256": crypto.Sha256Func,
"sha512": crypto.Sha512Func,
"signum": stdlib.SignumFunc,
"slice": stdlib.SliceFunc,
"sort": stdlib.SortFunc,
"split": stdlib.SplitFunc,
"strlen": stdlib.StrlenFunc,
"substr": stdlib.SubstrFunc,
"subtract": stdlib.SubtractFunc,
"timeadd": stdlib.TimeAddFunc,
"timestamp": timestampFunc,
"title": stdlib.TitleFunc,
"trim": stdlib.TrimFunc,
"trimprefix": stdlib.TrimPrefixFunc,
"trimspace": stdlib.TrimSpaceFunc,
"trimsuffix": stdlib.TrimSuffixFunc,
"try": tryfunc.TryFunc,
"upper": stdlib.UpperFunc,
"urlencode": encoding.URLEncodeFunc,
"uuidv4": uuid.V4Func,
"uuidv5": uuid.V5Func,
"values": stdlib.ValuesFunc,
"zipmap": stdlib.ZipmapFunc,
}
// timestampFunc constructs a function that returns a string representation of the current date and time.
//
// This function was imported from terraform's datetime utilities.
var timestampFunc = function.New(&function.Spec{
Params: []function.Parameter{},
Type: function.StaticReturnType(cty.String),
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
return cty.StringVal(time.Now().UTC().Format(time.RFC3339)), nil
},
})

237
bake/remote.go Normal file
View File

@@ -0,0 +1,237 @@
package bake
import (
"archive/tar"
"bytes"
"context"
"strings"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/driver"
"github.com/docker/buildx/util/progress"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/client/llb"
gwclient "github.com/moby/buildkit/frontend/gateway/client"
"github.com/pkg/errors"
)
type Input struct {
State *llb.State
URL string
}
func ReadRemoteFiles(ctx context.Context, nodes []builder.Node, url string, names []string, pw progress.Writer) ([]File, *Input, error) {
var filename string
st, ok := detectGitContext(url)
if !ok {
st, filename, ok = detectHTTPContext(url)
if !ok {
return nil, nil, errors.Errorf("not url context")
}
}
inp := &Input{State: st, URL: url}
var files []File
var node *builder.Node
for i, n := range nodes {
if n.Err == nil {
node = &nodes[i]
continue
}
}
if node == nil {
return nil, nil, nil
}
c, err := driver.Boot(ctx, ctx, node.Driver, pw)
if err != nil {
return nil, nil, err
}
ch, done := progress.NewChannel(pw)
defer func() { <-done }()
_, err = c.Build(ctx, client.SolveOpt{}, "buildx", func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
def, err := st.Marshal(ctx)
if err != nil {
return nil, err
}
res, err := c.Solve(ctx, gwclient.SolveRequest{
Definition: def.ToPB(),
})
if err != nil {
return nil, err
}
ref, err := res.SingleRef()
if err != nil {
return nil, err
}
if filename != "" {
files, err = filesFromURLRef(ctx, c, ref, inp, filename, names)
} else {
files, err = filesFromRef(ctx, ref, names)
}
return nil, err
}, ch)
if err != nil {
return nil, nil, err
}
return files, inp, nil
}
func IsRemoteURL(url string) bool {
if _, _, ok := detectHTTPContext(url); ok {
return true
}
if _, ok := detectGitContext(url); ok {
return true
}
return false
}
func detectHTTPContext(url string) (*llb.State, string, bool) {
if httpPrefix.MatchString(url) {
httpContext := llb.HTTP(url, llb.Filename("context"), llb.WithCustomName("[internal] load remote build context"))
return &httpContext, "context", true
}
return nil, "", false
}
func detectGitContext(ref string) (*llb.State, bool) {
found := false
if httpPrefix.MatchString(ref) && gitURLPathWithFragmentSuffix.MatchString(ref) {
found = true
}
for _, prefix := range []string{"git://", "github.com/", "git@"} {
if strings.HasPrefix(ref, prefix) {
found = true
break
}
}
if !found {
return nil, false
}
parts := strings.SplitN(ref, "#", 2)
branch := ""
if len(parts) > 1 {
branch = parts[1]
}
gitOpts := []llb.GitOption{llb.WithCustomName("[internal] load git source " + ref)}
st := llb.Git(parts[0], branch, gitOpts...)
return &st, true
}
func isArchive(header []byte) bool {
for _, m := range [][]byte{
{0x42, 0x5A, 0x68}, // bzip2
{0x1F, 0x8B, 0x08}, // gzip
{0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00}, // xz
} {
if len(header) < len(m) {
continue
}
if bytes.Equal(m, header[:len(m)]) {
return true
}
}
r := tar.NewReader(bytes.NewBuffer(header))
_, err := r.Next()
return err == nil
}
func filesFromURLRef(ctx context.Context, c gwclient.Client, ref gwclient.Reference, inp *Input, filename string, names []string) ([]File, error) {
stat, err := ref.StatFile(ctx, gwclient.StatRequest{Path: filename})
if err != nil {
return nil, err
}
dt, err := ref.ReadFile(ctx, gwclient.ReadRequest{
Filename: filename,
Range: &gwclient.FileRange{
Length: 1024,
},
})
if err != nil {
return nil, err
}
if isArchive(dt) {
bc := llb.Scratch().File(llb.Copy(inp.State, filename, "/", &llb.CopyInfo{
AttemptUnpack: true,
}))
inp.State = &bc
inp.URL = ""
def, err := bc.Marshal(ctx)
if err != nil {
return nil, err
}
res, err := c.Solve(ctx, gwclient.SolveRequest{
Definition: def.ToPB(),
})
if err != nil {
return nil, err
}
ref, err := res.SingleRef()
if err != nil {
return nil, err
}
return filesFromRef(ctx, ref, names)
}
inp.State = nil
name := inp.URL
inp.URL = ""
if len(dt) > stat.Size() {
if stat.Size() > 1024*512 {
return nil, errors.Errorf("non-archive definition URL bigger than maximum allowed size")
}
dt, err = ref.ReadFile(ctx, gwclient.ReadRequest{
Filename: filename,
})
if err != nil {
return nil, err
}
}
return []File{{Name: name, Data: dt}}, nil
}
func filesFromRef(ctx context.Context, ref gwclient.Reference, names []string) ([]File, error) {
// TODO: auto-remove parent dir in needed
var files []File
isDefault := false
if len(names) == 0 {
isDefault = true
names = defaultFilenames()
}
for _, name := range names {
_, err := ref.StatFile(ctx, gwclient.StatRequest{Path: name})
if err != nil {
if isDefault {
continue
}
return nil, err
}
dt, err := ref.ReadFile(ctx, gwclient.ReadRequest{Filename: name})
if err != nil {
return nil, err
}
files = append(files, File{Name: name, Data: dt})
}
return files, nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,60 +0,0 @@
package build
import (
"encoding/csv"
"strings"
"github.com/moby/buildkit/client"
"github.com/pkg/errors"
)
func ParseCacheEntry(in []string) ([]client.CacheOptionsEntry, error) {
imports := make([]client.CacheOptionsEntry, 0, len(in))
for _, in := range in {
csvReader := csv.NewReader(strings.NewReader(in))
fields, err := csvReader.Read()
if err != nil {
return nil, err
}
if isRefOnlyFormat(fields) {
for _, field := range fields {
imports = append(imports, client.CacheOptionsEntry{
Type: "registry",
Attrs: map[string]string{"ref": field},
})
}
continue
}
im := client.CacheOptionsEntry{
Attrs: map[string]string{},
}
for _, field := range fields {
parts := strings.SplitN(field, "=", 2)
if len(parts) != 2 {
return nil, errors.Errorf("invalid value %s", field)
}
key := strings.ToLower(parts[0])
value := parts[1]
switch key {
case "type":
im.Type = value
default:
im.Attrs[key] = value
}
}
if im.Type == "" {
return nil, errors.Errorf("type required form> %q", in)
}
imports = append(imports, im)
}
return imports, nil
}
func isRefOnlyFormat(in []string) bool {
for _, v := range in {
if strings.Contains(v, "=") {
return false
}
}
return true
}

115
build/git.go Normal file
View File

@@ -0,0 +1,115 @@
package build
import (
"context"
"os"
"path"
"path/filepath"
"strconv"
"strings"
"github.com/docker/buildx/util/gitutil"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
const DockerfileLabel = "com.docker.image.source.entrypoint"
func getGitAttributes(ctx context.Context, contextPath string, dockerfilePath string) (res map[string]string, _ error) {
res = make(map[string]string)
if contextPath == "" {
return
}
setGitLabels := false
if v, ok := os.LookupEnv("BUILDX_GIT_LABELS"); ok {
if v == "full" { // backward compatibility with old "full" mode
setGitLabels = true
} else if v, err := strconv.ParseBool(v); err == nil {
setGitLabels = v
}
}
setGitInfo := true
if v, ok := os.LookupEnv("BUILDX_GIT_INFO"); ok {
if v, err := strconv.ParseBool(v); err == nil {
setGitInfo = v
}
}
if !setGitLabels && !setGitInfo {
return
}
// figure out in which directory the git command needs to run in
var wd string
if filepath.IsAbs(contextPath) {
wd = contextPath
} else {
cwd, _ := os.Getwd()
wd, _ = filepath.Abs(filepath.Join(cwd, contextPath))
}
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("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("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 && !gitutil.IsUnknownRevision(err) {
return res, errors.Wrapf(err, "buildx: failed to get git commit")
} else if sha != "" {
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 {
res["label:"+specs.AnnotationRevision] = sha
}
if setGitInfo {
res["vcs:revision"] = sha
}
}
if rurl, err := gitc.RemoteURL(); err == nil && rurl != "" {
if setGitLabels {
res["label:"+specs.AnnotationSource] = rurl
}
if setGitInfo {
res["vcs:source"] = rurl
}
}
if setGitLabels {
if root, err := gitc.RootDir(); err != nil {
return res, errors.Wrapf(err, "buildx: failed to get git root dir")
} else if root != "" {
if dockerfilePath == "" {
dockerfilePath = filepath.Join(wd, "Dockerfile")
}
if !filepath.IsAbs(dockerfilePath) {
cwd, _ := os.Getwd()
dockerfilePath = filepath.Join(cwd, dockerfilePath)
}
dockerfilePath, _ = filepath.Rel(root, dockerfilePath)
if !strings.HasPrefix(dockerfilePath, "..") {
res["label:"+DockerfileLabel] = dockerfilePath
}
}
}
return
}

156
build/git_test.go Normal file
View File

@@ -0,0 +1,156 @@
package build
import (
"context"
"os"
"path"
"path/filepath"
"strings"
"testing"
"github.com/docker/buildx/util/gitutil"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func setupTest(tb testing.TB) {
gitutil.Mktmp(tb)
c, err := gitutil.New()
require.NoError(tb, err)
gitutil.GitInit(c, tb)
df := []byte("FROM alpine:latest\n")
assert.NoError(tb, os.WriteFile("Dockerfile", df, 0644))
gitutil.GitAdd(c, tb, "Dockerfile")
gitutil.GitCommit(c, tb, "initial commit")
gitutil.GitSetRemote(c, tb, "origin", "git@github.com:docker/buildx.git")
}
func TestGetGitAttributesNotGitRepo(t *testing.T) {
_, err := getGitAttributes(context.Background(), t.TempDir(), "Dockerfile")
assert.NoError(t, err)
}
func TestGetGitAttributesBadGitRepo(t *testing.T) {
tmp := t.TempDir()
require.NoError(t, os.MkdirAll(path.Join(tmp, ".git"), 0755))
_, err := getGitAttributes(context.Background(), tmp, "Dockerfile")
assert.Error(t, err)
}
func TestGetGitAttributesNoContext(t *testing.T) {
setupTest(t)
gitattrs, err := getGitAttributes(context.Background(), "", "Dockerfile")
assert.NoError(t, err)
assert.Empty(t, gitattrs)
}
func TestGetGitAttributes(t *testing.T) {
cases := []struct {
name string
envGitLabels string
envGitInfo string
expected []string
}{
{
name: "default",
envGitLabels: "",
envGitInfo: "",
expected: []string{
"vcs:revision",
"vcs:source",
},
},
{
name: "none",
envGitLabels: "false",
envGitInfo: "false",
expected: []string{},
},
{
name: "gitinfo",
envGitLabels: "false",
envGitInfo: "true",
expected: []string{
"vcs:revision",
"vcs:source",
},
},
{
name: "gitlabels",
envGitLabels: "true",
envGitInfo: "false",
expected: []string{
"label:" + DockerfileLabel,
"label:" + specs.AnnotationRevision,
"label:" + specs.AnnotationSource,
},
},
{
name: "both",
envGitLabels: "true",
envGitInfo: "",
expected: []string{
"label:" + DockerfileLabel,
"label:" + specs.AnnotationRevision,
"label:" + specs.AnnotationSource,
"vcs:revision",
"vcs:source",
},
},
}
for _, tt := range cases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
setupTest(t)
if tt.envGitLabels != "" {
t.Setenv("BUILDX_GIT_LABELS", tt.envGitLabels)
}
if tt.envGitInfo != "" {
t.Setenv("BUILDX_GIT_INFO", tt.envGitInfo)
}
gitattrs, err := getGitAttributes(context.Background(), ".", "Dockerfile")
require.NoError(t, err)
for _, e := range tt.expected {
assert.Contains(t, gitattrs, e)
assert.NotEmpty(t, gitattrs[e])
if e == "label:"+DockerfileLabel {
assert.Equal(t, "Dockerfile", gitattrs[e])
} else if e == "label:"+specs.AnnotationSource || e == "vcs:source" {
assert.Equal(t, "git@github.com:docker/buildx.git", gitattrs[e])
}
}
})
}
}
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")
require.NoError(t, os.Mkdir("dir", 0755))
require.NoError(t, os.WriteFile(filepath.Join("dir", "Dockerfile"), df, 0644))
t.Setenv("BUILDX_GIT_LABELS", "true")
gitattrs, _ := getGitAttributes(context.Background(), ".", "Dockerfile")
assert.Equal(t, 5, len(gitattrs))
assert.Contains(t, gitattrs, "label:"+DockerfileLabel)
assert.Equal(t, "Dockerfile", gitattrs["label:"+DockerfileLabel])
assert.Contains(t, gitattrs, "label:"+specs.AnnotationSource)
assert.Equal(t, "git@github.com:docker/buildx.git", gitattrs["label:"+specs.AnnotationSource])
assert.Contains(t, gitattrs, "label:"+specs.AnnotationRevision)
assert.True(t, strings.HasSuffix(gitattrs["label:"+specs.AnnotationRevision], "-dirty"))
assert.Contains(t, gitattrs, "vcs:source")
assert.Equal(t, "git@github.com:docker/buildx.git", gitattrs["vcs:source"])
assert.Contains(t, gitattrs, "vcs:revision")
assert.True(t, strings.HasSuffix(gitattrs["vcs:revision"], "-dirty"))
}

View File

@@ -1,108 +0,0 @@
package build
import (
"encoding/csv"
"os"
"strings"
"github.com/containerd/console"
"github.com/moby/buildkit/client"
"github.com/pkg/errors"
)
func ParseOutputs(inp []string) ([]client.ExportEntry, error) {
var outs []client.ExportEntry
if len(inp) == 0 {
return nil, nil
}
for _, s := range inp {
csvReader := csv.NewReader(strings.NewReader(s))
fields, err := csvReader.Read()
if err != nil {
return nil, err
}
out := client.ExportEntry{
Attrs: map[string]string{},
}
if len(fields) == 1 && fields[0] == s && !strings.HasPrefix(s, "type=") {
if s != "-" {
outs = append(outs, client.ExportEntry{
Type: client.ExporterLocal,
OutputDir: s,
})
continue
}
out = client.ExportEntry{
Type: client.ExporterTar,
Attrs: map[string]string{
"dest": s,
},
}
}
if out.Type == "" {
for _, field := range fields {
parts := strings.SplitN(field, "=", 2)
if len(parts) != 2 {
return nil, errors.Errorf("invalid value %s", field)
}
key := strings.TrimSpace(strings.ToLower(parts[0]))
value := parts[1]
switch key {
case "type":
out.Type = value
default:
out.Attrs[key] = value
}
}
}
if out.Type == "" {
return nil, errors.Errorf("type is required for output")
}
// handle client side
switch out.Type {
case client.ExporterLocal:
dest, ok := out.Attrs["dest"]
if !ok {
return nil, errors.Errorf("dest is required for local output")
}
out.OutputDir = dest
delete(out.Attrs, "dest")
case client.ExporterOCI, client.ExporterDocker, client.ExporterTar:
dest, ok := out.Attrs["dest"]
if !ok {
if out.Type != client.ExporterDocker {
dest = "-"
}
}
if dest == "-" {
if _, err := console.ConsoleFromFile(os.Stdout); err == nil {
return nil, errors.Errorf("output file is required for %s exporter. refusing to write to console", out.Type)
}
out.Output = os.Stdout
} else if dest != "" {
fi, err := os.Stat(dest)
if err != nil && !os.IsNotExist(err) {
return nil, errors.Wrapf(err, "invalid destination file: %s", dest)
}
if err == nil && fi.IsDir() {
return nil, errors.Errorf("destination file %s is a directory", dest)
}
f, err := os.Create(dest)
if err != nil {
return nil, errors.Errorf("failed to open %s", err)
}
out.Output = f
}
delete(out.Attrs, "dest")
case "registry":
out.Type = client.ExporterImage
out.Attrs["push"] = "true"
}
outs = append(outs, out)
}
return outs, nil
}

View File

@@ -1,60 +0,0 @@
package build
import (
"encoding/csv"
"strings"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/secrets/secretsprovider"
"github.com/pkg/errors"
)
func ParseSecretSpecs(sl []string) (session.Attachable, error) {
fs := make([]secretsprovider.FileSource, 0, len(sl))
for _, v := range sl {
s, err := parseSecret(v)
if err != nil {
return nil, err
}
fs = append(fs, *s)
}
store, err := secretsprovider.NewFileStore(fs)
if err != nil {
return nil, err
}
return secretsprovider.NewSecretProvider(store), nil
}
func parseSecret(value string) (*secretsprovider.FileSource, error) {
csvReader := csv.NewReader(strings.NewReader(value))
fields, err := csvReader.Read()
if err != nil {
return nil, errors.Wrap(err, "failed to parse csv secret")
}
fs := secretsprovider.FileSource{}
for _, field := range fields {
parts := strings.SplitN(field, "=", 2)
key := strings.ToLower(parts[0])
if len(parts) != 2 {
return nil, errors.Errorf("invalid field '%s' must be a key=value pair", field)
}
value := parts[1]
switch key {
case "type":
if value != "file" {
return nil, errors.Errorf("unsupported secret type %q", value)
}
case "id":
fs.ID = value
case "source", "src":
fs.FilePath = value
default:
return nil, errors.Errorf("unexpected key '%s' in '%s'", key, field)
}
}
return &fs, nil
}

View File

@@ -1,31 +0,0 @@
package build
import (
"strings"
"github.com/moby/buildkit/session"
"github.com/moby/buildkit/session/sshforward/sshprovider"
)
func ParseSSHSpecs(sl []string) (session.Attachable, error) {
configs := make([]sshprovider.AgentConfig, 0, len(sl))
for _, v := range sl {
c, err := parseSSH(v)
if err != nil {
return nil, err
}
configs = append(configs, *c)
}
return sshprovider.NewSSHAgentProvider(configs)
}
func parseSSH(value string) (*sshprovider.AgentConfig, error) {
parts := strings.SplitN(value, "=", 2)
cfg := sshprovider.AgentConfig{
ID: parts[0],
}
if len(parts) > 1 {
cfg.Paths = strings.Split(parts[1], ",")
}
return &cfg, nil
}

71
build/url.go Normal file
View File

@@ -0,0 +1,71 @@
package build
import (
"context"
"os"
"path/filepath"
"github.com/docker/buildx/driver"
"github.com/docker/buildx/util/progress"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/client/llb"
gwclient "github.com/moby/buildkit/frontend/gateway/client"
"github.com/pkg/errors"
)
func createTempDockerfileFromURL(ctx context.Context, d driver.Driver, url string, pw progress.Writer) (string, error) {
c, err := driver.Boot(ctx, ctx, d, pw)
if err != nil {
return "", err
}
var out string
ch, done := progress.NewChannel(pw)
defer func() { <-done }()
_, err = c.Build(ctx, client.SolveOpt{}, "buildx", func(ctx context.Context, c gwclient.Client) (*gwclient.Result, error) {
def, err := llb.HTTP(url, llb.Filename("Dockerfile"), llb.WithCustomNamef("[internal] load %s", url)).Marshal(ctx)
if err != nil {
return nil, err
}
res, err := c.Solve(ctx, gwclient.SolveRequest{
Definition: def.ToPB(),
})
if err != nil {
return nil, err
}
ref, err := res.SingleRef()
if err != nil {
return nil, err
}
stat, err := ref.StatFile(ctx, gwclient.StatRequest{
Path: "Dockerfile",
})
if err != nil {
return nil, err
}
if stat.Size() > 512*1024 {
return nil, errors.Errorf("Dockerfile %s bigger than allowed max size", url)
}
dt, err := ref.ReadFile(ctx, gwclient.ReadRequest{
Filename: "Dockerfile",
})
if err != nil {
return nil, err
}
dir, err := os.MkdirTemp("", "buildx")
if err != nil {
return nil, err
}
if err := os.WriteFile(filepath.Join(dir, "Dockerfile"), dt, 0600); err != nil {
return nil, err
}
out = dir
return nil, nil
}, ch)
if err != nil {
return "", err
}
return out, nil
}

View File

@@ -7,11 +7,18 @@ import (
"os"
"strings"
"github.com/docker/cli/opts"
"github.com/pkg/errors"
)
// archiveHeaderSize is the number of bytes in an archive header
const archiveHeaderSize = 512
const (
// archiveHeaderSize is the number of bytes in an archive header
archiveHeaderSize = 512
// mobyHostGatewayName defines a special string which users can append to
// --add-host to add an extra entry in /etc/hosts that maps
// host.docker.internal to the host IP
mobyHostGatewayName = "host-gateway"
)
func isLocalDir(c string) bool {
st, err := os.Stat(c)
@@ -38,18 +45,35 @@ func isArchive(header []byte) bool {
}
// toBuildkitExtraHosts converts hosts from docker key:value format to buildkit's csv format
func toBuildkitExtraHosts(inp []string) (string, error) {
func toBuildkitExtraHosts(inp []string, mobyDriver bool) (string, error) {
if len(inp) == 0 {
return "", nil
}
hosts := make([]string, 0, len(inp))
for _, h := range inp {
parts := strings.Split(h, ":")
if len(parts) != 2 || parts[0] == "" || net.ParseIP(parts[1]) == nil {
host, ip, ok := strings.Cut(h, ":")
if !ok || host == "" || ip == "" {
return "", errors.Errorf("invalid host %s", h)
}
hosts = append(hosts, parts[0]+"="+parts[1])
// Skip IP address validation for "host-gateway" string with moby driver
if !mobyDriver || ip != mobyHostGatewayName {
if net.ParseIP(ip) == nil {
return "", errors.Errorf("invalid host %s", h)
}
}
hosts = append(hosts, host+"="+ip)
}
return strings.Join(hosts, ","), nil
}
// toBuildkitUlimits converts ulimits from docker type=soft:hard format to buildkit's csv format
func toBuildkitUlimits(inp *opts.UlimitOpt) (string, error) {
if inp == nil || len(inp.GetList()) == 0 {
return "", nil
}
ulimits := make([]string, 0, len(inp.GetList()))
for _, ulimit := range inp.GetList() {
ulimits = append(ulimits, ulimit.String())
}
return strings.Join(ulimits, ","), nil
}

292
builder/builder.go Normal file
View File

@@ -0,0 +1,292 @@
package builder
import (
"context"
"os"
"sort"
"sync"
"github.com/docker/buildx/driver"
"github.com/docker/buildx/store"
"github.com/docker/buildx/store/storeutil"
"github.com/docker/buildx/util/dockerutil"
"github.com/docker/buildx/util/imagetools"
"github.com/docker/buildx/util/progress"
"github.com/docker/cli/cli/command"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
)
// Builder represents an active builder object
type Builder struct {
*store.NodeGroup
driverFactory driverFactory
nodes []Node
opts builderOpts
err error
}
type builderOpts struct {
dockerCli command.Cli
name string
txn *store.Txn
contextPathHash string
validate bool
}
// Option provides a variadic option for configuring the builder.
type Option func(b *Builder)
// WithName sets builder name.
func WithName(name string) Option {
return func(b *Builder) {
b.opts.name = name
}
}
// WithStore sets a store instance used at init.
func WithStore(txn *store.Txn) Option {
return func(b *Builder) {
b.opts.txn = txn
}
}
// WithContextPathHash is used for determining pods in k8s driver instance.
func WithContextPathHash(contextPathHash string) Option {
return func(b *Builder) {
b.opts.contextPathHash = contextPathHash
}
}
// WithSkippedValidation skips builder context validation.
func WithSkippedValidation() Option {
return func(b *Builder) {
b.opts.validate = false
}
}
// New initializes a new builder client
func New(dockerCli command.Cli, opts ...Option) (_ *Builder, err error) {
b := &Builder{
opts: builderOpts{
dockerCli: dockerCli,
validate: true,
},
}
for _, opt := range opts {
opt(b)
}
if b.opts.txn == nil {
// if store instance is nil we create a short-lived one using the
// default store and ensure we release it on completion
var release func()
b.opts.txn, release, err = storeutil.GetStore(dockerCli)
if err != nil {
return nil, err
}
defer release()
}
if b.opts.name != "" {
if b.NodeGroup, err = storeutil.GetNodeGroup(b.opts.txn, dockerCli, b.opts.name); err != nil {
return nil, err
}
} else {
if b.NodeGroup, err = storeutil.GetCurrentInstance(b.opts.txn, dockerCli); err != nil {
return nil, err
}
}
if b.opts.validate {
if err = b.Validate(); err != nil {
return nil, err
}
}
return b, nil
}
// Validate validates builder context
func (b *Builder) Validate() error {
if b.NodeGroup.DockerContext {
list, err := b.opts.dockerCli.ContextStore().List()
if err != nil {
return err
}
currentContext := b.opts.dockerCli.CurrentContext()
for _, l := range list {
if l.Name == b.Name && l.Name != currentContext {
return errors.Errorf("use `docker --context=%s buildx` to switch to context %q", l.Name, l.Name)
}
}
}
return nil
}
// ContextName returns builder context name if available.
func (b *Builder) ContextName() string {
ctxbuilders, err := b.opts.dockerCli.ContextStore().List()
if err != nil {
return ""
}
for _, cb := range ctxbuilders {
if b.NodeGroup.Driver == "docker" && len(b.NodeGroup.Nodes) == 1 && b.NodeGroup.Nodes[0].Endpoint == cb.Name {
return cb.Name
}
}
return ""
}
// ImageOpt returns registry auth configuration
func (b *Builder) ImageOpt() (imagetools.Opt, error) {
return storeutil.GetImageConfig(b.opts.dockerCli, b.NodeGroup)
}
// Boot bootstrap a builder
func (b *Builder) Boot(ctx context.Context) (bool, error) {
toBoot := make([]int, 0, len(b.nodes))
for idx, d := range b.nodes {
if d.Err != nil || d.Driver == nil || d.DriverInfo == nil {
continue
}
if d.DriverInfo.Status != driver.Running {
toBoot = append(toBoot, idx)
}
}
if len(toBoot) == 0 {
return false, nil
}
printer, err := progress.NewPrinter(context.TODO(), os.Stderr, os.Stderr, progress.PrinterModeAuto)
if err != nil {
return false, err
}
baseCtx := ctx
eg, _ := errgroup.WithContext(ctx)
for _, idx := range toBoot {
func(idx int) {
eg.Go(func() error {
pw := progress.WithPrefix(printer, b.NodeGroup.Nodes[idx].Name, len(toBoot) > 1)
_, err := driver.Boot(ctx, baseCtx, b.nodes[idx].Driver, pw)
if err != nil {
b.nodes[idx].Err = err
}
return nil
})
}(idx)
}
err = eg.Wait()
err1 := printer.Wait()
if err == nil {
err = err1
}
return true, err
}
// Inactive checks if all nodes are inactive for this builder.
func (b *Builder) Inactive() bool {
for _, d := range b.nodes {
if d.DriverInfo != nil && d.DriverInfo.Status == driver.Running {
return false
}
}
return true
}
// Err returns error if any.
func (b *Builder) Err() error {
return b.err
}
type driverFactory struct {
driver.Factory
once sync.Once
}
// Factory returns the driver factory.
func (b *Builder) Factory(ctx context.Context) (_ driver.Factory, err error) {
b.driverFactory.once.Do(func() {
if b.Driver != "" {
b.driverFactory.Factory, err = driver.GetFactory(b.Driver, true)
if err != nil {
return
}
} else {
// empty driver means nodegroup was implicitly created as a default
// driver for a docker context and allows falling back to a
// docker-container driver for older daemon that doesn't support
// buildkit (< 18.06).
ep := b.NodeGroup.Nodes[0].Endpoint
var dockerapi *dockerutil.ClientAPI
dockerapi, err = dockerutil.NewClientAPI(b.opts.dockerCli, b.NodeGroup.Nodes[0].Endpoint)
if err != nil {
return
}
// check if endpoint is healthy is needed to determine the driver type.
// if this fails then can't continue with driver selection.
if _, err = dockerapi.Ping(ctx); err != nil {
return
}
b.driverFactory.Factory, err = driver.GetDefaultFactory(ctx, ep, dockerapi, false)
if err != nil {
return
}
b.Driver = b.driverFactory.Factory.Name()
}
})
return b.driverFactory.Factory, err
}
// GetBuilders returns all builders
func GetBuilders(dockerCli command.Cli, txn *store.Txn) ([]*Builder, error) {
storeng, err := txn.List()
if err != nil {
return nil, err
}
builders := make([]*Builder, len(storeng))
seen := make(map[string]struct{})
for i, ng := range storeng {
b, err := New(dockerCli,
WithName(ng.Name),
WithStore(txn),
WithSkippedValidation(),
)
if err != nil {
return nil, err
}
builders[i] = b
seen[b.NodeGroup.Name] = struct{}{}
}
contexts, err := dockerCli.ContextStore().List()
if err != nil {
return nil, err
}
sort.Slice(contexts, func(i, j int) bool {
return contexts[i].Name < contexts[j].Name
})
for _, c := range contexts {
// if a context has the same name as an instance from the store, do not
// add it to the builders list. An instance from the store takes
// precedence over context builders.
if _, ok := seen[c.Name]; ok {
continue
}
b, err := New(dockerCli,
WithName(c.Name),
WithStore(txn),
WithSkippedValidation(),
)
if err != nil {
return nil, err
}
builders = append(builders, b)
}
return builders, nil
}

202
builder/node.go Normal file
View File

@@ -0,0 +1,202 @@
package builder
import (
"context"
"github.com/docker/buildx/driver"
ctxkube "github.com/docker/buildx/driver/kubernetes/context"
"github.com/docker/buildx/store"
"github.com/docker/buildx/store/storeutil"
"github.com/docker/buildx/util/dockerutil"
"github.com/docker/buildx/util/imagetools"
"github.com/docker/buildx/util/platformutil"
"github.com/moby/buildkit/util/grpcerrors"
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc/codes"
)
type Node struct {
store.Node
Driver driver.Driver
DriverInfo *driver.Info
Platforms []ocispecs.Platform
ImageOpt imagetools.Opt
ProxyConfig map[string]string
Version string
Err error
}
// Nodes returns nodes for this builder.
func (b *Builder) Nodes() []Node {
return b.nodes
}
// LoadNodes loads and returns nodes for this builder.
// TODO: this should be a method on a Node object and lazy load data for each driver.
func (b *Builder) LoadNodes(ctx context.Context, withData bool) (_ []Node, err error) {
eg, _ := errgroup.WithContext(ctx)
b.nodes = make([]Node, len(b.NodeGroup.Nodes))
defer func() {
if b.err == nil && err != nil {
b.err = err
}
}()
factory, err := b.Factory(ctx)
if err != nil {
return nil, err
}
imageopt, err := b.ImageOpt()
if err != nil {
return nil, err
}
for i, n := range b.NodeGroup.Nodes {
func(i int, n store.Node) {
eg.Go(func() error {
node := Node{
Node: n,
ProxyConfig: storeutil.GetProxyConfig(b.opts.dockerCli),
Platforms: n.Platforms,
}
defer func() {
b.nodes[i] = node
}()
dockerapi, err := dockerutil.NewClientAPI(b.opts.dockerCli, n.Endpoint)
if err != nil {
node.Err = err
return nil
}
contextStore := b.opts.dockerCli.ContextStore()
var kcc driver.KubeClientConfig
kcc, err = ctxkube.ConfigFromContext(n.Endpoint, contextStore)
if err != nil {
// err is returned if n.Endpoint is non-context name like "unix:///var/run/docker.sock".
// try again with name="default".
// FIXME(@AkihiroSuda): n should retain real context name.
kcc, err = ctxkube.ConfigFromContext("default", contextStore)
if err != nil {
logrus.Error(err)
}
}
tryToUseKubeConfigInCluster := false
if kcc == nil {
tryToUseKubeConfigInCluster = true
} else {
if _, err := kcc.ClientConfig(); err != nil {
tryToUseKubeConfigInCluster = true
}
}
if tryToUseKubeConfigInCluster {
kccInCluster := driver.KubeClientConfigInCluster{}
if _, err := kccInCluster.ClientConfig(); err == nil {
logrus.Debug("using kube config in cluster")
kcc = kccInCluster
}
}
d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, factory, n.Endpoint, dockerapi, imageopt.Auth, kcc, n.Flags, n.Files, n.DriverOpts, n.Platforms, b.opts.contextPathHash)
if err != nil {
node.Err = err
return nil
}
node.Driver = d
node.ImageOpt = imageopt
if withData {
if err := node.loadData(ctx); err != nil {
node.Err = err
}
}
return nil
})
}(i, n)
}
if err := eg.Wait(); err != nil {
return nil, err
}
// TODO: This should be done in the routine loading driver data
if withData {
kubernetesDriverCount := 0
for _, d := range b.nodes {
if d.DriverInfo != nil && len(d.DriverInfo.DynamicNodes) > 0 {
kubernetesDriverCount++
}
}
isAllKubernetesDrivers := len(b.nodes) == kubernetesDriverCount
if isAllKubernetesDrivers {
var nodes []Node
var dynamicNodes []store.Node
for _, di := range b.nodes {
// dynamic nodes are used in Kubernetes driver.
// Kubernetes' pods are dynamically mapped to BuildKit Nodes.
if di.DriverInfo != nil && len(di.DriverInfo.DynamicNodes) > 0 {
for i := 0; i < len(di.DriverInfo.DynamicNodes); i++ {
diClone := di
if pl := di.DriverInfo.DynamicNodes[i].Platforms; len(pl) > 0 {
diClone.Platforms = pl
}
nodes = append(nodes, di)
}
dynamicNodes = append(dynamicNodes, di.DriverInfo.DynamicNodes...)
}
}
// not append (remove the static nodes in the store)
b.NodeGroup.Nodes = dynamicNodes
b.nodes = nodes
b.NodeGroup.Dynamic = true
}
}
return b.nodes, nil
}
func (n *Node) loadData(ctx context.Context) error {
if n.Driver == nil {
return nil
}
info, err := n.Driver.Info(ctx)
if err != nil {
return err
}
n.DriverInfo = info
if n.DriverInfo.Status == driver.Running {
driverClient, err := n.Driver.Client(ctx)
if err != nil {
return err
}
workers, err := driverClient.ListWorkers(ctx)
if err != nil {
return errors.Wrap(err, "listing workers")
}
for _, w := range workers {
n.Platforms = append(n.Platforms, w.Platforms...)
}
n.Platforms = platformutil.Dedupe(n.Platforms)
inf, err := driverClient.Info(ctx)
if err != nil {
if st, ok := grpcerrors.AsGRPCStatus(err); ok && st.Code() == codes.Unimplemented {
n.Version, err = n.Driver.Version(ctx)
if err != nil {
return errors.Wrap(err, "getting version")
}
}
} else {
n.Version = inf.BuildkitVersion.Version
}
}
return nil
}

View File

@@ -4,42 +4,87 @@ import (
"fmt"
"os"
"github.com/containerd/containerd/pkg/seed"
"github.com/docker/buildx/commands"
"github.com/docker/buildx/version"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli-plugins/manager"
"github.com/docker/cli/cli-plugins/plugin"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/debug"
cliflags "github.com/docker/cli/cli/flags"
"github.com/spf13/cobra"
"github.com/moby/buildkit/solver/errdefs"
"github.com/moby/buildkit/util/stack"
_ "k8s.io/client-go/plugin/pkg/client/auth/azure"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
_ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
_ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
_ "github.com/docker/buildx/driver/docker"
_ "github.com/docker/buildx/driver/docker-container"
_ "github.com/docker/buildx/driver/kubernetes"
_ "github.com/docker/buildx/driver/remote"
)
func init() {
seed.WithTimeAndRand()
stack.SetVersionInfo(version.Version, version.Revision)
}
func runStandalone(cmd *command.DockerCli) error {
if err := cmd.Initialize(cliflags.NewClientOptions()); err != nil {
return err
}
rootCmd := commands.NewRootCmd(os.Args[0], false, cmd)
return rootCmd.Execute()
}
func runPlugin(cmd *command.DockerCli) error {
rootCmd := commands.NewRootCmd("buildx", true, cmd)
return plugin.RunPlugin(cmd, rootCmd, manager.Metadata{
SchemaVersion: "0.1.0",
Vendor: "Docker Inc.",
Version: version.Version,
})
}
func main() {
if os.Getenv("DOCKER_CLI_PLUGIN_ORIGINAL_CLI_COMMAND") == "" {
if len(os.Args) < 2 || os.Args[1] != manager.MetadataSubcommandName {
dockerCli, err := command.NewDockerCli()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
opts := cliflags.NewClientOptions()
dockerCli.Initialize(opts)
rootCmd := commands.NewRootCmd(os.Args[0], false, dockerCli)
if err := rootCmd.Execute(); err != nil {
os.Exit(1)
}
os.Exit(0)
}
cmd, err := command.NewDockerCli()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
plugin.Run(func(dockerCli command.Cli) *cobra.Command {
return commands.NewRootCmd("buildx", true, dockerCli)
},
manager.Metadata{
SchemaVersion: "0.1.0",
Vendor: "Docker Inc.",
Version: version.Version,
})
if plugin.RunningStandalone() {
err = runStandalone(cmd)
} else {
err = runPlugin(cmd)
}
if err == nil {
return
}
if sterr, ok := err.(cli.StatusError); ok {
if sterr.Status != "" {
fmt.Fprintln(cmd.Err(), sterr.Status)
}
// StatusError should only be used for errors, and all errors should
// have a non-zero exit status, so never exit with 0
if sterr.StatusCode == 0 {
os.Exit(1)
}
os.Exit(sterr.StatusCode)
}
for _, s := range errdefs.Sources(err) {
s.Print(cmd.Err())
}
if debug.IsEnabled() {
fmt.Fprintf(cmd.Err(), "ERROR: %+v", stack.Formatter(err))
} else {
fmt.Fprintf(cmd.Err(), "ERROR: %v\n", err)
}
os.Exit(1)
}

19
cmd/buildx/tracing.go Normal file
View File

@@ -0,0 +1,19 @@
package main
import (
"github.com/moby/buildkit/util/tracing/detect"
"go.opentelemetry.io/otel"
_ "github.com/moby/buildkit/util/tracing/detect/delegated"
_ "github.com/moby/buildkit/util/tracing/env"
)
func init() {
detect.ServiceName = "buildx"
// do not log tracing errors to stdio
otel.SetErrorHandler(skipErrors{})
}
type skipErrors struct{}
func (skipErrors) Handle(err error) {}

1
codecov.yml Normal file
View File

@@ -0,0 +1 @@
comment: false

View File

@@ -1,11 +1,20 @@
package commands
import (
"context"
"encoding/json"
"fmt"
"os"
"github.com/containerd/containerd/platforms"
"github.com/docker/buildx/bake"
"github.com/docker/buildx/build"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/util/buildflags"
"github.com/docker/buildx/util/confutil"
"github.com/docker/buildx/util/dockerutil"
"github.com/docker/buildx/util/progress"
"github.com/docker/buildx/util/tracing"
"github.com/docker/cli/cli/command"
"github.com/moby/buildkit/util/appcontext"
"github.com/pkg/errors"
@@ -14,36 +23,141 @@ import (
type bakeOptions struct {
files []string
printOnly bool
overrides []string
printOnly bool
commonOptions
}
func runBake(dockerCli command.Cli, targets []string, in bakeOptions) error {
func runBake(dockerCli command.Cli, targets []string, in bakeOptions) (err error) {
ctx := appcontext.Context()
if len(in.files) == 0 {
files, err := defaultFiles()
if err != nil {
return err
ctx, end, err := tracing.TraceCurrentCommand(ctx, "bake")
if err != nil {
return err
}
defer func() {
end(err)
}()
var url string
cmdContext := "cwd://"
if len(targets) > 0 {
if bake.IsRemoteURL(targets[0]) {
url = targets[0]
targets = targets[1:]
if len(targets) > 0 {
if bake.IsRemoteURL(targets[0]) {
cmdContext = targets[0]
targets = targets[1:]
}
}
}
if len(files) == 0 {
return errors.Errorf("no docker-compose.yml or dockerbuild.hcl found, specify build file with -f/--file")
}
in.files = files
}
if len(targets) == 0 {
targets = []string{"default"}
}
m, err := bake.ReadTargets(ctx, in.files, targets, in.overrides)
overrides := in.overrides
if in.exportPush {
if in.exportLoad {
return errors.Errorf("push and load may not be set together at the moment")
}
overrides = append(overrides, "*.push=true")
} else if in.exportLoad {
overrides = append(overrides, "*.output=type=docker")
}
if in.noCache != nil {
overrides = append(overrides, fmt.Sprintf("*.no-cache=%t", *in.noCache))
}
if in.pull != nil {
overrides = append(overrides, fmt.Sprintf("*.pull=%t", *in.pull))
}
if in.sbom != "" {
overrides = append(overrides, fmt.Sprintf("*.attest=%s", buildflags.CanonicalizeAttest("sbom", in.sbom)))
}
if in.provenance != "" {
overrides = append(overrides, fmt.Sprintf("*.attest=%s", buildflags.CanonicalizeAttest("provenance", in.provenance)))
}
contextPathHash, _ := os.Getwd()
ctx2, cancel := context.WithCancel(context.TODO())
defer cancel()
printer, err := progress.NewPrinter(ctx2, os.Stderr, os.Stderr, in.progress)
if err != nil {
return err
}
defer func() {
if printer != nil {
err1 := printer.Wait()
if err == nil {
err = err1
}
}
}()
var nodes []builder.Node
var files []bake.File
var inp *bake.Input
// instance only needed for reading remote bake files or building
if url != "" || !in.printOnly {
b, err := builder.New(dockerCli,
builder.WithName(in.builder),
builder.WithContextPathHash(contextPathHash),
)
if err != nil {
return err
}
if err = updateLastActivity(dockerCli, b.NodeGroup); err != nil {
return errors.Wrapf(err, "failed to update builder last activity time")
}
nodes, err = b.LoadNodes(ctx, false)
if err != nil {
return err
}
}
if url != "" {
files, inp, err = bake.ReadRemoteFiles(ctx, nodes, url, in.files, printer)
} else {
files, err = bake.ReadLocalFiles(in.files)
}
if err != nil {
return err
}
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
"BAKE_CMD_CONTEXT": cmdContext,
"BAKE_LOCAL_PLATFORM": platforms.DefaultString(),
})
if err != nil {
return err
}
// this function can update target context string from the input so call before printOnly check
bo, err := bake.TargetsToBuildOpt(tgts, inp)
if err != nil {
return err
}
if in.printOnly {
dt, err := json.MarshalIndent(map[string]map[string]bake.Target{"target": m}, "", " ")
dt, err := json.MarshalIndent(struct {
Group map[string]*bake.Group `json:"group,omitempty"`
Target map[string]*bake.Target `json:"target"`
}{
grps,
tgts,
}, "", " ")
if err != nil {
return err
}
err = printer.Wait()
printer = nil
if err != nil {
return err
}
@@ -51,37 +165,25 @@ func runBake(dockerCli command.Cli, targets []string, in bakeOptions) error {
return nil
}
bo, err := bake.TargetsToBuildOpt(m)
resp, err := build.Build(ctx, nodes, bo, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), printer)
if err != nil {
return err
return wrapBuildError(err, true)
}
return buildTargets(ctx, dockerCli, bo, in.progress)
}
func defaultFiles() ([]string, error) {
fns := []string{
"docker-compose.yml", // support app
"docker-compose.yaml", // support app
"docker-bake.json",
"docker-bake.override.json",
"docker-bake.hcl",
"docker-bake.override.hcl",
}
out := make([]string, 0, len(fns))
for _, f := range fns {
if _, err := os.Stat(f); err != nil {
if os.IsNotExist(errors.Cause(err)) {
continue
}
return nil, err
if len(in.metadataFile) > 0 {
dt := make(map[string]interface{})
for t, r := range resp {
dt[t] = decodeExporterResponse(r.ExporterResponse)
}
if err := writeMetadataFile(in.metadataFile, dt); err != nil {
return err
}
out = append(out, f)
}
return out, nil
return err
}
func bakeCmd(dockerCli command.Cli) *cobra.Command {
func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
var options bakeOptions
cmd := &cobra.Command{
@@ -89,6 +191,14 @@ func bakeCmd(dockerCli command.Cli) *cobra.Command {
Aliases: []string{"f"},
Short: "Build from a file",
RunE: func(cmd *cobra.Command, args []string) error {
// reset to nil to avoid override is unset
if !cmd.Flags().Lookup("no-cache").Changed {
options.noCache = nil
}
if !cmd.Flags().Lookup("pull").Changed {
options.pull = nil
}
options.commonOptions.builder = rootOpts.builder
return runBake(dockerCli, args, options)
},
}
@@ -96,10 +206,14 @@ func bakeCmd(dockerCli command.Cli) *cobra.Command {
flags := cmd.Flags()
flags.StringArrayVarP(&options.files, "file", "f", []string{}, "Build definition file")
flags.BoolVar(&options.exportLoad, "load", false, `Shorthand for "--set=*.output=type=docker"`)
flags.BoolVar(&options.printOnly, "print", false, "Print the options without building")
flags.StringArrayVar(&options.overrides, "set", nil, "Override target value (eg: target.key=value)")
flags.BoolVar(&options.exportPush, "push", false, `Shorthand for "--set=*.output=type=registry"`)
flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--set=*.attest=type=sbom"`)
flags.StringVar(&options.provenance, "provenance", "", `Shorthand for "--set=*.attest=type=provenance"`)
flags.StringArrayVar(&options.overrides, "set", nil, `Override target value (e.g., "targetpattern.key=value")`)
commonFlags(&options.commonOptions, flags)
commonBuildFlags(&options.commonOptions, flags)
return cmd
}

View File

@@ -1,97 +1,158 @@
package commands
import (
"bytes"
"context"
"encoding/base64"
"encoding/csv"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"github.com/containerd/console"
"github.com/docker/buildx/build"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/monitor"
"github.com/docker/buildx/store"
"github.com/docker/buildx/store/storeutil"
"github.com/docker/buildx/util/buildflags"
"github.com/docker/buildx/util/confutil"
"github.com/docker/buildx/util/dockerutil"
"github.com/docker/buildx/util/platformutil"
"github.com/docker/buildx/util/progress"
"github.com/docker/buildx/util/tracing"
"github.com/docker/cli-docs-tool/annotation"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config"
dockeropts "github.com/docker/cli/opts"
"github.com/docker/distribution/reference"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/go-units"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/session/auth/authprovider"
"github.com/moby/buildkit/solver/errdefs"
"github.com/moby/buildkit/util/appcontext"
"github.com/moby/buildkit/util/grpcerrors"
"github.com/morikuni/aec"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"google.golang.org/grpc/codes"
)
const defaultTargetName = "default"
type buildOptions struct {
commonOptions
contextPath string
dockerfileName string
tags []string
labels []string
buildArgs []string
printFunc string
cacheFrom []string
cacheTo []string
target string
platforms []string
secrets []string
ssh []string
outputs []string
imageIDFile string
extraHosts []string
networkMode string
allow []string
attests []string
buildArgs []string
cacheFrom []string
cacheTo []string
cgroupParent string
contexts []string
extraHosts []string
imageIDFile string
invoke string
labels []string
networkMode string
noCacheFilter []string
outputs []string
platforms []string
quiet bool
secrets []string
shmSize dockeropts.MemBytes
ssh []string
tags []string
target string
ulimits *dockeropts.UlimitOpt
commonOptions
}
type commonOptions struct {
builder string
metadataFile string
noCache *bool
progress string
pull *bool
exportPush bool
exportLoad bool
// unimplemented
squash bool
quiet bool
// hidden
// untrusted bool
// ulimits *opts.UlimitOpt
// memory opts.MemBytes
// memorySwap opts.MemSwapBytes
// shmSize opts.MemBytes
// cpuShares int64
// cpuPeriod int64
// cpuQuota int64
// cpuSetCpus string
// cpuSetMems string
// cgroupParent string
// isolation string
// compress bool
// securityOpt []string
sbom string
provenance string
}
type commonOptions struct {
noCache bool
progress string
pull bool
}
func runBuild(dockerCli command.Cli, in buildOptions) error {
if in.squash {
return errors.Errorf("squash currently not implemented")
}
if in.quiet {
return errors.Errorf("quiet currently not implemented")
}
func runBuild(dockerCli command.Cli, in buildOptions) (err error) {
ctx := appcontext.Context()
ctx, end, err := tracing.TraceCurrentCommand(ctx, "build")
if err != nil {
return err
}
defer func() {
end(err)
}()
noCache := false
if in.noCache != nil {
noCache = *in.noCache
}
pull := false
if in.pull != nil {
pull = *in.pull
}
if noCache && len(in.noCacheFilter) > 0 {
return errors.Errorf("--no-cache and --no-cache-filter cannot currently be used together")
}
if in.quiet && in.progress != progress.PrinterModeAuto && in.progress != progress.PrinterModeQuiet {
return errors.Errorf("progress=%s and quiet cannot be used together", in.progress)
} else if in.quiet {
in.progress = "quiet"
}
contexts, err := parseContextNames(in.contexts)
if err != nil {
return err
}
printFunc, err := parsePrintFunc(in.printFunc)
if err != nil {
return err
}
opts := build.Options{
Inputs: build.Inputs{
ContextPath: in.contextPath,
DockerfilePath: in.dockerfileName,
InStream: os.Stdin,
NamedContexts: contexts,
},
Tags: in.tags,
Labels: listToMap(in.labels),
BuildArgs: listToMap(in.buildArgs),
Pull: in.pull,
NoCache: in.noCache,
Target: in.target,
ImageIDFile: in.imageIDFile,
ExtraHosts: in.extraHosts,
NetworkMode: in.networkMode,
BuildArgs: listToMap(in.buildArgs, true),
ExtraHosts: in.extraHosts,
ImageIDFile: in.imageIDFile,
Labels: listToMap(in.labels, false),
NetworkMode: in.networkMode,
NoCache: noCache,
NoCacheFilter: in.noCacheFilter,
Pull: pull,
ShmSize: in.shmSize,
Tags: in.tags,
Target: in.target,
Ulimits: in.ulimits,
PrintFunc: printFunc,
}
platforms, err := platformutil.Parse(in.platforms)
@@ -100,21 +161,26 @@ func runBuild(dockerCli command.Cli, in buildOptions) error {
}
opts.Platforms = platforms
opts.Session = append(opts.Session, authprovider.NewDockerAuthProvider())
dockerConfig := config.LoadDefaultConfigFile(os.Stderr)
opts.Session = append(opts.Session, authprovider.NewDockerAuthProvider(dockerConfig))
secrets, err := build.ParseSecretSpecs(in.secrets)
secrets, err := buildflags.ParseSecretSpecs(in.secrets)
if err != nil {
return err
}
opts.Session = append(opts.Session, secrets)
ssh, err := build.ParseSSHSpecs(in.ssh)
sshSpecs := in.ssh
if len(sshSpecs) == 0 && buildflags.IsGitSSH(in.contextPath) {
sshSpecs = []string{"default"}
}
ssh, err := buildflags.ParseSSHSpecs(sshSpecs)
if err != nil {
return err
}
opts.Session = append(opts.Session, ssh)
outputs, err := build.ParseOutputs(in.outputs)
outputs, err := buildflags.ParseOutputs(in.outputs)
if err != nil {
return err
}
@@ -152,40 +218,236 @@ func runBuild(dockerCli command.Cli, in buildOptions) error {
}
}
}
opts.Exports = outputs
cacheImports, err := build.ParseCacheEntry(in.cacheFrom)
inAttests := append([]string{}, in.attests...)
if in.provenance != "" {
inAttests = append(inAttests, buildflags.CanonicalizeAttest("provenance", in.provenance))
}
if in.sbom != "" {
inAttests = append(inAttests, buildflags.CanonicalizeAttest("sbom", in.sbom))
}
opts.Attests, err = buildflags.ParseAttests(inAttests)
if err != nil {
return err
}
cacheImports, err := buildflags.ParseCacheEntry(in.cacheFrom)
if err != nil {
return err
}
opts.CacheFrom = cacheImports
cacheExports, err := build.ParseCacheEntry(in.cacheTo)
cacheExports, err := buildflags.ParseCacheEntry(in.cacheTo)
if err != nil {
return err
}
opts.CacheTo = cacheExports
return buildTargets(ctx, dockerCli, map[string]build.Options{"default": opts}, in.progress)
}
allow, err := buildflags.ParseEntitlements(in.allow)
if err != nil {
return err
}
opts.Allow = allow
func buildTargets(ctx context.Context, dockerCli command.Cli, opts map[string]build.Options, progressMode string) error {
dis, err := getDefaultDrivers(ctx, dockerCli)
// key string used for kubernetes "sticky" mode
contextPathHash, err := filepath.Abs(in.contextPath)
if err != nil {
contextPathHash = in.contextPath
}
b, err := builder.New(dockerCli,
builder.WithName(in.builder),
builder.WithContextPathHash(contextPathHash),
)
if err != nil {
return err
}
if err = updateLastActivity(dockerCli, b.NodeGroup); err != nil {
return errors.Wrapf(err, "failed to update builder last activity time")
}
nodes, err := b.LoadNodes(ctx, false)
if err != nil {
return err
}
ctx2, cancel := context.WithCancel(context.TODO())
defer cancel()
pw := progress.NewPrinter(ctx2, os.Stderr, progressMode)
imageID, res, err := buildTargets(ctx, dockerCli, nodes, map[string]build.Options{defaultTargetName: opts}, in.progress, in.metadataFile, in.invoke != "")
err = wrapBuildError(err, false)
if err != nil {
return err
}
_, err = build.Build(ctx, dis, opts, dockerAPI(dockerCli), dockerCli.ConfigFile(), pw)
return err
if in.invoke != "" {
cfg, err := parseInvokeConfig(in.invoke)
if err != nil {
return err
}
cfg.ResultCtx = res
con := console.Current()
if err := con.SetRaw(); err != nil {
return errors.Errorf("failed to configure terminal: %v", err)
}
err = monitor.RunMonitor(ctx, cfg, func(ctx context.Context) (*build.ResultContext, error) {
_, rr, err := buildTargets(ctx, dockerCli, nodes, map[string]build.Options{defaultTargetName: opts}, in.progress, in.metadataFile, true)
return rr, err
}, io.NopCloser(os.Stdin), nopCloser{os.Stdout}, nopCloser{os.Stderr})
if err != nil {
logrus.Warnf("failed to run monitor: %v", err)
}
con.Reset()
}
if in.quiet {
fmt.Println(imageID)
}
return nil
}
func buildCmd(dockerCli command.Cli) *cobra.Command {
var options buildOptions
type nopCloser struct {
io.WriteCloser
}
func (c nopCloser) Close() error { return nil }
func buildTargets(ctx context.Context, dockerCli command.Cli, nodes []builder.Node, opts map[string]build.Options, progressMode string, metadataFile string, allowNoOutput bool) (imageID string, res *build.ResultContext, err error) {
ctx2, cancel := context.WithCancel(context.TODO())
defer cancel()
printer, err := progress.NewPrinter(ctx2, os.Stderr, os.Stderr, progressMode)
if err != nil {
return "", nil, err
}
var mu sync.Mutex
var idx int
resp, err := build.BuildWithResultHandler(ctx, nodes, opts, dockerutil.NewClient(dockerCli), confutil.ConfigDir(dockerCli), printer, func(driverIndex int, gotRes *build.ResultContext) {
mu.Lock()
defer mu.Unlock()
if res == nil || driverIndex < idx {
idx, res = driverIndex, gotRes
}
}, allowNoOutput)
err1 := printer.Wait()
if err == nil {
err = err1
}
if err != nil {
return "", nil, err
}
if len(metadataFile) > 0 && resp != nil {
if err := writeMetadataFile(metadataFile, decodeExporterResponse(resp[defaultTargetName].ExporterResponse)); err != nil {
return "", nil, err
}
}
printWarnings(os.Stderr, printer.Warnings(), progressMode)
for k := range resp {
if opts[k].PrintFunc != nil {
if err := printResult(opts[k].PrintFunc, resp[k].ExporterResponse); err != nil {
return "", nil, err
}
}
}
return resp[defaultTargetName].ExporterResponse["containerimage.digest"], res, err
}
func parseInvokeConfig(invoke string) (cfg build.ContainerConfig, err error) {
cfg.Tty = true
if invoke == "default" {
return cfg, nil
}
csvReader := csv.NewReader(strings.NewReader(invoke))
fields, err := csvReader.Read()
if err != nil {
return cfg, err
}
if len(fields) == 1 && !strings.Contains(fields[0], "=") {
cfg.Cmd = []string{fields[0]}
return cfg, nil
}
for _, field := range fields {
parts := strings.SplitN(field, "=", 2)
if len(parts) != 2 {
return cfg, errors.Errorf("invalid value %s", field)
}
key := strings.ToLower(parts[0])
value := parts[1]
switch key {
case "args":
cfg.Cmd = append(cfg.Cmd, value) // TODO: support JSON
case "entrypoint":
cfg.Entrypoint = append(cfg.Entrypoint, value) // TODO: support JSON
case "env":
cfg.Env = append(cfg.Env, value)
case "user":
cfg.User = &value
case "cwd":
cfg.Cwd = &value
case "tty":
cfg.Tty, err = strconv.ParseBool(value)
if err != nil {
return cfg, errors.Errorf("failed to parse tty: %v", err)
}
default:
return cfg, errors.Errorf("unknown key %q", key)
}
}
return cfg, nil
}
func printWarnings(w io.Writer, warnings []client.VertexWarning, mode string) {
if len(warnings) == 0 || mode == progress.PrinterModeQuiet {
return
}
fmt.Fprintf(w, "\n ")
sb := &bytes.Buffer{}
if len(warnings) == 1 {
fmt.Fprintf(sb, "1 warning found")
} else {
fmt.Fprintf(sb, "%d warnings found", len(warnings))
}
if logrus.GetLevel() < logrus.DebugLevel {
fmt.Fprintf(sb, " (use --debug to expand)")
}
fmt.Fprintf(sb, ":\n")
fmt.Fprint(w, aec.Apply(sb.String(), aec.YellowF))
for _, warn := range warnings {
fmt.Fprintf(w, " - %s\n", warn.Short)
if logrus.GetLevel() < logrus.DebugLevel {
continue
}
for _, d := range warn.Detail {
fmt.Fprintf(w, "%s\n", d)
}
if warn.URL != "" {
fmt.Fprintf(w, "More info: %s\n", warn.URL)
}
if warn.SourceInfo != nil && warn.Range != nil {
src := errdefs.Source{
Info: warn.SourceInfo,
Ranges: warn.Range,
}
src.Print(w)
}
fmt.Fprintf(w, "\n")
}
}
func newBuildOptions() buildOptions {
ulimits := make(map[string]*units.Ulimit)
return buildOptions{
ulimits: dockeropts.NewUlimitOpt(&ulimits),
}
}
func buildCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
options := newBuildOptions()
cmd := &cobra.Command{
Use: "build [OPTIONS] PATH | URL | -",
@@ -194,99 +456,291 @@ func buildCmd(dockerCli command.Cli) *cobra.Command {
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
options.contextPath = args[0]
options.builder = rootOpts.builder
cmd.Flags().VisitAll(checkWarnedFlags)
return runBuild(dockerCli, options)
},
}
var platformsDefault []string
if v := os.Getenv("DOCKER_DEFAULT_PLATFORM"); v != "" {
platformsDefault = []string{v}
}
flags := cmd.Flags()
flags.BoolVar(&options.exportPush, "push", false, "Shorthand for --output=type=registry")
flags.BoolVar(&options.exportLoad, "load", false, "Shorthand for --output=type=docker")
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-host"})
flags.StringSliceVar(&options.allow, "allow", []string{}, `Allow extra privileged entitlement (e.g., "network.host", "security.insecure")`)
flags.StringArrayVarP(&options.tags, "tag", "t", []string{}, "Name and optionally a tag in the 'name:tag' format")
flags.StringArrayVar(&options.buildArgs, "build-arg", []string{}, "Set build-time variables")
flags.StringVarP(&options.dockerfileName, "file", "f", "", "Name of the Dockerfile (Default is 'PATH/Dockerfile')")
flags.StringArrayVar(&options.cacheFrom, "cache-from", []string{}, `External cache sources (e.g., "user/app:cache", "type=local,src=path/to/dir")`)
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/#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/#file"})
flags.StringVar(&options.imageIDFile, "iidfile", "", "Write the image ID to the file")
flags.StringArrayVar(&options.labels, "label", []string{}, "Set metadata for an image")
flags.StringArrayVar(&options.cacheFrom, "cache-from", []string{}, "External cache sources (eg. user/app:cache, type=local,src=path/to/dir)")
flags.StringArrayVar(&options.cacheTo, "cache-to", []string{}, "Cache export destinations (eg. user/app:cache, type=local,dest=path/to/dir)")
flags.BoolVar(&options.exportLoad, "load", false, `Shorthand for "--output=type=docker"`)
flags.StringVar(&options.target, "target", "", "Set the target build stage to build.")
flags.StringVar(&options.networkMode, "network", "default", `Set the networking mode for the "RUN" instructions during build`)
flags.StringArrayVar(&options.noCacheFilter, "no-cache-filter", []string{}, "Do not cache specified stages")
flags.StringArrayVarP(&options.outputs, "output", "o", []string{}, `Output destination (format: "type=local,dest=path")`)
flags.StringArrayVar(&options.platforms, "platform", platformsDefault, "Set target platform for build")
if isExperimental() {
flags.StringVar(&options.printFunc, "print", "", "Print result of information request (e.g., outline, targets) [experimental]")
}
flags.BoolVar(&options.exportPush, "push", false, `Shorthand for "--output=type=registry"`)
// not implemented
flags.BoolVarP(&options.quiet, "quiet", "q", false, "Suppress the build output and print image ID on success")
flags.StringVar(&options.networkMode, "network", "default", "Set the networking mode for the RUN instructions during build")
flags.StringSliceVar(&options.extraHosts, "add-host", []string{}, "Add a custom host-to-IP mapping (host:ip)")
flags.StringVar(&options.imageIDFile, "iidfile", "", "Write the image ID to the file")
flags.BoolVar(&options.squash, "squash", false, "Squash newly built layers into a single new layer")
flags.MarkHidden("quiet")
flags.MarkHidden("squash")
flags.StringArrayVar(&options.secrets, "secret", []string{}, `Secret to expose to the build (format: "id=mysecret[,src=/local/secret]")`)
flags.Var(&options.shmSize, "shm-size", `Size of "/dev/shm"`)
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"})
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/#target"})
flags.Var(options.ulimits, "ulimit", "Ulimit options")
flags.StringArrayVar(&options.attests, "attest", []string{}, `Attestation parameters (format: "type=sbom,generator=image")`)
flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--attest=type=sbom"`)
flags.StringVar(&options.provenance, "provenance", "", `Shortand for "--attest=type=provenance"`)
if isExperimental() {
flags.StringVar(&options.invoke, "invoke", "", "Invoke a command after the build [experimental]")
}
// hidden flags
var ignore string
var ignoreSlice []string
var ignoreBool bool
var ignoreInt int64
flags.StringVar(&ignore, "ulimit", "", "Ulimit options")
flags.MarkHidden("ulimit")
flags.StringSliceVar(&ignoreSlice, "security-opt", []string{}, "Security options")
flags.MarkHidden("security-opt")
flags.BoolVar(&ignoreBool, "compress", false, "Compress the build context using gzip")
flags.MarkHidden("compress")
flags.StringVarP(&ignore, "memory", "m", "", "Memory limit")
flags.MarkHidden("memory")
flags.StringVar(&ignore, "memory-swap", "", "Swap limit equal to memory plus swap: '-1' to enable unlimited swap")
flags.MarkHidden("memory-swap")
flags.StringVar(&ignore, "shm-size", "", "Size of /dev/shm")
flags.MarkHidden("shm-size")
flags.Int64VarP(&ignoreInt, "cpu-shares", "c", 0, "CPU shares (relative weight)")
flags.MarkHidden("cpu-shares")
flags.Int64Var(&ignoreInt, "cpu-period", 0, "Limit the CPU CFS (Completely Fair Scheduler) period")
flags.MarkHidden("cpu-period")
flags.Int64Var(&ignoreInt, "cpu-quota", 0, "Limit the CPU CFS (Completely Fair Scheduler) quota")
flags.MarkHidden("cpu-quota")
flags.StringVar(&ignore, "cpuset-cpus", "", "CPUs in which to allow execution (0-3, 0,1)")
flags.MarkHidden("cpuset-cpus")
flags.StringVar(&ignore, "cpuset-mems", "", "MEMs in which to allow execution (0-3, 0,1)")
flags.MarkHidden("cpuset-mems")
flags.StringVar(&ignore, "cgroup-parent", "", "Optional parent cgroup for the container")
flags.MarkHidden("cgroup-parent")
flags.StringVar(&ignore, "isolation", "", "Container isolation technology")
flags.MarkHidden("isolation")
flags.SetAnnotation("isolation", "flag-warn", []string{"isolation flag is deprecated with BuildKit."})
platformsDefault := []string{}
if v := os.Getenv("DOCKER_DEFAULT_PLATFORM"); v != "" {
platformsDefault = []string{v}
}
flags.StringArrayVar(&options.platforms, "platform", platformsDefault, "Set target platform for build")
flags.StringSliceVar(&ignoreSlice, "security-opt", []string{}, "Security options")
flags.MarkHidden("security-opt")
flags.SetAnnotation("security-opt", "flag-warn", []string{`security-opt flag is deprecated. "RUN --security=insecure" should be used with BuildKit.`})
flags.StringArrayVar(&options.secrets, "secret", []string{}, "Secret file to expose to the build: id=mysecret,src=/local/secret")
flags.BoolVar(&ignoreBool, "squash", false, "Squash newly built layers into a single new layer")
flags.MarkHidden("squash")
flags.SetAnnotation("squash", "flag-warn", []string{"experimental flag squash is removed with BuildKit. You should squash inside build using a multi-stage Dockerfile for efficiency."})
flags.StringArrayVar(&options.ssh, "ssh", []string{}, "SSH agent socket or keys to expose to the build (format: default|<id>[=<socket>|<key>[,<key>]])")
flags.StringVarP(&ignore, "memory", "m", "", "Memory limit")
flags.MarkHidden("memory")
flags.StringArrayVarP(&options.outputs, "output", "o", []string{}, "Output destination (format: type=local,dest=path)")
flags.StringVar(&ignore, "memory-swap", "", `Swap limit equal to memory plus swap: "-1" to enable unlimited swap`)
flags.MarkHidden("memory-swap")
commonFlags(&options.commonOptions, flags)
flags.Int64VarP(&ignoreInt, "cpu-shares", "c", 0, "CPU shares (relative weight)")
flags.MarkHidden("cpu-shares")
flags.Int64Var(&ignoreInt, "cpu-period", 0, "Limit the CPU CFS (Completely Fair Scheduler) period")
flags.MarkHidden("cpu-period")
flags.Int64Var(&ignoreInt, "cpu-quota", 0, "Limit the CPU CFS (Completely Fair Scheduler) quota")
flags.MarkHidden("cpu-quota")
flags.StringVar(&ignore, "cpuset-cpus", "", `CPUs in which to allow execution ("0-3", "0,1")`)
flags.MarkHidden("cpuset-cpus")
flags.StringVar(&ignore, "cpuset-mems", "", `MEMs in which to allow execution ("0-3", "0,1")`)
flags.MarkHidden("cpuset-mems")
flags.BoolVar(&ignoreBool, "rm", true, "Remove intermediate containers after a successful build")
flags.MarkHidden("rm")
flags.BoolVar(&ignoreBool, "force-rm", false, "Always remove intermediate containers")
flags.MarkHidden("force-rm")
commonBuildFlags(&options.commonOptions, flags)
return cmd
}
func commonFlags(options *commonOptions, flags *pflag.FlagSet) {
flags.BoolVar(&options.noCache, "no-cache", false, "Do not use cache when building the image")
flags.StringVar(&options.progress, "progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output")
flags.BoolVar(&options.pull, "pull", false, "Always attempt to pull a newer version of the image")
func commonBuildFlags(options *commonOptions, flags *pflag.FlagSet) {
options.noCache = flags.Bool("no-cache", false, "Do not use cache when building the image")
flags.StringVar(&options.progress, "progress", "auto", `Set type of progress output ("auto", "plain", "tty"). Use plain to show container output`)
options.pull = flags.Bool("pull", false, "Always attempt to pull all referenced images")
flags.StringVar(&options.metadataFile, "metadata-file", "", "Write build result metadata to the file")
}
func listToMap(values []string) map[string]string {
func checkWarnedFlags(f *pflag.Flag) {
if !f.Changed {
return
}
for t, m := range f.Annotations {
switch t {
case "flag-warn":
logrus.Warn(m[0])
}
}
}
func listToMap(values []string, defaultEnv bool) map[string]string {
result := make(map[string]string, len(values))
for _, value := range values {
kv := strings.SplitN(value, "=", 2)
if len(kv) == 1 {
result[kv[0]] = ""
if defaultEnv {
v, ok := os.LookupEnv(kv[0])
if ok {
result[kv[0]] = v
}
} else {
result[kv[0]] = ""
}
} else {
result[kv[0]] = kv[1]
}
}
return result
}
func parseContextNames(values []string) (map[string]build.NamedContext, error) {
if len(values) == 0 {
return nil, nil
}
result := make(map[string]build.NamedContext, len(values))
for _, value := range values {
kv := strings.SplitN(value, "=", 2)
if len(kv) != 2 {
return nil, errors.Errorf("invalid context value: %s, expected key=value", value)
}
named, err := reference.ParseNormalizedNamed(kv[0])
if err != nil {
return nil, errors.Wrapf(err, "invalid context name %s", kv[0])
}
name := strings.TrimSuffix(reference.FamiliarString(named), ":latest")
result[name] = build.NamedContext{Path: kv[1]}
}
return result, nil
}
func parsePrintFunc(str string) (*build.PrintFunc, error) {
if str == "" {
return nil, nil
}
csvReader := csv.NewReader(strings.NewReader(str))
fields, err := csvReader.Read()
if err != nil {
return nil, err
}
f := &build.PrintFunc{}
for _, field := range fields {
parts := strings.SplitN(field, "=", 2)
if len(parts) == 2 {
if parts[0] == "format" {
f.Format = parts[1]
} else {
return nil, errors.Errorf("invalid print field: %s", field)
}
} else {
if f.Name != "" {
return nil, errors.Errorf("invalid print value: %s", str)
}
f.Name = field
}
}
return f, nil
}
func writeMetadataFile(filename string, dt interface{}) error {
b, err := json.MarshalIndent(dt, "", " ")
if err != nil {
return err
}
return ioutils.AtomicWriteFile(filename, b, 0644)
}
func decodeExporterResponse(exporterResponse map[string]string) map[string]interface{} {
out := make(map[string]interface{})
for k, v := range exporterResponse {
dt, err := base64.StdEncoding.DecodeString(v)
if err != nil {
out[k] = v
continue
}
var raw map[string]interface{}
if err = json.Unmarshal(dt, &raw); err != nil || len(raw) == 0 {
out[k] = v
continue
}
out[k] = json.RawMessage(dt)
}
return out
}
func wrapBuildError(err error, bake bool) error {
if err == nil {
return nil
}
st, ok := grpcerrors.AsGRPCStatus(err)
if ok {
if st.Code() == codes.Unimplemented && strings.Contains(st.Message(), "unsupported frontend capability moby.buildkit.frontend.contexts") {
msg := "current frontend does not support --build-context."
if bake {
msg = "current frontend does not support defining additional contexts for targets."
}
msg += " Named contexts are supported since Dockerfile v1.4. Use #syntax directive in Dockerfile or update to latest BuildKit."
return &wrapped{err, msg}
}
}
return err
}
type wrapped struct {
err error
msg string
}
func (w *wrapped) Error() string {
return w.msg
}
func (w *wrapped) Unwrap() error {
return w.err
}
func isExperimental() bool {
if v, ok := os.LookupEnv("BUILDX_EXPERIMENTAL"); ok {
vv, _ := strconv.ParseBool(v)
return vv
}
return false
}
func updateLastActivity(dockerCli command.Cli, ng *store.NodeGroup) error {
txn, release, err := storeutil.GetStore(dockerCli)
if err != nil {
return err
}
defer release()
return txn.UpdateLastActivity(ng)
}

View File

@@ -1,13 +1,27 @@
package commands
import (
"bytes"
"context"
"encoding/csv"
"fmt"
"net/url"
"os"
"strings"
"time"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/driver"
remoteutil "github.com/docker/buildx/driver/remote/util"
"github.com/docker/buildx/store"
"github.com/docker/buildx/store/storeutil"
"github.com/docker/buildx/util/cobrautil"
"github.com/docker/buildx/util/confutil"
"github.com/docker/buildx/util/dockerutil"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
dopts "github.com/docker/cli/opts"
"github.com/google/shlex"
"github.com/moby/buildkit/util/appcontext"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -22,6 +36,10 @@ type createOptions struct {
actionAppend bool
actionLeave bool
use bool
flags string
configFile string
driverOpts []string
bootstrap bool
// upgrade bool // perform upgrade of the driver
}
@@ -47,23 +65,7 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
}
}
driverName := in.driver
if driverName == "" {
f, err := driver.GetDefaultFactory(ctx, dockerCli.Client(), true)
if err != nil {
return err
}
if f == nil {
return errors.Errorf("no valid drivers found")
}
driverName = f.Name()
}
if driver.GetFactory(driverName, true) == nil {
return errors.Errorf("failed to find driver %q", in.driver)
}
txn, release, err := getStore(dockerCli)
txn, release, err := storeutil.GetStore(dockerCli)
if err != nil {
return err
}
@@ -77,6 +79,19 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
}
}
if !in.actionLeave && !in.actionAppend {
contexts, err := dockerCli.ContextStore().List()
if err != nil {
return err
}
for _, c := range contexts {
if c.Name == name {
logrus.Warnf("instance name %q already exists as context builder", name)
break
}
}
}
ng, err := txn.NodeGroupByName(name)
if err != nil {
if os.IsNotExist(errors.Cause(err)) {
@@ -84,51 +99,137 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
logrus.Warnf("failed to find %q for append, creating a new instance instead", in.name)
}
if in.actionLeave {
return errors.Errorf("failed to find instance %q for leave", name)
return errors.Errorf("failed to find instance %q for leave", in.name)
}
} else {
return err
}
}
buildkitHost := os.Getenv("BUILDKIT_HOST")
driverName := in.driver
if driverName == "" {
if ng != nil {
driverName = ng.Driver
} else if len(args) == 0 && buildkitHost != "" {
driverName = "remote"
} else {
var arg string
if len(args) > 0 {
arg = args[0]
}
f, err := driver.GetDefaultFactory(ctx, arg, dockerCli.Client(), true)
if err != nil {
return err
}
if f == nil {
return errors.Errorf("no valid drivers found")
}
driverName = f.Name()
}
}
if ng != nil {
if in.nodeName == "" && !in.actionAppend {
return errors.Errorf("existing instance for %s but no append mode, specify --node to make changes for existing instances", name)
return errors.Errorf("existing instance for %q but no append mode, specify --node to make changes for existing instances", name)
}
if driverName != ng.Driver {
return errors.Errorf("existing instance for %q but has mismatched driver %q", name, ng.Driver)
}
}
if _, err := driver.GetFactory(driverName, true); err != nil {
return err
}
ngOriginal := ng
if ngOriginal != nil {
ngOriginal = ngOriginal.Copy()
}
if ng == nil {
ng = &store.NodeGroup{
Name: name,
Name: name,
Driver: driverName,
}
}
if ng.Driver == "" || in.driver != "" {
ng.Driver = driverName
var flags []string
if in.flags != "" {
flags, err = shlex.Split(in.flags)
if err != nil {
return errors.Wrap(err, "failed to parse buildkit flags")
}
}
var ep string
var setEp bool
if in.actionLeave {
if err := ng.Leave(in.nodeName); err != nil {
return err
}
} else {
if len(args) > 0 {
switch {
case driverName == "kubernetes":
if len(args) > 0 {
logrus.Warnf("kubernetes driver does not support endpoint args %q", args[0])
}
// naming endpoint to make --append works
ep = (&url.URL{
Scheme: driverName,
Path: "/" + in.name,
RawQuery: (&url.Values{
"deployment": {in.nodeName},
"kubeconfig": {os.Getenv("KUBECONFIG")},
}).Encode(),
}).String()
setEp = false
case driverName == "remote":
if len(args) > 0 {
ep = args[0]
} else if buildkitHost != "" {
ep = buildkitHost
} else {
return errors.Errorf("no remote endpoint provided")
}
ep, err = validateBuildkitEndpoint(ep)
if err != nil {
return err
}
setEp = true
case len(args) > 0:
ep, err = validateEndpoint(dockerCli, args[0])
if err != nil {
return err
}
} else {
setEp = true
default:
if dockerCli.CurrentContext() == "default" && dockerCli.DockerEndpoint().TLSData != nil {
return errors.Errorf("could not create a builder instance with TLS data loaded from environment. Please use `docker context create <context-name>` to create a context for current environment and then create a builder instance with `docker buildx create <context-name>`")
}
ep, err = getCurrentEndpoint(dockerCli)
ep, err = dockerutil.GetCurrentEndpoint(dockerCli)
if err != nil {
return err
}
setEp = false
}
if err := ng.Update(in.nodeName, ep, in.platform, len(args) > 0, in.actionAppend); err != nil {
m, err := csvToMap(in.driverOpts)
if err != nil {
return err
}
if in.configFile == "" {
// if buildkit config is not provided, check if the default one is
// available and use it
if f, ok := confutil.DefaultConfigFile(dockerCli); ok {
logrus.Warnf("Using default BuildKit config in %s", f)
in.configFile = f
}
}
if err := ng.Update(in.nodeName, ep, in.platform, setEp, in.actionAppend, flags, in.configFile, m); err != nil {
return err
}
}
@@ -137,8 +238,41 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
return err
}
b, err := builder.New(dockerCli,
builder.WithName(ng.Name),
builder.WithStore(txn),
builder.WithSkippedValidation(),
)
if err != nil {
return err
}
timeoutCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
defer cancel()
nodes, err := b.LoadNodes(timeoutCtx, true)
if err != nil {
return err
}
for _, node := range nodes {
if err := node.Err; err != nil {
err := errors.Errorf("failed to initialize builder %s (%s): %s", ng.Name, node.Name, err)
var err2 error
if ngOriginal == nil {
err2 = txn.Remove(ng.Name)
} else {
err2 = txn.Save(ngOriginal)
}
if err2 != nil {
logrus.Warnf("Could not rollback to previous state: %s", err2)
}
return err
}
}
if in.use && ep != "" {
current, err := getCurrentEndpoint(dockerCli)
current, err := dockerutil.GetCurrentEndpoint(dockerCli)
if err != nil {
return err
}
@@ -147,6 +281,12 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
}
}
if in.bootstrap {
if _, err = b.Boot(ctx); err != nil {
return err
}
}
fmt.Printf("%s\n", ng.Name)
return nil
}
@@ -154,6 +294,14 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
func createCmd(dockerCli command.Cli) *cobra.Command {
var options createOptions
var drivers bytes.Buffer
for _, d := range driver.GetFactories(true) {
if len(drivers.String()) > 0 {
drivers.WriteString(", ")
}
drivers.WriteString(fmt.Sprintf(`"%s"`, d.Name()))
}
cmd := &cobra.Command{
Use: "create [OPTIONS] [CONTEXT|ENDPOINT]",
Short: "Create a new builder instance",
@@ -166,15 +314,66 @@ func createCmd(dockerCli command.Cli) *cobra.Command {
flags := cmd.Flags()
flags.StringVar(&options.name, "name", "", "Builder instance name")
flags.StringVar(&options.driver, "driver", "", "Driver to use (eg. docker-container)")
flags.StringVar(&options.driver, "driver", "", fmt.Sprintf("Driver to use (available: %s)", drivers.String()))
flags.StringVar(&options.nodeName, "node", "", "Create/modify node with given name")
flags.StringVar(&options.flags, "buildkitd-flags", "", "Flags for buildkitd daemon")
flags.StringVar(&options.configFile, "config", "", "BuildKit config file")
flags.StringArrayVar(&options.platform, "platform", []string{}, "Fixed platforms for current node")
flags.StringArrayVar(&options.driverOpts, "driver-opt", []string{}, "Options for the driver")
flags.BoolVar(&options.bootstrap, "bootstrap", false, "Boot builder after creation")
flags.BoolVar(&options.actionAppend, "append", false, "Append a node to builder instead of changing it")
flags.BoolVar(&options.actionLeave, "leave", false, "Remove a node from builder instead of changing it")
flags.BoolVar(&options.use, "use", false, "Set the current builder instance")
_ = flags
// hide builder persistent flag for this command
cobrautil.HideInheritedFlags(cmd, "builder")
return cmd
}
func csvToMap(in []string) (map[string]string, error) {
if len(in) == 0 {
return nil, nil
}
m := make(map[string]string, len(in))
for _, s := range in {
csvReader := csv.NewReader(strings.NewReader(s))
fields, err := csvReader.Read()
if err != nil {
return nil, err
}
for _, v := range fields {
p := strings.SplitN(v, "=", 2)
if len(p) != 2 {
return nil, errors.Errorf("invalid value %q, expecting k=v", v)
}
m[p[0]] = p[1]
}
}
return m, nil
}
// validateEndpoint validates that endpoint is either a context or a docker host
func validateEndpoint(dockerCli command.Cli, ep string) (string, error) {
dem, err := dockerutil.GetDockerEndpoint(dockerCli, ep)
if err == nil && dem != nil {
if ep == "default" {
return dem.Host, nil
}
return ep, nil
}
h, err := dopts.ParseHost(true, ep)
if err != nil {
return "", errors.Wrapf(err, "failed to parse endpoint %s", ep)
}
return h, nil
}
// validateBuildkitEndpoint validates that endpoint is a valid buildkit host
func validateBuildkitEndpoint(ep string) (string, error) {
if err := remoteutil.IsValidEndpoint(ep); err != nil {
return "", err
}
return ep, nil
}

26
commands/create_test.go Normal file
View File

@@ -0,0 +1,26 @@
package commands
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestCsvToMap(t *testing.T) {
d := []string{
"\"tolerations=key=foo,value=bar;key=foo2,value=bar2\",replicas=1",
"namespace=default",
}
r, err := csvToMap(d)
require.NoError(t, err)
require.Contains(t, r, "tolerations")
require.Equal(t, r["tolerations"], "key=foo,value=bar;key=foo2,value=bar2")
require.Contains(t, r, "replicas")
require.Equal(t, r["replicas"], "1")
require.Contains(t, r, "namespace")
require.Equal(t, r["namespace"], "default")
}

206
commands/diskusage.go Normal file
View File

@@ -0,0 +1,206 @@
package commands
import (
"fmt"
"io"
"os"
"strings"
"text/tabwriter"
"time"
"github.com/docker/buildx/builder"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/opts"
"github.com/docker/go-units"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/util/appcontext"
"github.com/spf13/cobra"
"golang.org/x/sync/errgroup"
)
type duOptions struct {
builder string
filter opts.FilterOpt
verbose bool
}
func runDiskUsage(dockerCli command.Cli, opts duOptions) error {
ctx := appcontext.Context()
pi, err := toBuildkitPruneInfo(opts.filter.Value())
if err != nil {
return err
}
b, err := builder.New(dockerCli, builder.WithName(opts.builder))
if err != nil {
return err
}
nodes, err := b.LoadNodes(ctx, false)
if err != nil {
return err
}
for _, node := range nodes {
if node.Err != nil {
return node.Err
}
}
out := make([][]*client.UsageInfo, len(nodes))
eg, ctx := errgroup.WithContext(ctx)
for i, node := range nodes {
func(i int, node builder.Node) {
eg.Go(func() error {
if node.Driver != nil {
c, err := node.Driver.Client(ctx)
if err != nil {
return err
}
du, err := c.DiskUsage(ctx, client.WithFilter(pi.Filter))
if err != nil {
return err
}
out[i] = du
return nil
}
return nil
})
}(i, node)
}
if err := eg.Wait(); err != nil {
return err
}
tw := tabwriter.NewWriter(os.Stdout, 1, 8, 1, '\t', 0)
first := true
for _, du := range out {
if du == nil {
continue
}
if opts.verbose {
printVerbose(tw, du)
} else {
if first {
printTableHeader(tw)
first = false
}
for _, di := range du {
printTableRow(tw, di)
}
tw.Flush()
}
}
if opts.filter.Value().Len() == 0 {
printSummary(tw, out)
}
tw.Flush()
return nil
}
func duCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
options := duOptions{filter: opts.NewFilterOpt()}
cmd := &cobra.Command{
Use: "du",
Short: "Disk usage",
Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
options.builder = rootOpts.builder
return runDiskUsage(dockerCli, options)
},
}
flags := cmd.Flags()
flags.Var(&options.filter, "filter", "Provide filter values")
flags.BoolVar(&options.verbose, "verbose", false, "Provide a more verbose output")
return cmd
}
func printKV(w io.Writer, k string, v interface{}) {
fmt.Fprintf(w, "%s:\t%v\n", k, v)
}
func printVerbose(tw *tabwriter.Writer, du []*client.UsageInfo) {
for _, di := range du {
printKV(tw, "ID", di.ID)
if len(di.Parents) != 0 {
printKV(tw, "Parent", strings.Join(di.Parents, ","))
}
printKV(tw, "Created at", di.CreatedAt)
printKV(tw, "Mutable", di.Mutable)
printKV(tw, "Reclaimable", !di.InUse)
printKV(tw, "Shared", di.Shared)
printKV(tw, "Size", units.HumanSize(float64(di.Size)))
if di.Description != "" {
printKV(tw, "Description", di.Description)
}
printKV(tw, "Usage count", di.UsageCount)
if di.LastUsedAt != nil {
printKV(tw, "Last used", units.HumanDuration(time.Since(*di.LastUsedAt))+" ago")
}
if di.RecordType != "" {
printKV(tw, "Type", di.RecordType)
}
fmt.Fprintf(tw, "\n")
}
tw.Flush()
}
func printTableHeader(tw *tabwriter.Writer) {
fmt.Fprintln(tw, "ID\tRECLAIMABLE\tSIZE\tLAST ACCESSED")
}
func printTableRow(tw *tabwriter.Writer, di *client.UsageInfo) {
id := di.ID
if di.Mutable {
id += "*"
}
size := units.HumanSize(float64(di.Size))
if di.Shared {
size += "*"
}
lastAccessed := ""
if di.LastUsedAt != nil {
lastAccessed = units.HumanDuration(time.Since(*di.LastUsedAt)) + " ago"
}
fmt.Fprintf(tw, "%-40s\t%-5v\t%-10s\t%s\n", id, !di.InUse, size, lastAccessed)
}
func printSummary(tw *tabwriter.Writer, dus [][]*client.UsageInfo) {
total := int64(0)
reclaimable := int64(0)
shared := int64(0)
for _, du := range dus {
for _, di := range du {
if di.Size > 0 {
total += di.Size
if !di.InUse {
reclaimable += di.Size
}
}
if di.Shared {
shared += di.Size
}
}
}
if shared > 0 {
fmt.Fprintf(tw, "Shared:\t%s\n", units.HumanSize(float64(shared)))
fmt.Fprintf(tw, "Private:\t%s\n", units.HumanSize(float64(total-shared)))
}
fmt.Fprintf(tw, "Reclaimable:\t%s\n", units.HumanSize(float64(reclaimable)))
fmt.Fprintf(tw, "Total:\t%s\n", units.HumanSize(float64(total)))
tw.Flush()
}

View File

@@ -1,12 +1,15 @@
package commands
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/util/imagetools"
"github.com/docker/buildx/util/progress"
"github.com/docker/cli/cli/command"
"github.com/docker/distribution/reference"
"github.com/moby/buildkit/util/appcontext"
@@ -18,10 +21,12 @@ import (
)
type createOptions struct {
builder string
files []string
tags []string
dryrun bool
actionAppend bool
progress string
}
func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
@@ -35,7 +40,7 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
fileArgs := make([]string, len(in.files))
for i, f := range in.files {
dt, err := ioutil.ReadFile(f)
dt, err := os.ReadFile(f)
if err != nil {
return err
}
@@ -75,35 +80,48 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
if len(repos) == 0 {
return errors.Errorf("no repositories specified, please set a reference in tag or source")
}
if len(repos) > 1 {
return errors.Errorf("multiple repositories currently not supported, found %v", repos)
}
var repo string
for r := range repos {
repo = r
var defaultRepo *string
if len(repos) == 1 {
for repo := range repos {
defaultRepo = &repo
}
}
for i, s := range srcs {
if s.Ref == nil && s.Desc.MediaType == "" && s.Desc.Digest != "" {
n, err := reference.ParseNormalizedNamed(repo)
if s.Ref == nil {
if defaultRepo == nil {
return errors.Errorf("multiple repositories specified, cannot infer repository for %q", args[i])
}
n, err := reference.ParseNormalizedNamed(*defaultRepo)
if err != nil {
return err
}
r, err := reference.WithDigest(n, s.Desc.Digest)
if err != nil {
return err
if s.Desc.MediaType == "" && s.Desc.Digest != "" {
r, err := reference.WithDigest(n, s.Desc.Digest)
if err != nil {
return err
}
srcs[i].Ref = r
sourceRefs = true
} else {
srcs[i].Ref = reference.TagNameOnly(n)
}
srcs[i].Ref = r
sourceRefs = true
}
}
ctx := appcontext.Context()
r := imagetools.New(imagetools.Opt{
Auth: dockerCli.ConfigFile(),
})
b, err := builder.New(dockerCli, builder.WithName(in.builder))
if err != nil {
return err
}
imageopt, err := b.ImageOpt()
if err != nil {
return err
}
r := imagetools.New(imageopt)
if sourceRefs {
eg, ctx2 := errgroup.WithContext(ctx)
@@ -117,8 +135,15 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
if err != nil {
return err
}
srcs[i].Ref = nil
srcs[i].Desc = desc
if srcs[i].Desc.Digest == "" {
srcs[i].Desc = desc
} else {
var err error
srcs[i].Desc, err = mergeDesc(desc, srcs[i].Desc)
if err != nil {
return err
}
}
return nil
})
}(i)
@@ -128,12 +153,7 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
}
}
descs := make([]ocispec.Descriptor, len(srcs))
for i := range descs {
descs[i] = srcs[i].Desc
}
dt, desc, err := r.Combine(ctx, repo, descs)
dt, desc, err := r.Combine(ctx, srcs)
if err != nil {
return err
}
@@ -144,31 +164,58 @@ func runCreate(dockerCli command.Cli, in createOptions, args []string) error {
}
// new resolver cause need new auth
r = imagetools.New(imagetools.Opt{
Auth: dockerCli.ConfigFile(),
})
r = imagetools.New(imageopt)
for _, t := range tags {
if err := r.Push(ctx, t, desc, dt); err != nil {
return err
}
fmt.Println(t.String())
ctx2, cancel := context.WithCancel(context.TODO())
defer cancel()
printer, err := progress.NewPrinter(ctx2, os.Stderr, os.Stderr, in.progress)
if err != nil {
return err
}
return nil
eg, _ := errgroup.WithContext(ctx)
pw := progress.WithPrefix(printer, "internal", true)
for _, t := range tags {
t := t
eg.Go(func() error {
return progress.Wrap(fmt.Sprintf("pushing %s", t.String()), pw.Write, func(sub progress.SubLogger) error {
eg2, _ := errgroup.WithContext(ctx)
for _, s := range srcs {
if reference.Domain(s.Ref) == reference.Domain(t) && reference.Path(s.Ref) == reference.Path(t) {
continue
}
s := s
eg2.Go(func() error {
sub.Log(1, []byte(fmt.Sprintf("copying %s from %s to %s\n", s.Desc.Digest.String(), s.Ref.String(), t.String())))
return r.Copy(ctx, s, t)
})
}
if err := eg2.Wait(); err != nil {
return err
}
sub.Log(1, []byte(fmt.Sprintf("pushing %s to %s\n", desc.Digest.String(), t.String())))
return r.Push(ctx, t, desc, dt)
})
})
}
err = eg.Wait()
err1 := printer.Wait()
if err == nil {
err = err1
}
return err
}
type src struct {
Desc ocispec.Descriptor
Ref reference.Named
}
func parseSources(in []string) ([]*src, error) {
out := make([]*src, len(in))
func parseSources(in []string) ([]*imagetools.Source, error) {
out := make([]*imagetools.Source, len(in))
for i, in := range in {
s, err := parseSource(in)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse source %q, valid sources are digests, refereces and descriptors", in)
return nil, errors.Wrapf(err, "failed to parse source %q, valid sources are digests, references and descriptors", in)
}
out[i] = s
}
@@ -187,11 +234,11 @@ func parseRefs(in []string) ([]reference.Named, error) {
return refs, nil
}
func parseSource(in string) (*src, error) {
func parseSource(in string) (*imagetools.Source, error) {
// source can be a digest, reference or a descriptor JSON
dgst, err := digest.Parse(in)
if err == nil {
return &src{
return &imagetools.Source{
Desc: ocispec.Descriptor{
Digest: dgst,
},
@@ -202,39 +249,54 @@ func parseSource(in string) (*src, error) {
ref, err := reference.ParseNormalizedNamed(in)
if err == nil {
return &src{
return &imagetools.Source{
Ref: ref,
}, nil
} else if !strings.HasPrefix(in, "{") {
return nil, err
}
var s src
var s imagetools.Source
if err := json.Unmarshal([]byte(in), &s.Desc); err != nil {
return nil, errors.WithStack(err)
}
return &s, nil
}
func createCmd(dockerCli command.Cli) *cobra.Command {
func createCmd(dockerCli command.Cli, opts RootOptions) *cobra.Command {
var options createOptions
cmd := &cobra.Command{
Use: "create [OPTIONS] [SOURCE] [SOURCE...]",
Short: "Create a new image based on source images",
RunE: func(cmd *cobra.Command, args []string) error {
options.builder = *opts.Builder
return runCreate(dockerCli, options, args)
},
}
flags := cmd.Flags()
flags.StringArrayVarP(&options.files, "file", "f", []string{}, "Read source descriptor from file")
flags.StringArrayVarP(&options.tags, "tag", "t", []string{}, "Set reference for new image")
flags.BoolVar(&options.dryrun, "dry-run", false, "Show final image instead of pushing")
flags.BoolVar(&options.actionAppend, "append", false, "Append to existing manifest")
_ = flags
flags.StringVar(&options.progress, "progress", "auto", `Set type of progress output ("auto", "plain", "tty"). Use plain to show container output`)
return cmd
}
func mergeDesc(d1, d2 ocispec.Descriptor) (ocispec.Descriptor, error) {
if d2.Size != 0 && d1.Size != d2.Size {
return ocispec.Descriptor{}, errors.Errorf("invalid size mismatch for %s, %d != %d", d1.Digest, d2.Size, d1.Size)
}
if d2.MediaType != "" {
d1.MediaType = d2.MediaType
}
if len(d2.Annotations) != 0 {
d1.Annotations = d2.Annotations // no merge so support removes
}
if d2.Platform != nil {
d1.Platform = d2.Platform // missing items filled in later from image config
}
return d1, nil
}

View File

@@ -1,68 +1,65 @@
package commands
import (
"fmt"
"os"
"github.com/containerd/containerd/images"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/util/imagetools"
"github.com/docker/cli-docs-tool/annotation"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/moby/buildkit/util/appcontext"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
type inspectOptions struct {
raw bool
builder string
format string
raw bool
}
func runInspect(dockerCli command.Cli, in inspectOptions, name string) error {
ctx := appcontext.Context()
r := imagetools.New(imagetools.Opt{
Auth: dockerCli.ConfigFile(),
})
if in.format != "" && in.raw {
return errors.Errorf("format and raw cannot be used together")
}
dt, desc, err := r.Get(ctx, name)
b, err := builder.New(dockerCli, builder.WithName(in.builder))
if err != nil {
return err
}
imageopt, err := b.ImageOpt()
if err != nil {
return err
}
if in.raw {
fmt.Printf("%s\n", dt)
return nil
p, err := imagetools.NewPrinter(ctx, imageopt, name, in.format)
if err != nil {
return err
}
switch desc.MediaType {
// case images.MediaTypeDockerSchema2Manifest, specs.MediaTypeImageManifest:
// TODO: handle distribution manifest and schema1
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
imagetools.PrintManifestList(dt, desc, name, os.Stdout)
default:
fmt.Printf("%s\n", dt)
}
return nil
return p.Print(in.raw, dockerCli.Out())
}
func inspectCmd(dockerCli command.Cli) *cobra.Command {
func inspectCmd(dockerCli command.Cli, rootOpts RootOptions) *cobra.Command {
var options inspectOptions
cmd := &cobra.Command{
Use: "inspect [OPTIONS] NAME",
Short: "Show details of image in the registry",
Short: "Show details of an image in the registry",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
options.builder = *rootOpts.Builder
return runInspect(dockerCli, options, args[0])
},
}
flags := cmd.Flags()
flags.BoolVar(&options.raw, "raw", false, "Show original JSON manifest")
flags.StringVar(&options.format, "format", "", "Format the output using the given Go template")
flags.SetAnnotation("format", annotation.DefaultValue, []string{`"{{.Manifest}}"`})
_ = flags
flags.BoolVar(&options.raw, "raw", false, "Show original, unformatted JSON manifest")
return cmd
}

View File

@@ -5,15 +5,19 @@ import (
"github.com/spf13/cobra"
)
func RootCmd(dockerCli command.Cli) *cobra.Command {
type RootOptions struct {
Builder *string
}
func RootCmd(dockerCli command.Cli, opts RootOptions) *cobra.Command {
cmd := &cobra.Command{
Use: "imagetools",
Short: "Commands to work on images in registry",
}
cmd.AddCommand(
inspectCmd(dockerCli),
createCmd(dockerCli),
createCmd(dockerCli, opts),
inspectCmd(dockerCli, opts),
)
return cmd

View File

@@ -8,113 +8,87 @@ import (
"text/tabwriter"
"time"
"github.com/docker/buildx/build"
"github.com/docker/buildx/driver"
"github.com/docker/buildx/store"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/util/platformutil"
"github.com/docker/buildx/util/progress"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/moby/buildkit/util/appcontext"
specs "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/cobra"
"golang.org/x/sync/errgroup"
)
type inspectOptions struct {
bootstrap bool
builder string
}
type dinfo struct {
di *build.DriverInfo
info *driver.Info
platforms []specs.Platform
err error
}
type nginfo struct {
ng *store.NodeGroup
drivers []dinfo
err error
}
func runInspect(dockerCli command.Cli, in inspectOptions, args []string) error {
func runInspect(dockerCli command.Cli, in inspectOptions) error {
ctx := appcontext.Context()
txn, release, err := getStore(dockerCli)
b, err := builder.New(dockerCli,
builder.WithName(in.builder),
builder.WithSkippedValidation(),
)
if err != nil {
return err
}
defer release()
var ng *store.NodeGroup
if len(args) > 0 {
ng, err = getNodeGroup(txn, dockerCli, args[0])
if err != nil {
return err
}
} else {
ng, err = getCurrentInstance(txn, dockerCli)
if err != nil {
return err
}
}
if ng == nil {
ng = &store.NodeGroup{
Name: "default",
Nodes: []store.Node{{
Name: "default",
Endpoint: "default",
}},
}
}
ngi := &nginfo{ng: ng}
timeoutCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
timeoutCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
defer cancel()
err = loadNodeGroupData(timeoutCtx, dockerCli, ngi)
nodes, err := b.LoadNodes(timeoutCtx, true)
if in.bootstrap {
var ok bool
ok, err = boot(ctx, ngi)
ok, err = b.Boot(ctx)
if err != nil {
return err
}
if ok {
ngi = &nginfo{ng: ng}
err = loadNodeGroupData(ctx, dockerCli, ngi)
nodes, err = b.LoadNodes(timeoutCtx, true)
}
}
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
fmt.Fprintf(w, "Name:\t%s\n", ngi.ng.Name)
fmt.Fprintf(w, "Driver:\t%s\n", ngi.ng.Driver)
fmt.Fprintf(w, "Name:\t%s\n", b.Name)
fmt.Fprintf(w, "Driver:\t%s\n", b.Driver)
if !b.NodeGroup.LastActivity.IsZero() {
fmt.Fprintf(w, "Last Activity:\t%v\n", b.NodeGroup.LastActivity)
}
if err != nil {
fmt.Fprintf(w, "Error:\t%s\n", err.Error())
} else if ngi.err != nil {
fmt.Fprintf(w, "Error:\t%s\n", ngi.err.Error())
} else if b.Err() != nil {
fmt.Fprintf(w, "Error:\t%s\n", b.Err().Error())
}
if err == nil {
fmt.Fprintln(w, "")
fmt.Fprintln(w, "Nodes:")
for i, n := range ngi.ng.Nodes {
for i, n := range nodes {
if i != 0 {
fmt.Fprintln(w, "")
}
fmt.Fprintf(w, "Name:\t%s\n", n.Name)
fmt.Fprintf(w, "Endpoint:\t%s\n", n.Endpoint)
if err := ngi.drivers[i].di.Err; err != nil {
fmt.Fprintf(w, "Error:\t%s\n", err.Error())
} else if err := ngi.drivers[i].err; err != nil {
var driverOpts []string
for k, v := range n.DriverOpts {
driverOpts = append(driverOpts, fmt.Sprintf("%s=%q", k, v))
}
if len(driverOpts) > 0 {
fmt.Fprintf(w, "Driver Options:\t%s\n", strings.Join(driverOpts, " "))
}
if err := n.Err; err != nil {
fmt.Fprintf(w, "Error:\t%s\n", err.Error())
} else {
fmt.Fprintf(w, "Status:\t%s\n", ngi.drivers[i].info.Status)
fmt.Fprintf(w, "Platforms:\t%s\n", strings.Join(platformutil.Format(platformutil.Dedupe(append(n.Platforms, ngi.drivers[i].platforms...))), ", "))
fmt.Fprintf(w, "Status:\t%s\n", nodes[i].DriverInfo.Status)
if len(n.Flags) > 0 {
fmt.Fprintf(w, "Flags:\t%s\n", strings.Join(n.Flags, " "))
}
if nodes[i].Version != "" {
fmt.Fprintf(w, "Buildkit:\t%s\n", nodes[i].Version)
}
fmt.Fprintf(w, "Platforms:\t%s\n", strings.Join(platformutil.FormatInGroups(n.Node.Platforms, n.Platforms), ", "))
}
}
}
@@ -124,7 +98,7 @@ func runInspect(dockerCli command.Cli, in inspectOptions, args []string) error {
return nil
}
func inspectCmd(dockerCli command.Cli) *cobra.Command {
func inspectCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
var options inspectOptions
cmd := &cobra.Command{
@@ -132,52 +106,16 @@ func inspectCmd(dockerCli command.Cli) *cobra.Command {
Short: "Inspect current builder instance",
Args: cli.RequiresMaxArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runInspect(dockerCli, options, args)
options.builder = rootOpts.builder
if len(args) > 0 {
options.builder = args[0]
}
return runInspect(dockerCli, options)
},
}
flags := cmd.Flags()
flags.BoolVar(&options.bootstrap, "bootstrap", false, "Ensure builder has booted before inspecting")
_ = flags
return cmd
}
func boot(ctx context.Context, ngi *nginfo) (bool, error) {
toBoot := make([]int, 0, len(ngi.drivers))
for i, d := range ngi.drivers {
if d.err != nil || d.di.Err != nil || d.di.Driver == nil || d.info == nil {
continue
}
if d.info.Status != driver.Running {
toBoot = append(toBoot, i)
}
}
if len(toBoot) == 0 {
return false, nil
}
pw := progress.NewPrinter(context.TODO(), os.Stderr, "auto")
mw := progress.NewMultiWriter(pw)
eg, _ := errgroup.WithContext(ctx)
for _, idx := range toBoot {
func(idx int) {
eg.Go(func() error {
pw := mw.WithPrefix(ngi.ng.Nodes[idx].Name, len(toBoot) > 1)
_, err := driver.Boot(ctx, ngi.drivers[idx].di.Driver, pw)
if err != nil {
ngi.drivers[idx].err = err
}
close(pw.Status())
<-pw.Done()
return nil
})
}(idx)
}
return true, eg.Wait()
}

View File

@@ -3,6 +3,7 @@ package commands
import (
"os"
"github.com/docker/buildx/util/cobrautil"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config"
@@ -48,5 +49,8 @@ func installCmd(dockerCli command.Cli) *cobra.Command {
Hidden: true,
}
// hide builder persistent flag for this command
cobrautil.HideInheritedFlags(cmd, "builder")
return cmd
}

View File

@@ -4,12 +4,13 @@ import (
"context"
"fmt"
"io"
"os"
"strings"
"text/tabwriter"
"time"
"github.com/docker/buildx/store"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/store/storeutil"
"github.com/docker/buildx/util/cobrautil"
"github.com/docker/buildx/util/platformutil"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
@@ -24,51 +25,30 @@ type lsOptions struct {
func runLs(dockerCli command.Cli, in lsOptions) error {
ctx := appcontext.Context()
txn, release, err := getStore(dockerCli)
txn, release, err := storeutil.GetStore(dockerCli)
if err != nil {
return err
}
defer release()
ctx, cancel := context.WithTimeout(ctx, 7*time.Second)
current, err := storeutil.GetCurrentInstance(txn, dockerCli)
if err != nil {
return err
}
builders, err := builder.GetBuilders(dockerCli, txn)
if err != nil {
return err
}
timeoutCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
defer cancel()
ll, err := txn.List()
if err != nil {
return err
}
builders := make([]*nginfo, len(ll))
for i, ng := range ll {
builders[i] = &nginfo{ng: ng}
}
list, err := dockerCli.ContextStore().ListContexts()
if err != nil {
return err
}
ctxbuilders := make([]*nginfo, len(list))
for i, l := range list {
ctxbuilders[i] = &nginfo{ng: &store.NodeGroup{
Name: l.Name,
Nodes: []store.Node{{
Name: l.Name,
Endpoint: l.Name,
}},
}}
}
builders = append(builders, ctxbuilders...)
eg, _ := errgroup.WithContext(ctx)
eg, _ := errgroup.WithContext(timeoutCtx)
for _, b := range builders {
func(b *nginfo) {
func(b *builder.Builder) {
eg.Go(func() error {
err = loadNodeGroupData(ctx, dockerCli, b)
if b.err == nil && err != nil {
b.err = err
}
_, _ = b.LoadNodes(timeoutCtx, true)
return nil
})
}(b)
@@ -78,62 +58,62 @@ func runLs(dockerCli command.Cli, in lsOptions) error {
return err
}
currentName := "default"
current, err := getCurrentInstance(txn, dockerCli)
if err != nil {
return err
}
if current != nil {
currentName = current.Name
if current.Name == "default" {
currentName = current.Nodes[0].Endpoint
}
}
w := tabwriter.NewWriter(dockerCli.Out(), 0, 0, 1, ' ', 0)
fmt.Fprintf(w, "NAME/NODE\tDRIVER/ENDPOINT\tSTATUS\tBUILDKIT\tPLATFORMS\n")
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
fmt.Fprintf(w, "NAME/NODE\tDRIVER/ENDPOINT\tSTATUS\tPLATFORMS\n")
currentSet := false
printErr := false
for _, b := range builders {
if !currentSet && b.ng.Name == currentName {
b.ng.Name += " *"
currentSet = true
if current.Name == b.Name {
b.Name += " *"
}
if ok := printBuilder(w, b); !ok {
printErr = true
}
printngi(w, b)
}
w.Flush()
return nil
}
func printngi(w io.Writer, ngi *nginfo) {
var err string
if ngi.err != nil {
err = ngi.err.Error()
}
fmt.Fprintf(w, "%s\t%s\t%s\t\n", ngi.ng.Name, ngi.ng.Driver, err)
if ngi.err == nil {
for idx, n := range ngi.ng.Nodes {
d := ngi.drivers[idx]
var err string
if d.err != nil {
err = d.err.Error()
} else if d.di.Err != nil {
err = d.di.Err.Error()
}
var status string
if d.info != nil {
status = d.info.Status.String()
}
p := append(n.Platforms, d.platforms...)
if err != "" {
fmt.Fprintf(w, " %s\t%s\t%s\n", n.Name, n.Endpoint, err)
if printErr {
_, _ = fmt.Fprintf(dockerCli.Err(), "\n")
for _, b := range builders {
if b.Err() != nil {
_, _ = fmt.Fprintf(dockerCli.Err(), "Cannot load builder %s: %s\n", b.Name, strings.TrimSpace(b.Err().Error()))
} else {
fmt.Fprintf(w, " %s\t%s\t%s\t%s\n", n.Name, n.Endpoint, status, strings.Join(platformutil.Format(p), ", "))
for _, d := range b.Nodes() {
if d.Err != nil {
_, _ = fmt.Fprintf(dockerCli.Err(), "Failed to get status for %s (%s): %s\n", b.Name, d.Name, strings.TrimSpace(d.Err.Error()))
}
}
}
}
}
return nil
}
func printBuilder(w io.Writer, b *builder.Builder) (ok bool) {
ok = true
var err string
if b.Err() != nil {
ok = false
err = "error"
}
fmt.Fprintf(w, "%s\t%s\t%s\t\t\n", b.Name, b.Driver, err)
if b.Err() == nil {
for _, n := range b.Nodes() {
var status string
if n.DriverInfo != nil {
status = n.DriverInfo.Status.String()
}
if n.Err != nil {
ok = false
fmt.Fprintf(w, " %s\t%s\t%s\t\t\n", n.Name, n.Endpoint, "error")
} else {
fmt.Fprintf(w, " %s\t%s\t%s\t%s\t%s\n", n.Name, n.Endpoint, status, n.Version, strings.Join(platformutil.FormatInGroups(n.Node.Platforms, n.Platforms), ", "))
}
}
}
return
}
func lsCmd(dockerCli command.Cli) *cobra.Command {
@@ -148,5 +128,8 @@ func lsCmd(dockerCli command.Cli) *cobra.Command {
},
}
// hide builder persistent flag for this command
cobrautil.HideInheritedFlags(cmd, "builder")
return cmd
}

48
commands/print.go Normal file
View File

@@ -0,0 +1,48 @@
package commands
import (
"fmt"
"io"
"log"
"os"
"github.com/docker/buildx/build"
"github.com/docker/docker/api/types/versions"
"github.com/moby/buildkit/frontend/subrequests"
"github.com/moby/buildkit/frontend/subrequests/outline"
"github.com/moby/buildkit/frontend/subrequests/targets"
)
func printResult(f *build.PrintFunc, res map[string]string) error {
switch f.Name {
case "outline":
return printValue(outline.PrintOutline, outline.SubrequestsOutlineDefinition.Version, f.Format, res)
case "targets":
return printValue(targets.PrintTargets, targets.SubrequestsTargetsDefinition.Version, f.Format, res)
case "subrequests.describe":
return printValue(subrequests.PrintDescribe, subrequests.SubrequestsDescribeDefinition.Version, f.Format, res)
default:
if dt, ok := res["result.txt"]; ok {
fmt.Print(dt)
} else {
log.Printf("%s %+v", f, res)
}
}
return nil
}
type printFunc func([]byte, io.Writer) error
func printValue(printer printFunc, version string, format string, res map[string]string) error {
if format == "json" {
fmt.Fprintln(os.Stdout, res["result.json"])
return nil
}
if res["version"] != "" && versions.LessThan(version, res["version"]) && res["result.txt"] != "" {
// structure is too new and we don't know how to print it
fmt.Fprint(os.Stdout, res["result.txt"])
return nil
}
return printer([]byte(res["result.json"]), os.Stdout)
}

205
commands/prune.go Normal file
View File

@@ -0,0 +1,205 @@
package commands
import (
"fmt"
"os"
"strings"
"text/tabwriter"
"time"
"github.com/docker/buildx/builder"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types/filters"
"github.com/docker/go-units"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/util/appcontext"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"golang.org/x/sync/errgroup"
)
type pruneOptions struct {
builder string
all bool
filter opts.FilterOpt
keepStorage opts.MemBytes
force bool
verbose bool
}
const (
normalWarning = `WARNING! This will remove all dangling build cache. Are you sure you want to continue?`
allCacheWarning = `WARNING! This will remove all build cache. Are you sure you want to continue?`
)
func runPrune(dockerCli command.Cli, opts pruneOptions) error {
ctx := appcontext.Context()
pruneFilters := opts.filter.Value()
pruneFilters = command.PruneFilters(dockerCli, pruneFilters)
pi, err := toBuildkitPruneInfo(pruneFilters)
if err != nil {
return err
}
warning := normalWarning
if opts.all {
warning = allCacheWarning
}
if !opts.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), warning) {
return nil
}
b, err := builder.New(dockerCli, builder.WithName(opts.builder))
if err != nil {
return err
}
nodes, err := b.LoadNodes(ctx, false)
if err != nil {
return err
}
for _, node := range nodes {
if node.Err != nil {
return node.Err
}
}
ch := make(chan client.UsageInfo)
printed := make(chan struct{})
tw := tabwriter.NewWriter(os.Stdout, 1, 8, 1, '\t', 0)
first := true
total := int64(0)
go func() {
defer close(printed)
for du := range ch {
total += du.Size
if opts.verbose {
printVerbose(tw, []*client.UsageInfo{&du})
} else {
if first {
printTableHeader(tw)
first = false
}
printTableRow(tw, &du)
tw.Flush()
}
}
}()
eg, ctx := errgroup.WithContext(ctx)
for _, node := range nodes {
func(node builder.Node) {
eg.Go(func() error {
if node.Driver != nil {
c, err := node.Driver.Client(ctx)
if err != nil {
return err
}
popts := []client.PruneOption{
client.WithKeepOpt(pi.KeepDuration, opts.keepStorage.Value()),
client.WithFilter(pi.Filter),
}
if opts.all {
popts = append(popts, client.PruneAll)
}
return c.Prune(ctx, ch, popts...)
}
return nil
})
}(node)
}
if err := eg.Wait(); err != nil {
return err
}
close(ch)
<-printed
tw = tabwriter.NewWriter(os.Stdout, 1, 8, 1, '\t', 0)
fmt.Fprintf(tw, "Total:\t%s\n", units.HumanSize(float64(total)))
tw.Flush()
return nil
}
func pruneCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
options := pruneOptions{filter: opts.NewFilterOpt()}
cmd := &cobra.Command{
Use: "prune",
Short: "Remove build cache",
Args: cli.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
options.builder = rootOpts.builder
return runPrune(dockerCli, options)
},
}
flags := cmd.Flags()
flags.BoolVarP(&options.all, "all", "a", false, "Include internal/frontend images")
flags.Var(&options.filter, "filter", `Provide filter values (e.g., "until=24h")`)
flags.Var(&options.keepStorage, "keep-storage", "Amount of disk space to keep for cache")
flags.BoolVar(&options.verbose, "verbose", false, "Provide a more verbose output")
flags.BoolVarP(&options.force, "force", "f", false, "Do not prompt for confirmation")
return cmd
}
func toBuildkitPruneInfo(f filters.Args) (*client.PruneInfo, error) {
var until time.Duration
untilValues := f.Get("until") // canonical
unusedForValues := f.Get("unused-for") // deprecated synonym for "until" filter
if len(untilValues) > 0 && len(unusedForValues) > 0 {
return nil, errors.Errorf("conflicting filters %q and %q", "until", "unused-for")
}
untilKey := "until"
if len(unusedForValues) > 0 {
untilKey = "unused-for"
}
untilValues = append(untilValues, unusedForValues...)
switch len(untilValues) {
case 0:
// nothing to do
case 1:
var err error
until, err = time.ParseDuration(untilValues[0])
if err != nil {
return nil, errors.Wrapf(err, "%q filter expects a duration (e.g., '24h')", untilKey)
}
default:
return nil, errors.Errorf("filters expect only one value")
}
filters := make([]string, 0, f.Len())
for _, filterKey := range f.Keys() {
if filterKey == untilKey {
continue
}
values := f.Get(filterKey)
switch len(values) {
case 0:
filters = append(filters, filterKey)
case 1:
if filterKey == "id" {
filters = append(filters, filterKey+"~="+values[0])
} else {
filters = append(filters, filterKey+"=="+values[0])
}
default:
return nil, errors.Errorf("filters expect only one value")
}
}
return &client.PruneInfo{
KeepDuration: until,
Filter: []string{strings.Join(filters, ",")},
}, nil
}

View File

@@ -2,54 +2,80 @@ package commands
import (
"context"
"fmt"
"time"
"github.com/docker/buildx/builder"
"github.com/docker/buildx/store"
"github.com/docker/buildx/store/storeutil"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/moby/buildkit/util/appcontext"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"golang.org/x/sync/errgroup"
)
type rmOptions struct {
builder string
keepState bool
keepDaemon bool
allInactive bool
force bool
}
func runRm(dockerCli command.Cli, in rmOptions, args []string) error {
const (
rmInactiveWarning = `WARNING! This will remove all builders that are not in running state. Are you sure you want to continue?`
)
func runRm(dockerCli command.Cli, in rmOptions) error {
ctx := appcontext.Context()
txn, release, err := getStore(dockerCli)
if in.allInactive && !in.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), rmInactiveWarning) {
return nil
}
txn, release, err := storeutil.GetStore(dockerCli)
if err != nil {
return err
}
defer release()
if len(args) > 0 {
ng, err := getNodeGroup(txn, dockerCli, args[0])
if err != nil {
return err
}
err1 := stop(ctx, dockerCli, ng, true)
if err := txn.Remove(ng.Name); err != nil {
return err
}
return err1
if in.allInactive {
return rmAllInactive(ctx, txn, dockerCli, in)
}
ng, err := getCurrentInstance(txn, dockerCli)
b, err := builder.New(dockerCli,
builder.WithName(in.builder),
builder.WithStore(txn),
builder.WithSkippedValidation(),
)
if err != nil {
return err
}
if ng != nil {
err1 := stop(ctx, dockerCli, ng, true)
if err := txn.Remove(ng.Name); err != nil {
return err
}
nodes, err := b.LoadNodes(ctx, false)
if err != nil {
return err
}
if cb := b.ContextName(); cb != "" {
return errors.Errorf("context builder cannot be removed, run `docker context rm %s` to remove this context", cb)
}
err1 := rm(ctx, nodes, in)
if err := txn.Remove(b.Name); err != nil {
return err
}
if err1 != nil {
return err1
}
_, _ = fmt.Fprintf(dockerCli.Err(), "%s removed\n", b.Name)
return nil
}
func rmCmd(dockerCli command.Cli) *cobra.Command {
func rmCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
var options rmOptions
cmd := &cobra.Command{
@@ -57,55 +83,79 @@ func rmCmd(dockerCli command.Cli) *cobra.Command {
Short: "Remove a builder instance",
Args: cli.RequiresMaxArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runRm(dockerCli, options, args)
options.builder = rootOpts.builder
if len(args) > 0 {
if options.allInactive {
return errors.New("cannot specify builder name when --all-inactive is set")
}
options.builder = args[0]
}
return runRm(dockerCli, options)
},
}
flags := cmd.Flags()
flags.BoolVar(&options.keepState, "keep-state", false, "Keep BuildKit state")
flags.BoolVar(&options.keepDaemon, "keep-daemon", false, "Keep the buildkitd daemon running")
flags.BoolVar(&options.allInactive, "all-inactive", false, "Remove all inactive builders")
flags.BoolVarP(&options.force, "force", "f", false, "Do not prompt for confirmation")
return cmd
}
func stop(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup, rm bool) error {
dis, err := driversForNodeGroup(ctx, dockerCli, ng)
if err != nil {
return err
}
for _, di := range dis {
if di.Driver != nil {
if err := di.Driver.Stop(ctx, true); err != nil {
func rm(ctx context.Context, nodes []builder.Node, in rmOptions) (err error) {
for _, node := range nodes {
if node.Driver == nil {
continue
}
// Do not stop the buildkitd daemon when --keep-daemon is provided
if !in.keepDaemon {
if err := node.Driver.Stop(ctx, true); err != nil {
return err
}
if rm {
if err := di.Driver.Rm(ctx, true); err != nil {
return err
}
}
}
if di.Err != nil {
err = di.Err
if err := node.Driver.Rm(ctx, true, !in.keepState, !in.keepDaemon); err != nil {
return err
}
if node.Err != nil {
err = node.Err
}
}
return err
}
func stopCurrent(ctx context.Context, dockerCli command.Cli, rm bool) error {
dis, err := getDefaultDrivers(ctx, dockerCli)
func rmAllInactive(ctx context.Context, txn *store.Txn, dockerCli command.Cli, in rmOptions) error {
builders, err := builder.GetBuilders(dockerCli, txn)
if err != nil {
return err
}
for _, di := range dis {
if di.Driver != nil {
if err := di.Driver.Stop(ctx, true); err != nil {
return err
}
if rm {
if err := di.Driver.Rm(ctx, true); err != nil {
return err
timeoutCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
defer cancel()
eg, _ := errgroup.WithContext(timeoutCtx)
for _, b := range builders {
func(b *builder.Builder) {
eg.Go(func() error {
nodes, err := b.LoadNodes(timeoutCtx, true)
if err != nil {
return errors.Wrapf(err, "cannot load %s", b.Name)
}
}
}
if di.Err != nil {
err = di.Err
}
if b.Dynamic {
return nil
}
if b.Inactive() {
rmerr := rm(ctx, nodes, in)
if err := txn.Remove(b.Name); err != nil {
return err
}
_, _ = fmt.Fprintf(dockerCli.Err(), "%s removed\n", b.Name)
return rmerr
}
return nil
})
}(b)
}
return err
return eg.Wait()
}

View File

@@ -1,40 +1,93 @@
package commands
import (
"os"
imagetoolscmd "github.com/docker/buildx/commands/imagetools"
"github.com/docker/buildx/util/logutil"
"github.com/docker/cli-docs-tool/annotation"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli-plugins/plugin"
"github.com/docker/cli/cli/command"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
func NewRootCmd(name string, isPlugin bool, dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{
Short: "Build with BuildKit",
Short: "Docker Buildx",
Long: `Extended build capabilities with BuildKit`,
Use: name,
Annotations: map[string]string{
annotation.CodeDelimiter: `"`,
},
}
if isPlugin {
cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
return plugin.PersistentPreRunE(cmd, args)
}
} else {
// match plugin behavior for standalone mode
// https://github.com/docker/cli/blob/6c9eb708fa6d17765d71965f90e1c59cea686ee9/cli-plugins/plugin/plugin.go#L117-L127
cmd.SilenceUsage = true
cmd.SilenceErrors = true
cmd.TraverseChildren = true
cmd.DisableFlagsInUseLine = true
cli.DisableFlagsInUseLine(cmd)
}
logrus.SetFormatter(&logutil.Formatter{})
logrus.AddHook(logutil.NewFilter([]logrus.Level{
logrus.DebugLevel,
},
"serving grpc connection",
"stopping session",
"using default config store",
))
// filter out useless commandConn.CloseWrite warning message that can occur
// when listing builder instances with "buildx ls" for those that are
// unreachable: "commandConn.CloseWrite: commandconn: failed to wait: signal: killed"
// https://github.com/docker/cli/blob/3fb4fb83dfb5db0c0753a8316f21aea54dab32c5/cli/connhelper/commandconn/commandconn.go#L203-L214
logrus.AddHook(logutil.NewFilter([]logrus.Level{
logrus.WarnLevel,
},
"commandConn.CloseWrite:",
"commandConn.CloseRead:",
))
addCommands(cmd, dockerCli)
return cmd
}
type rootOptions struct {
builder string
}
func addCommands(cmd *cobra.Command, dockerCli command.Cli) {
opts := &rootOptions{}
rootFlags(opts, cmd.PersistentFlags())
cmd.AddCommand(
buildCmd(dockerCli),
bakeCmd(dockerCli),
buildCmd(dockerCli, opts),
bakeCmd(dockerCli, opts),
createCmd(dockerCli),
rmCmd(dockerCli),
rmCmd(dockerCli, opts),
lsCmd(dockerCli),
useCmd(dockerCli),
inspectCmd(dockerCli),
stopCmd(dockerCli),
useCmd(dockerCli, opts),
inspectCmd(dockerCli, opts),
stopCmd(dockerCli, opts),
installCmd(dockerCli),
uninstallCmd(dockerCli),
versionCmd(dockerCli),
imagetoolscmd.RootCmd(dockerCli),
pruneCmd(dockerCli, opts),
duCmd(dockerCli, opts),
imagetoolscmd.RootCmd(dockerCli, imagetoolscmd.RootOptions{Builder: &opts.builder}),
)
}
func rootFlags(options *rootOptions, flags *pflag.FlagSet) {
flags.StringVar(&options.builder, "builder", os.Getenv("BUILDX_BUILDER"), "Override the configured builder instance")
}

View File

@@ -1,6 +1,9 @@
package commands
import (
"context"
"github.com/docker/buildx/builder"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/moby/buildkit/util/appcontext"
@@ -8,40 +11,28 @@ import (
)
type stopOptions struct {
builder string
}
func runStop(dockerCli command.Cli, in stopOptions, args []string) error {
func runStop(dockerCli command.Cli, in stopOptions) error {
ctx := appcontext.Context()
txn, release, err := getStore(dockerCli)
b, err := builder.New(dockerCli,
builder.WithName(in.builder),
builder.WithSkippedValidation(),
)
if err != nil {
return err
}
defer release()
if len(args) > 0 {
ng, err := getNodeGroup(txn, dockerCli, args[0])
if err != nil {
return err
}
if err := stop(ctx, dockerCli, ng, false); err != nil {
return err
}
return nil
}
ng, err := getCurrentInstance(txn, dockerCli)
nodes, err := b.LoadNodes(ctx, false)
if err != nil {
return err
}
if ng != nil {
return stop(ctx, dockerCli, ng, false)
}
return stopCurrent(ctx, dockerCli, false)
return stop(ctx, nodes)
}
func stopCmd(dockerCli command.Cli) *cobra.Command {
func stopCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
var options stopOptions
cmd := &cobra.Command{
@@ -49,15 +40,27 @@ func stopCmd(dockerCli command.Cli) *cobra.Command {
Short: "Stop builder instance",
Args: cli.RequiresMaxArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runStop(dockerCli, options, args)
options.builder = rootOpts.builder
if len(args) > 0 {
options.builder = args[0]
}
return runStop(dockerCli, options)
},
}
flags := cmd.Flags()
// flags.StringArrayVarP(&options.outputs, "output", "o", []string{}, "Output destination (format: type=local,dest=path)")
_ = flags
return cmd
}
func stop(ctx context.Context, nodes []builder.Node) (err error) {
for _, node := range nodes {
if node.Driver != nil {
if err := node.Driver.Stop(ctx, true); err != nil {
return err
}
}
if node.Err != nil {
err = node.Err
}
}
return err
}

View File

@@ -3,6 +3,7 @@ package commands
import (
"os"
"github.com/docker/buildx/util/cobrautil"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/config"
@@ -54,5 +55,8 @@ func uninstallCmd(dockerCli command.Cli) *cobra.Command {
Hidden: true,
}
// hide builder persistent flag for this command
cobrautil.HideInheritedFlags(cmd, "builder")
return cmd
}

View File

@@ -3,6 +3,8 @@ package commands
import (
"os"
"github.com/docker/buildx/store/storeutil"
"github.com/docker/buildx/util/dockerutil"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
"github.com/pkg/errors"
@@ -12,22 +14,23 @@ import (
type useOptions struct {
isGlobal bool
isDefault bool
builder string
}
func runUse(dockerCli command.Cli, in useOptions, name string) error {
txn, release, err := getStore(dockerCli)
func runUse(dockerCli command.Cli, in useOptions) error {
txn, release, err := storeutil.GetStore(dockerCli)
if err != nil {
return err
}
defer release()
if _, err := txn.NodeGroupByName(name); err != nil {
if _, err := txn.NodeGroupByName(in.builder); err != nil {
if os.IsNotExist(errors.Cause(err)) {
if name == "default" && name != dockerCli.CurrentContext() {
if in.builder == "default" && in.builder != dockerCli.CurrentContext() {
return errors.Errorf("run `docker context use default` to switch to default context")
}
if name == "default" || name == dockerCli.CurrentContext() {
ep, err := getCurrentEndpoint(dockerCli)
if in.builder == "default" || in.builder == dockerCli.CurrentContext() {
ep, err := dockerutil.GetCurrentEndpoint(dockerCli)
if err != nil {
return err
}
@@ -36,49 +39,50 @@ func runUse(dockerCli command.Cli, in useOptions, name string) error {
}
return nil
}
list, err := dockerCli.ContextStore().ListContexts()
list, err := dockerCli.ContextStore().List()
if err != nil {
return err
}
for _, l := range list {
if l.Name == name {
return errors.Errorf("run `docker context use %s` to switch to context %s", name, name)
if l.Name == in.builder {
return errors.Errorf("run `docker context use %s` to switch to context %s", in.builder, in.builder)
}
}
}
return errors.Wrapf(err, "failed to find instance %q", name)
return errors.Wrapf(err, "failed to find instance %q", in.builder)
}
ep, err := getCurrentEndpoint(dockerCli)
ep, err := dockerutil.GetCurrentEndpoint(dockerCli)
if err != nil {
return err
}
if err := txn.SetCurrent(ep, name, in.isGlobal, in.isDefault); err != nil {
if err := txn.SetCurrent(ep, in.builder, in.isGlobal, in.isDefault); err != nil {
return err
}
return nil
}
func useCmd(dockerCli command.Cli) *cobra.Command {
func useCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
var options useOptions
cmd := &cobra.Command{
Use: "use [OPTIONS] NAME",
Short: "Set the current builder instance",
Args: cli.ExactArgs(1),
Args: cli.RequiresMaxArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runUse(dockerCli, options, args[0])
options.builder = rootOpts.builder
if len(args) > 0 {
options.builder = args[0]
}
return runUse(dockerCli, options)
},
}
flags := cmd.Flags()
flags.BoolVar(&options.isGlobal, "global", false, "Builder persists context changes")
flags.BoolVar(&options.isDefault, "default", false, "Set builder as default for current context")
_ = flags
return cmd
}

View File

@@ -1,331 +0,0 @@
package commands
import (
"context"
"os"
"path/filepath"
"github.com/docker/buildx/build"
"github.com/docker/buildx/driver"
"github.com/docker/buildx/store"
"github.com/docker/buildx/util/platformutil"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/cli/context/docker"
dopts "github.com/docker/cli/opts"
dockerclient "github.com/docker/docker/client"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
)
// getStore returns current builder instance store
func getStore(dockerCli command.Cli) (*store.Txn, func(), error) {
dir := filepath.Dir(dockerCli.ConfigFile().Filename)
s, err := store.New(dir)
if err != nil {
return nil, nil, err
}
return s.Txn()
}
// getCurrentEndpoint returns the current default endpoint value
func getCurrentEndpoint(dockerCli command.Cli) (string, error) {
name := dockerCli.CurrentContext()
if name != "default" {
return name, nil
}
de, err := getDockerEndpoint(dockerCli, name)
if err != nil {
return "", errors.Errorf("docker endpoint for %q not found", name)
}
return de, nil
}
// getDockerEndpoint returns docker endpoint string for given context
func getDockerEndpoint(dockerCli command.Cli, name string) (string, error) {
list, err := dockerCli.ContextStore().ListContexts()
if err != nil {
return "", err
}
for _, l := range list {
if l.Name == name {
ep, ok := l.Endpoints["docker"]
if !ok {
return "", errors.Errorf("context %q does not have a Docker endpoint", name)
}
typed, ok := ep.(docker.EndpointMeta)
if !ok {
return "", errors.Errorf("endpoint %q is not of type EndpointMeta, %T", ep, ep)
}
return typed.Host, nil
}
}
return "", nil
}
// validateEndpoint validates that endpoint is either a context or a docker host
func validateEndpoint(dockerCli command.Cli, ep string) (string, error) {
de, err := getDockerEndpoint(dockerCli, ep)
if err == nil && de != "" {
if ep == "default" {
return de, nil
}
return ep, nil
}
h, err := dopts.ParseHost(true, ep)
if err != nil {
return "", errors.Wrapf(err, "failed to parse endpoint %s", ep)
}
return h, nil
}
// getCurrentInstance finds the current builder instance
func getCurrentInstance(txn *store.Txn, dockerCli command.Cli) (*store.NodeGroup, error) {
ep, err := getCurrentEndpoint(dockerCli)
if err != nil {
return nil, err
}
ng, err := txn.Current(ep)
if err != nil {
return nil, err
}
if ng == nil {
ng, _ = getNodeGroup(txn, dockerCli, dockerCli.CurrentContext())
}
return ng, nil
}
// getNodeGroup returns nodegroup based on the name
func getNodeGroup(txn *store.Txn, dockerCli command.Cli, name string) (*store.NodeGroup, error) {
ng, err := txn.NodeGroupByName(name)
if err != nil {
if !os.IsNotExist(errors.Cause(err)) {
return nil, err
}
}
if ng != nil {
return ng, nil
}
if name == "default" {
name = dockerCli.CurrentContext()
}
list, err := dockerCli.ContextStore().ListContexts()
if err != nil {
return nil, err
}
for _, l := range list {
if l.Name == name {
return &store.NodeGroup{
Name: "default",
Nodes: []store.Node{
{
Name: "default",
Endpoint: name,
},
},
}, nil
}
}
return nil, errors.Errorf("no builder %q found", name)
}
// driversForNodeGroup returns drivers for a nodegroup instance
func driversForNodeGroup(ctx context.Context, dockerCli command.Cli, ng *store.NodeGroup) ([]build.DriverInfo, error) {
eg, _ := errgroup.WithContext(ctx)
dis := make([]build.DriverInfo, len(ng.Nodes))
var f driver.Factory
if ng.Driver != "" {
f = driver.GetFactory(ng.Driver, true)
if f == nil {
return nil, errors.Errorf("failed to find driver %q", f)
}
} else {
dockerapi, err := clientForEndpoint(dockerCli, ng.Nodes[0].Endpoint)
if err != nil {
return nil, err
}
f, err = driver.GetDefaultFactory(ctx, dockerapi, false)
if err != nil {
return nil, err
}
ng.Driver = f.Name()
}
for i, n := range ng.Nodes {
func(i int, n store.Node) {
eg.Go(func() error {
di := build.DriverInfo{
Name: n.Name,
Platform: n.Platforms,
}
defer func() {
dis[i] = di
}()
dockerapi, err := clientForEndpoint(dockerCli, n.Endpoint)
if err != nil {
di.Err = err
return nil
}
// TODO: replace the following line with dockerclient.WithAPIVersionNegotiation option in clientForEndpoint
dockerapi.NegotiateAPIVersion(ctx)
d, err := driver.GetDriver(ctx, "buildx_buildkit_"+n.Name, f, dockerapi)
if err != nil {
di.Err = err
return nil
}
di.Driver = d
return nil
})
}(i, n)
}
if err := eg.Wait(); err != nil {
return nil, err
}
return dis, nil
}
// clientForEndpoint returns a docker client for an endpoint
func clientForEndpoint(dockerCli command.Cli, name string) (dockerclient.APIClient, error) {
list, err := dockerCli.ContextStore().ListContexts()
if err != nil {
return nil, err
}
for _, l := range list {
if l.Name == name {
dep, ok := l.Endpoints["docker"]
if !ok {
return nil, errors.Errorf("context %q does not have a Docker endpoint", name)
}
epm, ok := dep.(docker.EndpointMeta)
if !ok {
return nil, errors.Errorf("endpoint %q is not of type EndpointMeta, %T", dep, dep)
}
ep, err := docker.WithTLSData(dockerCli.ContextStore(), name, epm)
if err != nil {
return nil, err
}
clientOpts, err := ep.ClientOpts()
if err != nil {
return nil, err
}
return dockerclient.NewClientWithOpts(clientOpts...)
}
}
ep := docker.Endpoint{
EndpointMeta: docker.EndpointMeta{
Host: name,
},
}
clientOpts, err := ep.ClientOpts()
if err != nil {
return nil, err
}
return dockerclient.NewClientWithOpts(clientOpts...)
}
// getDefaultDrivers returns drivers based on current cli config
func getDefaultDrivers(ctx context.Context, dockerCli command.Cli) ([]build.DriverInfo, error) {
txn, release, err := getStore(dockerCli)
if err != nil {
return nil, err
}
defer release()
ng, err := getCurrentInstance(txn, dockerCli)
if err != nil {
return nil, err
}
if ng != nil {
return driversForNodeGroup(ctx, dockerCli, ng)
}
d, err := driver.GetDriver(ctx, "buildx_buildkit_default", nil, dockerCli.Client())
if err != nil {
return nil, err
}
return []build.DriverInfo{
{
Name: "default",
Driver: d,
},
}, nil
}
func loadInfoData(ctx context.Context, d *dinfo) error {
if d.di.Driver == nil {
return nil
}
info, err := d.di.Driver.Info(ctx)
if err != nil {
return err
}
d.info = info
if info.Status == driver.Running {
c, err := d.di.Driver.Client(ctx)
if err != nil {
return err
}
workers, err := c.ListWorkers(ctx)
if err != nil {
return errors.Wrap(err, "listing workers")
}
for _, w := range workers {
for _, p := range w.Platforms {
d.platforms = append(d.platforms, p)
}
}
d.platforms = platformutil.Dedupe(d.platforms)
}
return nil
}
func loadNodeGroupData(ctx context.Context, dockerCli command.Cli, ngi *nginfo) error {
eg, _ := errgroup.WithContext(ctx)
dis, err := driversForNodeGroup(ctx, dockerCli, ngi.ng)
if err != nil {
return err
}
ngi.drivers = make([]dinfo, len(dis))
for i, di := range dis {
d := di
ngi.drivers[i].di = &d
func(d *dinfo) {
eg.Go(func() error {
if err := loadInfoData(ctx, d); err != nil {
d.err = err
}
return nil
})
}(&ngi.drivers[i])
}
return eg.Wait()
}
func dockerAPI(dockerCli command.Cli) *api {
return &api{dockerCli: dockerCli}
}
type api struct {
dockerCli command.Cli
}
func (a *api) DockerAPI(name string) (dockerclient.APIClient, error) {
if name == "" {
name = a.dockerCli.CurrentContext()
}
return clientForEndpoint(a.dockerCli, name)
}

View File

@@ -3,6 +3,7 @@ package commands
import (
"fmt"
"github.com/docker/buildx/util/cobrautil"
"github.com/docker/buildx/version"
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/command"
@@ -17,11 +18,15 @@ func runVersion(dockerCli command.Cli) error {
func versionCmd(dockerCli command.Cli) *cobra.Command {
cmd := &cobra.Command{
Use: "version",
Short: "Show buildx version information ",
Short: "Show buildx version information",
Args: cli.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
return runVersion(dockerCli)
},
}
// hide builder persistent flag for this command
cobrautil.HideInheritedFlags(cmd, "builder")
return cmd
}

144
docker-bake.hcl Normal file
View File

@@ -0,0 +1,144 @@
variable "GO_VERSION" {
default = "1.19"
}
variable "DOCS_FORMATS" {
default = "md"
}
variable "DESTDIR" {
default = "./bin"
}
# Special target: https://github.com/docker/metadata-action#bake-definition
target "meta-helper" {
tags = ["docker/buildx-bin:local"]
}
target "_common" {
args = {
GO_VERSION = GO_VERSION
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
}
}
group "default" {
targets = ["binaries"]
}
group "validate" {
targets = ["lint", "validate-vendor", "validate-docs"]
}
target "lint" {
inherits = ["_common"]
dockerfile = "./hack/dockerfiles/lint.Dockerfile"
output = ["type=cacheonly"]
}
target "validate-vendor" {
inherits = ["_common"]
dockerfile = "./hack/dockerfiles/vendor.Dockerfile"
target = "validate"
output = ["type=cacheonly"]
}
target "validate-docs" {
inherits = ["_common"]
args = {
FORMATS = DOCS_FORMATS
BUILDX_EXPERIMENTAL = 1 // enables experimental cmds/flags for docs generation
}
dockerfile = "./hack/dockerfiles/docs.Dockerfile"
target = "validate"
output = ["type=cacheonly"]
}
target "validate-authors" {
inherits = ["_common"]
dockerfile = "./hack/dockerfiles/authors.Dockerfile"
target = "validate"
output = ["type=cacheonly"]
}
target "update-vendor" {
inherits = ["_common"]
dockerfile = "./hack/dockerfiles/vendor.Dockerfile"
target = "update"
output = ["."]
}
target "update-docs" {
inherits = ["_common"]
args = {
FORMATS = DOCS_FORMATS
BUILDX_EXPERIMENTAL = 1 // enables experimental cmds/flags for docs generation
}
dockerfile = "./hack/dockerfiles/docs.Dockerfile"
target = "update"
output = ["./docs/reference"]
}
target "update-authors" {
inherits = ["_common"]
dockerfile = "./hack/dockerfiles/authors.Dockerfile"
target = "update"
output = ["."]
}
target "mod-outdated" {
inherits = ["_common"]
dockerfile = "./hack/dockerfiles/vendor.Dockerfile"
target = "outdated"
no-cache-filter = ["outdated"]
output = ["type=cacheonly"]
}
target "test" {
inherits = ["_common"]
target = "test-coverage"
output = ["${DESTDIR}/coverage"]
}
target "binaries" {
inherits = ["_common"]
target = "binaries"
output = ["${DESTDIR}/build"]
platforms = ["local"]
}
target "binaries-cross" {
inherits = ["binaries"]
platforms = [
"darwin/amd64",
"darwin/arm64",
"linux/amd64",
"linux/arm/v6",
"linux/arm/v7",
"linux/arm64",
"linux/ppc64le",
"linux/riscv64",
"linux/s390x",
"windows/amd64",
"windows/arm64"
]
}
target "release" {
inherits = ["binaries-cross"]
target = "release"
output = ["${DESTDIR}/release"]
}
target "image" {
inherits = ["meta-helper", "binaries"]
output = ["type=image"]
}
target "image-cross" {
inherits = ["meta-helper", "binaries-cross"]
output = ["type=image"]
}
target "image-local" {
inherits = ["image"]
output = ["type=docker"]
}

90
docs/generate.go Normal file
View File

@@ -0,0 +1,90 @@
package main
import (
"log"
"os"
"github.com/docker/buildx/commands"
clidocstool "github.com/docker/cli-docs-tool"
"github.com/docker/cli/cli/command"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
// import drivers otherwise factories are empty
// for --driver output flag usage
_ "github.com/docker/buildx/driver/docker"
_ "github.com/docker/buildx/driver/docker-container"
_ "github.com/docker/buildx/driver/kubernetes"
_ "github.com/docker/buildx/driver/remote"
)
const defaultSourcePath = "docs/reference/"
type options struct {
source string
formats []string
}
func gen(opts *options) error {
log.SetFlags(0)
dockerCLI, err := command.NewDockerCli()
if err != nil {
return err
}
cmd := &cobra.Command{
Use: "docker [OPTIONS] COMMAND [ARG...]",
Short: "The base command for the Docker CLI.",
DisableAutoGenTag: true,
}
cmd.AddCommand(commands.NewRootCmd("buildx", true, dockerCLI))
c, err := clidocstool.New(clidocstool.Options{
Root: cmd,
SourceDir: opts.source,
Plugin: true,
})
if err != nil {
return err
}
for _, format := range opts.formats {
switch format {
case "md":
if err = c.GenMarkdownTree(cmd); err != nil {
return err
}
case "yaml":
if err = c.GenYamlTree(cmd); err != nil {
return err
}
default:
return errors.Errorf("unknown format %q", format)
}
}
return nil
}
func run() error {
opts := &options{}
flags := pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError)
flags.StringVar(&opts.source, "source", defaultSourcePath, "Docs source folder")
flags.StringSliceVar(&opts.formats, "formats", []string{}, "Format (md, yaml)")
if err := flags.Parse(os.Args[1:]); err != nil {
return err
}
if len(opts.formats) == 0 {
return errors.New("Docs format required")
}
return gen(opts)
}
func main() {
if err := run(); err != nil {
log.Printf("ERROR: %+v", err)
os.Exit(1)
}
}

48
docs/guides/cicd.md Normal file
View File

@@ -0,0 +1,48 @@
# CI/CD
## GitHub Actions
Docker provides a [GitHub Action that will build and push your image](https://github.com/docker/build-push-action/#about)
using Buildx. Here is a simple workflow:
```yaml
name: ci
on:
push:
branches:
- 'main'
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v2
with:
push: true
tags: user/app:latest
```
In this example we are also using 3 other actions:
* [`setup-buildx`](https://github.com/docker/setup-buildx-action) action will create and boot a builder using by
default the `docker-container` [builder driver](https://docs.docker.com/engine/reference/commandline/buildx_create/#driver).
This is **not required but recommended** using it to be able to build multi-platform images, export cache, etc.
* [`setup-qemu`](https://github.com/docker/setup-qemu-action) action can be useful if you want
to add emulation support with QEMU to be able to build against more platforms.
* [`login`](https://github.com/docker/login-action) action will take care to log
in against a Docker registry.

View File

@@ -0,0 +1,23 @@
# CNI networking
It can be useful to use a bridge network for your builder if for example you
encounter a network port contention during multiple builds. If you're using
the BuildKit image, CNI is not yet available in it, but you can create
[a custom BuildKit image with CNI support](https://github.com/moby/buildkit/blob/master/docs/cni-networking.md).
Now build this image:
```console
$ docker buildx build --tag buildkit-cni:local --load .
```
Then [create a `docker-container` builder](https://docs.docker.com/engine/reference/commandline/buildx_create/) that
will use this image:
```console
$ docker buildx create --use \
--name mybuilder \
--driver docker-container \
--driver-opt "image=buildkit-cni:local" \
--buildkitd-flags "--oci-worker-net=cni"
```

View File

@@ -0,0 +1,20 @@
# Color output controls
Buildx has support for modifying the colors that are used to output information
to the terminal. You can set the environment variable `BUILDKIT_COLORS` to
something like `run=123,20,245:error=yellow:cancel=blue:warning=white` to set
the colors that you would like to use:
![Progress output custom colors](https://user-images.githubusercontent.com/1951866/180584033-24522385-cafd-4a54-a4a2-18f5ce74eb27.png)
Setting `NO_COLOR` to anything will disable any colorized output as recommended
by [no-color.org](https://no-color.org/):
![Progress output no color](https://user-images.githubusercontent.com/1951866/180584037-e28f9997-dd4c-49cf-8b26-04864815de19.png)
> **Note**
>
> Parsing errors will be reported but ignored. This will result in default
> color values being used where needed.
See also [the list of pre-defined colors](https://github.com/moby/buildkit/blob/master/util/progress/progressui/colors.go).

View File

@@ -0,0 +1,34 @@
# Using a custom network
[Create a network](https://docs.docker.com/engine/reference/commandline/network_create/)
named `foonet`:
```console
$ docker network create foonet
```
[Create a `docker-container` builder](https://docs.docker.com/engine/reference/commandline/buildx_create/)
named `mybuilder` that will use this network:
```console
$ docker buildx create --use \
--name mybuilder \
--driver docker-container \
--driver-opt "network=foonet"
```
Boot and [inspect `mybuilder`](https://docs.docker.com/engine/reference/commandline/buildx_inspect/):
```console
$ docker buildx inspect --bootstrap
```
[Inspect the builder container](https://docs.docker.com/engine/reference/commandline/inspect/)
and see what network is being used:
{% raw %}
```console
$ docker inspect buildx_buildkit_mybuilder0 --format={{.NetworkSettings.Networks}}
map[foonet:0xc00018c0c0]
```
{% endraw %}

View File

@@ -0,0 +1,63 @@
# Using a custom registry configuration
If you [create a `docker-container` or `kubernetes` builder](https://docs.docker.com/engine/reference/commandline/buildx_create/) and
have specified certificates for registries in the [BuildKit daemon configuration](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md),
the files will be copied into the container under `/etc/buildkit/certs` and
configuration will be updated to reflect that.
Take the following `buildkitd.toml` configuration that will be used for
pushing an image to this registry using self-signed certificates:
```toml
# /etc/buildkitd.toml
debug = true
[registry."myregistry.com"]
ca=["/etc/certs/myregistry.pem"]
[[registry."myregistry.com".keypair]]
key="/etc/certs/myregistry_key.pem"
cert="/etc/certs/myregistry_cert.pem"
```
Here we have configured a self-signed certificate for `myregistry.com` registry.
Now [create a `docker-container` builder](https://docs.docker.com/engine/reference/commandline/buildx_create/)
that will use this BuildKit configuration:
```console
$ docker buildx create --use \
--name mybuilder \
--driver docker-container \
--config /etc/buildkitd.toml
```
Inspecting the builder container, you can see that buildkitd configuration
has changed:
```console
$ docker exec -it buildx_buildkit_mybuilder0 cat /etc/buildkit/buildkitd.toml
```
```toml
debug = true
[registry]
[registry."myregistry.com"]
ca = ["/etc/buildkit/certs/myregistry.com/myregistry.pem"]
[[registry."myregistry.com".keypair]]
cert = "/etc/buildkit/certs/myregistry.com/myregistry_cert.pem"
key = "/etc/buildkit/certs/myregistry.com/myregistry_key.pem"
```
And certificates copied inside the container:
```console
$ docker exec -it buildx_buildkit_mybuilder0 ls /etc/buildkit/certs/myregistry.com/
myregistry.pem myregistry_cert.pem myregistry_key.pem
```
Now you should be able to push to the registry with this builder:
```console
$ docker buildx build --push --tag myregistry.com/myimage:latest .
```

View File

@@ -0,0 +1,31 @@
# OpenTelemetry support
To capture the trace to [Jaeger](https://github.com/jaegertracing/jaeger), set
`JAEGER_TRACE` environment variable to the collection address using a `driver-opt`.
First create a Jaeger container:
```console
$ docker run -d --name jaeger -p "6831:6831/udp" -p "16686:16686" jaegertracing/all-in-one
```
Then [create a `docker-container` builder](https://docs.docker.com/engine/reference/commandline/buildx_create/)
that will use the Jaeger instance via the `JAEGER_TRACE` env var:
```console
$ docker buildx create --use \
--name mybuilder \
--driver docker-container \
--driver-opt "network=host" \
--driver-opt "env.JAEGER_TRACE=localhost:6831"
```
Boot and [inspect `mybuilder`](https://docs.docker.com/engine/reference/commandline/buildx_inspect/):
```console
$ docker buildx inspect --bootstrap
```
Buildx commands should be traced at `http://127.0.0.1:16686/`:
![OpenTelemetry Buildx Bake](https://user-images.githubusercontent.com/1951866/124468052-ef085400-dd98-11eb-84ab-7ac8e261dd52.png)

View File

@@ -0,0 +1,62 @@
# Registry mirror
You can define a registry mirror to use for your builds by providing a [BuildKit daemon configuration](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md)
while creating a builder with the [`--config` flags](https://docs.docker.com/engine/reference/commandline/buildx_create/#config).
```toml
# /etc/buildkitd.toml
debug = true
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]
```
> **Note**
>
> `debug = true` has been added to be able to debug requests
> in the BuildKit daemon and see if the mirror is effectively used.
Then [create a `docker-container` builder](https://docs.docker.com/engine/reference/commandline/buildx_create/)
that will use this BuildKit configuration:
```console
$ docker buildx create --use \
--name mybuilder \
--driver docker-container \
--config /etc/buildkitd.toml
```
Boot and [inspect `mybuilder`](https://docs.docker.com/engine/reference/commandline/buildx_inspect/):
```console
$ docker buildx inspect --bootstrap
```
Build an image:
```console
$ docker buildx build --load . -f-<<EOF
FROM alpine
RUN echo "hello world"
EOF
```
Now let's check the BuildKit logs in the builder container:
```console
$ docker logs buildx_buildkit_mybuilder0
```
```text
...
time="2022-02-06T17:47:48Z" level=debug msg="do request" request.header.accept="application/vnd.docker.container.image.v1+json, */*" request.header.user-agent=containerd/1.5.8+unknown request.method=GET spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg="fetch response received" response.header.accept-ranges=bytes response.header.age=1356 response.header.alt-svc="h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"" response.header.cache-control="public, max-age=3600" response.header.content-length=1469 response.header.content-type=application/octet-stream response.header.date="Sun, 06 Feb 2022 17:25:17 GMT" response.header.etag="\"774380abda8f4eae9a149e5d5d3efc83\"" response.header.expires="Sun, 06 Feb 2022 18:25:17 GMT" response.header.last-modified="Wed, 24 Nov 2021 21:07:57 GMT" response.header.server=UploadServer response.header.x-goog-generation=1637788077652182 response.header.x-goog-hash="crc32c=V3DSrg==" response.header.x-goog-hash.1="md5=d0OAq9qPTq6aFJ5dXT78gw==" response.header.x-goog-metageneration=1 response.header.x-goog-storage-class=STANDARD response.header.x-goog-stored-content-encoding=identity response.header.x-goog-stored-content-length=1469 response.header.x-guploader-uploadid=ADPycduqQipVAXc3tzXmTzKQ2gTT6CV736B2J628smtD1iDytEyiYCgvvdD8zz9BT1J1sASUq9pW_ctUyC4B-v2jvhIxnZTlKg response.status="200 OK" spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg="fetch response received" response.header.accept-ranges=bytes response.header.age=760 response.header.alt-svc="h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"" response.header.cache-control="public, max-age=3600" response.header.content-length=1471 response.header.content-type=application/octet-stream response.header.date="Sun, 06 Feb 2022 17:35:13 GMT" response.header.etag="\"35d688bd15327daafcdb4d4395e616a8\"" response.header.expires="Sun, 06 Feb 2022 18:35:13 GMT" response.header.last-modified="Wed, 24 Nov 2021 21:07:12 GMT" response.header.server=UploadServer response.header.x-goog-generation=1637788032100793 response.header.x-goog-hash="crc32c=aWgRjA==" response.header.x-goog-hash.1="md5=NdaIvRUyfar8201DleYWqA==" response.header.x-goog-metageneration=1 response.header.x-goog-storage-class=STANDARD response.header.x-goog-stored-content-encoding=identity response.header.x-goog-stored-content-length=1471 response.header.x-guploader-uploadid=ADPycdtR-gJYwC7yHquIkJWFFG8FovDySvtmRnZBqlO3yVDanBXh_VqKYt400yhuf0XbQ3ZMB9IZV2vlcyHezn_Pu3a1SMMtiw response.status="200 OK" spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg=fetch spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg=fetch spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg=fetch spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg=fetch spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg="do request" request.header.accept="application/vnd.docker.image.rootfs.diff.tar.gzip, */*" request.header.user-agent=containerd/1.5.8+unknown request.method=GET spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
time="2022-02-06T17:47:48Z" level=debug msg="fetch response received" response.header.accept-ranges=bytes response.header.age=1356 response.header.alt-svc="h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"" response.header.cache-control="public, max-age=3600" response.header.content-length=2818413 response.header.content-type=application/octet-stream response.header.date="Sun, 06 Feb 2022 17:25:17 GMT" response.header.etag="\"1d55e7be5a77c4a908ad11bc33ebea1c\"" response.header.expires="Sun, 06 Feb 2022 18:25:17 GMT" response.header.last-modified="Wed, 24 Nov 2021 21:07:06 GMT" response.header.server=UploadServer response.header.x-goog-generation=1637788026431708 response.header.x-goog-hash="crc32c=ZojF+g==" response.header.x-goog-hash.1="md5=HVXnvlp3xKkIrRG8M+vqHA==" response.header.x-goog-metageneration=1 response.header.x-goog-storage-class=STANDARD response.header.x-goog-stored-content-encoding=identity response.header.x-goog-stored-content-length=2818413 response.header.x-guploader-uploadid=ADPycdsebqxiTBJqZ0bv9zBigjFxgQydD2ESZSkKchpE0ILlN9Ibko3C5r4fJTJ4UR9ddp-UBd-2v_4eRpZ8Yo2llW_j4k8WhQ response.status="200 OK" spanID=9460e5b6e64cec91 traceID=b162d3040ddf86d6614e79c66a01a577
...
```
As you can see, requests come from the GCR registry mirror (`response.header.x-goog*`).

View File

@@ -0,0 +1,33 @@
# Resource limiting
## Max parallelism
You can limit the parallelism of the BuildKit solver, which is particularly useful
for low-powered machines, using a [BuildKit daemon configuration](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md)
while creating a builder with the [`--config` flags](https://docs.docker.com/engine/reference/commandline/buildx_create/#config).
```toml
# /etc/buildkitd.toml
[worker.oci]
max-parallelism = 4
```
Now you can [create a `docker-container` builder](https://docs.docker.com/engine/reference/commandline/buildx_create/)
that will use this BuildKit configuration to limit parallelism.
```console
$ docker buildx create --use \
--name mybuilder \
--driver docker-container \
--config /etc/buildkitd.toml
```
## Limit on TCP connections
We are also now limiting TCP connections to **4 per registry** with an additional
connection not used for layer pulls and pushes. This limitation will be able to
manage TCP connection per host to avoid your build being stuck while pulling
images. The additional connection is used for metadata requests
(image config retrieval) to enhance the overall build time.
More info: [moby/buildkit#2259](https://github.com/moby/buildkit/pull/2259)

14
docs/manuals/README.md Normal file
View File

@@ -0,0 +1,14 @@
# Buildx manuals 📚
This directory contains a bunch of useful docs for how to use Buildx features.
> **Note**
>
> The markdown files in this directory (excluding this README) are reused
> downstream by the
> [Docker documentation repository](https://github.com/docker/docs).
>
> If you wish to contribute to these docs, be sure to first review the
> [documentation contribution guidelines](https://docs.docker.com/contribute/overview/).
>
> Thank you!

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

3
docs/manuals/cache/backends/azblob.md vendored Normal file
View File

@@ -0,0 +1,3 @@
# Azure Blob Storage cache storage
Moved to [docs.docker.com](https://docs.docker.com/build/building/cache/backends/azblob)

3
docs/manuals/cache/backends/gha.md vendored Normal file
View File

@@ -0,0 +1,3 @@
# GitHub Actions cache storage
Moved to [docs.docker.com](https://docs.docker.com/build/building/cache/backends/gha)

3
docs/manuals/cache/backends/index.md vendored Normal file
View File

@@ -0,0 +1,3 @@
# Cache storage backends
Moved to [docs.docker.com](https://docs.docker.com/build/building/cache/backends)

3
docs/manuals/cache/backends/inline.md vendored Normal file
View File

@@ -0,0 +1,3 @@
# Inline cache storage
Moved to [docs.docker.com](https://docs.docker.com/build/building/cache/backends/inline)

3
docs/manuals/cache/backends/local.md vendored Normal file
View File

@@ -0,0 +1,3 @@
# Local cache storage
Moved to [docs.docker.com](https://docs.docker.com/build/building/cache/backends/local)

View File

@@ -0,0 +1,3 @@
# Registry cache storage
Moved to [docs.docker.com](https://docs.docker.com/build/building/cache/backends/registry)

3
docs/manuals/cache/backends/s3.md vendored Normal file
View File

@@ -0,0 +1,3 @@
# Amazon S3 cache storage
Moved to [docs.docker.com](https://docs.docker.com/build/building/cache/backends/s3)

View File

@@ -0,0 +1,3 @@
# Docker container driver
Moved to [docs.docker.com](https://docs.docker.com/build/building/drivers/docker-container)

View File

@@ -0,0 +1,3 @@
# Docker driver
Moved to [docs.docker.com](https://docs.docker.com/build/building/drivers/docker)

View File

@@ -0,0 +1,3 @@
# Buildx drivers overview
Moved to [docs.docker.com](https://docs.docker.com/build/building/drivers)

View File

@@ -0,0 +1,3 @@
# Kubernetes driver
Moved to [docs.docker.com](https://docs.docker.com/build/building/drivers/kubernetes)

View File

@@ -0,0 +1,3 @@
# Remote driver
Moved to [docs.docker.com](https://docs.docker.com/build/building/drivers/remote)

View File

@@ -0,0 +1,3 @@
# Image and registry exporters
Moved to [docs.docker.com](https://docs.docker.com/build/building/exporters/image-registry)

View File

@@ -0,0 +1,3 @@
# Exporters overview
Moved to [docs.docker.com](https://docs.docker.com/build/building/exporters)

View File

@@ -0,0 +1,3 @@
# Local and tar exporters
Moved to [docs.docker.com](https://docs.docker.com/build/building/exporters/local-tar)

View File

@@ -0,0 +1,3 @@
# OCI and Docker exporters
Moved to [docs.docker.com](https://docs.docker.com/build/building/exporters/oci-docker)

43
docs/reference/buildx.md Normal file
View File

@@ -0,0 +1,43 @@
# buildx
```
docker buildx [OPTIONS] COMMAND
```
<!---MARKER_GEN_START-->
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 |
### Options
| Name | Type | Default | Description |
|:------------------------|:---------|:--------|:-----------------------------------------|
| [`--builder`](#builder) | `string` | | Override the configured builder instance |
<!---MARKER_GEN_END-->
## Examples
### <a name="builder"></a> Override the configured builder instance (--builder)
You can also use the `BUILDX_BUILDER` environment variable.

View File

@@ -0,0 +1,174 @@
# buildx bake
```
docker buildx bake [OPTIONS] [TARGET...]
```
<!---MARKER_GEN_START-->
Build from a file
### Aliases
`docker buildx bake`, `docker buildx f`
### 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`](#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-->
## Description
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/bake/)
guide for introduction to writing bake files.
> **Note**
>
> `buildx bake` command may receive backwards incompatible features in the future
> if needed. We are looking for feedback on improving the command and extending
> the functionality further.
## Examples
### <a name="builder"></a> Override the configured builder instance (--builder)
Same as [`buildx --builder`](buildx.md#builder).
### <a name="file"></a> Specify a build definition file (-f, --file)
Use the `-f` / `--file` option to specify the build definition file to use.
The file can be an HCL, JSON or Compose file. If multiple files are specified
they are all read and configurations are combined.
You can pass the names of the targets to build, to build only specific target(s).
The following example builds the `db` and `webapp-release` targets that are
defined in the `docker-bake.dev.hcl` file:
```hcl
# docker-bake.dev.hcl
group "default" {
targets = ["db", "webapp-dev"]
}
target "webapp-dev" {
dockerfile = "Dockerfile.webapp"
tags = ["docker.io/username/webapp"]
}
target "webapp-release" {
inherits = ["webapp-dev"]
platforms = ["linux/amd64", "linux/arm64"]
}
target "db" {
dockerfile = "Dockerfile.db"
tags = ["docker.io/username/db"]
}
```
```console
$ docker buildx bake -f docker-bake.dev.hcl db webapp-release
```
See our [file definition](https://docs.docker.com/build/bake/file-definition/)
guide for more details.
### <a name="no-cache"></a> Do not use cache when building the image (--no-cache)
Same as `build --no-cache`. Do not use cache when building the image.
### <a name="print"></a> Print the options without building (--print)
Prints the resulting options of the targets desired to be built, in a JSON
format, without starting a build.
```console
$ docker buildx bake -f docker-bake.hcl --print db
{
"group": {
"default": {
"targets": [
"db"
]
}
},
"target": {
"db": {
"context": "./",
"dockerfile": "Dockerfile",
"tags": [
"docker.io/tiborvass/db"
]
}
}
}
```
### <a name="progress"></a> Set type of progress output (--progress)
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)
```
--set targetpattern.key[.subkey]=value
```
Override target configurations from command line. The pattern matching syntax
is defined in https://golang.org/pkg/path/#Match.
```console
$ docker buildx bake --set target.args.mybuildarg=value
$ docker buildx bake --set target.platform=linux/arm64
$ docker buildx bake --set foo*.args.mybuildarg=value # overrides build arg for all targets starting with 'foo'
$ docker buildx bake --set *.platform=linux/arm64 # overrides platform for all targets
$ docker buildx bake --set foo*.no-cache # bypass caching only for targets starting with 'foo'
```
Complete list of overridable fields:
* `args`
* `cache-from`
* `cache-to`
* `context`
* `dockerfile`
* `labels`
* `no-cache`
* `no-cache-filter`
* `output`
* `platform`
* `pull`
* `push`
* `secrets`
* `ssh`
* `tags`
* `target`

View File

@@ -0,0 +1,620 @@
# buildx build
```
docker buildx build [OPTIONS] PATH | URL | -
```
<!---MARKER_GEN_START-->
Start a build
### Aliases
`docker buildx build`, `docker buildx b`
### 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-->
Flags marked with `[experimental]` need to be explicitly enabled by setting the
`BUILDX_EXPERIMENTAL=1` environment variable.
## Description
The `buildx build` command starts a build using BuildKit. This command is similar
to the UI of `docker build` command and takes the same flags and arguments.
For documentation on most of these flags, refer to the [`docker build`
documentation](https://docs.docker.com/engine/reference/commandline/build/). In
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)
```
--allow=ENTITLEMENT
```
Allow extra privileged entitlement. List of entitlements:
- `network.host` - Allows executions with host networking.
- `security.insecure` - Allows executions without sandbox. See
[related Dockerfile extensions](https://docs.docker.com/engine/reference/builder/#run---securitysandbox).
For entitlements to be enabled, the `buildkitd` daemon also needs to allow them
with `--allow-insecure-entitlement` (see [`create --buildkitd-flags`](buildx_create.md#buildkitd-flags))
**Examples**
```console
$ docker buildx create --use --name insecure-builder --buildkitd-flags '--allow-insecure-entitlement security.insecure'
$ 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/#build-arg).
There are also useful built-in build args like:
* `BUILDKIT_CONTEXT_KEEP_GIT_DIR=<bool>` trigger git context to keep the `.git` directory
* `BUILDKIT_INLINE_BUILDINFO_ATTRS=<bool>` inline build info attributes in image config or not
* `BUILDKIT_INLINE_CACHE=<bool>` inline cache metadata to image config or not
* `BUILDKIT_MULTI_PLATFORM=<bool>` opt into deterministic output regardless of multi-platform output or not
```console
$ docker buildx build --build-arg BUILDKIT_MULTI_PLATFORM=1 .
```
> **Note**
>
> More built-in build args can be found in [Dockerfile reference docs](https://docs.docker.com/engine/reference/builder/#buildkit-built-in-build-args).
### <a name="build-context"></a> Additional build contexts (--build-context)
```
--build-context=name=VALUE
```
Define additional build context with specified contents. In Dockerfile the context can be accessed when `FROM name` or `--from=name` is used.
When Dockerfile defines a stage with the same name it is overwritten.
The value can be a local source directory, [local OCI layout compliant directory](https://github.com/opencontainers/image-spec/blob/main/image-layout.md), container image (with docker-image:// prefix), Git or HTTP URL.
Replace `alpine:latest` with a pinned one:
```console
$ docker buildx build --build-context alpine=docker-image://alpine@sha256:0123456789 .
```
Expose a secondary local source directory:
```console
$ docker buildx build --build-context project=path/to/project/source .
# docker buildx build --build-context project=https://github.com/myuser/project.git .
```
```dockerfile
# syntax=docker/dockerfile:1
FROM alpine
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),
either by tag, or by digest:
```console
$ 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
# syntax=docker/dockerfile:1
FROM alpine
RUN apk add git
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).
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)
Same as [`buildx --builder`](buildx.md#builder).
### <a name="cache-from"></a> Use an external cache source for a build (--cache-from)
```
--cache-from=[NAME|type=TYPE[,KEY=VALUE]]
```
Use an external cache source for a build. Supported types are `registry`,
`local`, `gha` and `s3`.
- [`registry` source](https://github.com/moby/buildkit#registry-push-image-and-cache-separately)
can import cache from a cache manifest or (special) image configuration on the
registry.
- [`local` source](https://github.com/moby/buildkit#local-directory-1) can
import cache from local files previously exported with `--cache-to`.
- [`gha` source](https://github.com/moby/buildkit#github-actions-cache-experimental)
can import cache from a previously exported cache with `--cache-to` in your
GitHub repository
- [`s3` source](https://github.com/moby/buildkit#s3-cache-experimental)
can import cache from a previously exported cache with `--cache-to` in your
S3 bucket
If no type is specified, `registry` exporter is used with a specified reference.
`docker` driver currently only supports importing build cache from the registry.
```console
$ docker buildx build --cache-from=user/app:cache .
$ docker buildx build --cache-from=user/app .
$ docker buildx build --cache-from=type=registry,ref=user/app .
$ docker buildx build --cache-from=type=local,src=path/to/cache .
$ docker buildx build --cache-from=type=gha .
$ docker buildx build --cache-from=type=s3,region=eu-west-1,bucket=mybucket .
```
More info about cache exporters and available attributes: https://github.com/moby/buildkit#export-cache
### <a name="cache-to"></a> Export build cache to an external cache destination (--cache-to)
```
--cache-to=[NAME|type=TYPE[,KEY=VALUE]]
```
Export build cache to an external cache destination. Supported types are
`registry`, `local`, `inline`, `gha` and `s3`.
- [`registry` type](https://github.com/moby/buildkit#registry-push-image-and-cache-separately) exports build cache to a cache manifest in the registry.
- [`local` type](https://github.com/moby/buildkit#local-directory-1) exports
cache to a local directory on the client.
- [`inline` type](https://github.com/moby/buildkit#inline-push-image-and-cache-together)
writes the cache metadata into the image configuration.
- [`gha` type](https://github.com/moby/buildkit#github-actions-cache-experimental)
exports cache through the [GitHub Actions Cache service API](https://github.com/tonistiigi/go-actions-cache/blob/master/api.md#authentication).
- [`s3` type](https://github.com/moby/buildkit#s3-cache-experimental) exports
cache to a S3 bucket.
`docker` driver currently only supports exporting inline cache metadata to image
configuration. Alternatively, `--build-arg BUILDKIT_INLINE_CACHE=1` can be used
to trigger inline cache exporter.
Attribute key:
- `mode` - Specifies how many layers are exported with the cache. `min` on only
exports layers already in the final build stage, `max` exports layers for
all stages. Metadata is always exported for the whole build.
```console
$ docker buildx build --cache-to=user/app:cache .
$ docker buildx build --cache-to=type=inline .
$ docker buildx build --cache-to=type=registry,ref=user/app .
$ docker buildx build --cache-to=type=local,dest=path/to/cache .
$ docker buildx build --cache-to=type=gha .
$ docker buildx build --cache-to=type=s3,region=eu-west-1,bucket=mybucket .
```
More info about cache exporters and available attributes: https://github.com/moby/buildkit#export-cache
### <a name="load"></a> Load the single-platform build result to `docker images` (--load)
Shorthand for [`--output=type=docker`](#docker). Will automatically load the
single-platform build result to `docker images`.
### <a name="metadata-file"></a> Write build result metadata to the file (--metadata-file)
To output build metadata such as the image digest, pass the `--metadata-file` flag.
The metadata will be written as a JSON object to the specified file. The
directory of the specified file must already exist and be writable.
```console
$ docker buildx build --load --metadata-file metadata.json .
$ cat metadata.json
```
```json
{
"containerimage.buildinfo": {
"frontend": "dockerfile.v0",
"attrs": {
"context": "https://github.com/crazy-max/buildkit-buildsources-test.git#master",
"filename": "Dockerfile",
"source": "docker/dockerfile:master"
},
"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"
}
]
},
"containerimage.config.digest": "sha256:2937f66a9722f7f4a2df583de2f8cb97fc9196059a410e7f00072fc918930e66",
"containerimage.descriptor": {
"annotations": {
"config.digest": "sha256:2937f66a9722f7f4a2df583de2f8cb97fc9196059a410e7f00072fc918930e66",
"org.opencontainers.image.created": "2022-02-08T21:28:03Z"
},
"digest": "sha256:19ffeab6f8bc9293ac2c3fdf94ebe28396254c993aea0b5a542cfb02e0883fa3",
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"size": 506
},
"containerimage.digest": "sha256:19ffeab6f8bc9293ac2c3fdf94ebe28396254c993aea0b5a542cfb02e0883fa3"
}
```
### <a name="output"></a> Set the export action for the build result (-o, --output)
```
-o, --output=[PATH,-,type=TYPE[,KEY=VALUE]
```
Sets the export action for the build result. In `docker build` all builds finish
by creating a container image and exporting it to `docker images`. `buildx` makes
this step configurable allowing results to be exported directly to the client,
oci image tarballs, registry etc.
Buildx with `docker` driver currently only supports local, tarball exporter and
image exporter. `docker-container` driver supports all the exporters.
If just the path is specified as a value, `buildx` will use the local exporter
with this path as the destination. If the value is "-", `buildx` will use `tar`
exporter and write to `stdout`.
```console
$ docker buildx build -o . .
$ docker buildx build -o outdir .
$ docker buildx build -o - - > out.tar
$ docker buildx build -o type=docker .
$ docker buildx build -o type=docker,dest=- . > myimage.tar
$ docker buildx build -t tonistiigi/foo -o type=registry
```
Supported exported types are:
#### `local`
The `local` export type writes all result files to a directory on the client. The
new files will be owned by the current user. On multi-platform builds, all results
will be put in subdirectories by their platform.
Attribute key:
- `dest` - destination directory where files will be written
#### `tar`
The `tar` export type writes all result files as a single tarball on the client.
On multi-platform builds all results will be put in subdirectories by their platform.
Attribute key:
- `dest` - destination path where tarball will be written. “-” writes to stdout.
#### `oci`
The `oci` export type writes the result image or manifest list as an [OCI image
layout](https://github.com/opencontainers/image-spec/blob/v1.0.1/image-layout.md)
tarball on the client.
Attribute key:
- `dest` - destination path where tarball will be written. “-” writes to stdout.
#### `docker`
The `docker` export type writes the single-platform result image as a [Docker image
specification](https://github.com/docker/docker/blob/v20.10.2/image/spec/v1.2.md)
tarball on the client. Tarballs created by this exporter are also OCI compatible.
Currently, multi-platform images cannot be exported with the `docker` export type.
The most common usecase for multi-platform images is to directly push to a registry
(see [`registry`](#registry)).
Attribute keys:
- `dest` - destination path where tarball will be written. If not specified the
tar will be loaded automatically to the current docker instance.
- `context` - name for the docker context where to import the result
#### `image`
The `image` exporter writes the build result as an image or a manifest list. When
using `docker` driver the image will appear in `docker images`. Optionally, image
can be automatically pushed to a registry by specifying attributes.
Attribute keys:
- `name` - name (references) for the new image.
- `push` - boolean to automatically push the image.
#### `registry`
The `registry` exporter is a shortcut for `type=image,push=true`.
### <a name="platform"></a> Set the target platforms for the build (--platform)
```
--platform=value[,value]
```
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 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
built for all of the specified platforms and joined together into a single manifest
list.
If the `Dockerfile` needs to invoke the `RUN` command, the builder needs runtime
support for the specified platform. In a clean setup, you can only execute `RUN`
commands for your system architecture.
If your kernel supports [`binfmt_misc`](https://en.wikipedia.org/wiki/Binfmt_misc)
launchers for secondary architectures, buildx will pick them up automatically.
Docker desktop releases come with `binfmt_misc` automatically configured for `arm64`
and `arm` architectures. You can see what runtime platforms your current builder
instance supports by running `docker buildx inspect --bootstrap`.
Inside a `Dockerfile`, you can access the current platform value through
`TARGETPLATFORM` build argument. Please refer to the [`docker build`
documentation](https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope)
for the full description of automatic platform argument variants .
The formatting for the platform specifier is defined in the [containerd source
code](https://github.com/containerd/containerd/blob/v1.4.3/platforms/platforms.go#L63).
```console
$ docker buildx build --platform=linux/arm64 .
$ docker buildx build --platform=linux/amd64,linux/arm64,linux/arm/v7 .
$ docker buildx build --platform=darwin .
```
### <a name="progress"></a> Set type of progress output (--progress)
```
--progress=VALUE
```
Set type of progress output (auto, plain, tty). Use plain to show container
output (default "auto").
> **Note**
>
> You can also use the `BUILDKIT_PROGRESS` environment variable to set its value.
The following example uses `plain` output during the build:
```console
$ docker buildx build --load --progress=plain .
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 227B 0.0s done
#1 DONE 0.1s
#2 [internal] load .dockerignore
#2 transferring context: 129B 0.0s done
#2 DONE 0.0s
...
```
> **Note**
>
> 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)
```
--secret=[type=TYPE[,KEY=VALUE]
```
Exposes secret to the build. The secret can be used by the build using
[`RUN --mount=type=secret` mount](https://docs.docker.com/engine/reference/builder/#run---mounttypesecret).
If `type` is unset it will be detected. Supported types are:
#### `file`
Attribute keys:
- `id` - ID of the secret. Defaults to basename of the `src` path.
- `src`, `source` - Secret filename. `id` used if unset.
```dockerfile
# syntax=docker/dockerfile:1
FROM python:3
RUN pip install awscli
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \
aws s3 cp s3://... ...
```
```console
$ docker buildx build --secret id=aws,src=$HOME/.aws/credentials .
```
#### `env`
Attribute keys:
- `id` - ID of the secret. Defaults to `env` name.
- `env` - Secret environment variable. `id` used if unset, otherwise will look for `src`, `source` if `id` unset.
```dockerfile
# syntax=docker/dockerfile:1
FROM node:alpine
RUN --mount=type=bind,target=. \
--mount=type=secret,id=SECRET_TOKEN \
SECRET_TOKEN=$(cat /run/secrets/SECRET_TOKEN) yarn run test
```
```console
$ SECRET_TOKEN=token docker buildx build --secret id=SECRET_TOKEN .
```
### <a name="shm-size"></a> Size of /dev/shm (--shm-size)
The format is `<number><unit>`. `number` must be greater than `0`. Unit is
optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g`
(gigabytes). If you omit the unit, the system uses bytes.
### <a name="ssh"></a> SSH agent socket or keys to expose to the build (--ssh)
```
--ssh=default|<id>[=<socket>|<key>[,<key>]]
```
This can be useful when some commands in your Dockerfile need specific SSH
authentication (e.g., cloning a private repository).
`--ssh` exposes SSH agent socket or keys to the build and can be used with the
[`RUN --mount=type=ssh` mount](https://docs.docker.com/engine/reference/builder/#run---mounttypessh).
Example to access Gitlab using an SSH agent socket:
```dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN apk add --no-cache openssh-client
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
RUN --mount=type=ssh ssh -q -T git@gitlab.com 2>&1 | tee /hello
# "Welcome to GitLab, @GITLAB_USERNAME_ASSOCIATED_WITH_SSHKEY" should be printed here
# with the type of build progress is defined as `plain`.
```
```console
$ eval $(ssh-agent)
$ ssh-add ~/.ssh/id_rsa
(Input your passphrase here)
$ docker buildx build --ssh default=$SSH_AUTH_SOCK .
```
### <a name="ulimit"></a> Set ulimits (--ulimit)
`--ulimit` is specified with a soft and hard limit as such:
`<type>=<soft limit>[:<hard limit>]`, for example:
```console
$ docker buildx build --ulimit nofile=1024:1024 .
```
> **Note**
>
> If you do not provide a `hard limit`, the `soft limit` is used
> for both values. If no `ulimits` are set, they are inherited from
> the default `ulimits` set on the daemon.

Some files were not shown because too many files have changed in this diff Show More