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

exporter: export multiple refs with local/image exporter #499

Merged
merged 7 commits into from
Jul 25, 2018

Conversation

tonistiigi
Copy link
Member

@tonistiigi tonistiigi commented Jul 11, 2018

based on #496

Add support for:

Example:

from --platform=$BUILDPLATFORM busybox AS bb
arg TARGETPLATFORM
run echo "i am $TARGETPLATFORM" > /whoami
from scratch
copy --from=bb whoami .
buildctl build --frontend-opt platform=linux/arm,linux/amd64,windows/arm,windows/amd64 --frontend=dockerfile.v0 --local context=. --local dockerfile=. --exporter=local --exporter-opt output=/tmp/out
> ls -l /tmp/out
drwxr-xr-x 2 root root 4096 Jul 10 22:49 linux_amd64
drwxr-xr-x 2 root root 4096 Jul 10 22:49 linux_arm_v7
drwxr-xr-x 2 root root 4096 Jul 10 22:49 windows_amd64
drwxr-xr-x 2 root root 4096 Jul 10 22:49 windows_arm_v7
> cat /tmp/out/linux_arm_v7/whoami
i am linux/arm/v7


func getPlatformArgs(bp, tp specs.Platform) []instructions.KeyValuePairOptional {
m := map[string]string{
"BUILDPLATFORM": platforms.Format(bp),
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should add underscore prefixes to these reserved args?

Copy link
Member Author

Choose a reason for hiding this comment

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

One thing to note is that these args are in no way "reserved". I think this can be introduced with no disruption to current users. These args do not leak the RUN processes unless explicitly exposed with ARG, like the current global args. If the user happens to use or wants to use an ARG with the same name they can do that and it overrides the automatic values.

That being said we should, of course, get the names right so we don't need to change them.

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

If the user happens to use or wants to use an ARG with the same name they can do that and it overrides the automatic values.

They can but they should not?
Maybe we should print warning, because people may use the same name accidentally without being aware of this PR

Copy link
Member

Choose a reason for hiding this comment

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

Actually someone is already using ENV TARGETOS=.. TARGETARCH=.. in his/her own Dockerfile

https://raw.githubusercontent.com/ARwMq9b6/dnsproxy/master/cmd/dnsproxy/Dockerfile

Copy link
Member Author

Choose a reason for hiding this comment

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

Users should always get the behavior they expect. If these vars are used in the Dockerfile and user doesn't know about the automatic values and uses them as regular ones they will behave as regular ones. Only way the automatic behavior applies is if the Dockerfile author knows about the automatic behavior and uses these vars without passing in the values.

Copy link
Member Author

Choose a reason for hiding this comment

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

For the link, there is no behavior change. This Dockerfile will continue to work exactly like before.

To fill these vars automatically they would need to expose it as arg in a stage and not provide the value(eg. explicitly break the current behavior)

Copy link
Member

Choose a reason for hiding this comment

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

Namespacing these will be tricky yes; not sure it underscores would work (esthetically, it feels ugly, but of course that's personal).

we're a bit limited because arg double as env vars, so (officially) dots aren't allowed, which could've been used for namespacing (then again, we don't want these names to become too long)

Separate from the namespacing discussion; wondering if they should be named TARGET_OS and TARGET_ARCH

Copy link
Member Author

Choose a reason for hiding this comment

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

For TARGET_OS, the current is similar to GOOS/GOARCH

Copy link
Member

Choose a reason for hiding this comment

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

hm yeah 🤔

@tonistiigi tonistiigi force-pushed the caps3 branch 2 times, most recently from f1ea11d to fb31d5a Compare July 13, 2018 00:55
@tonistiigi tonistiigi changed the title exporter: export multiple refs with local exporter exporter: export multiple refs with local/image exporter Jul 16, 2018
@tonistiigi
Copy link
Member Author

tonistiigi commented Jul 16, 2018

I added support to image/oci exporter as well so we can now export manifest lists. Still needs more tests and a containerd vendor update. I'll try to move some commits to separate PRs to ease the review.

demo:

asciicast

@tonistiigi
Copy link
Member Author

Added tests for the image and local exporters. Ready for review.

@tonistiigi
Copy link
Member Author

@tiborvass Do you want to review this as well?

@tonistiigi
Copy link
Member Author

ping @tiborvass


var p exptypes.Platforms
if err := json.Unmarshal(platformsBytes, &p); err != nil {
return nil, err
Copy link
Collaborator

Choose a reason for hiding this comment

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

errors.Wrapf

}

refs := make([]cache.ImmutableRef, 0, len(inp.Refs))
layersMap := make(map[string]int, len(refs))
Copy link
Collaborator

Choose a reason for hiding this comment

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

len(refs) == 0 all the time

Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe you meant len(inp.Refs)

@@ -242,6 +247,7 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
}
if d.base != nil {
d.state = d.base.state
d.platform = d.base.platform
Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry I'm not very familiar with this part, but just making sure we're not overwriting d.platform. Shouldn't this be under if d.platform == nil ?

Copy link
Member Author

Choose a reason for hiding this comment

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

If you are inheriting from a stage you should also inherit the platform of that stage. I don't think any other case makes sense.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Copy link
Collaborator

@tiborvass tiborvass left a comment

Choose a reason for hiding this comment

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

LGTM

@tiborvass tiborvass merged commit d87d9d4 into moby:master Jul 25, 2018
if i.meta == nil {
i.meta = make(map[string][]byte)
i.meta[k] = []byte(v)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this not be:

			if i.meta == nil {
				i.meta = make(map[string][]byte)
			}
			i.meta[k] = []byte(v)

? Same in the OCI one.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I decided yes, or at least worthy of a PR: #558

@westurner
Copy link

Is there a list of the values of e.g. TARGETARCH somewhere?

The use case here is templating TARGETARCH into a URL that already uses x86_64 | aarch64 | ppe64le. E.g. arm is not specific enough to distinguish between the various arm architectures.

@tonistiigi
Copy link
Member Author

@westurner I'm not sure what you mean by all possible values. There is no strict list. Eg. https://github.com/tonistiigi/wasm-cli-plugin uses --platform=wasi/wasm and didn't require any changes. https://github.com/containerd/containerd/blob/master/platforms/platforms.go#L17 defines the format.

@westurner
Copy link

When I specify --platform=linux/arm64, is there a platform variable with the value aarch64? Such as maybe TARGETARCH? Or do I get to sound it out every time?

A table with the most common outputs given the inputs in the docs would eliminate the need to run https://gist.github.com/sujaypillai/74d15e0d690a265a1b705cf3b26c6082#file-predefined_platform_arg with each platform value listed in the docs:
https://github.com/docker/buildx/#---platformvaluevalue:

docker buildx build --platform=linux/arm64 .
docker buildx build --platform=linux/amd64,linux/arm64,linux/arm/v7 .
docker buildx build --platform=darwin .

(Another related documentation issue: It's not clear (from the buildx docs) whether it's still necessary to specify docker buildx build --platform. docker build --platform works now, correct?)

@tonistiigi
Copy link
Member Author

is there a platform variable with the value aarch64?

No, based on https://github.com/containerd/containerd/blob/master/platforms/platforms.go#L86-L94 aarch64 is normalized to arm64. --platform=linux/arm64 means TARGETARCH=arm64 . --platform=linux/aarch64 means TARGETARCH=arm64. --platform=foo/bar means TARGETARCH=bar.

By running https://gist.github.com/sujaypillai/74d15e0d690a265a1b705cf3b26c6082#file-predefined_platform_arg you just see the values for one specific node and a specific --platform value. As I said, there is no definitive list. If you add different nodes and pass different --platform values you get different sets of output.

docker build --platform works now, correct?

The difference is that buildx allows you to specify multiple values with --platform with container driver while docker build currently does not.

@westurner
Copy link

westurner commented Apr 27, 2020 via email

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

Successfully merging this pull request may close these issues.

6 participants