-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5113 from daghack/invalid-default-arg-in-from
adds InvalidDefaultArgInFrom lint check
- Loading branch information
Showing
6 changed files
with
269 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,7 @@ var lintTests = integration.TestFuncs( | |
testAllTargetUnmarshal, | ||
testRedundantTargetPlatform, | ||
testSecretsUsedInArgOrEnv, | ||
testInvalidDefaultArgInFrom, | ||
) | ||
|
||
func testSecretsUsedInArgOrEnv(t *testing.T, sb integration.Sandbox) { | ||
|
@@ -643,9 +644,9 @@ LABEL org.opencontainers.image.authors="[email protected]" | |
|
||
func testWarningsBeforeError(t *testing.T, sb integration.Sandbox) { | ||
dockerfile := []byte(` | ||
# warning: stage name should be lowercase | ||
FROM scratch AS BadStageName | ||
FROM ${BAR} AS base | ||
MAINTAINER [email protected] | ||
BADCMD | ||
`) | ||
checkLinterWarnings(t, sb, &lintTestParams{ | ||
Dockerfile: dockerfile, | ||
|
@@ -655,20 +656,20 @@ FROM ${BAR} AS base | |
Description: "Stage names should be lowercase", | ||
URL: "https://docs.docker.com/go/dockerfile/rule/stage-name-casing/", | ||
Detail: "Stage name 'BadStageName' should be lowercase", | ||
Line: 3, | ||
Line: 2, | ||
Level: 1, | ||
}, | ||
{ | ||
RuleName: "UndefinedArgInFrom", | ||
Description: "FROM command must use declared ARGs", | ||
URL: "https://docs.docker.com/go/dockerfile/rule/undefined-arg-in-from/", | ||
Detail: "FROM argument 'BAR' is not declared", | ||
RuleName: "MaintainerDeprecated", | ||
Description: "The MAINTAINER instruction is deprecated, use a label instead to define an image author", | ||
URL: "https://docs.docker.com/go/dockerfile/rule/maintainer-deprecated/", | ||
Detail: "Maintainer instruction is deprecated in favor of using label", | ||
Level: 1, | ||
Line: 4, | ||
Line: 3, | ||
}, | ||
}, | ||
StreamBuildErr: "failed to solve: base name (${BAR}) should not be blank", | ||
UnmarshalBuildErr: "base name (${BAR}) should not be blank", | ||
StreamBuildErr: "failed to solve: dockerfile parse error on line 4: unknown instruction: BADCMD", | ||
UnmarshalBuildErr: "dockerfile parse error on line 4: unknown instruction: BADCMD", | ||
BuildErrLocation: 4, | ||
}) | ||
} | ||
|
@@ -1042,6 +1043,104 @@ FROM --platform=${TARGETPLATFORM} scratch | |
}) | ||
} | ||
|
||
func testInvalidDefaultArgInFrom(t *testing.T, sb integration.Sandbox) { | ||
dockerfile := []byte(` | ||
ARG VERSION | ||
FROM busybox:$VERSION | ||
`) | ||
checkLinterWarnings(t, sb, &lintTestParams{ | ||
Dockerfile: dockerfile, | ||
FrontendAttrs: map[string]string{ | ||
"build-arg:VERSION": "latest", | ||
}, | ||
Warnings: []expectedLintWarning{ | ||
{ | ||
RuleName: "InvalidDefaultArgInFrom", | ||
Description: "Default value for global ARG results in an empty or invalid base image name", | ||
URL: "https://docs.docker.com/go/dockerfile/rule/invalid-default-arg-in-from/", | ||
Detail: "Default value for ARG busybox:$VERSION results in empty or invalid base image name", | ||
Line: 3, | ||
Level: 1, | ||
}, | ||
}, | ||
}) | ||
|
||
dockerfile = []byte(` | ||
ARG IMAGE | ||
FROM $IMAGE | ||
`) | ||
checkLinterWarnings(t, sb, &lintTestParams{ | ||
Dockerfile: dockerfile, | ||
FrontendAttrs: map[string]string{ | ||
"build-arg:IMAGE": "busybox:latest", | ||
}, | ||
Warnings: []expectedLintWarning{ | ||
{ | ||
RuleName: "InvalidDefaultArgInFrom", | ||
Description: "Default value for global ARG results in an empty or invalid base image name", | ||
URL: "https://docs.docker.com/go/dockerfile/rule/invalid-default-arg-in-from/", | ||
Detail: "Default value for ARG $IMAGE results in empty or invalid base image name", | ||
Line: 3, | ||
Level: 1, | ||
}, | ||
}, | ||
}) | ||
|
||
dockerfile = []byte(` | ||
ARG SFX="box:" | ||
FROM busy${SFX} | ||
`) | ||
checkLinterWarnings(t, sb, &lintTestParams{ | ||
Dockerfile: dockerfile, | ||
FrontendAttrs: map[string]string{ | ||
"build-arg:SFX": "box:latest", | ||
}, | ||
Warnings: []expectedLintWarning{ | ||
{ | ||
RuleName: "InvalidDefaultArgInFrom", | ||
Description: "Default value for global ARG results in an empty or invalid base image name", | ||
URL: "https://docs.docker.com/go/dockerfile/rule/invalid-default-arg-in-from/", | ||
Detail: "Default value for ARG busy${SFX} results in empty or invalid base image name", | ||
Line: 3, | ||
Level: 1, | ||
}, | ||
}, | ||
}) | ||
|
||
dockerfile = []byte(` | ||
ARG VERSION="latest" | ||
FROM busybox:${VERSION} | ||
`) | ||
checkLinterWarnings(t, sb, &lintTestParams{ | ||
Dockerfile: dockerfile, | ||
FrontendAttrs: map[string]string{ | ||
"build-arg:VERSION": "latest", | ||
}, | ||
}) | ||
|
||
dockerfile = []byte(` | ||
ARG BUSYBOX_VARIANT="" | ||
FROM busybox:stable${BUSYBOX_VARIANT} | ||
`) | ||
checkLinterWarnings(t, sb, &lintTestParams{ | ||
Dockerfile: dockerfile, | ||
FrontendAttrs: map[string]string{ | ||
"build-arg:BUSYBOX_VARIANT": "-musl", | ||
}, | ||
}) | ||
|
||
dockerfile = []byte(` | ||
ARG BUSYBOX_VARIANT | ||
FROM busybox:stable${BUSYBOX_VARIANT} | ||
`) | ||
checkLinterWarnings(t, sb, &lintTestParams{ | ||
Dockerfile: dockerfile, | ||
FrontendAttrs: map[string]string{ | ||
"build-arg:BUSYBOX_VARIANT": "-musl", | ||
}, | ||
}) | ||
} | ||
|
||
func checkUnmarshal(t *testing.T, sb integration.Sandbox, lintTest *lintTestParams) { | ||
destDir, err := os.MkdirTemp("", "buildkit") | ||
require.NoError(t, err) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
frontend/dockerfile/docs/rules/invalid-default-arg-in-from.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
--- | ||
title: InvalidDefaultArgInFrom | ||
description: Default value for global ARG results in an empty or invalid base image name | ||
aliases: | ||
- /go/dockerfile/rule/invalid-default-arg-in-from/ | ||
--- | ||
|
||
## Output | ||
|
||
```text | ||
Using the global ARGs with default values should produce a valid build. | ||
``` | ||
|
||
## Description | ||
|
||
An `ARG` used in an image reference should be valid when no build arguments are used. An image build should not require `--build-arg` to be used to produce a valid build. | ||
|
||
## Examples | ||
|
||
❌ Bad: don't rely on an ARG being set for an image reference to be valid | ||
|
||
```dockerfile | ||
ARG TAG | ||
FROM busybox:${TAG} | ||
``` | ||
|
||
✅ Good: include a default for the ARG | ||
|
||
```dockerfile | ||
ARG TAG=latest | ||
FROM busybox:${TAG} | ||
``` | ||
|
||
✅ Good: ARG can be empty if the image would be valid with it empty | ||
|
||
```dockerfile | ||
ARG VARIANT | ||
FROM busybox:stable${VARIANT} | ||
``` | ||
|
||
✅ Good: Use a default value if the build arg is not present | ||
|
||
```dockerfile | ||
ARG TAG | ||
FROM alpine:${TAG:-3.14} | ||
``` | ||
|
39 changes: 39 additions & 0 deletions
39
frontend/dockerfile/linter/docs/InvalidDefaultArgInFrom.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
## Output | ||
|
||
```text | ||
Using the global ARGs with default values should produce a valid build. | ||
``` | ||
|
||
## Description | ||
|
||
An `ARG` used in an image reference should be valid when no build arguments are used. An image build should not require `--build-arg` to be used to produce a valid build. | ||
|
||
## Examples | ||
|
||
❌ Bad: don't rely on an ARG being set for an image reference to be valid | ||
|
||
```dockerfile | ||
ARG TAG | ||
FROM busybox:${TAG} | ||
``` | ||
|
||
✅ Good: include a default for the ARG | ||
|
||
```dockerfile | ||
ARG TAG=latest | ||
FROM busybox:${TAG} | ||
``` | ||
|
||
✅ Good: ARG can be empty if the image would be valid with it empty | ||
|
||
```dockerfile | ||
ARG VARIANT | ||
FROM busybox:stable${VARIANT} | ||
``` | ||
|
||
✅ Good: Use a default value if the build arg is not present | ||
|
||
```dockerfile | ||
ARG TAG | ||
FROM alpine:${TAG:-3.14} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters