packages feed

hadolint 1.18.0 → 1.18.1

raw patch · 5 files changed

+139/−19 lines, 5 filesdep ~language-docker

Dependency ranges changed: language-docker

Files

README.md view
@@ -121,6 +121,13 @@ hadolint --config /path/to/config.yaml Dockerfile ``` +To pass a custom configuration file (using relative or absolute path) to a container,+use the following command:++```bash+docker run --rm -i -v ./your/path/to/hadolint.yaml:/root/.config/hadolint.yaml hadolint/hadolint < Dockerfile+```+ ## Inline ignores  It is also possible to ignore rules by using a special comment directly above the Dockerfile@@ -191,6 +198,11 @@ | [DL3026](https://github.com/hadolint/hadolint/wiki/DL3026)   | Use only an allowed registry in the FROM image                                                                                                      | | [DL3027](https://github.com/hadolint/hadolint/wiki/DL3027)   | Do not use `apt` as it is meant to be a end-user tool, use `apt-get` or `apt-cache` instead                                                         | | [DL3028](https://github.com/hadolint/hadolint/wiki/DL3028)   | Pin versions in gem install. Instead of `gem install <gem>` use `gem install <gem>:<version>`                                                       |+| [DL3029](https://github.com/hadolint/hadolint/wiki/DL3029)   | Do not use --platform flag with FROM.                                                                                                               |+| [DL3030](https://github.com/hadolint/hadolint/wiki/DL3030)   | Use the `-y` switch to avoid manual input `yum install -y <package>`                                                                                |+| [DL3031](https://github.com/hadolint/hadolint/wiki/DL3031)   | Do not use `yum update`                                                                                                                             |+| [DL3032](https://github.com/hadolint/hadolint/wiki/DL3032)   | `yum clean all` missing after yum command.                                                                                                          |+| [DL3033](https://github.com/hadolint/hadolint/wiki/DL3033)   | Specify version with `yum install -y <package>-<version>`                                                                                           | | [DL4000](https://github.com/hadolint/hadolint/wiki/DL4000)   | MAINTAINER is deprecated.                                                                                                                           | | [DL4001](https://github.com/hadolint/hadolint/wiki/DL4001)   | Either use Wget or Curl but not both.                                                                                                               | | [DL4003](https://github.com/hadolint/hadolint/wiki/DL4003)   | Multiple `CMD` instructions found.                                                                                                                  |
hadolint.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 417883d2c2a9328b25a066609f646f6e0169178dd2f403009304327ddeef2720+-- hash: f2454ac92e402e2007f598a079c8998996473f8fc6501b81e3eb1f9cd98d5f56  name:           hadolint-version:        1.18.0+version:        1.18.1 synopsis:       Dockerfile Linter JavaScript API description:    A smarter Dockerfile linter that helps you build best practice Docker images. category:       Development@@ -57,7 +57,7 @@     , containers     , directory >=1.3.0     , filepath-    , language-docker >=9.1.0 && <10+    , language-docker >=9.1.2 && <10     , megaparsec >=7.0     , mtl     , split >=0.2@@ -77,7 +77,7 @@     , containers     , gitrev >=1.3.1     , hadolint-    , language-docker >=9.1.0 && <10+    , language-docker >=9.1.2 && <10     , megaparsec >=7.0     , optparse-applicative >=0.14.0     , text@@ -103,7 +103,7 @@     , bytestring >=0.10     , hadolint     , hspec-    , language-docker >=9.1.0 && <10+    , language-docker >=9.1.2 && <10     , megaparsec >=7.0     , split >=0.2     , text
src/Hadolint/Rules.hs view
@@ -185,6 +185,7 @@     , noApkUpgrade     , noLatestTag     , noUntagged+    , noPlatformFlag     , aptGetVersionPinned     , aptGetCleanup     , apkAddVersionPinned@@ -204,6 +205,10 @@     , usePipefail     , noApt     , gemVersionPinned+    , yumYes+    , noYumUpdate+    , yumCleanup+    , yumVersionPinned     ]  optionalRules :: RulesConfig -> [Rule]@@ -589,13 +594,16 @@     check _ = True     forgotToPinVersion cmd =         isPipInstall cmd && not (hasBuildConstraint cmd) && not (all versionFixed (packages cmd))-    -- Check if the command is a pip* install command, and that specific pacakges are being listed-    isPipInstall cmd@(Shell.Command name _ _) = "pip" `Text.isPrefixOf` name && relevantInstall cmd+    -- Check if the command is a pip* install command, and that specific packages are being listed+    isPipInstall cmd = (isStdPipInstall cmd || isPythonPipInstall cmd) && not (requirementInstall cmd)+    isStdPipInstall cmd@(Shell.Command name _ _) = "pip" `Text.isPrefixOf` name && ["install"] `isInfixOf` Shell.getArgs cmd+    isPythonPipInstall cmd@(Shell.Command name _ _) = "python" `Text.isPrefixOf` name &&+        ["-m", "pip", "install"] `isInfixOf` Shell.getArgs cmd     -- If the user is installing requirements from a file or just the local module, then we are not interested     -- in running this rule-    relevantInstall cmd =-        ["install"] `isInfixOf` Shell.getArgs cmd &&-        not (["--requirement"] `isInfixOf` Shell.getArgs cmd || ["-r"] `isInfixOf` Shell.getArgs cmd || ["."] `isInfixOf` Shell.getArgs cmd)+    requirementInstall cmd = ["--requirement"] `isInfixOf` Shell.getArgs cmd ||+        ["-r"] `isInfixOf` Shell.getArgs cmd ||+        ["."] `isInfixOf` Shell.getArgs cmd     hasBuildConstraint cmd = Shell.hasFlag "constraint" cmd || Shell.hasFlag "c" cmd     packages cmd =         stripInstallPrefix $@@ -612,10 +620,12 @@             , "platform"             , "prefix"             , "progress-bar"+            , "proxy"             , "python-version"             , "root"             , "src"             , "t", "target"+            , "trusted-host"             , "upgrade-strategy"             ] cmd     versionFixed package = hasVersionSymbol package || isVersionedGit package@@ -624,7 +634,7 @@     hasVersionSymbol package = or [s `Text.isInfixOf` package | s <- versionSymbols]  stripInstallPrefix :: [Text.Text] -> [Text.Text]-stripInstallPrefix = dropWhile (== "install")+stripInstallPrefix cmd = dropWhile (== "install") (dropWhile (/= "install") cmd)  {-|   Rule for pinning NPM packages to version, tag, or commit@@ -698,8 +708,8 @@  isArchive :: Text.Text -> Bool isArchive path =-    True `elem`-    [ ftype `Text.isSuffixOf` path+    or+    ([ ftype `Text.isSuffixOf` path     | ftype <-           [ ".tar"           , ".gz"@@ -717,10 +727,10 @@           , ".Z"           , ".tZ"           ]-    ]+    ])  isUrl :: Text.Text -> Bool-isUrl path = True `elem` [proto `Text.isPrefixOf` path | proto <- ["https://", "http://"]]+isUrl path = or ([proto `Text.isPrefixOf` path | proto <- ["https://", "http://"]])  copyInsteadAdd :: Rule copyInsteadAdd = instructionRule code severity message check@@ -742,7 +752,7 @@         | length sources > 1 = endsWithSlash t         | otherwise = True     check _ = True-    endsWithSlash (TargetPath t) = Text.last t == '/' -- it is safe to use last, as the target is never empty+    endsWithSlash (TargetPath t) = not (Text.null t) && Text.last t == '/'  copyFromExists :: Rule copyFromExists dockerfile = instructionRuleLine code severity message check dockerfile@@ -862,6 +872,71 @@     check (Run (RunArgs args _)) = argumentsRule (all versionFixed . gems) args     check _ = True     versionFixed package = ":" `Text.isInfixOf` package++noPlatformFlag :: Rule+noPlatformFlag = instructionRule code severity message check+  where+    code = "DL3029"+    severity = WarningC+    message = "Do not use --platform flag with FROM"+    check (From BaseImage {platform = Just p}) = p == ""+    check _ = True++yumYes :: Rule+yumYes = instructionRule code severity message check+  where+    code = "DL3030"+    severity = WarningC+    message = "Use the -y switch to avoid manual input `yum install -y <package`"+    check (Run (RunArgs args _)) = argumentsRule (Shell.noCommands forgotYumYesOption) args+    check _ = True+    forgotYumYesOption cmd = isYumInstall cmd && not (hasYesOption cmd)+    isYumInstall = Shell.cmdHasArgs "yum" ["install", "groupinstall", "localinstall"]+    hasYesOption = Shell.hasAnyFlag ["y", "assumeyes"]++noYumUpdate :: Rule+noYumUpdate = instructionRule code severity message check+  where+    code = "DL3031"+    severity = ErrorC+    message = "Do not use yum update."+    check (Run (RunArgs args _)) =+      argumentsRule (Shell.noCommands (+                       Shell.cmdHasArgs "yum" ["update",+                                               "update-to",+                                               "upgrade",+                                               "upgrade-to"])) args+    check _ = True++yumCleanup :: Rule+yumCleanup = instructionRule code severity message check+  where+    code = "DL3032"+    severity = WarningC+    message = "`yum clean all` missing after yum command."+    check (Run (RunArgs args _)) = argumentsRule (Shell.noCommands yumInstall) args ||+                                   (argumentsRule (Shell.anyCommands yumInstall) args &&+                                    argumentsRule (Shell.anyCommands yumClean) args)+    check _ = True+    yumInstall = Shell.cmdHasArgs "yum" ["install"]+    yumClean = Shell.cmdHasArgs "yum" ["clean", "all"]++yumVersionPinned :: Rule+yumVersionPinned = instructionRule code severity message check+  where+    code = "DL3033"+    severity = WarningC+    message = "Specify version with `yum install -y <package>-<version>`."+    check (Run (RunArgs args _)) = argumentsRule (all versionFixed . yumPackages) args+    check _ = True+    versionFixed package = "-" `Text.isInfixOf` package+                        || ".rpm" `Text.isSuffixOf` package++yumPackages :: Shell.ParsedShell -> [Text.Text]+yumPackages args = [arg | cmd <- Shell.presentCommands args,+                          Shell.cmdHasArgs "yum" ["install"] cmd,+                          arg <- Shell.getArgsNoFlags cmd,+                          arg /= "install"]  gems :: Shell.ParsedShell -> [Text.Text] gems shell =
src/Hadolint/Shell.hs view
@@ -143,6 +143,9 @@ noCommands :: (Command -> Bool) -> ParsedShell -> Bool noCommands check = allCommands (not . check) +anyCommands :: (Command -> Bool) -> ParsedShell -> Bool+anyCommands check script = any check (presentCommands script)+ findCommandNames :: ParsedShell -> [Text] findCommandNames script = map name (presentCommands script) @@ -195,5 +198,6 @@ dropFlagArg :: [Text.Text] -> Command -> Command dropFlagArg flagsToDrop Command {name, arguments, flags} = Command name filterdArgs flags   where-    idsToDrop = Set.fromList [fId + 2 | CmdPart f fId <- flags, f `elem` flagsToDrop]+    idsToDrop = Set.fromList [getValueId fId arguments | CmdPart f fId <- flags, f `elem` flagsToDrop]     filterdArgs = [arg | arg@(CmdPart _ aId) <- arguments, not (aId `Set.member` idsToDrop)]+getValueId fId flags = foldl min (maxBound :: Int) $ filter (>fId) $ map partId flags 
test/Spec.hs view
@@ -23,6 +23,8 @@             it "explicit latest" $ ruleCatches noLatestTag "FROM debian:latest"             it "explicit latest with name" $ ruleCatches noLatestTag "FROM debian:latest AS builder"             it "explicit tagged" $ ruleCatchesNot noLatestTag "FROM debian:jessie"+            it "explicit platform flag" $ ruleCatches noPlatformFlag "FROM --platform=linux debian:jessie"+            it "no platform flag" $ ruleCatchesNot noPlatformFlag "FROM debian:jessie"             it "explicit SHA" $                 ruleCatchesNot noLatestTag                     "FROM hub.docker.io/debian@sha256:\@@ -188,6 +190,20 @@                 ruleCatchesNot gemVersionPinned "RUN gem install bundler:2.0.1 -- --use-system-libraries=true"                 onBuildRuleCatchesNot gemVersionPinned "RUN gem install bundler:2.0.1 -- --use-system-libraries=true"         --+        describe "yum rules" $ do+            it "yum update" $ do+                ruleCatches noYumUpdate "RUN yum update"+                onBuildRuleCatches noYumUpdate "RUN yum update"+            it "yum version pinning" $ do+                ruleCatches yumVersionPinned "RUN yum install -y tomcat && yum clean all"+                onBuildRuleCatches yumVersionPinned "RUN yum install -y tomcat && yum clean all"+            it "yum no clean all" $ do+                ruleCatches yumCleanup "RUN yum install -y mariadb-10.4"+                onBuildRuleCatches yumCleanup "RUN yum install -y mariadb-10.4"+            it "yum non-interactive" $ do+                ruleCatches yumYes "RUN yum install httpd-2.4.24 && yum clean all"+                onBuildRuleCatches yumYes "RUN yum install httpd-2.4.24 && yum clean all"+        --         describe "apt-get rules" $ do             it "apt" $                 let dockerFile =@@ -431,9 +447,15 @@             it "pip version pinned with flag --target" $ do                 ruleCatchesNot pipVersionPinned "RUN pip3 install --target /opt/yamllint yamllint==1.20.0"                 onBuildRuleCatchesNot pipVersionPinned "RUN pip3 install --target /opt/yamllint yamllint==1.20.0"+            it "pip version pinned with flag --trusted-host" $ do+                ruleCatchesNot pipVersionPinned "RUN pip3 install --trusted-host host example==1.2.2"+                onBuildRuleCatchesNot pipVersionPinned "RUN pip3 install --trusted-host host example==1.2.2"             it "pip version pinned with python -m" $ do                 ruleCatchesNot pipVersionPinned "RUN python -m pip install example==1.2.2"                 onBuildRuleCatchesNot pipVersionPinned "RUN python -m pip install example==1.2.2"+            it "pip version not pinned with python -m" $ do+                ruleCatches pipVersionPinned "RUN python -m pip install example"+                onBuildRuleCatches pipVersionPinned "RUN python -m pip install --index-url url example"             it "pip install git" $ do                 ruleCatchesNot                     pipVersionPinned@@ -497,6 +519,13 @@             it "pip install constraints file - short version argument" $ do                 ruleCatchesNot pipVersionPinned "RUN pip install pykafka -c http://foo.bar.baz"                 onBuildRuleCatchesNot pipVersionPinned "RUN pip install pykafka -c http://foo.bar.baz"+            it "pip install --index-url with --extra-index-url with basic auth" $ do+                ruleCatchesNot+                    pipVersionPinned+                    "RUN pip install --index-url https://user:pass@eg.com/foo --extra-index-url https://user:pass@ex-eg.io/foo foobar==1.0.0"+                onBuildRuleCatchesNot+                    pipVersionPinned+                    "RUN pip install --index-url https://user:pass@eg.com/foo --extra-index-url https://user:pass@ex-eg.io/foo foobar==1.0.0"         --         describe "npm pinning" $ do             it "version pinned in package.json" $ do@@ -681,7 +710,7 @@              it "Defaults the shell to sh" $                 let dockerFile = Text.unlines-                        [ "RUN echo $RANDOM" -- $RANDOM is not available in sh+                        [ "RUN echo $RANDOM"                         ]                 in do                   ruleCatches shellcheck dockerFile@@ -690,7 +719,7 @@             it "Can change the shell check to bash" $                 let dockerFile = Text.unlines                         [ "SHELL [\"/bin/bash\", \"-eo\", \"pipefail\", \"-c\"]"-                        , "RUN echo $RANDOM" -- $RANDOM is available in bash+                        , "RUN echo $RANDOM"                         ]                 in do                   ruleCatchesNot shellcheck dockerFile