Skip to content

fix(vex): handle 304 status code#10307

Open
alegrey91 wants to merge 1 commit intoaquasecurity:mainfrom
alegrey91:fix/handle-etag-status-code
Open

fix(vex): handle 304 status code#10307
alegrey91 wants to merge 1 commit intoaquasecurity:mainfrom
alegrey91:fix/handle-etag-status-code

Conversation

@alegrey91
Copy link
Copy Markdown
Contributor

@alegrey91 alegrey91 commented Mar 3, 2026

Description

Currently, trivy deletes the content of the vex cache every time a new download happens.
This action is not always needed, since when an ETag is provided, the server may respond with 304 Not Modified, meaning the existing content at dst is still valid.
In that case, trivy should not destroy dst. Instead, we can move it aside as a backup and restore it on 304.
This particular case happens when a Vexhub repository has a small ' update_interval '.
Here's the original PR where we noticed the bug: kubewarden/sbomscanner#867
cc @fabriziosestito

Related issues

There's no open issue for it.

Remove this section if you don't have related PRs.

Checklist

  • I've read the guidelines for contributing to this repository.
  • I've followed the conventions in the PR title.
  • I've added tests that prove my fix is effective or that my feature works.
  • I've updated the documentation with the relevant information (if needed).
  • I've added usage information (if the PR introduces new options)
  • I've included a "before" and "after" example to the description (if the PR is a user interface change).

@alegrey91 alegrey91 changed the title fix(pkg/downloader): handle 304 status code fix(downloader): handle 304 status code Mar 3, 2026
@alegrey91 alegrey91 changed the title fix(downloader): handle 304 status code fix(vex): handle 304 status code Mar 3, 2026
@alegrey91 alegrey91 force-pushed the fix/handle-etag-status-code branch 2 times, most recently from e2637f6 to 486981c Compare March 3, 2026 14:31
@alegrey91 alegrey91 marked this pull request as ready for review March 3, 2026 15:00
@alegrey91 alegrey91 requested a review from knqyf263 as a code owner March 3, 2026 15:00
@alegrey91 alegrey91 force-pushed the fix/handle-etag-status-code branch from 940a4a3 to 3809871 Compare March 4, 2026 11:03
@knqyf263
Copy link
Copy Markdown
Collaborator

Could we simplify this a bit? I think os.Rename works for both files and directories on all platforms, including Windows, as long as they are on the same volume. Since backup is always in the same parent directory as dst, this should be guaranteed. We also os.RemoveAll(backup) before renaming, so the target never exists — I don't think the Windows limitation applies here.

If so, we could handle everything in download.go alone without platform-specific files:

 func Download(ctx context.Context, src, dst, pwd string, opts Options) (string, error) {
-	// go-getter doesn't allow the dst directory already exists if the src is directory.
-	_ = os.RemoveAll(dst)
+	// go-getter doesn't allow the dst directory already exists if the src is directory.
+	// We rename dst as a backup and restore it if the download is skipped or fails.
+	dst = filepath.Clean(dst)
+	cleanup, err := backupDst(dst)
+	if err != nil {
+		return "", xerrors.Errorf("failed to back up dst: %w", err)
+	}
+	defer cleanup()
// backupDst renames dst aside so that go-getter can create it fresh.
// It returns a cleanup function that restores dst on error or removes the backup on success.
func backupDst(dst string) (cleanup func(), err error) {
	backup := dst + ".backup"
	_ = os.RemoveAll(backup)

	if err := os.Rename(dst, backup); errors.Is(err, os.ErrNotExist) {
		return func() {}, nil
	} else if err != nil {
		return nil, xerrors.Errorf("failed to rename dst: %w", err)
	}

	return func() {
		if _, err := os.Stat(dst); errors.Is(err, os.ErrNotExist) {
			if err := os.Rename(backup, dst); err != nil {
				log.Warn("Failed to restore backup", log.FilePath(backup), log.Err(err))
			}
			return
		}
		if err := os.RemoveAll(backup); err != nil {
			log.Warn("Failed to remove backup", log.FilePath(backup), log.Err(err))
		}
	}, nil
}

@alegrey91
Copy link
Copy Markdown
Contributor Author

Hello @knqyf263, I used a platform-specific files because I had failing tests on windows. I can restore it and test again. Maybe they were just flaky.

@alegrey91 alegrey91 force-pushed the fix/handle-etag-status-code branch from 0a30633 to 8d58439 Compare March 20, 2026 13:53
@alegrey91
Copy link
Copy Markdown
Contributor Author

@knqyf263 fixed. Thanks for the suggestion.

Co-authored-by: Fabrizio Sestito <fabrizio.sestito@suse.com>
Signed-off-by: Alessio Greggi <alessio.greggi@suse.com>
@alegrey91 alegrey91 force-pushed the fix/handle-etag-status-code branch from 8d58439 to 33241ab Compare March 26, 2026 14:27
@alegrey91
Copy link
Copy Markdown
Contributor Author

@knqyf263 I've rebased the branch to main but some tests are failing. Could you please re-run them?

@alegrey91
Copy link
Copy Markdown
Contributor Author

@knqyf263 any updates on this?

@knqyf263
Copy link
Copy Markdown
Collaborator

knqyf263 commented Apr 1, 2026

Due to the impact of the recent incident, all tokens have been revoked, and IP restrictions and rulesets have been introduced for the aquasecurity organization. As a result, the CI/CD is currently not functioning. We are working to restore it as soon as possible, so we would appreciate your patience.

@alegrey91
Copy link
Copy Markdown
Contributor Author

Due to the impact of the recent incident, all tokens have been revoked, and IP restrictions and rulesets have been introduced for the aquasecurity organization. As a result, the CI/CD is currently not functioning. We are working to restore it as soon as possible, so we would appreciate your patience.

Apologize for that. Take your time and thanks for clarifying ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants