@@ -2,67 +2,84 @@ package libvuln
22
33import (
44 "context"
5- "fmt "
5+ "errors "
66 "io"
77 "log/slog"
88
99 "github.com/google/uuid"
1010 "github.com/jackc/pgx/v5/pgxpool"
1111
12+ "github.com/quay/claircore"
1213 "github.com/quay/claircore/datastore/postgres"
1314 "github.com/quay/claircore/libvuln/driver"
1415 "github.com/quay/claircore/libvuln/jsonblob"
1516)
1617
18+ // BUG(hank) The OfflineImport function is a wart, needed to work around
19+ // some package namespacing issues. It should get refactored if claircore
20+ // gets merged into clair.
21+
1722// OfflineImport takes the format written into the io.Writer provided to
1823// NewOfflineUpdater and imports the contents into the provided pgxpool.Pool.
1924//
2025// The format provided on "in" should be the same output from [jsonblob.Store], with
2126// any compression undone.
2227func OfflineImport (ctx context.Context , pool * pgxpool.Pool , in io.Reader ) error {
23- // BUG(hank) The OfflineImport function is a wart, needed to work around
24- // some package namespacing issues. It should get refactored if claircore
25- // gets merged into clair.
2628 s := postgres .NewMatcherStore (pool )
27- l , err := jsonblob .Load (ctx , in )
29+ l , err := jsonblob .NewLoader (ctx , in )
2830 if err != nil {
2931 return err
3032 }
3133
32- ops , err := s .GetUpdateOperations (ctx , driver .VulnerabilityKind )
33- if err != nil {
34- return err
35- }
34+ // Don't bother checking the fingerprint, just gogogo.
35+
36+ for e , seq := range l .All () {
37+ l := slog .With ("updater" , e .Updater )
38+ l .InfoContext (ctx , "new update" )
3639
37- Update:
38- for l .Next () {
39- e := l .Entry ()
40- log := slog .With ("updater" , e .Updater )
41- for _ , op := range ops [e .Updater ] {
42- // This only helps if updaters don't keep something that
43- // changes in the fingerprint.
44- if op .Fingerprint == e .Fingerprint {
45- log .InfoContext (ctx , "fingerprint match, skipping" )
46- continue Update
47- }
48- }
4940 var ref uuid.UUID
50- if e .Enrichment != nil {
51- if ref , err = s .UpdateEnrichments (ctx , e .Updater , e .Fingerprint , e .Enrichment ); err != nil {
52- return fmt .Errorf ("updating enrichements: %w" , err )
41+ var err error
42+ var vulnCt , enrichCt int
43+ switch e .Kind {
44+ case driver .VulnerabilityKind :
45+ wrap := func (yield func (* claircore.Vulnerability , error ) bool ) {
46+ for v := range seq {
47+ vulnCt ++
48+ if ! yield (v , nil ) {
49+ return
50+ }
51+ jsonblob .ReturnVulnerability (v )
52+ }
5353 }
54- }
55- if e .Vuln != nil {
56- if ref , err = s .UpdateVulnerabilities (ctx , e .Updater , e .Fingerprint , e .Vuln ); err != nil {
57- return fmt .Errorf ("updating vulnerabilities: %w" , err )
54+ ref , err = s .UpdateVulnerabilitiesIter (ctx , e .Updater , e .Fingerprint , wrap )
55+ case driver .EnrichmentKind :
56+ wrap := func (yield func (* driver.EnrichmentRecord , error ) bool ) {
57+ for _ , e := range seq {
58+ enrichCt ++
59+ if ! yield (e , nil ) {
60+ return
61+ }
62+ jsonblob .ReturnEnrichment (e )
63+ }
5864 }
65+ ref , err = s .UpdateEnrichmentsIter (ctx , e .Updater , e .Fingerprint , wrap )
66+ default :
67+ panic ("unreachable" )
68+ }
69+ if err == nil {
70+ l .InfoContext (
71+ ctx , "update imported" ,
72+ "ref" , ref ,
73+ "vuln_count" , len (e .Vuln ),
74+ "enrichment_count" , len (e .Enrichment ),
75+ )
76+ } else {
77+ l .InfoContext (ctx , "update failed" , "reason" , err )
78+ break
5979 }
60- log .InfoContext (ctx , "update imported" ,
61- "ref" , ref ,
62- "vuln_count" , len (e .Vuln ),
63- "enrichment_count" , len (e .Enrichment ))
6480 }
65- if err := l .Err (); err != nil {
81+
82+ if err := errors .Join (err , l .Err ()); err != nil {
6683 return err
6784 }
6885 return nil
0 commit comments