@@ -159,20 +159,14 @@ func populate(ctx context.Context, loader registry.Load, graphLoader registry.Gr
159159 }
160160 }
161161
162- expectedBundles , err := expectedGraphBundles (imagesToAdd , graphLoader , overwrite )
163- if err != nil {
164-
165- return err
166-
167- }
168162 populator := registry .NewDirectoryPopulator (loader , graphLoader , querier , unpackedImageMap , overwrittenBundles )
169163
170164 if err := populator .Populate (mode ); err != nil {
171165
172166 return err
173167
174168 }
175- return checkForBundles (ctx , querier .(* sqlite.SQLQuerier ), graphLoader , expectedBundles )
169+ return checkForBundles (ctx , querier .(* sqlite.SQLQuerier ), graphLoader , imagesToAdd )
176170}
177171
178172type DeleteFromRegistryRequest struct {
@@ -399,121 +393,38 @@ func checkForBundlePaths(querier registry.GRPCQuery, bundlePaths []string) ([]st
399393
400394// replaces mode selects highest version as channel head and
401395// prunes any bundles in the upgrade chain after the channel head.
402- // check for the presence of all bundles after a replaces-mode add.
403- func checkForBundles (ctx context.Context , q * sqlite.SQLQuerier , g registry.GraphLoader , required map [ string ]* registry.Package ) error {
396+ // check for the presence of newly added bundles after a replaces-mode add.
397+ func checkForBundles (ctx context.Context , q * sqlite.SQLQuerier , g registry.GraphLoader , required [ ]* registry.Bundle ) error {
404398 var errs []error
405- for _ , pkg := range required {
406- graph , err := g .Generate (pkg . Name )
399+ for _ , bundle := range required {
400+ graph , err := g .Generate (bundle . Package )
407401 if err != nil {
408- errs = append (errs , fmt .Errorf ("unable to verify added bundles for package %s: %v" , pkg . Name , err ))
402+ errs = append (errs , fmt .Errorf ("unable to verify added bundles for package %s: %v" , bundle . Package , err ))
409403 continue
410404 }
411405
412- for channel , missing := range pkg .Channels {
413- // trace replaces chain for reachable bundles
406+ for _ , channel := range bundle .Channels {
407+ var foundImage bool
414408 for next := []registry.BundleKey {graph .Channels [channel ].Head }; len (next ) > 0 ; next = next [1 :] {
415- delete (missing .Nodes , next [0 ])
409+ if next [0 ].BundlePath == bundle .BundleImage {
410+ foundImage = true
411+ break
412+ }
416413 for edge := range graph .Channels [channel ].Nodes [next [0 ]] {
417414 next = append (next , edge )
418415 }
419416 }
420417
421- for bundle := range missing .Nodes {
422- // check if bundle is deprecated. Bundles readded after deprecation should not be present in index and can be ignored.
423- deprecated , err := isDeprecated (ctx , q , bundle )
424- if err != nil {
425- errs = append (errs , fmt .Errorf ("could not validate pruned bundle %s (%s) as deprecated: %v" , bundle .CsvName , bundle .BundlePath , err ))
426- }
427- if ! deprecated {
428- errs = append (errs , fmt .Errorf ("added bundle %s pruned from package %s, channel %s: this may be due to incorrect channel head (%s)" , bundle .BundlePath , pkg .Name , channel , graph .Channels [channel ].Head .CsvName ))
429- }
418+ if foundImage {
419+ continue
430420 }
431- }
432- }
433- return utilerrors .NewAggregate (errs )
434- }
435-
436- func isDeprecated (ctx context.Context , q * sqlite.SQLQuerier , bundle registry.BundleKey ) (bool , error ) {
437- props , err := q .GetPropertiesForBundle (ctx , bundle .CsvName , bundle .Version , bundle .BundlePath )
438- if err != nil {
439- return false , err
440- }
441- for _ , prop := range props {
442- if prop .Type == registry .DeprecatedType {
443- return true , nil
444- }
445- }
446- return false , nil
447- }
448421
449- // expectedGraphBundles returns a set of package-channel-bundle tuples that MUST be present following an add.
450- /* opm index add drops bundles that replace a channel head, and since channel head selection heuristics
451- * choose the bundle with the greatest semver as the channel head, any bundle that replaces such a bundle
452- * will be dropped from the graph following an add.
453- * eg: 1.0.1 <- 1.0.1-new
454- *
455- * 1.0.1-new replaces 1.0.1 but will not be chosen as the channel head because of its non-empty pre-release version.
456- * expectedGraphBundles gives a set of bundles (old bundles from the graphLoader and the newly added set of bundles from
457- * imagesToAdd) that must be present following an add to ensure no bundle is dropped.
458- *
459- * Overwritten bundles will only be verified on the channels of the newly added version.
460- * Any inherited channels due to addition of a new bundle on its tail bundles may not be verified
461- * eg: 1.0.1 (alpha) <-[1.0.2 (alpha, stable)]
462- * When 1.0.2 in alpha and stable channels is added replacing 1.0.1, 1.0.1's presence will only be marked as expected on
463- * the alpha channel, not on the inherited stable channel.
464- */
465- func expectedGraphBundles (imagesToAdd []* registry.Bundle , graphLoader registry.GraphLoader , overwrite bool ) (map [string ]* registry.Package , error ) {
466- expectedBundles := map [string ]* registry.Package {}
467- for _ , bundle := range imagesToAdd {
468- version , err := bundle .Version ()
469- if err != nil {
470- return nil , err
471- }
472- newBundleKey := registry.BundleKey {
473- BundlePath : bundle .BundleImage ,
474- Version : version ,
475- CsvName : bundle .Name ,
476- }
477- var pkg * registry.Package
478- var ok bool
479- if pkg , ok = expectedBundles [bundle .Package ]; ! ok {
480- var err error
481- if pkg , err = graphLoader .Generate (bundle .Package ); err != nil {
482- if err != registry .ErrPackageNotInDatabase {
483- return nil , err
484- }
485- pkg = & registry.Package {
486- Name : bundle .Package ,
487- Channels : map [string ]registry.Channel {},
488- }
422+ var headSkips []string
423+ for b := range graph .Channels [channel ].Nodes [graph .Channels [channel ].Head ] {
424+ headSkips = append (headSkips , b .CsvName )
489425 }
426+ errs = append (errs , fmt .Errorf ("add prunes bundle %s (%s) from package %s, channel %s: this may be due to incorrect channel head (%s, skips/replaces %v)" , bundle .Name , bundle .BundleImage , bundle .Package , channel , graph .Channels [channel ].Head .CsvName , headSkips ))
490427 }
491- for c , channelEntries := range pkg .Channels {
492- for oldBundle := range channelEntries .Nodes {
493- if oldBundle .CsvName == bundle .Name {
494- if overwrite {
495- delete (pkg .Channels [c ].Nodes , oldBundle )
496- if len (pkg .Channels [c ].Nodes ) == 0 {
497- delete (pkg .Channels , c )
498- }
499- } else {
500- return nil , registry.BundleImageAlreadyAddedErr {ErrorString : fmt .Sprintf ("Bundle %s already exists" , bundle .BundleImage )}
501- }
502- }
503- }
504- }
505- for _ , c := range bundle .Channels {
506- if _ , ok := pkg .Channels [c ]; ! ok {
507- pkg .Channels [c ] = registry.Channel {
508- Nodes : map [registry.BundleKey ]map [registry.BundleKey ]struct {}{},
509- }
510- }
511- // This can miss out on some channels, when a new bundle has channels that the one it replaces does not.
512- // eg: When bundle A in channel A replaces bundle B in channel B is added, bundle B is also added to channel A
513- // but it is only expected to be in channel B, presence in channel A will be ignored
514- pkg .Channels [c ].Nodes [newBundleKey ] = nil
515- }
516- expectedBundles [bundle .Package ] = pkg
517428 }
518- return expectedBundles , nil
429+ return utilerrors . NewAggregate ( errs )
519430}
0 commit comments