@@ -2520,6 +2520,172 @@ var _ = Describe("Subscription", func() {
2520
2520
_ , err = fetchSubscription (crc , generatedNamespace .GetName (), subName , subscriptionHasCurrentCSV ("example-operator.v0.2.0" ))
2521
2521
Expect (err ).Should (BeNil ())
2522
2522
})
2523
+
2524
+ It ("should recreate failing unpacking jobs when unpack retry is specified" , func () {
2525
+ By ("Ensuring a registry to host bundle images" )
2526
+ local , err := Local (c )
2527
+ Expect (err ).NotTo (HaveOccurred (), "cannot determine if test running locally or on CI: %s" , err )
2528
+
2529
+ var registryURL string
2530
+ var copyImage func (src , srcTag , dst , dstTag string ) error
2531
+ if local {
2532
+ registryURL , err = createDockerRegistry (c , generatedNamespace .GetName ())
2533
+ Expect (err ).NotTo (HaveOccurred (), "error creating container registry: %s" , err )
2534
+ defer deleteDockerRegistry (c , generatedNamespace .GetName ())
2535
+
2536
+ // ensure registry pod is ready before attempting port-forwarding
2537
+ _ = awaitPod (GinkgoT (), c , generatedNamespace .GetName (), registryName , podReady )
2538
+
2539
+ err = registryPortForward (generatedNamespace .GetName ())
2540
+ Expect (err ).NotTo (HaveOccurred (), "port-forwarding local registry: %s" , err )
2541
+ copyImage = func (src , srcTag , dst , dstTag string ) error {
2542
+ _ , err := skopeoLocalCopy (src , srcTag , dst , dstTag )
2543
+ return err
2544
+ }
2545
+ } else {
2546
+ registryURL = fmt .Sprintf ("%s/%s" , openshiftregistryFQDN , generatedNamespace .GetName ())
2547
+ registryAuth , err := openshiftRegistryAuth (c , generatedNamespace .GetName ())
2548
+ Expect (err ).NotTo (HaveOccurred (), "error getting openshift registry authentication: %s" , err )
2549
+ copyImage = func (src , srcTag , dst , dstTag string ) error {
2550
+ skopeoArgs := skopeoCopyCmd (src , srcTag , dst , dstTag , registryAuth )
2551
+ err = createSkopeoPod (c , skopeoArgs , generatedNamespace .GetName ())
2552
+ if err != nil {
2553
+ return fmt .Errorf ("error creating skopeo pod: %v" , err )
2554
+ }
2555
+
2556
+ // wait for skopeo pod to exit successfully
2557
+ awaitPod (GinkgoT (), c , generatedNamespace .GetName (), skopeo , func (pod * corev1.Pod ) bool {
2558
+ return pod .Status .Phase == corev1 .PodSucceeded
2559
+ })
2560
+
2561
+ if err := deleteSkopeoPod (c , generatedNamespace .GetName ()); err != nil {
2562
+ return fmt .Errorf ("error deleting skopeo pod: %s" , err )
2563
+ }
2564
+ return nil
2565
+ }
2566
+ }
2567
+
2568
+ // testImage is the name of the image used throughout the test - the image overwritten by skopeo
2569
+ // the tag is generated randomly and appended to the end of the testImage
2570
+ srcImage := "quay.io/olmtest/example-operator-bundle:0.1.0"
2571
+ srcTag := "0.1.0"
2572
+ bundleImage := fmt .Sprint ("docker://" , registryURL , "/unpack-retry-bundle" , ":" )
2573
+ bundleTag := genName ("x" )
2574
+
2575
+ unpackRetryCatalog := fmt .Sprintf (`
2576
+ ---
2577
+ schema: olm.package
2578
+ name: unpack-retry-package
2579
+ defaultChannel: stable
2580
+ ---
2581
+ schema: olm.channel
2582
+ package: unpack-retry-package
2583
+ name: stable
2584
+ entries:
2585
+ - name: unpack-retry-operator.v1.0.0
2586
+ ---
2587
+ schema: olm.bundle
2588
+ name: unpack-retry-operator.v1.0.0
2589
+ package: unpack-retry-package
2590
+ image: %s%s
2591
+ properties:
2592
+ - type: olm.package
2593
+ value:
2594
+ packageName: unpack-retry-package
2595
+ version: 1.0.0
2596
+ ` , bundleImage , bundleTag )
2597
+
2598
+ By ("creating a catalog referencing a non-existent bundle image" )
2599
+ unpackRetryProvider , err := NewRawFileBasedCatalogProvider (unpackRetryCatalog )
2600
+ Expect (err ).ToNot (HaveOccurred ())
2601
+ Expect (magicCatalog .UpdateCatalog (context .Background (), unpackRetryProvider )).To (Succeed ())
2602
+
2603
+ By ("creating a subscription for the missing bundle" )
2604
+ unpackRetrySubName := fmt .Sprintf ("%s-unpack-retry-package-sub" , generatedNamespace .GetName ())
2605
+ createSubscriptionForCatalog (crc , generatedNamespace .GetName (), unpackRetrySubName , catalogSourceName , "unpack-retry-package" , stableChannel , "" , operatorsv1alpha1 .ApprovalAutomatic )
2606
+
2607
+ By ("waiting for bundle unpack to fail" )
2608
+ Eventually (
2609
+ func () error {
2610
+ fetched , err := crc .OperatorsV1alpha1 ().Subscriptions (generatedNamespace .GetName ()).Get (context .Background (), unpackRetrySubName , metav1.GetOptions {})
2611
+ if err != nil {
2612
+ return err
2613
+ }
2614
+ if cond := fetched .Status .GetCondition (v1alpha1 .SubscriptionBundleUnpackFailed ); cond .Status != corev1 .ConditionTrue || cond .Reason != "BundleUnpackFailed" {
2615
+ return fmt .Errorf ("%s condition not found" , v1alpha1 .SubscriptionBundleUnpackFailed )
2616
+ }
2617
+ return nil
2618
+ },
2619
+ 5 * time .Minute ,
2620
+ interval ,
2621
+ ).Should (Succeed ())
2622
+
2623
+ By ("patching operator group to enable unpack retries" )
2624
+ ogNN := types.NamespacedName {Name : operatorGroup .GetName (), Namespace : generatedNamespace .GetName ()}
2625
+ setBundleUnpackRetryMinimumIntervalAnnotation (context .Background (), ctx .Ctx ().Client (), ogNN , "1s" )
2626
+
2627
+ By ("ensuring failing bundle unpack jobs are retried" )
2628
+ Eventually (func () error {
2629
+ fetched , err := crc .OperatorsV1alpha1 ().Subscriptions (generatedNamespace .GetName ()).Get (context .Background (), unpackRetrySubName , metav1.GetOptions {})
2630
+ if err != nil {
2631
+ return err
2632
+ }
2633
+ if cond := fetched .Status .GetCondition (v1alpha1 .SubscriptionBundleUnpacking ); cond .Status != corev1 .ConditionTrue {
2634
+ return fmt .Errorf ("missing expected condition %s on subscription %s" , v1alpha1 .SubscriptionBundleUnpacking , unpackRetrySubName )
2635
+ }
2636
+ return nil
2637
+ }).Should (Succeed ())
2638
+
2639
+ By ("Ensuring successful bundle unpack jobs are not retried" )
2640
+ Consistently (func () error {
2641
+ fetched , err := crc .OperatorsV1alpha1 ().Subscriptions (generatedNamespace .GetName ()).Get (context .Background (), subName , metav1.GetOptions {})
2642
+ if err != nil {
2643
+ return err
2644
+ }
2645
+ if cond := fetched .Status .GetCondition (v1alpha1 .SubscriptionBundleUnpacking ); cond .Status != corev1 .ConditionUnknown {
2646
+ return fmt .Errorf ("unexpected unpack condition %s on subscription %s" , v1alpha1 .SubscriptionBundleUnpacking , subName )
2647
+ }
2648
+ if cond := fetched .Status .GetCondition (v1alpha1 .SubscriptionBundleUnpackFailed ); cond .Status != corev1 .ConditionUnknown {
2649
+ return fmt .Errorf ("unexpected unpack condition %s on subscription %s" , v1alpha1 .SubscriptionBundleUnpackFailed , subName )
2650
+ }
2651
+ return nil
2652
+ }).Should (Succeed ())
2653
+
2654
+ By ("patching operator group to disable unpack retries" )
2655
+ setBundleUnpackRetryMinimumIntervalAnnotation (context .Background (), ctx .Ctx ().Client (), ogNN , "" )
2656
+
2657
+ By ("ensuring failing bundle unpack jobs are no longer retried" )
2658
+ Eventually (func () error {
2659
+ fetched , err := crc .OperatorsV1alpha1 ().Subscriptions (generatedNamespace .GetName ()).Get (context .Background (), unpackRetrySubName , metav1.GetOptions {})
2660
+ if err != nil {
2661
+ return err
2662
+ }
2663
+ if cond := fetched .Status .GetCondition (v1alpha1 .SubscriptionBundleUnpackFailed ); cond .Status != corev1 .ConditionTrue {
2664
+ return fmt .Errorf ("missing expected condition %s on subscription %s" , v1alpha1 .SubscriptionBundleUnpacking , unpackRetrySubName )
2665
+ }
2666
+ return nil
2667
+ }).Should (Succeed ())
2668
+
2669
+ Consistently (func () error {
2670
+ fetched , err := crc .OperatorsV1alpha1 ().Subscriptions (generatedNamespace .GetName ()).Get (context .Background (), unpackRetrySubName , metav1.GetOptions {})
2671
+ if err != nil {
2672
+ return err
2673
+ }
2674
+ if cond := fetched .Status .GetCondition (v1alpha1 .SubscriptionBundleUnpacking ); cond .Status != corev1 .ConditionUnknown {
2675
+ return fmt .Errorf ("mnexpected condition %s on subscription %s" , v1alpha1 .SubscriptionBundleUnpacking , unpackRetrySubName )
2676
+ }
2677
+ return nil
2678
+ }).Should (Succeed ())
2679
+
2680
+ By ("pushing missing bundle image" )
2681
+ Expect (copyImage (srcImage , srcTag , bundleImage , bundleTag )).To (Succeed ())
2682
+
2683
+ By ("patching operator group to enable unpack retries" )
2684
+ setBundleUnpackRetryMinimumIntervalAnnotation (context .Background (), ctx .Ctx ().Client (), ogNN , "1s" )
2685
+
2686
+ By ("waiting for checking for installPlan to indicate unpack succeeds" )
2687
+ Expect (fetchSubscription (crc , magicCatalog .GetNamespace (), unpackRetrySubName , subscriptionHasInstallPlanChecker )).To (Succeed ())
2688
+ })
2523
2689
})
2524
2690
})
2525
2691
})
0 commit comments