Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: add new --sync-output flag to bake #1197

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jedevc
Copy link
Collaborator

@jedevc jedevc commented Jul 5, 2022

Potentially fixes #1089. Depends on a server that includes that patch here: moby/buildkit#2947

This proposal patch introduces a new syncable output option, which ensures that all builds finish simultaneously in the solver, so that no outputs are completed independently of each other. This allows bake to easily express the notion that either all builds should succeed and output or none of them should.

Usage:

$ docker buildx bake --sync-output

Comments and thoughts appreciated 🎉

@jedevc jedevc changed the title bake: add new --sync-output flag Proposal: add new --sync-output flag to bake Jul 5, 2022
@ciaranmcnulty
Copy link

Yes that's exactly what I had in mind 👍

Copy link
Member

@crazy-max crazy-max left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed an extra commit as simple test case but we should look at implementing integration tests (pretty much like BuildKit with testutil).

Comment on lines +741 to +790
func Build(ctx context.Context, drivers []DriverInfo, opt map[string]Options, docker DockerAPI, configDir string, w progress.Writer, syncOutputs bool) (resp map[string]*client.SolveResponse, err error) {
return BuildWithResultHandler(ctx, drivers, opt, docker, configDir, w, nil, syncOutputs, false)
}

func BuildWithResultHandler(ctx context.Context, drivers []DriverInfo, opt map[string]Options, docker DockerAPI, configDir string, w progress.Writer, resultHandleFunc func(driverIndex int, rCtx *ResultContext), allowNoOutput bool) (resp map[string]*client.SolveResponse, err error) {
func BuildWithResultHandler(ctx context.Context, drivers []DriverInfo, opt map[string]Options, docker DockerAPI, configDir string, w progress.Writer, resultHandleFunc func(driverIndex int, rCtx *ResultContext), syncOutputs bool, allowNoOutput bool) (resp map[string]*client.SolveResponse, err error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should look at refactoring these funcs in a follow-up

Copy link
Collaborator Author

@jedevc jedevc Sep 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, have avoided making too many changes since #1296 refactors around this as well.

@@ -25,6 +25,7 @@ Build from a file
| [`--pull`](#pull) | | | Always attempt to pull all referenced images |
| `--push` | | | Shorthand for `--set=*.output=type=registry` |
| [`--set`](#set) | `stringArray` | | Override target value (e.g., `targetpattern.key=value`) |
| `--sync-output` | | | Ensure all builds complete before beginning output |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe --sync would be enough? There are some cases where we might not need to output anything but keep build result synced (type=cacheonly)?

Suggested change
| `--sync-output` | | | Ensure all builds complete before beginning output |
| `--sync` | | | Ensure all builds complete before returning result |

Let's also add a simple example here for this flag.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think --sync isn't enough, you want to hint it is about synching the 'stuff at the end'

@jedevc
Copy link
Collaborator Author

jedevc commented Oct 17, 2022

Have updated with the new Evaluate API introduced in moby/buildkit#3137.

Still not sure about the flag name, but the functionality should be correct now (have tested with buildkit before+after the evaluate API merged to check the StatFile fallback works correctly).

@jedevc
Copy link
Collaborator Author

jedevc commented Nov 30, 2022

Adding to the v0.10 milestone, think this would be good to get in there.

Revisiting this after a while, I wonder if maybe we might want to make this the default behavior? Or some other way that doesn't involve needing to add lots more flags, IMO not needing a lot of extra flags on the cli is one of the selling points of bake 🤔

@jedevc jedevc added this to the v0.10 milestone Nov 30, 2022
jedevc and others added 2 commits November 30, 2022 16:22
This patch introduces a new syncable output option, which ensures that
all builds finish simultaneously in the solver, so that no outputs are
completed independently of each other. This allows bake to easily
express the notion that either all builds should succeed and output or
none of them should.

Signed-off-by: Justin Chadwell <[email protected]>
@jedevc
Copy link
Collaborator Author

jedevc commented Mar 2, 2023

Ping @tonistiigi @crazy-max any thoughts on the overall approach here? I'm a bit hesitant around adding new flags to the CLI though 🤔

Possible approaches:

  • Just add the new flag (clutters the command line)
  • Make the synced outputs default (slows down quite a few builds)
  • Maybe add a sync key or similar to each group in bake, all targets part of that group would be synced? We could allow setting it at the command line using --set (though this doesn't work very well if you don't use groups, and just specify multiple targets).

@Nithos
Copy link

Nithos commented Mar 3, 2023

Does the current action support group entries currently into the targets input? If so adding a sync to a group definition is a fairly elegant solution that avoids the flags. I am assuming that the group would get decomposed and automatically parallelize the process rather than having to manually deconstruct the list of targets present within the group and run through the GH matrix.

@crazy-max
Copy link
Member

Having a sync field for group is a good idea. Hence my suggestion to have a less opinionated flag named --sync instead of --sync-output.

I'm thinking about another use case now. Should we have a fail-fast strategy that cancels all in-progress targets in the group if any target fails? I think this is the current behavior.

@jedevc
Copy link
Collaborator Author

jedevc commented Mar 3, 2023

Yeah, if we have a sync field, having the ability to sync at different points would be good:

  • fail-fast is the current behavior
  • output syncs at the output stage, like this patch
  • fail-slow (naming is hard) is the opposite of fail-fast, all builds are run to completion (though we might also want to have variants of this that sync at output or after).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Option to only tag images at end of bake
4 participants