Skip to content

Commit 622c67b

Browse files
authored
feat(plugin): add support for nested archives (#6845)
Signed-off-by: knqyf263 <[email protected]>
1 parent 04af59c commit 622c67b

File tree

5 files changed

+26
-5
lines changed

5 files changed

+26
-5
lines changed

docs/docs/plugin/user-guide.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ $ trivy plugin install referrer
4040

4141
This command will download the plugin and install it in the plugin cache.
4242

43-
44-
4543
Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set.
4644
Trivy will now search XDG_DATA_HOME for the location of the Trivy plugins cache.
4745
The preference order is as follows:
@@ -55,7 +53,10 @@ Furthermore, it is possible to download plugins that are not registered in the i
5553
$ trivy plugin install github.com/aquasecurity/trivy-plugin-kubectl
5654
```
5755
```bash
58-
$ trivy plugin install myplugin.tar.gz
56+
$ trivy plugin install https://github.com/aquasecurity/trivy-plugin-kubectl/archive/refs/heads/main.zip
57+
```
58+
```bash
59+
$ trivy plugin install ./myplugin.tar.gz
5960
```
6061

6162
If the plugin's Git repository is [properly tagged](./developer-guide.md#tagging-plugin-repositories), you can specify the version to install like this:

pkg/plugin/manager.go

+8
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ func (m *Manager) install(ctx context.Context, src string, opts Options) (Plugin
116116
}
117117
defer os.RemoveAll(tempDir)
118118

119+
if entries, err := os.ReadDir(tempDir); err != nil {
120+
return Plugin{}, xerrors.Errorf("failed to read %s: %w", tempDir, err)
121+
} else if len(entries) == 1 && entries[0].IsDir() {
122+
// A single directory may be contained within an archive file.
123+
// e.g. https://github.com/aquasecurity/trivy-plugin-referrer/archive/refs/heads/main.zip
124+
tempDir = filepath.Join(tempDir, entries[0].Name())
125+
}
126+
119127
m.logger.DebugContext(ctx, "Loading the plugin metadata...")
120128
plugin, err := m.loadMetadata(tempDir)
121129
if err != nil {

pkg/plugin/manager_unix_test.go

+14-2
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,17 @@ func modifyManifest(t *testing.T, worktree, version string) {
6363
}
6464

6565
func TestManager_Install(t *testing.T) {
66-
gs := setupGitRepository(t, "test_plugin", "testdata/test_plugin")
66+
gs := setupGitRepository(t, "test_plugin", "testdata/test_plugin/test_plugin")
6767
t.Cleanup(gs.Close)
6868

6969
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
7070
zr := zip.NewWriter(w)
71-
require.NoError(t, zr.AddFS(os.DirFS("testdata/test_plugin")))
71+
switch r.URL.Path {
72+
case "/test_plugin.zip":
73+
require.NoError(t, zr.AddFS(os.DirFS("testdata/test_plugin/test_plugin")))
74+
case "/test_nested.zip":
75+
require.NoError(t, zr.AddFS(os.DirFS("testdata/test_plugin")))
76+
}
7277
require.NoError(t, zr.Close())
7378
}))
7479
t.Cleanup(ts.Close)
@@ -119,6 +124,13 @@ func TestManager_Install(t *testing.T) {
119124
wantFile: ".trivy/plugins/test_plugin/test.sh",
120125
wantLogs: fmt.Sprintf(wantLogs, ts.URL+"/test_plugin.zip", "0.2.0"),
121126
},
127+
{
128+
name: "nested archive",
129+
pluginName: ts.URL + "/test_nested.zip",
130+
want: wantPlugin,
131+
wantFile: ".trivy/plugins/test_plugin/test.sh",
132+
wantLogs: fmt.Sprintf(wantLogs, ts.URL+"/test_nested.zip", "0.2.0"),
133+
},
122134
{
123135
name: "local path",
124136
pluginName: "testdata/test_plugin",

0 commit comments

Comments
 (0)