-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Enable multiple exporters (alternative) #4134
Conversation
// TODO: separate these out, and return multiple exporter responses to the | ||
// client | ||
for _, resp := range resps { | ||
for k, v := range resp { | ||
if exporterResponse == nil { | ||
exporterResponse = make(map[string]string) | ||
} | ||
exporterResponse[k] = v | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only aspect of the overall design I'm a little unsure on. I think for now, I'd be ok this, since we already have the precedent with multiple cache exporters (see the similar comment I've added there). However, long term, I think we should split out the exporter response more (while keeping this merging behavior for the deprecated field):
message SolveResponse {
map<string, string> ExporterResponseDeprecated = 1;
repeated ExporterResponse ExporterResponses = 2;
repeated ExporterCacheResponse CacheExporterResponses = 2;
FrontendResponse FrontendRessponse = 3;
}
If we take this option, I'm happy to follow-up asap with a PR to do this, but I don't think the handling for this belongs in this one, for two reasons: 1. #2760 has already been open for more than a year and 2. we should fix this for the multiple cache exporters as well, which has already merged and been released in v0.11.
Looking through the original PR, I see notice this discussed previously: #2760 (comment). This is also a viable approach, where we could make sure that exporters didn't overwrite each other's keys - though this is potentially a non-backwards compatible change (depending on details).
949750f
to
6728e37
Compare
This will be very useful! |
6728e37
to
0f3e7ff
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jedevc There is no need to push to the original PR - this branch works just fine. I admit I did not quite understand some of your suggestions - reading the code made things much more clearer, thanks.
b111cb3
to
deb9b41
Compare
session/filesync/filesync.go
Outdated
} | ||
f, ok := sp.fs[id] | ||
if !ok { | ||
return errors.Errorf("exporter %q not found", id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be confusing for the user if internal ids were used (e.g. local1
). Maybe use the path as ID (see below)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that hitting this is indicative of a buildkit internal error, I'd rather have the id printed here.
This would mean that somehow buildkit has requested to export to an exporter that the client never created.
606823e
to
16a74c3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
|
||
require.Equal(t, resp.ExporterResponse["image.name"], target2) | ||
require.FileExists(t, filepath.Join(destDir, "out.tar")) | ||
require.FileExists(t, filepath.Join(destDir, "out2.tar")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we validate the contents of the image and the tar?
if err != nil { | ||
return nil, err | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably these lines didn't need to be moved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likely not, I was just trying to match the structure of the non-map case - I can move it back if it's significant.
16a74c3
to
5438a4b
Compare
@tonistiigi are there any blockers on this? I'd really like to be able to close this piece out, feels like it could be a strong feature to include in v0.13. |
Subscribed to this also 👍 This is useful when you have a workflows which use the image as an artifact without a registry in between but the local storage |
Needs rebase |
Needs rebase again |
@jedevc Could you rebase? |
Signed-off-by: Justin Chadwell <[email protected]>
Signed-off-by: Justin Chadwell <[email protected]>
Co-authored-by: fahed dorgaa <[email protected]> Co-authored-by: a-palchikov <[email protected]> Signed-off-by: Justin Chadwell <[email protected]>
Co-authored-by: a-palchikov <[email protected]> Signed-off-by: Justin Chadwell <[email protected]>
Signed-off-by: Justin Chadwell <[email protected]>
This preps for the case where a single exporter source does not map neatly onto a single inline cache - such as introducing multiple exporters. We also introduce laziness here - each exporter chooses to attempt extracting the inline cache on demand, which ensures that we avoid creating inline caches for exporters that do not support them. Co-authored-by: a-palchikov <[email protected]> Co-authored-by: fahed dorgaa <[email protected]> Signed-off-by: Justin Chadwell <[email protected]>
This patch adds multi-plexing to the local file transfer protocol (from server to client). This is implementation-wise similar to the multiplexing from the containerd content store transfer protocol, using a GRPC header to select the appropriate target. Signed-off-by: Justin Chadwell <[email protected]>
Co-authored-by: a-palchikov <[email protected]> Co-authored-by: fahed dorgaa <[email protected]> Signed-off-by: Justin Chadwell <[email protected]>
This patch adds support for multiple exporters at the control API, and propogates the resulting required changes through the client and the solver. A few notable changes: - Each exporter instance now has an associated identifier - Build records in the build history now have multiple possible descriptors to built content - Exporter responses are all merged together (like we currently do with multiple cache exporters). We likely will need to revisit this design later, since now cache exporters do not line up one-to-one with exporters. For backwards compatability, new clients will continue to produce requests that contain the now deprecated exporter fields, as well as the new ones. New servers will attempt to use deprecated fields if they are present. Co-authored-by: a-palchikov <[email protected]> Co-authored-by: fahed dorgaa <[email protected]> Signed-off-by: Justin Chadwell <[email protected]>
Higher-level clients should be able to check server-side caps to ensure that when they attempt to use multiple exporters, that the feature is actually supported. Signed-off-by: Justin Chadwell <[email protected]>
We can derive exporter ids from their place in the exporter array in a SolveRequest - this removes the need to manually generate and handle multiple sets of IDs. Signed-off-by: Justin Chadwell <[email protected]>
044b717
to
1c1777b
Compare
Rebased. Since this has an approval, once the tests pass, I'm going to merge it. |
Signed-off-by: Justin Chadwell <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM thanks for the effort on this long-waiting feature!
I'm a bit worry of the exporter responses handling on client side but your suggestion in #4134 (comment) seems like a good approach as follow-up.
As discussed we could start looking at making changes in buildx (and GHA as well to deal correctly with whatever digest user wants to consume). We also already consume the master image in our e2e tests https://github.com/docker/buildx/blob/6b63e7e3de2ef20c5d7349d7b9b277d6f0a58755/.github/workflows/e2e.yml#L70 but we should do the same for the integration tests in https://github.com/docker/buildx/blob/master/.github/workflows/build.yml when running the workflow manually so we can specify a custom image.
That being said, could we make a list of tasks that should be fulfilled in #1555 for follow-ups similar to moby/moby#45897 (a new issue is fine too)
Some small reworks of #2760.
@a-palchikov would you be able to review this to check that this still hits the spirit of the original? The logic behind splitting this out was that while I was reviewing I found myself just endlessly nitpicking, which is quite a slow way to do review, so I thought I'd just try fixing them myself. If you're happy with the changes I've made, I'm happy to push to #2760, or try and continue the discussion in here, whichever works for you best.
Notable changes from the original include:
Resolve
method for the exporter (which means that even exporters of the same type are guaranteed to have unique IDs).DiffCopy
using gRPC headers (similar to the existing approach for exposing containerd content stores), which allows for multiple local/tar exporters.result.MutableResult
refactor (which was used primarily by frontends to avoid concurrent map-access). We can follow this up later.ExportImage
method, while preserving the ability for exporters to request inline cache on demand (instead of requiring access through the metadata map).