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

buildctl: new CLI ("Option C+") #807

Merged
merged 1 commit into from
Mar 8, 2019
Merged

Conversation

AkihiroSuda
Copy link
Member

@AkihiroSuda AkihiroSuda commented Jan 31, 2019

See #807 (comment)

Fix #774

Signed-off-by: Akihiro Suda [email protected]

@AkihiroSuda AkihiroSuda changed the title buildctl: migrate --frontend to CSV style buildctl: CSV-style --frontend and --export Jan 31, 2019
@tonistiigi tonistiigi added this to the v0.4.0 milestone Feb 1, 2019
@AkihiroSuda AkihiroSuda force-pushed the csv-frontend branch 2 times, most recently from 57aefd9 to 7a263e6 Compare February 1, 2019 09:55
Copy link
Member

@tonistiigi tonistiigi left a comment

Choose a reason for hiding this comment

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

I'm not 100% sure its a good idea but maybe we could support single value --frontend=dockerfile.v0, --export=oci as well if value is not csv.

cmd/buildctl/build.go Outdated Show resolved Hide resolved
cmd/buildctl/build.go Outdated Show resolved Hide resolved
@tonistiigi
Copy link
Member

cc @tiborvass @thaJeztah

@tiborvass
Copy link
Collaborator

Bikeshed warning: I think I find type weird in this case. It's not a frontend type it's the name of the frontend image. So name, image, ... ?

README.md Outdated Show resolved Hide resolved
@thaJeztah
Copy link
Member

Good point (type vs name). I'm a bit cautious with using image= for that, as (I think) that should be an implementation detail (buildkit happens to use an image for distribution)

@tonistiigi
Copy link
Member

More options:

  • leave frontend with 2 flags, with --frontend-opt accepting csv
  • make all fields to take name,<csv> format instead. eg --frontend dockerfile.v0,target=foo, --export oci, --export image,name=foo

@thaJeztah
Copy link
Member

leave frontend with 2 flags, with --frontend-opt accepting csv

For frontend this would possibly still work; I don't think multiple frontends can be used on a single build? (unless I'm forgetting something).

For exporter we must group them together in a single flag.

make all fields to take name,<csv> format instead

I think (should check) that in docker we made an exception for the first parameter to be positional (at least we talked about it), so:

