moby / buildkit

concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit
https://github.com/moby/moby/issues/34227
Apache License 2.0
8.19k stars 1.16k forks source link

`LegacyKeyValueFormat` linter is noisy with very little practical value #5130

Open tianon opened 4 months ago

tianon commented 4 months ago

At the risk of being a broken record, I still firmly believe it is a mistake to even attempt to deprecate the ENV key value syntax in favor of only supporting ENV key=value. Parsing the former is much simpler, and more in line with the way other Dockerfile instructions are parsed (and have been parsed historically). It is also much easier to generate from other code correctly and safely. As I noted on that other issue, if there are cases where the behavior of the former is ambiguous, that should be the thing we detect and warn about, not just trying to deprecate the entire syntax.

For the current linting rule, I would propose that it either be removed or somehow disabled by default, as it is causing unnecessary and noisy churn across the industry with very little practical benefit. :bow: :heart:

Examples of unnecessary churn/noise:

tonistiigi commented 4 months ago

The syntax is deprecated and discouraged (since 2020). We should either remove the deprecation or we should warn. I don't see any point of deprecating but then still saying "it is fine, keep using it". If there are many Dockerfiles that use the deprecated syntax 4 years later, that is a sign that nobody follows the deprecation documentation, and if we want to change user's behavior, we need to tell them that they are using a deprecated command.

Personally, I tend to agree with the justification for deprecation. In addition to ambiguous cases:

as it is causing unnecessary and noisy churn across the industry

It is only shown until you fix it one time. There is a #check=skip= directive in top of the file if you want to take a risk of using deprecated syntax.

@colinhemmings

tianon commented 4 months ago

Yes, I agree with your first point -- I argued against the deprecation back in 2020, and still do think we should reverse course on it because I still think it's a net negative.

"It's more consistent with ARG" isn't really compelling to me given that ENV came first and ARG was intentionally designed in a different way, which I also disagree with.

The way I see the "multiple ways to do the same thing" argument is no different than shell vs JSON syntax. It's a little hiccup for new users, but experienced users learn quickly. I do think there is value in having a warning for cases like ENV foo bar baz=buzz where it is clearly ambiguous, and I think that's a better use of a linting warning.

tonistiigi commented 4 months ago

The way I see the "multiple ways to do the same thing" argument is no different than shell vs JSON syntax.

But we did add a check for that as well. While non-JSON is allowed from CMD/ENTRYPOINT we now warn against it and ask user to only use JSON.

tianon commented 4 months ago

And RUN and VOLUME and COPY? (in all of which JSON vs non-JSON each have useful use cases)

Nefcanto commented 2 months ago

I recommend that you change this lint's word order. First specifying the problem and then presenting the solution.

I have mentioned it in another issue https://github.com/moby/moby/issues/48327#issuecomment-2288381403

thaJeztah commented 2 months ago

Copying from the other ticket (which was discussing format of the error-message);

Using active voice would probably be good ("use X" instead of "X should be used").

Perhaps more along the lines how we format Deprecated: messages in our Go codebase, e.g.;

LegacyKeyValueFormat: The "ENV key value" format is deprecated. Use "ENV key value" format instead.

Not sure where to fit in the line 15 though;

LegacyKeyValueFormat: The "ENV key value" format is deprecated. Use "ENV key value" format instead. (line 15)

I'm used to linters pointing out the issue inline, but not sure if possible, and not sure if that could make the output more noisy / harder to read if it's in more complex parts of a Dockerfile;

Dockerfile:15: The "ENV key value" format is deprecated. Use "ENV key value" format instead (LegacyKeyValueFormat).
ENV NODE_ENV production
    ^

I guess that's the intent of the current output, which may work well for a single error, but with the "lines before / after" becomes quite verbose, and also puts a lot of separation between the error and the line containing the error / issue.

Whapow commented 2 months ago

The deprecation error needs to at least be limited to actual Docker ENV lines, currently hitting false-positives within RUN commands: Screenshot 2024-08-15 at 12 51 24 PM

thaJeztah commented 2 months ago

currently hitting false-positives within RUN commands:

Yes, that's a bug; it's tracked in https://github.com/moby/buildkit/issues/5240, and I saw a patch is being worked on (but not yet complete)

tianon commented 2 months ago

I don't think this is the appropriate place to discuss rewording the linter notice -- I'm calling for removal or disabling-by-default of it, and don't think rewording it is sufficient.

mcandre commented 2 months ago

Parser ambiguity is never a good thing. The latest docker build... behavior is useful in encouraging engineers to migrate away from risky legacy syntax. I hope hadolint et all follow suit, as linter suites and CI/CD pipelines tend to run more frequently overall than image builds.

The Docker logs and documentation do a terrible job of explaining the reason for the deprecation. The historical parser ambiguity context is essential, but it is hidden in the GitHub issues.

thompson-shaun commented 2 months ago

The Docker logs and documentation do a terrible job of explaining the reason for the deprecation. The historical parser ambiguity context is essential, but it is hidden in the GitHub issues.

Would we typically link to this kind of information in the docs @dvdksn?

thaJeztah commented 2 months ago

Something like https://staticcheck.dev/docs/checks or https://securego.io/docs/rules/g103 could be nice it gives a page with context about each rule (not sure how "SEO friendly" the current Dockerfile rules are to find them through Google).

tonistiigi commented 2 months ago

Something like https://staticcheck.dev/docs/checks or https://securego.io/docs/rules/g103 could be nice it gives a page with context about each rule (not sure how "SEO friendly" the current Dockerfile rules are to find them through Google).

https://docs.docker.com/reference/build-checks/ are docs for each rule.

thompson-shaun commented 1 month ago

The check doc is the top result via google atm 🥇

I was mostly curious if the GitHub issue context was worth adding to the check's page for historical purposes.

dvdksn commented 1 month ago

I'm not gonna send readers to GitHub issues where people argue about the pros and cons of this syntax. It's deprecated, don't use it.

mcandre commented 1 month ago

I don't care one whit about SEO. I'm asking for the CLI to explain why it bothers to drop support for the old syntax. No reason is given for a seemingly arbitrary warning.

A link from stderr to the relevant documentation page would be sufficient to clear up the confusion.

thompson-shaun commented 1 month ago

Links to the warning documentation are added when using docker buildx build with --debug. That being said, it might be good for us to link to the list of checks when --debug isn't being used.

Thanks for the feedback @mcandre -- I'll create a separate issue for any changes related to the output changes and link it here so this issue stays focused on its original purpose.

tianon commented 1 month ago

The so-called "legacy" syntax is only legacy because when ARG was added, it was added with a syntax that was different (intentionally) from the existing ENV syntax, so I don't really think "parser ambiguity" is a fair complaint here given that it wasn't ambiguous until the ARG foo=bar syntax was added. Again, however, I think a linting warning explicitly for the ambiguous cases is much more fruitful than deprecating the entire "legacy" syntax (which has some strong upsides in its favor) and trying to shift every usage such that we can remove it (especially, again, because there are upsides to the older syntax).