feat(plugin): add support for nested archives (#6845)

Signed-off-by: knqyf263 <knqyf263@gmail.com>
This commit is contained in:
Teppei Fukuda
2024-06-07 13:26:58 +04:00
committed by GitHub
parent 04af59c290
commit 622c67b764
5 changed files with 26 additions and 5 deletions

View File

@@ -40,8 +40,6 @@ $ trivy plugin install referrer
This command will download the plugin and install it in the plugin cache. This command will download the plugin and install it in the plugin cache.
Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set. Trivy adheres to the XDG specification, so the location depends on whether XDG_DATA_HOME is set.
Trivy will now search XDG_DATA_HOME for the location of the Trivy plugins cache. Trivy will now search XDG_DATA_HOME for the location of the Trivy plugins cache.
The preference order is as follows: The preference order is as follows:
@@ -55,7 +53,10 @@ Furthermore, it is possible to download plugins that are not registered in the i
$ trivy plugin install github.com/aquasecurity/trivy-plugin-kubectl $ trivy plugin install github.com/aquasecurity/trivy-plugin-kubectl
``` ```
```bash ```bash
$ trivy plugin install myplugin.tar.gz $ trivy plugin install https://github.com/aquasecurity/trivy-plugin-kubectl/archive/refs/heads/main.zip
```
```bash
$ trivy plugin install ./myplugin.tar.gz
``` ```
If the plugin's Git repository is [properly tagged](./developer-guide.md#tagging-plugin-repositories), you can specify the version to install like this: If the plugin's Git repository is [properly tagged](./developer-guide.md#tagging-plugin-repositories), you can specify the version to install like this:

View File

@@ -116,6 +116,14 @@ func (m *Manager) install(ctx context.Context, src string, opts Options) (Plugin
} }
defer os.RemoveAll(tempDir) defer os.RemoveAll(tempDir)
if entries, err := os.ReadDir(tempDir); err != nil {
return Plugin{}, xerrors.Errorf("failed to read %s: %w", tempDir, err)
} else if len(entries) == 1 && entries[0].IsDir() {
// A single directory may be contained within an archive file.
// e.g. https://github.com/aquasecurity/trivy-plugin-referrer/archive/refs/heads/main.zip
tempDir = filepath.Join(tempDir, entries[0].Name())
}
m.logger.DebugContext(ctx, "Loading the plugin metadata...") m.logger.DebugContext(ctx, "Loading the plugin metadata...")
plugin, err := m.loadMetadata(tempDir) plugin, err := m.loadMetadata(tempDir)
if err != nil { if err != nil {

View File

@@ -63,12 +63,17 @@ func modifyManifest(t *testing.T, worktree, version string) {
} }
func TestManager_Install(t *testing.T) { func TestManager_Install(t *testing.T) {
gs := setupGitRepository(t, "test_plugin", "testdata/test_plugin") gs := setupGitRepository(t, "test_plugin", "testdata/test_plugin/test_plugin")
t.Cleanup(gs.Close) t.Cleanup(gs.Close)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
zr := zip.NewWriter(w) zr := zip.NewWriter(w)
require.NoError(t, zr.AddFS(os.DirFS("testdata/test_plugin"))) switch r.URL.Path {
case "/test_plugin.zip":
require.NoError(t, zr.AddFS(os.DirFS("testdata/test_plugin/test_plugin")))
case "/test_nested.zip":
require.NoError(t, zr.AddFS(os.DirFS("testdata/test_plugin")))
}
require.NoError(t, zr.Close()) require.NoError(t, zr.Close())
})) }))
t.Cleanup(ts.Close) t.Cleanup(ts.Close)
@@ -119,6 +124,13 @@ func TestManager_Install(t *testing.T) {
wantFile: ".trivy/plugins/test_plugin/test.sh", wantFile: ".trivy/plugins/test_plugin/test.sh",
wantLogs: fmt.Sprintf(wantLogs, ts.URL+"/test_plugin.zip", "0.2.0"), wantLogs: fmt.Sprintf(wantLogs, ts.URL+"/test_plugin.zip", "0.2.0"),
}, },
{
name: "nested archive",
pluginName: ts.URL + "/test_nested.zip",
want: wantPlugin,
wantFile: ".trivy/plugins/test_plugin/test.sh",
wantLogs: fmt.Sprintf(wantLogs, ts.URL+"/test_nested.zip", "0.2.0"),
},
{ {
name: "local path", name: "local path",
pluginName: "testdata/test_plugin", pluginName: "testdata/test_plugin",