dockerfilelint
Advanced tools
Comparing version 1.7.0 to 1.8.0
@@ -5,2 +5,6 @@ # Change Log | ||
# [1.8.0](https://github.com/replicatedhq/dockerfilelint/compare/v1.7.0...v1.8.0) (2020-08-10) | ||
# [1.7.0](https://github.com/replicatedhq/dockerfilelint/compare/v1.5.1...v1.7.0) (2020-08-10) | ||
@@ -7,0 +11,0 @@ |
@@ -41,3 +41,3 @@ var parser = require('./parser'); | ||
} else { | ||
baseImage = args.split(':'); | ||
baseImage = args.split(' ')[0].split(":"); | ||
} | ||
@@ -47,3 +47,3 @@ var result = []; | ||
result.push('missing_tag'); | ||
} else if (baseImage[1] === 'latest') { | ||
} else if (baseImage[baseImage.length - 1] === 'latest') { | ||
result.push('latest_tag'); | ||
@@ -165,3 +165,35 @@ } | ||
return []; | ||
}, | ||
is_valid_healthcheck: function (args) { | ||
// if the first argument is 'NONE", there shouldnt be any more arguments | ||
var words = parser.words(args); | ||
if (words[0] === "none") { | ||
if (words.length === 1) { | ||
return []; | ||
} | ||
return ['invalid_format']; | ||
} | ||
// check for allowed options in 'HEALTHCHECK [options] CMD' | ||
// extract only HEALTHCHECK options before CMD | ||
// (as CMD in itself can have options) | ||
var allowedoptions = ["--interval", | ||
"--timeout", | ||
"--start-period", | ||
"--retries"]; | ||
var cmd = /\ [^-].*/.exec(args); | ||
if (cmd != null) { | ||
var options = args.substring(0, cmd.index).match(/--\w+/g); | ||
if (!options.reduce((valid, item) => valid && | ||
(allowedoptions.indexOf(item) > -1), true)) return ['invalid_format']; | ||
if (options != null) { | ||
var optparams = args.substring(0, cmd.index).match(/--\w+=\d+\w*/g); | ||
return ((optparams != null) && (optparams.length == options.length)) ? | ||
[] : ['healthcheck_options_missing_args']; | ||
} | ||
} | ||
return []; | ||
} | ||
} |
@@ -273,2 +273,7 @@ 'use strict'; | ||
break; | ||
case 'healthcheck': | ||
checks.is_valid_healthcheck(args).forEach(function(item) { | ||
items.push(messages.build(state.rules, item, line)); | ||
}); | ||
break; | ||
default: | ||
@@ -275,0 +280,0 @@ items.push(messages.build(state.rules, 'invalid_command', line)); |
@@ -171,3 +171,8 @@ var reference = module.exports = { | ||
'category': 'Optimization' | ||
}, | ||
'healthcheck_options_missing_args': { | ||
'title': 'Missing Argument for HEALTHCHECK option', | ||
'description': 'HEALTHCHECK options (like \'--timeout\') must have extra arguments (e.g. `\--timeout=30s\') ', | ||
'category': 'Possible Bug' | ||
} | ||
} |
{ | ||
"name": "dockerfilelint", | ||
"version": "1.7.0", | ||
"version": "1.8.0", | ||
"description": "A linter for Dockerfiles to find bugs and encourage best practices", | ||
@@ -5,0 +5,0 @@ "main": "./lib/index.js", |
@@ -6,4 +6,12 @@ # Linter and validator for Dockerfile | ||
`Dockerfilelint` is an node module that analyzes a Dockerfile and looks for common traps, mistakes and helps enforce best practices: | ||
`dockerfilelint` is an node module that analyzes a Dockerfile and looks for common traps, mistakes and helps enforce best practices. | ||
## Installation | ||
Global installation with npm package manager. | ||
```shell | ||
npm install -g dockerfilelint | ||
``` | ||
## Testing | ||
@@ -13,3 +21,5 @@ Start unit tests with `npm test`, `yarn run test`, or `docker-compose -f docker-compose.test.yml up` | ||
## Running | ||
#### From the command line: | ||
```shell | ||
@@ -20,2 +30,3 @@ ./bin/dockerfilelint <path/to/Dockerfile> | ||
#### Command Line options | ||
```shell | ||
@@ -45,2 +56,3 @@ Usage: dockerfilelint [files | content..] [options] | ||
#### Configuring | ||
You can configure the linter by creating a `.dockerfilelintrc` with the following syntax: | ||
@@ -52,5 +64,5 @@ ```yaml | ||
The keys for the rules can be any file in the /lib/reference.js file. At this time, it's only possible to disable rules. They are all enabled by default. | ||
The keys for the rules can be any file in the /lib/reference.js file. At this time, it's only possible to disable rules. They are all enabled by default. | ||
The following rules are supported: | ||
The following rules are supported: | ||
``` | ||
@@ -86,2 +98,3 @@ required_params | ||
#### From a Docker container | ||
(Replace the ``pwd``/Dockerfile with the path to your local Dockerfile) | ||
@@ -93,6 +106,9 @@ ```shell | ||
#### Online | ||
If you don't want to install this locally you can try it out on [https://fromlatest.io](https://www.fromlatest.io/#/). | ||
## Checks performed | ||
### `FROM` | ||
- [x] This should be the first command in the Dockerfile | ||
@@ -106,5 +122,7 @@ - [x] Base image should specify a tag | ||
### `MAINTAINER` | ||
- [x] Should be followed by exactly 1 parameter (@ sign) | ||
### `RUN` | ||
- [x] sudo is not included in the command | ||
@@ -121,2 +139,3 @@ - [x] apt-get [install | upgrade | remove] should include a -y flag | ||
### `CMD` | ||
- [x] Only a single `CMD` layer is allowed | ||
@@ -127,5 +146,7 @@ - [ ] Better handling of escaped quotes | ||
### `LABEL` | ||
- [x] Format should be key=value | ||
### `EXPOSE` | ||
- [x] Only the container port should be listed | ||
@@ -137,2 +158,3 @@ - [ ] All ports should be exposed in a single cache layer (line) | ||
### `ENV` | ||
- [x] Format of `ENV` | ||
@@ -142,2 +164,3 @@ - [ ] Best practice of only using a single `ENV` line to reduce cache layer count | ||
### `ADD` | ||
- [x] Command should have at least 2 parameters | ||
@@ -150,2 +173,3 @@ - [x] Source command(s) cannot be absolute or relative paths that exist outside of the current build context | ||
### `COPY` | ||
- [ ] Implement checking (similar to ADD) | ||
@@ -155,5 +179,7 @@ - [ ] Do not `COPY` multiple files on a single command to best use cache | ||
### `ENTRYPOINT` | ||
- [ ] Support | ||
### `VOLUME` | ||
- [ ] Format | ||
@@ -164,5 +190,7 @@ - [ ] Any build steps after VOLUME is declare should not change VOLUME contents | ||
### `USER` | ||
- [x] Should be followed by exactly 1 parameter | ||
### `WORKDIR` | ||
- [x] Validate that it has exactly 1 parameter | ||
@@ -172,2 +200,3 @@ - [x] `WORKDIR` can only expand variables previously set in `ENV` commands | ||
### `ARG` | ||
- [ ] Support | ||
@@ -177,11 +206,19 @@ - [ ] Prevent redefining the built in ARGs (proxy) | ||
### `ONBUILD` | ||
- [ ] Support | ||
### `STOPSIGNAL` | ||
- [ ] Validate input | ||
- [ ] Only present one time | ||
### `HEALTHCHECK` | ||
- [x] No additional parameters when only parameter is `NONE` | ||
- [x] Options before `CMD` are valid | ||
- [x] Options before `CMD` have additional arguments | ||
### Misc | ||
- [x] Only valid Dockerfile commands are present | ||
- [x] All commands should have at least 1 parameter | ||
- [x] Check that commands are written as upper case commands |
@@ -126,2 +126,14 @@ var expect = require('chai').expect | ||
}); | ||
describe("#is_valid_healthcheck(args)", function () { | ||
it("validates healthcheck command is valid", function(){ | ||
expect(checks.is_valid_healthcheck("none")).to.be.empty; | ||
expect(checks.is_valid_healthcheck("none invalidargument")).to.eql(['invalid_format']); | ||
expect(checks.is_valid_healthcheck("--invalid=10s cmd")).to.eql(['invalid_format']); | ||
expect(checks.is_valid_healthcheck("--interval=10s cmd")).to.be.empty; | ||
expect(checks.is_valid_healthcheck("--interval=10s cmd argument --someotherargument")).to.be.empty; | ||
expect(checks.is_valid_healthcheck("--interval cmd argument")).to.eql(['healthcheck_options_missing_args']); | ||
expect(checks.is_valid_healthcheck("--interval=10s --timeout cmd argument")).to.eql(['healthcheck_options_missing_args']); | ||
}) | ||
}); | ||
}); |
@@ -84,2 +84,43 @@ var expect = require('chai').expect | ||
describe("#from-with-as", function () { | ||
it("validates the Dockerfile detects latest when using as", function () { | ||
var expected = [ | ||
{ title: 'Base Image Latest Tag', | ||
line: 1, | ||
rule: 'latest_tag'} | ||
]; | ||
const lintResult = dockerfilelint.run('./test/examples', fs.readFileSync('./test/examples/Dockerfile.from-as', 'UTF-8')); | ||
_.forEach(lintResult, function(r) { | ||
delete r['description']; | ||
delete r['category']; | ||
}); | ||
expect(lintResult).to.have.length(expected.length); | ||
expect(lintResult).to.deep.equal(expected); | ||
}); | ||
}); | ||
describe("#from-with-port", function () { | ||
it("validates the Dockerfile detects latest when it has a port", function () { | ||
var expected = [ | ||
{ title: 'Base Image Latest Tag', | ||
line: 1, | ||
rule: 'latest_tag'} | ||
]; | ||
const lintResult = dockerfilelint.run('./test/examples', fs.readFileSync('./test/examples/Dockerfile.from-with-port', 'UTF-8')); | ||
_.forEach(lintResult, function(r) { | ||
delete r['description']; | ||
delete r['category']; | ||
}); | ||
expect(lintResult).to.have.length(expected.length); | ||
expect(lintResult).to.deep.equal(expected); | ||
}); | ||
}); | ||
describe("#from-with-port-no-latest", function () { | ||
it("validates the Dockerfile detects not latest when it has a port", function () { | ||
const lintResult = dockerfilelint.run('./test/examples', fs.readFileSync('./test/examples/Dockerfile.from-with-port-no-latest', 'UTF-8')); | ||
expect(lintResult).to.have.length(0); | ||
}); | ||
}); | ||
describe("#shell", function() { | ||
@@ -86,0 +127,0 @@ it("validates the shell command is accepted when entered correctly", function() { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
230621
57
1987
208