Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Commit 435a51f

Browse files
committed
Add scan message after docker build, add e2e tests
Signed-off-by: Guillaume Tardif <[email protected]>
1 parent ee4e85a commit 435a51f

File tree

4 files changed

+141
-7
lines changed

4 files changed

+141
-7
lines changed

cli/mobycli/exec.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/docker/compose-cli/api/context/store"
3131
"github.com/docker/compose-cli/cli/metrics"
3232
"github.com/docker/compose-cli/cli/mobycli/resolvepath"
33+
"github.com/docker/compose-cli/utils"
3334
)
3435

3536
var delegatedContextTypes = []string{store.DefaultContextType}
@@ -100,6 +101,10 @@ func Exec(root *cobra.Command) {
100101
fmt.Fprintln(os.Stderr, err)
101102
os.Exit(1)
102103
}
104+
command := metrics.GetCommand(os.Args[1:])
105+
if command == "build" {
106+
utils.DisplayScanSuggestMsg()
107+
}
103108
metrics.Track(store.DefaultContextType, os.Args[1:], metrics.SuccessStatus)
104109

105110
os.Exit(0)

local/compose/build.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"strings"
2626

2727
"github.com/docker/compose-cli/api/compose"
28+
"github.com/docker/compose-cli/utils"
2829

2930
"github.com/compose-spec/compose-go/types"
3031
"github.com/containerd/containerd/platforms"
@@ -67,7 +68,9 @@ func (s *composeService) Build(ctx context.Context, project *types.Project, opti
6768

6869
err := s.build(ctx, project, opts, options.Progress)
6970
if err == nil {
70-
displayScanSuggestMsg(imagesToBuild)
71+
if len(imagesToBuild) > 0 {
72+
utils.DisplayScanSuggestMsg()
73+
}
7174
}
7275

7376
return err
@@ -125,7 +128,9 @@ func (s *composeService) ensureImagesExists(ctx context.Context, project *types.
125128

126129
err := s.build(ctx, project, opts, mode)
127130
if err == nil {
128-
displayScanSuggestMsg(imagesToBuild)
131+
if len(imagesToBuild) > 0 {
132+
utils.DisplayScanSuggestMsg()
133+
}
129134
}
130135
return err
131136
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
Copyright 2020 Docker Compose CLI authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package e2e
18+
19+
import (
20+
"io"
21+
"io/ioutil"
22+
"net/http"
23+
"os"
24+
"path/filepath"
25+
"runtime"
26+
"strings"
27+
"testing"
28+
29+
"gotest.tools/v3/assert"
30+
"gotest.tools/v3/icmd"
31+
32+
. "github.com/docker/compose-cli/utils/e2e"
33+
)
34+
35+
func TestDisplayScanMessageAfterBuild(t *testing.T) {
36+
c := NewParallelE2eCLI(t, binDir)
37+
setupScanPlugin(t, c)
38+
39+
res := c.RunDockerCmd("info")
40+
res.Assert(t, icmd.Expected{Out: "scan: Docker Scan"})
41+
42+
t.Run("display when docker build", func(t *testing.T) {
43+
res := c.RunDockerCmd("build", "-t", "test-image-scan-msg", "./fixtures/build-test/nginx-build")
44+
res.Assert(t, icmd.Expected{Out: "Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them"})
45+
})
46+
47+
t.Run("do not display if envvar DOCKER_SCAN_SUGGEST=false", func(t *testing.T) {
48+
cmd := c.NewDockerCmd("build", "-t", "test-image-scan-msg", "./fixtures/build-test/nginx-build")
49+
cmd.Env = append(cmd.Env, "DOCKER_SCAN_SUGGEST=false")
50+
res := icmd.StartCmd(cmd)
51+
assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
52+
})
53+
54+
t.Run("display on compose build", func(t *testing.T) {
55+
res := c.RunDockerCmd("compose", "-f", "./fixtures/build-test/compose.yml", "build")
56+
res.Assert(t, icmd.Expected{Out: "Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them"})
57+
})
58+
59+
_ = c.RunDockerOrExitError("rmi", "build-test_nginx")
60+
61+
t.Run("display on compose up if image is built", func(t *testing.T) {
62+
res := c.RunDockerCmd("compose", "-f", "./fixtures/build-test/compose.yml", "up", "-d")
63+
defer c.RunDockerCmd("compose", "-f", "./fixtures/build-test/compose.yml", "down")
64+
res.Assert(t, icmd.Expected{Out: "Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them"})
65+
})
66+
67+
t.Run("do not display on compose up if no image built", func(t *testing.T) { // re-run the same Compose aproject
68+
res := c.RunDockerCmd("compose", "-f", "./fixtures/build-test/compose.yml", "up", "-d")
69+
defer c.RunDockerCmd("compose", "-f", "./fixtures/build-test/compose.yml", "down")
70+
assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
71+
})
72+
73+
t.Run("do not display if scan already invoked", func(t *testing.T) {
74+
_ = os.MkdirAll(filepath.Join(c.ConfigDir, "scan"), 0755)
75+
scanConfigFile := filepath.Join(c.ConfigDir, "scan", "config.json")
76+
err := ioutil.WriteFile(scanConfigFile, []byte(`{"optin":true}`), 0644)
77+
assert.NilError(t, err)
78+
79+
res := c.RunDockerCmd("build", "-t", "test-image-scan-msg", "./fixtures/build-test/nginx-build")
80+
assert.Assert(t, !strings.Contains(res.Combined(), "docker scan"), res.Combined())
81+
})
82+
}
83+
84+
func setupScanPlugin(t *testing.T, c *E2eCLI) {
85+
_ = os.MkdirAll(filepath.Join(c.ConfigDir, "cli-plugins"), 0755)
86+
87+
scanPluginFile := "docker-scan"
88+
scanPluginURL := "https://github.com/docker/scan-cli-plugin/releases/download/v0.7.0/docker-scan_linux_amd64"
89+
if runtime.GOOS == "windows" {
90+
scanPluginFile += ".exe"
91+
scanPluginURL = "https://github.com/docker/scan-cli-plugin/releases/download/v0.7.0/docker-scan_windows_amd64.exe"
92+
}
93+
if runtime.GOOS == "darwin" {
94+
scanPluginURL = "https://github.com/docker/scan-cli-plugin/releases/download/v0.7.0/docker-scan_darwin_amd64"
95+
}
96+
97+
localScanBinary := filepath.Join("..", "..", "..", "bin", scanPluginFile)
98+
if _, err := os.Stat(localScanBinary); os.IsNotExist(err) {
99+
out, err := os.Create(localScanBinary)
100+
assert.NilError(t, err)
101+
defer out.Close() //nolint:errcheck
102+
resp, err := http.Get(scanPluginURL)
103+
assert.NilError(t, err)
104+
defer resp.Body.Close() //nolint:errcheck
105+
_, err = io.Copy(out, resp.Body)
106+
assert.NilError(t, err)
107+
}
108+
109+
finalScanBinaryFile := filepath.Join(c.ConfigDir, "cli-plugins", scanPluginFile)
110+
111+
out, err := os.Create(finalScanBinaryFile)
112+
assert.NilError(t, err)
113+
defer out.Close() //nolint:errcheck
114+
in, err := os.Open(localScanBinary)
115+
assert.NilError(t, err)
116+
defer in.Close() //nolint:errcheck
117+
_, err = io.Copy(out, in)
118+
assert.NilError(t, err)
119+
120+
err = os.Chmod(finalScanBinaryFile, 7777)
121+
assert.NilError(t, err)
122+
}

local/compose/scan_suggest.go renamed to utils/scan_suggest.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
limitations under the License.
1515
*/
1616

17-
package compose
17+
package utils
1818

1919
import (
2020
"encoding/json"
@@ -28,16 +28,18 @@ import (
2828
cliConfig "github.com/docker/cli/cli/config"
2929
)
3030

31-
func displayScanSuggestMsg(builtImages []string) {
32-
if len(builtImages) <= 0 {
31+
// DisplayScanSuggestMsg displlay a message suggesting users can scan new image
32+
func DisplayScanSuggestMsg() {
33+
if os.Getenv("DOCKER_SCAN_SUGGEST") == "false" {
3334
return
3435
}
35-
if os.Getenv("DOCKER_SCAN_SUGGEST") == "false" {
36+
if !scanAvailable() {
3637
return
3738
}
38-
if !scanAvailable() || scanAlreadyInvoked() {
39+
if scanAlreadyInvoked() {
3940
return
4041
}
42+
fmt.Println()
4143
fmt.Println("Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them")
4244
}
4345

0 commit comments

Comments
 (0)