First param uses =, so "positional" rule does not take effect. type does therefore not have to be the first option (in this case, it's set last)

--exporter opt=foo=bar,opt=bla=bla,type=image

First parameter does not have a =, so the "positional" rule takes effect: first parameter is type

--exporter image,opt=foo=bar,opt=bla=bla,type=image

Invalid: both first (positional), and last (type=) option specify a type

--exporter image,opt=foo=bar,opt=bla=bla,type=image

@tonistiigi
Copy link
Member

First param uses =, so "positional" rule does not take effect. type does therefore not have to be the first option (in this case, it's set last)

The main problem atm (in addition to this being cumbersome and hard to name) is the point you brought up that type could actually be a key that the frontend uses. Also, this "primary" positional value is required in all cases and only having options with no type/name never makes sense. So if we would do this, I'd make it a requirement and only way to define the value (in addition to the hidden compatibility with old syntax).

@tonistiigi
Copy link
Member

Let's also make sure that there is a sane way to do comma separated values as they are quite common (platform,name,cache-from) and add examples for how to do it.

@AkihiroSuda
Copy link
Member Author

Let's also make sure that there is a sane way to do comma separated values

type=foo,"opt=opt1,opt2,opt3" ? (Although we might want to remove type=)
https://play.golang.org/p/R_p_syvcX31

@AkihiroSuda
Copy link
Member Author

Another options is to rather deprecate CSV and restore the legacy form (sorry for going back and forth), with support for multiple (e.g.) exporters, but not sure how it can be implemented with any existing CLI library.

--exporter image --exporter-opt name=docker.io/username/image1,docker.io/username/image2 --exporter oci --exporter-opt output=/path/to/tar

@tonistiigi
Copy link
Member

Any counterarguments for #807 (comment) ?

...,"opt=opt1,opt2,opt3"

I think this is acceptable if it's documented.

@tiborvass
Copy link
Collaborator

I'm fine with the proposal, but just so everyone is on the same page:
type=foo,"opt=opt1,opt2,opt3" means that you would have to type 'type=foo,"opt=opt1,opt2,opt3"' in a shell to escape the double quotes ".

@tonistiigi
Copy link
Member

@tiborvass or escape them

@thaJeztah
Copy link
Member

So the format would support both

type=foo,"opt=opt1,opt2,opt3"

and

type=foo,opt=opt1,opt=opt2,opt=opt3

(both being equivalent)?

@tonistiigi
Copy link
Member

type=foo,opt=opt1,opt=opt2,opt=opt3

We could support both with CLI magic but the second one would just convert to the first one. In API it is a comma separated string.

The proposed format is:

foo,bar=baz,"opt=opt1,opt2,opt3"

@AkihiroSuda
Copy link
Member Author

Also, this "primary" positional value is required in all cases and only having options with no type/name never makes sense. So if we would do this, I'd make it a requirement and only way to define the value (in addition to the hidden compatibility with old syntax).

How should it work with --export-cache and --import-cache? (#615)

If we focus on compatibility, the flag would be like --export-cache localhost:5000/myrepo:buildcache,type=registry, but I'm wondering it looks inconsistent to have type= in non-primary key-value.

@tonistiigi
Copy link
Member

How should it work with --export-cache and --import-cache?

--export-cache=registry,ref=localhost:5000/myrepo:buildcache

@AkihiroSuda
Copy link
Member Author

Off-topic: do we also want to remove type= from RUN --mount and docker run/service --mount?

@tonistiigi
Copy link
Member

tonistiigi commented Feb 18, 2019

Off-topic: do we also want to remove type= from RUN --mount and docker run/service --mount?

I don't think so. It would be good to figure out syntax for docker build though.

docker build -o ./out .
docker build -o - . | tar xv
docker build -o files,dest=output .
docker build -o tarball,dest=- .
docker build -o tarball,dest=out.tgz .
docker build -o registry,name=ref . # not required before distributed build
docker build -o oci-image,name=ref . # after containerd
docker build -o cache-registry,name=ref . # after containerd
docker build -o cache-local,name=ref . # after containerd
docker build --cache-from ref
docker build --cache-from local,dir=/foo

?

Maybe in docker it makes more sense to explicitly require type= on the longform values.

There is still an option to not do the positional value in buildctl and leave frontend as an exception. This isn't super bad as frontend is also the only one where it doesn't make sense to have an array of values.

@AkihiroSuda
Copy link
Member Author

I'll try to update PR to support both --frontend FRONTEND and --frontend type=FRONTEND

@tonistiigi
Copy link
Member

tonistiigi commented Feb 18, 2019

@AkihiroSuda

And for opt? I don't think we should do --frontend type=FRONTEND,foo=bar. It doesn't fit the actual API data types. We could do it for the other flags though.

@AkihiroSuda
Copy link
Member Author

To sum up:

Should be supported

  • --frontend dockerfile.v0,target=foo
  • --export-cache registry,ref=localhost:5000/myrepo:buildcache (same applies to --import-cache)
  • --export-cache type=registry,ref=localhost:5000/myrepo:buildcache
  • --export docker,name=myimage
  • --export docker,"names=myimage1,myimage2" (can be separate PR)
  • --secret id=secretname,src=filepath
  • --secret file,id=secretname,src=filepath
  • --secret type=file,id=secretname,src=filepath

Should be supported but deprecated

  • --frontend dockerfile.v0 --frontend-opt target=foo
  • --export-cache localhost:5000/myrepo:buildcache
  • --exporter docker --exporter-opt name=myimage
  • --exporter docker --exporter-opt names=myimage1,myimage2

Should NOT be supported

  • --frontend type=dockerfile.v0,target=foo (should print a warning like "frontend missing, you meant --frontend dockerfile.v0,target=foo?")
  • --export-cache registry

Let me know if this is not correct.

@tonistiigi
Copy link
Member

I think it's confusing to support multiple variants together.

Option A

Should be supported

  • --frontend dockerfile.v0,target=foo
  • --export-cache registry,ref=localhost:5000/myrepo:buildcache (same applies to --import-cache)
  • --export docker,name=myimage
  • --export docker,"names=myimage1,myimage2" (can be separate PR)
  • --secret id=secretname,src=filepath
  • --secret file,id=secretname,src=filepath

Should be supported but deprecated

  • --export-cache type=registry,ref=localhost:5000/myrepo:buildcache (never existed on a release)
  • --secret type=file,id=secretname,src=filepath
  • --frontend dockerfile.v0 --frontend-opt target=foo
  • --export-cache localhost:5000/myrepo:buildcache
  • --exporter docker --exporter-opt name=myimage
  • --exporter docker --exporter-opt names=myimage1,myimage2

Should NOT be supported

  • --frontend type=dockerfile.v0,target=foo (should print a warning like "frontend missing, you meant --frontend dockerfile.v0,target=foo?")
  • --export-cache registry

Option B

Should be supported

  • --frontend dockerfile.v0
  • --frontend-opts target=foo,platform=linux/arm
  • --export-cache registry,ref=localhost:5000/myrepo:buildcache (same applies to --import-cache)
  • --export docker,name=myimage
  • --export docker,"names=myimage1,myimage2" (can be separate PR)
  • --secret id=secretname,src=filepath
  • --secret file,id=secretname,src=filepath

Should be supported but deprecated

  • --export-cache type=registry,ref=localhost:5000/myrepo:buildcache (never existed on a release)
  • --secret type=file,id=secretname,src=filepath
  • --frontend dockerfile.v0 --frontend-opt target=foo (could also be just supported)
  • --export-cache localhost:5000/myrepo:buildcache
  • --exporter docker --exporter-opt name=myimage
  • --exporter docker --exporter-opt names=myimage1,myimage2

Should NOT be supported

  • --frontend type=dockerfile.v0,target=foo (should print a warning like "frontend missing, you meant --frontend dockerfile.v0,target=foo?")
  • --export-cache registry

Option C

Should be supported

  • --frontend dockerfile.v0
  • --frontend-opts target=foo,platform=linux/arm
  • --export-cache type=registry,ref=localhost:5000/myrepo:buildcache
  • --export type=docker,name=myimage
  • --export type=docker,"names=myimage1,myimage2" (can be separate PR)
  • --secret type=file,id=secretname,src=filepath
  • --secret id=secretname,src=filepath (could be supported with default type value)

Should be supported but deprecated

  • --frontend dockerfile.v0 --frontend-opt target=foo (could also be just supported)
  • --export-cache localhost:5000/myrepo:buildcache
  • --exporter docker --exporter-opt name=myimage
  • --exporter docker --exporter-opt names=myimage1,myimage2

Should NOT be supported

  • --export-cache registry,ref=localhost:5000/myrepo:buildcache (same applies to --import-cache)
  • --frontend type=dockerfile.v0,target=foo (should print a warning like "frontend missing, you meant --frontend dockerfile.v0,target=foo?")
  • --export-cache registry

AkihiroSuda added a commit to AkihiroSuda/buildkit_poc that referenced this pull request Mar 1, 2019
AkihiroSuda added a commit to AkihiroSuda/buildkit_poc that referenced this pull request Mar 1, 2019
AkihiroSuda added a commit to AkihiroSuda/buildkit_poc that referenced this pull request Mar 1, 2019
@AkihiroSuda
Copy link
Member Author

Update PR to use --export-cache type=local,dest=/path/to/dir --import-cache type=registry,src=example.com/foo. RFC.

@tonistiigi
Copy link
Member

It's not too important but I'd rather leave the src/dest only to values where it points to a file/path and leave it to ref if it is a reference.

@AkihiroSuda
Copy link
Member Author

@thaJeztah @tiborvass @ijc WDYT?

@@ -122,7 +122,7 @@ During development, Dockerfile frontend (dockerfile.v0) is also part of the Buil

```
buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=.
buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --frontend-opt target=foo --frontend-opt build-arg:foo=bar
buildctl build --frontend=dockerfile.v0 --local context=. --local dockerfile=. --opt target=foo --opt build-arg:foo=bar
Copy link
Member

Choose a reason for hiding this comment

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

Bit on the fence on the --frontend-opt -> --opt change, as it's not clear to me that they are related to each other. 😅

Copy link
Member

Choose a reason for hiding this comment

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

Why should you as a user care if they are related or not?

Copy link
Member

Choose a reason for hiding this comment

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

To understand that an option is related to the frontend, not to (e.g.) the --output.

If we drop the prefix, should we also drop the --export- prefix from --export-cache?

Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't say they are strictly related to the frontend. They are more like options for the build request, while the other options are for a specific component (exporter, cache) or are cli side (local, secret).

Copy link
Member

Choose a reason for hiding this comment

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

Ah; gotcha - guess I got confused because they previously were prefixed

@AkihiroSuda
Copy link
Member Author

〉leave it to ref if it is a reference.

Could you be more specific about the reason for this?

@tonistiigi
Copy link
Member

@AkihiroSuda I'm quite sure that we can't make it into a rule that every exporter/importer will only have a src/dest option in the future. That's why its a generic map in the API. For paths, src/dest seems obvious, for refs I've not seen it before. I'm willing to change my mind though if people think the other logic makes more sense.

AkihiroSuda added a commit to AkihiroSuda/buildkit_poc that referenced this pull request Mar 5, 2019
@AkihiroSuda
Copy link
Member Author

reverted --import-cache type=registry,src=... --export-cache type=registry,dest=...

@AkihiroSuda
Copy link
Member Author

rebased

@AkihiroSuda
Copy link
Member Author

Any task left?

@tonistiigi
Copy link
Member

@tiborvass @thaJeztah @ijc

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@tiborvass tiborvass merged commit 2a857a3 into moby:master Mar 8, 2019
crazy-max pushed a commit to crazy-max/dockerfile that referenced this pull request Jan 8, 2022
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.

4 participants