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

Docker lint #12426

Merged
merged 8 commits into from
Jul 30, 2021
Merged

Docker lint #12426

merged 8 commits into from
Jul 30, 2021

Conversation

kaos
Copy link
Member

@kaos kaos commented Jul 26, 2021

Continuing docker support, with linting of Dockerfiles, using hadolint.

This will be useful in and of itself, to have a way of linting a projects Dockerfiles, even before having full support for building Docker images with Pants.

Example use:

# src/Dockerfile
FROM base
COPY files /
...
# src/BUILD
docker_image(name="our-image")
$ ./pants lint src/Dockerfile

We need the docker_image in the BUILD file in order to connect the Dockerfile with the hadolint tool, which operates on the sources of docker_image targets.

To configure hadolint, either provide a .hadolint.yaml file in your project root, or point at your preferred config file to use with the [hadolint].config option. (Which becomes --hadolint-config=path/to/config.yaml on the command line.)

@stuhood stuhood requested a review from benjyw July 26, 2021 22:24
@benjyw
Copy link
Contributor

benjyw commented Jul 27, 2021

Perhaps we should hold off on this until the other PRs have been merged? This can be #4 in the PR breakdown... :)

@kaos kaos changed the title Docker lint WIP: Docker lint Jul 27, 2021
@kaos
Copy link
Member Author

kaos commented Jul 27, 2021

Actually, I think we could sneak this in as PR 2, as it is rather small, and doesn't have any dependencies to the other code besides the DockerImage target type.

If you agree, I'll prepare this one once the first PR is merged.

@benjyw
Copy link
Contributor

benjyw commented Jul 27, 2021

Sure, sounds OK to me!

Example lint results:

    $ ./pants lint docker:helloworld
    18:54:08.20 [INFO] Completed: lint - hadolint succeeded.

    ✓ hadolint succeeded.

    $ ./pants lint docker:helloworld
    18:48:00.57 [WARN] Completed: lint - hadolint failed (exit code 1).
    docker/Dockerfile:2 DL3008 warning: Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
    docker/Dockerfile:2 DL3009 info: Delete the apt-get lists after installing something
    docker/Dockerfile:2 DL3015 info: Avoid additional packages by specifying `--no-install-recommends`

    𐄂 hadolint failed.

[ci skip-rust]

[ci skip-build-wheels]
@kaos kaos changed the title WIP: Docker lint Docker lint Jul 28, 2021
@kaos
Copy link
Member Author

kaos commented Jul 28, 2021

@benjyw OK, this is ready for review now.

@kaos kaos requested a review from Eric-Arellano July 28, 2021 16:55
Copy link
Contributor

@Eric-Arellano Eric-Arellano left a comment

Choose a reason for hiding this comment

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

Super neat! A couple things to still do, please:

  1. Move into a dedicated backend/docker/lint/hadolint/ folder with its own register.py (don't forget to add to that init/BUILD). This is really important to v2 that linters are always opt-in, as many people may not want to use it.
  2. You need to register the SkipHadolintField via a PluginField:
    def rules():
    return [
    ShellLibrary.register_plugin_field(SkipShfmtField),
    Shunit2Tests.register_plugin_field(SkipShfmtField),
    ]
  3. The ExternalTool should get a --skip option. In your @rule, return `LintResults([], linter_name="hadolint") if skip is set.
  4. The subsystem should get an --args option w/ type=shell_str. Mix it into the argv.
  5. It'd be great to support config files. Looks like they both do autodiscovery and allow custom locations with --config. Please use the ConfigFiles functionality for this and add the options --config and --config-discovery. See flake8/subsystem.py and flake8/rules.py for an example. (You do not need to have two separate rules and all that partition stuff)
  6. This needs some tests. You can mostly copy pasta {shellcheck,shfmt}/rules_integration_test.py, although also test the --config option like done in flake8/rules_integration_test.py for example.

Generally, adding a linter can mostly be copy pasta from the other linters. I encourage you to look at how the others like shellcheck and shfmt are implemented.

src/python/pants/backend/docker/lint.py Outdated Show resolved Hide resolved
src/python/pants/backend/docker/lint.py Outdated Show resolved Hide resolved
# Rust tests and lints will be skipped. Delete if not intended.
[ci skip-rust]

# Building wheels and fs_util will be skipped. Delete if not intended.
[ci skip-build-wheels]
@kaos kaos requested a review from Eric-Arellano July 29, 2021 09:44
# Rust tests and lints will be skipped. Delete if not intended.
[ci skip-rust]

# Building wheels and fs_util will be skipped. Delete if not intended.
[ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended.
[ci skip-rust]

# Building wheels and fs_util will be skipped. Delete if not intended.
[ci skip-build-wheels]
Copy link
Contributor

@Eric-Arellano Eric-Arellano left a comment

Choose a reason for hiding this comment

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

Super well done! I'm excited for this to land 👏

kaos added 2 commits July 29, 2021 23:13
# Rust tests and lints will be skipped. Delete if not intended.
[ci skip-rust]

# Building wheels and fs_util will be skipped. Delete if not intended.
[ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended.
[ci skip-rust]

# Building wheels and fs_util will be skipped. Delete if not intended.
[ci skip-build-wheels]
),
),
)
config_files = await Get(ConfigFiles, ConfigFilesRequest, hadolint.config_request())
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, sorry, one small perf thing: this can now go into the MultiGet right above.

Comment on lines 84 to 85
results = [LintResult.from_fallible_process_result(process_result)]
return LintResults(results, linter_name="hadolint")
Copy link
Contributor

Choose a reason for hiding this comment

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

(Subjective style nit that you can feel free to disagree on): might be simpler to inline this, imo the var doesn't add much and adds yet another name to the namespace

@@ -0,0 +1,92 @@
# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
Copy link
Contributor

@Eric-Arellano Eric-Arellano Jul 29, 2021

Choose a reason for hiding this comment

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

Oh didn't realize Docker is still under an experimental backend. This linter should be aligned with the normal Docker backend.

@benjyw do you think it should be experimental still? Now that we have Hadolint, Docker support is a Real Thing, more than just ./pants tailor. For example, our Shell support is only linters + a test runner.

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's worry about that later. We still have to add the core functionality.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay. @kaos can you please rename this folder to be experimental then? Note that this backend doesn't work without first activating the core Docker backend.

Copy link
Member Author

Choose a reason for hiding this comment

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

Looking at terraform, only the register file is under experimental.. same here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah that's fine, given how stable we expect this code itself to be. Thanks!

kaos added 2 commits July 30, 2021 07:20
# Rust tests and lints will be skipped. Delete if not intended.
[ci skip-rust]

# Building wheels and fs_util will be skipped. Delete if not intended.
[ci skip-build-wheels]
Signed-off-by: Andreas Stenius <[email protected]>

# Rust tests and lints will be skipped. Delete if not intended.
[ci skip-rust]

# Building wheels and fs_util will be skipped. Delete if not intended.
[ci skip-build-wheels]
@Eric-Arellano Eric-Arellano merged commit b44edcb into pantsbuild:main Jul 30, 2021
@kaos kaos deleted the docker_lint branch July 30, 2021 07:13
@kaos kaos mentioned this pull request Jul 30, 2021
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.

3 participants