github.com/quay/claircore@v1.5.28/datastore/postgres/manifestscanned.go (about) 1 package postgres 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/prometheus/client_golang/prometheus" 9 "github.com/prometheus/client_golang/prometheus/promauto" 10 11 "github.com/quay/claircore" 12 "github.com/quay/claircore/indexer" 13 ) 14 15 var ( 16 manifestScannedCounter = promauto.NewCounterVec( 17 prometheus.CounterOpts{ 18 Namespace: "claircore", 19 Subsystem: "indexer", 20 Name: "manifestscanned_total", 21 Help: "Total number of database queries issued in the ManifestScanned method.", 22 }, 23 []string{"query"}, 24 ) 25 26 manifestScannedDuration = promauto.NewHistogramVec( 27 prometheus.HistogramOpts{ 28 Namespace: "claircore", 29 Subsystem: "indexer", 30 Name: "manifestscanned_duration_seconds", 31 Help: "The duration of all queries issued in the ManifestScanned method", 32 }, 33 []string{"query"}, 34 ) 35 ) 36 37 // ManifestScanned determines if a manifest has been scanned by ALL the provided 38 // scanners. 39 func (s *IndexerStore) ManifestScanned(ctx context.Context, hash claircore.Digest, vs indexer.VersionedScanners) (bool, error) { 40 const ( 41 selectScanned = ` 42 SELECT scanner_id 43 FROM scanned_manifest 44 JOIN manifest ON scanned_manifest.manifest_id = manifest.id 45 WHERE manifest.hash = $1; 46 ` 47 ) 48 49 // get the ids of the scanners we are testing for. 50 expectedIDs, err := s.selectScanners(ctx, vs) 51 if err != nil { 52 return false, err 53 } 54 55 // get a map of the found ids which have scanned this package 56 foundIDs := map[int64]struct{}{} 57 58 start := time.Now() 59 rows, err := s.pool.Query(ctx, selectScanned, hash) 60 if err != nil { 61 return false, fmt.Errorf("failed to select scanner IDs for manifest: %w", err) 62 } 63 manifestScannedCounter.WithLabelValues("selectScanned").Add(1) 64 manifestScannedDuration.WithLabelValues("selectScanned").Observe(time.Since(start).Seconds()) 65 defer rows.Close() 66 var t int64 67 for rows.Next() { 68 if err := rows.Scan(&t); err != nil { 69 return false, fmt.Errorf("failed to select scanner IDs for manifest: %w", err) 70 } 71 foundIDs[t] = struct{}{} 72 } 73 if err := rows.Err(); err != nil { 74 return false, fmt.Errorf("failed to select scanner IDs for manifest: %w", err) 75 } 76 77 // compare the expectedIDs array with our foundIDs. if we get a lookup 78 // miss we can say the manifest has not been scanned by all the layers provided 79 for _, id := range expectedIDs { 80 if _, ok := foundIDs[id]; !ok { 81 return false, nil 82 } 83 } 84 85 return true, nil 86 }