From 2325970208484912d646b044965d505c0d56df77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20R=C3=B6hrich?= Date: Tue, 20 Jul 2021 13:09:01 +0200 Subject: [PATCH] Feature: Silence DL3009,DL3019 for cache mounts In case the cache directories DL3009 and DL3019 respectively are provided via BuildKit cache mount, the two rules need not warn a user to remove the directories. fixes: #671 --- src/Hadolint/Rule/DL3009.hs | 12 ++++++++++-- src/Hadolint/Rule/DL3019.hs | 20 ++++++++++++++++---- test/DL3009.hs | 4 ++++ test/DL3019.hs | 9 +++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/Hadolint/Rule/DL3009.hs b/src/Hadolint/Rule/DL3009.hs index 5cb40b5a..305e71cf 100644 --- a/src/Hadolint/Rule/DL3009.hs +++ b/src/Hadolint/Rule/DL3009.hs @@ -23,8 +23,9 @@ rule = veryCustomRule check (emptyState Empty) markFailures message = "Delete the apt-get lists after installing something" check line st (From from) = st |> modify (rememberStage line from) - check line st (Run (RunArgs args _)) - | foldArguments forgotToCleanup args = st |> modify (rememberLine line) + check line st (Run (RunArgs args flags)) + | hasNoCacheMount flags && foldArguments forgotToCleanup args = + st |> modify (rememberLine line) | otherwise = st check _ st _ = st @@ -59,6 +60,13 @@ forgotToCleanup args hasUpdate = any (Shell.cmdHasArgs "apt-get" ["update"]) (Shell.presentCommands args) +hasNoCacheMount :: RunFlags -> Bool +hasNoCacheMount RunFlags + { mount = + Just (CacheMount CacheOpts {cTarget = TargetPath {unTargetPath = p}}) + } = Text.dropWhileEnd (=='/') p /= "/var/lib/apt/lists" +hasNoCacheMount RunFlags {} = True + -- | Even though dockerfiles without a FROM are not valid, we still want to provide some feedback for this rule -- so we pretend there is a base image at the start of the file if there is none emptyImage :: BaseImage diff --git a/src/Hadolint/Rule/DL3019.hs b/src/Hadolint/Rule/DL3019.hs index a801a144..a55a6e2a 100644 --- a/src/Hadolint/Rule/DL3019.hs +++ b/src/Hadolint/Rule/DL3019.hs @@ -1,5 +1,6 @@ module Hadolint.Rule.DL3019 (rule) where +import qualified Data.Text as Text import Hadolint.Rule import Hadolint.Shell (ParsedShell) import qualified Hadolint.Shell as Shell @@ -11,9 +12,20 @@ rule = simpleRule code severity message check code = "DL3019" severity = DLInfoC message = - "Use the `--no-cache` switch to avoid the need to use `--update` and remove \ - \`/var/cache/apk/*` when done installing packages" - check (Run (RunArgs args _)) = foldArguments (Shell.noCommands forgotCacheOption) args + "Use the `--no-cache` switch to avoid the need to use `--update` and \ + \remove `/var/cache/apk/*` when done installing packages" + check (Run (RunArgs args flags)) = hasCacheMount flags + || foldArguments (Shell.noCommands forgotCacheOption) args check _ = True - forgotCacheOption cmd = Shell.cmdHasArgs "apk" ["add"] cmd && not (Shell.hasFlag "no-cache" cmd) {-# INLINEABLE rule #-} + +hasCacheMount :: RunFlags -> Bool +hasCacheMount RunFlags + { mount = + Just (CacheMount CacheOpts {cTarget = TargetPath {unTargetPath = p}}) + } = Text.dropWhileEnd (=='/') p == "/var/cache/apk" +hasCacheMount RunFlags {} = False + +forgotCacheOption :: Shell.Command -> Bool +forgotCacheOption cmd = Shell.cmdHasArgs "apk" ["add"] cmd + && not (Shell.hasFlag "no-cache" cmd) diff --git a/test/DL3009.hs b/test/DL3009.hs index d6cb4893..09b7bf32 100644 --- a/test/DL3009.hs +++ b/test/DL3009.hs @@ -75,3 +75,7 @@ tests = do in do ruleCatchesNot "DL3009" $ Text.unlines dockerFile onBuildRuleCatchesNot "DL3009" $ Text.unlines dockerFile + + it "don't warn: BuildKit cache mount to apt lists directory" $ do + ruleCatchesNot "DL3009" "RUN --mount=type=cache,target=/var/lib/apt/lists apt-get update && apt-get install python" + onBuildRuleCatchesNot "DL3009" "RUN --mount=type=cache,target=/var/lib/apt/lists apt-get update && apt-get install python" diff --git a/test/DL3019.hs b/test/DL3019.hs index eea6bc42..2f80c07d 100644 --- a/test/DL3019.hs +++ b/test/DL3019.hs @@ -14,3 +14,12 @@ tests = do it "apk add without --no-cache" $ do ruleCatchesNot "DL3019" "RUN apk add --no-cache flex=2.6.4-r1" onBuildRuleCatchesNot "DL3019" "RUN apk add --no-cache flex=2.6.4-r1" + it "don't warn: apk add with BuildKit cache mount" $ do + ruleCatchesNot "DL3019" "RUN --mount=type=cache,target=/var/cache/apk apk add -U curl=7.77.0" + onBuildRuleCatchesNot "DL3019" "RUN --mount=type=cache,target=/var/cache/apk apk add -U curl=7.77.0" + it "don't warn: apk add with BuildKit cache mount in wrong dir and --no-cache" $ do + ruleCatchesNot "DL3019" "RUN --mount=type=cache,target=/var/cache/foo apk add --no-cache -U curl=7.77.0" + onBuildRuleCatchesNot "DL3019" "RUN --mount=type=cache,target=/var/cache/foo apk add --no-cache -U curl=7.77.0" + it "warn: apk add with BuildKit cache mount to wrong dir" $ do + ruleCatches "DL3019" "RUN --mount=type=cache,target=/var/cache/foo apk add -U curl=7.77.0" + onBuildRuleCatches "DL3019" "RUN --mount=type=cache,target=/var/cache/foo apk add -U curl=7.77.0"