-
Notifications
You must be signed in to change notification settings - Fork 135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(scanner): Write vulnerabilities and enrichments using iterators #11168
Conversation
Images are ready for the commit at 90bff64. To use with deploy scripts, first |
db5c7f2
to
61c4029
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #11168 +/- ##
==========================================
+ Coverage 47.98% 48.00% +0.01%
==========================================
Files 2330 2330
Lines 166761 166827 +66
==========================================
+ Hits 80022 80077 +55
- Misses 80386 80393 +7
- Partials 6353 6357 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
cf85fba
to
6cf35d7
Compare
6cf35d7
to
f895924
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few initial notes. Honestly this iterator stuff is looking pretty confusing, and it may take me a while to fully understand what is going on and why this may work.
In the meantime, have you tried running this in a cluster yet? I'd love to see some metrics comparisons between the old way and this PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add comments to each iter/yield to make it clear what it's job is? I'm following through everything, and I find myself jumping between three files (updater.go, jsonblob.go, and Claircore's updatevulnerabilities.go/enrichment.go), and it's hard to follow
Yes, see testing instructions. You can see metrics comparison here: https://redhat-internal.slack.com/archives/C020W1C61G8/p1713481469821819 |
f895924
to
4ead053
Compare
Added some. Clarify if you're expecting something else, please. One way to better understand these iterators is by replacing the Then replace each Hypothetical example (never tested): func (u *Updater) Import(ctx context.Context, in io.Reader) (err error) {
ctx = zlog.ContextWithValues(ctx, "component", "matcher/updater/Updater.Import")
iter, iterErr := jsonBlobIterateFunc(in)
// For each update operation in the JSON blob file.
for op, it := range iter {
var ops map[string][]driver.UpdateOperation
ops, err = u.store.GetUpdateOperations(ctx, op.Kind, op.Updater)
if err != nil {
break
}
for _, o := range ops[op.Updater] {
// This only helps if updaters don't keep something that
// changes in the fingerprint.
if o.Fingerprint == op.Fingerprint {
zlog.Info(ctx).
Str("updater", op.Updater).
Msg("fingerprint match, skipping")
continue
}
}
var ref uuid.UUID
count := 0
switch op.Kind {
case driver.VulnerabilityKind:
ref, err = u.store.UpdateVulnerabilitiesIter(ctx, op.Updater, op.Fingerprint, func(yieldC chan *claircore.Vulnerability)) {
// For each vulnerability in the update operation.
for vuln, _, yieldC := it {
count++
// Offer one vulnerability to the datastore iterator.
yieldC <- vuln
})
if err := it.Err(); err != nil {
yieldC <- err // example, right?
}
})
case driver.EnrichmentKind:
ref, err = u.store.UpdateEnrichmentsIter(ctx, op.Updater, op.Fingerprint, func(yieldC chan *driver.EnrichmentRecord)) {
// For each enrichment in the update operation.
for _, e, yieldC := it {
count++
// Offer one enrichment to the datastore iterator.
yieldC <- e
})
if err := iterErr(); err != nil {
yieldC <- err
}
})
default:
zlog.Warn(ctx).Str("kind", string(op.Kind)).Msg("unknown kind, skipping")
}
if err != nil {
err = fmt.Errorf("updating %s: %w", op.Kind, err)
return false
}
zlog.Info(ctx).
Str("updater", op.Updater).
Str("kind", string(op.Kind)).
Str("ref", ref.String()).
Int("count", count).
Msg("update imported")
})
if err := iterErr(); err != nil {
return fmt.Errorf("iterating on the reader: %w", err)
}
if err != nil {
return err
}
return nil
} |
4ead053
to
dd6b5bc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more comments to enhance my understanding as well as some nits
dd6b5bc
to
9798cc8
Compare
@jvdm: The following tests failed, say
Full PR test history. Your PR dashboard. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
Signed-off-by: J. Victor Martins <jvdm@sdf.org>
Signed-off-by: J. Victor Martins <jvdm@sdf.org>
Signed-off-by: J. Victor Martins <jvdm@sdf.org>
1c824c3
to
90bff64
Compare
Description
Adopt ClairCore's iterator interface to update vulnerabilities and enrichments. Create a fork of the JSON blob reader to allow individual record reading per operation in the JSON blob files (where vulnerabilities are stored in our bundles). Create our own "offline importer" method,
Updater.Import()
, which leverages the new JSON blob interface and the ClairCore datastore iterators.The result is that the Matcher keeps one vulnerability in memory at a time, and the datastore code will batch vulnerabilities before sending them to the DB, effectively reducing memory consumption to a minimum during vulnerability updates.
Checklist
Testing Performed
Here I tell how I validated my change
Deploy to openshift,
enable, and verified successful vulnerability bundle download and writes to the DB.ROX_SCANNER_V4_MULTI_BUNDLE=true
, change vulnerability URL tohttps://definitions.stackrox.io/v4/vulnerability-bundles/dev/vulnerabilities.zip
Reminder for reviewers
In addition to reviewing code here, reviewers must also review testing and request further testing in case the
performed one does not seem sufficient. As a reviewer, you must not approve the change until you understand the
performed testing and you are satisfied with it.