packages feed

hadolint 1.6.0 → 1.6.1

raw patch · 3 files changed

+94/−13 lines, 3 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Hadolint.Rules: allFromImages :: Dockerfile -> [(Linenumber, BaseImage)]
+ Hadolint.Rules: allImageNames :: Dockerfile -> [(Linenumber, String)]
+ Hadolint.Rules: fromAlias :: BaseImage -> Maybe ImageAlias
+ Hadolint.Rules: fromName :: BaseImage -> String
- Hadolint.Rules: aptGetCleanup :: Rule
+ Hadolint.Rules: aptGetCleanup :: Dockerfile -> [RuleCheck]

Files

hadolint.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 8953f4990fda4e78c53418a6f7426bc5f60f367bf771ed9e7bf015eac0868247+-- hash: dad086f0af35e0c451cefe4a1513876be3f752b5251b47db3267dc37fc59edd6  name:           hadolint-version:        1.6.0+version:        1.6.1 synopsis:       Dockerfile Linter JavaScript API description:    A smarter Dockerfile linter that helps you build best practice Docker images. category:       Development
src/Hadolint/Rules.hs view
@@ -169,14 +169,20 @@ bashCommands :: [String] -> [[String]] bashCommands = splitOneOf [";", "|", "&&"] +allFromImages :: Dockerfile -> [(Linenumber, BaseImage)]+allFromImages dockerfile = [(l, f) | (l, From f) <- instr]+  where+    instr = fmap (lineNumber &&& instruction) dockerfile+ allAliasedImages :: Dockerfile -> [(Linenumber, ImageAlias)] allAliasedImages dockerfile =-    [(l, a) | (l, From (UntaggedImage _ (Just a))) <- instr] ++-    [(l, a) | (l, From (TaggedImage _ _ (Just a))) <- instr] ++-    [(l, a) | (l, From (DigestedImage _ _ (Just a))) <- instr]+    [(l, alias) | (l, Just alias) <- map extractAlias (allFromImages dockerfile)]   where-    instr = fmap (lineNumber &&& instruction) dockerfile+    extractAlias (l, f) = (l, fromAlias f) +allImageNames :: Dockerfile -> [(Linenumber, String)]+allImageNames dockerfile = [(l, fromName baseImage) | (l, baseImage) <- allFromImages dockerfile]+ -- | Returns a list of all image aliases in FROM instructions that --  are defined before the given line number. previouslyDefinedAliases :: Linenumber -> Dockerfile -> [String]@@ -194,6 +200,16 @@         From (DigestedImage _ _ (Just (ImageAlias alias))) -> predicate alias         _ -> True +fromName :: BaseImage -> String+fromName (UntaggedImage Image {imageName} _) = imageName+fromName (TaggedImage Image {imageName} _ _) = imageName+fromName (DigestedImage Image {imageName} _ _) = imageName++fromAlias :: BaseImage -> Maybe ImageAlias+fromAlias (UntaggedImage _ alias) = alias+fromAlias (TaggedImage _ _ alias) = alias+fromAlias (DigestedImage _ _ alias) = alias+ absoluteWorkdir = instructionRule code severity message check   where     code = "DL3000"@@ -335,15 +351,33 @@     noOption arg = arg `notElem` options && not ("--" `isPrefixOf` arg)     options = ["apt-get", "install", "-d", "-f", "-m", "-q", "-y", "-qq"] -aptGetCleanup = instructionRule code severity message check+aptGetCleanup dockerfile = instructionRuleState code severity message check Nothing dockerfile   where     code = "DL3009"     severity = InfoC     message = "Delete the apt-get lists after installing something"-    check (Run (Arguments args)) = not (hasUpdate args) || hasCleanup args-    check _ = True+    withState st res = (st, res)+    -- | 'check' returns a tuple (state, check_result)+    --   The state in this case is the FROM instruction where the current instruction we are+    --   inspecting is nested in.+    --   We only care for users to delete the lists folder if the FROM clase we're is is the last one+    --   or if it is used as the base image for another FROM clause.+    check _ line f@(From _) = withState (Just (line, f)) True -- Remember the last FROM instruction found+    check st@(Just (line, From baseimage)) _ (Run (Arguments args))+        | not (hasUpdate args) || not (imageIsUsed line baseimage) = withState st True+        | otherwise = withState st (hasCleanup args)+    check st _ _ = withState st True     hasCleanup cmd = ["rm", "-rf", "/var/lib/apt/lists/*"] `isInfixOf` cmd     hasUpdate cmd = ["apt-get", "update"] `isInfixOf` cmd+    imageIsUsed line baseimage = isLastImage line baseimage || imageIsUsedLater line baseimage+    isLastImage line baseimage =+        case reverse (allFromImages dockerfile) of+            lst:_ -> (line, baseimage) == lst+            _ -> True+    imageIsUsedLater line baseimage =+        case fromAlias baseimage of+            Nothing -> True+            Just (ImageAlias alias) -> alias `elem` [i | (l, i) <- allImageNames dockerfile, l > line]  dropOptionsWithArg :: [String] -> [String] -> [String] dropOptionsWithArg os [] = []
test/Spec.hs view
@@ -65,11 +65,58 @@             it "apt-get version pinning" $                 ruleCatches aptGetVersionPinned "RUN apt-get update && apt-get install python"             it "apt-get no cleanup" $-                ruleCatches aptGetCleanup "RUN apt-get update && apt-get install python"+                let dockerfile =+                        [ "FROM scratch"+                        , "RUN apt-get update && apt-get install python"+                        ]+                in ruleCatches aptGetCleanup $ unlines dockerfile+            it "apt-get cleanup in stage image" $+                let dockerfile =+                        [ "FROM ubuntu as foo"+                        , "RUN apt-get update && apt-get install python"+                        , "FROM scratch"+                        , "RUN echo hey!"+                        ]+                in ruleCatchesNot aptGetCleanup $ unlines dockerfile+            it "apt-get no cleanup in last stage" $+                let dockerfile =+                        [ "FROM ubuntu as foo"+                        , "RUN hey!"+                        , "FROM scratch"+                        , "RUN apt-get update && apt-get install python"+                        ]+                in ruleCatches aptGetCleanup $ unlines dockerfile+            it "apt-get no cleanup in intermediate stage" $+                let dockerfile =+                        [ "FROM ubuntu as foo"+                        , "RUN apt-get update && apt-get install python"+                        , "FROM foo"+                        , "RUN hey!"+                        ]+                in ruleCatches aptGetCleanup $ unlines dockerfile+            it "now warn apt-get cleanup in intermediate stage that cleans lists" $+                let dockerfile =+                        [ "FROM ubuntu as foo"+                        , "RUN apt-get update && apt-get install python && rm -rf /var/lib/apt/lists/*"+                        , "FROM foo"+                        , "RUN hey!"+                        ]+                in ruleCatchesNot aptGetCleanup $ unlines dockerfile+            it "no warn apt-get cleanup in intermediate stage when stage not used later" $+                let dockerfile =+                        [ "FROM ubuntu as foo"+                        , "RUN apt-get update && apt-get install python"+                        , "FROM scratch"+                        , "RUN hey!"+                        ]+                in ruleCatchesNot aptGetCleanup $ unlines dockerfile             it "apt-get cleanup" $-                ruleCatchesNot-                    aptGetCleanup-                    "RUN apt-get update && apt-get install python && rm -rf /var/lib/apt/lists/*"+                let dockerfile =+                        [ "FROM scratch"+                        , "RUN apt-get update && apt-get install python && rm -rf /var/lib/apt/lists/*"+                        ]+                in ruleCatchesNot aptGetCleanup $ unlines dockerfile+             it "apt-get pinned chained" $                 let dockerfile =                         [ "RUN apt-get update \\"