@@ -1254,9 +1254,9 @@ var _ = Describe("Subscription", func() {
1254
1254
require .Len (GinkgoT (), installPlan .Status .CatalogSources , 1 )
1255
1255
})
1256
1256
1257
- // CatSrc :
1257
+ // CatSrc1 :
1258
1258
//
1259
- // Package A (apackage)
1259
+ // Package 1 (apackage)
1260
1260
// Default Channel: Stable
1261
1261
// Channel Stable:
1262
1262
// Operator A (Requires: CRD 1, CRD 2 )
@@ -1266,12 +1266,19 @@ var _ = Describe("Subscription", func() {
1266
1266
// Default Channel: Stable
1267
1267
// Channel Stable:
1268
1268
// Operator B (Provides: CRD)
1269
- // CatSrc2:
1269
+ // Channel Alpha:
1270
+ // Operator D (Provides: CRD)
1270
1271
//
1271
- // Package B (bpackage)
1272
+ // CatSrc2:
1273
+ // Package 2 (bpackage)
1272
1274
// Default Channel: Stable
1273
1275
// Channel Stable:
1274
1276
// Operator C (Provides: CRD 2)
1277
+ // Package 3 (cpackage)
1278
+ // Default Channel: Stable
1279
+ // Channel Stable:
1280
+ // Operator E (Provides: CRD 2)
1281
+ //
1275
1282
// Then create a subscription:
1276
1283
//
1277
1284
// CatalogSource: CatSrc
@@ -1280,10 +1287,11 @@ var _ = Describe("Subscription", func() {
1280
1287
// StartingCSV: CSV A
1281
1288
//
1282
1289
// Check installed:
1290
+ // CSV A, CSV B, CSV E
1283
1291
//
1284
- // CSV A, CSV B, CSV C
1285
- //
1286
- // CSV A required B and C but didn't get them from Package A
1292
+ // CSV ABC: not chosen as it is the same package with CSV A
1293
+ // CSV D: not chosen as it is in non-default channel
1294
+ // CSV C: not chosen as it is the same package with CSV B (which is chosen)
1287
1295
It ("creation with dependencies required and provided in different versions of an operator in the same package" , func () {
1288
1296
1289
1297
defer cleaner .NotifyTestComplete (true )
@@ -1335,6 +1343,7 @@ var _ = Describe("Subscription", func() {
1335
1343
// Create CSV
1336
1344
packageName1 := genName ("apackage" )
1337
1345
packageName2 := genName ("bpackage" )
1346
+ packageName3 := genName ("cpackage" )
1338
1347
1339
1348
namedStrategy := newNginxInstallStrategy ((genName ("dep" )), permissions , nil )
1340
1349
depNamedStrategy := newNginxInstallStrategy ((genName ("dep" )), permissions , nil )
@@ -1350,6 +1359,8 @@ var _ = Describe("Subscription", func() {
1350
1359
csvC := newCSV ("nginx-c-dep" , testNamespace , "" , semver .MustParse ("0.1.0" ), []apiextensions.CustomResourceDefinition {crd2 }, nil , depNamedStrategy2 )
1351
1360
// csvD provides CRD1 in the same catalogsource with csvA (apackage)
1352
1361
csvD := newCSV ("nginx-d-dep" , testNamespace , "" , semver .MustParse ("0.1.0" ), []apiextensions.CustomResourceDefinition {crd }, nil , depNamedStrategy )
1362
+ // csvE provides CRD2 in the different catalogsource with csvC (bpackage)
1363
+ csvE := newCSV ("nginx-e-dep" , testNamespace , "" , semver .MustParse ("0.1.0" ), []apiextensions.CustomResourceDefinition {crd2 }, nil , depNamedStrategy2 )
1353
1364
1354
1365
// Create PackageManifests 1
1355
1366
// Contain csvA, ABC and B
@@ -1382,6 +1393,13 @@ var _ = Describe("Subscription", func() {
1382
1393
},
1383
1394
DefaultChannelName : stableChannel ,
1384
1395
},
1396
+ {
1397
+ PackageName : packageName3 ,
1398
+ Channels : []registry.PackageChannel {
1399
+ {Name : stableChannel , CurrentCSVName : csvE .GetName ()},
1400
+ },
1401
+ DefaultChannelName : stableChannel ,
1402
+ },
1385
1403
}
1386
1404
1387
1405
catalogSourceName := genName ("catsrc" )
@@ -1402,7 +1420,7 @@ var _ = Describe("Subscription", func() {
1402
1420
}
1403
1421
1404
1422
catalogSourceName2 := genName ("catsrc" )
1405
- catsrc2 , cleanup2 := createInternalCatalogSource (kubeClient , crClient , catalogSourceName2 , testNamespace , manifests2 , []apiextensions.CustomResourceDefinition {crd2 }, []v1alpha1.ClusterServiceVersion {csvC })
1423
+ catsrc2 , cleanup2 := createInternalCatalogSource (kubeClient , crClient , catalogSourceName2 , testNamespace , manifests2 , []apiextensions.CustomResourceDefinition {crd2 }, []v1alpha1.ClusterServiceVersion {csvC , csvE })
1406
1424
defer cleanup2 ()
1407
1425
1408
1426
// Ensure that the catalog source is resolved before we create a subscription.
@@ -1424,7 +1442,7 @@ var _ = Describe("Subscription", func() {
1424
1442
// Fetch CSVs A, B and C
1425
1443
_ , err = fetchCSV (GinkgoT (), crClient , csvB .Name , testNamespace , csvSucceededChecker )
1426
1444
require .NoError (GinkgoT (), err )
1427
- _ , err = fetchCSV (GinkgoT (), crClient , csvC .Name , testNamespace , csvSucceededChecker )
1445
+ _ , err = fetchCSV (GinkgoT (), crClient , csvE .Name , testNamespace , csvSucceededChecker )
1428
1446
require .NoError (GinkgoT (), err )
1429
1447
_ , err = fetchCSV (GinkgoT (), crClient , csvA .Name , testNamespace , csvSucceededChecker )
1430
1448
require .NoError (GinkgoT (), err )
@@ -1435,6 +1453,187 @@ var _ = Describe("Subscription", func() {
1435
1453
_ , err = crClient .OperatorsV1alpha1 ().ClusterServiceVersions (testNamespace ).Get (context .TODO (), csvD .Name , metav1.GetOptions {})
1436
1454
require .Error (GinkgoT (), err )
1437
1455
})
1456
+
1457
+ // csvA owns CRD1 & csvB owns CRD2 and requires CRD1
1458
+ // Create subscription for csvB lead to installation of csvB and csvA
1459
+ // Update catsrc to upgrade csvA to csvNewA which now requires CRD1
1460
+ // csvNewA can't be installed due to no other operators provide CRD1 for it
1461
+ // (Note: OLM can't pick csvA as dependency for csvNewA as it is from the same
1462
+ // same package)
1463
+ // Update catsrc again to upgrade csvB to csvNewB which now owns both CRD1 and
1464
+ // CRD2.
1465
+ // Now csvNewA and csvNewB are installed successfully as csvNewB provides CRD1
1466
+ // that csvNewA requires
1467
+ It ("creation in case of transferring providedAPIs" , func () {
1468
+
1469
+ kubeClient := newKubeClient ()
1470
+ crClient := newCRClient ()
1471
+
1472
+ permissions := deploymentPermissions ()
1473
+
1474
+ crdPlural := genName ("ins" )
1475
+ crdName := crdPlural + ".cluster.com"
1476
+ crdPlural2 := genName ("ins" )
1477
+ crdName2 := crdPlural2 + ".cluster.com"
1478
+
1479
+ crd := apiextensions.CustomResourceDefinition {
1480
+ ObjectMeta : metav1.ObjectMeta {
1481
+ Name : crdName ,
1482
+ },
1483
+ Spec : apiextensions.CustomResourceDefinitionSpec {
1484
+ Group : "cluster.com" ,
1485
+ Version : "v1alpha1" ,
1486
+ Names : apiextensions.CustomResourceDefinitionNames {
1487
+ Plural : crdPlural ,
1488
+ Singular : crdPlural ,
1489
+ Kind : crdPlural ,
1490
+ ListKind : "list" + crdPlural ,
1491
+ },
1492
+ Scope : "Namespaced" ,
1493
+ },
1494
+ }
1495
+
1496
+ crd2 := apiextensions.CustomResourceDefinition {
1497
+ ObjectMeta : metav1.ObjectMeta {
1498
+ Name : crdName2 ,
1499
+ },
1500
+ Spec : apiextensions.CustomResourceDefinitionSpec {
1501
+ Group : "cluster.com" ,
1502
+ Version : "v1alpha1" ,
1503
+ Names : apiextensions.CustomResourceDefinitionNames {
1504
+ Plural : crdPlural2 ,
1505
+ Singular : crdPlural2 ,
1506
+ Kind : crdPlural2 ,
1507
+ ListKind : "list" + crdPlural2 ,
1508
+ },
1509
+ Scope : "Namespaced" ,
1510
+ },
1511
+ }
1512
+
1513
+ // Create CSV
1514
+ packageName1 := genName ("apackage" )
1515
+ packageName2 := genName ("bpackage" )
1516
+
1517
+ namedStrategy := newNginxInstallStrategy ((genName ("dep" )), permissions , nil )
1518
+ namedStrategy2 := newNginxInstallStrategy ((genName ("dep" )), permissions , nil )
1519
+ // csvA provides CRD
1520
+ csvA := newCSV ("nginx-a" , testNamespace , "" , semver .MustParse ("0.1.0" ), []apiextensions.CustomResourceDefinition {crd }, nil , namedStrategy )
1521
+ // csvB provides CRD2 and requires CRD
1522
+ csvB := newCSV ("nginx-b" , testNamespace , "" , semver .MustParse ("0.1.0" ), []apiextensions.CustomResourceDefinition {crd2 }, []apiextensions.CustomResourceDefinition {crd }, namedStrategy2 )
1523
+ // New csvA requires CRD (transfer CRD ownership to the new csvB)
1524
+ csvNewA := newCSV ("nginx-new-a" , testNamespace , "nginx-a" , semver .MustParse ("0.2.0" ), nil , []apiextensions.CustomResourceDefinition {crd }, namedStrategy )
1525
+ // New csvB provides CRD and CRD2
1526
+ csvNewB := newCSV ("nginx-new-b" , testNamespace , "nginx-b" , semver .MustParse ("0.2.0" ), []apiextensions.CustomResourceDefinition {crd , crd2 }, nil , namedStrategy2 )
1527
+
1528
+ // Create PackageManifests 1
1529
+ // Contain csvA, ABC and B
1530
+ manifests := []registry.PackageManifest {
1531
+ {
1532
+ PackageName : packageName1 ,
1533
+ Channels : []registry.PackageChannel {
1534
+ {Name : stableChannel , CurrentCSVName : csvA .GetName ()},
1535
+ },
1536
+ DefaultChannelName : stableChannel ,
1537
+ },
1538
+ {
1539
+ PackageName : packageName2 ,
1540
+ Channels : []registry.PackageChannel {
1541
+ {Name : stableChannel , CurrentCSVName : csvB .GetName ()},
1542
+ },
1543
+ DefaultChannelName : stableChannel ,
1544
+ },
1545
+ }
1546
+
1547
+ catalogSourceName := genName ("catsrc" )
1548
+ catsrc , cleanup := createInternalCatalogSource (kubeClient , crClient , catalogSourceName , testNamespace , manifests , []apiextensions.CustomResourceDefinition {crd , crd2 }, []v1alpha1.ClusterServiceVersion {csvA , csvB })
1549
+ defer cleanup ()
1550
+
1551
+ // Ensure that the catalog source is resolved before we create a subscription.
1552
+ _ , err := fetchCatalogSourceOnStatus (crClient , catsrc .GetName (), testNamespace , catalogSourceRegistryPodSynced )
1553
+ require .NoError (GinkgoT (), err )
1554
+
1555
+ subscriptionSpec := & v1alpha1.SubscriptionSpec {
1556
+ CatalogSource : catsrc .GetName (),
1557
+ CatalogSourceNamespace : catsrc .GetNamespace (),
1558
+ Package : packageName2 ,
1559
+ Channel : stableChannel ,
1560
+ StartingCSV : csvB .GetName (),
1561
+ InstallPlanApproval : v1alpha1 .ApprovalAutomatic ,
1562
+ }
1563
+
1564
+ // Create a subscription that has a dependency
1565
+ subscriptionName := genName ("sub-" )
1566
+ cleanupSubscription := createSubscriptionForCatalogWithSpec (GinkgoT (), crClient , testNamespace , subscriptionName , subscriptionSpec )
1567
+ defer cleanupSubscription ()
1568
+
1569
+ subscription , err := fetchSubscription (crClient , testNamespace , subscriptionName , subscriptionStateAtLatestChecker )
1570
+ require .NoError (GinkgoT (), err )
1571
+ require .NotNil (GinkgoT (), subscription )
1572
+
1573
+ // Check that a single catalog source was used to resolve the InstallPlan
1574
+ _ , err = fetchInstallPlan (GinkgoT (), crClient , subscription .Status .InstallPlanRef .Name , buildInstallPlanPhaseCheckFunc (v1alpha1 .InstallPlanPhaseComplete ))
1575
+ require .NoError (GinkgoT (), err )
1576
+ // Fetch CSVs A and B
1577
+ _ , err = fetchCSV (GinkgoT (), crClient , csvA .Name , testNamespace , csvSucceededChecker )
1578
+ require .NoError (GinkgoT (), err )
1579
+ _ , err = fetchCSV (GinkgoT (), crClient , csvB .Name , testNamespace , csvSucceededChecker )
1580
+ require .NoError (GinkgoT (), err )
1581
+
1582
+ // Update PackageManifest
1583
+ manifests = []registry.PackageManifest {
1584
+ {
1585
+ PackageName : packageName1 ,
1586
+ Channels : []registry.PackageChannel {
1587
+ {Name : stableChannel , CurrentCSVName : csvNewA .GetName ()},
1588
+ },
1589
+ DefaultChannelName : stableChannel ,
1590
+ },
1591
+ {
1592
+ PackageName : packageName2 ,
1593
+ Channels : []registry.PackageChannel {
1594
+ {Name : stableChannel , CurrentCSVName : csvB .GetName ()},
1595
+ },
1596
+ DefaultChannelName : stableChannel ,
1597
+ },
1598
+ }
1599
+ updateInternalCatalog (GinkgoT (), kubeClient , crClient , catalogSourceName , testNamespace , []apiextensions.CustomResourceDefinition {crd , crd2 }, []v1alpha1.ClusterServiceVersion {csvNewA , csvA , csvB }, manifests )
1600
+ csvAsub := strings .Join ([]string {packageName1 , stableChannel , catalogSourceName , testNamespace }, "-" )
1601
+ _ , err = fetchSubscription (crClient , testNamespace , csvAsub , subscriptionStateUpgradeAvailableChecker )
1602
+ require .NoError (GinkgoT (), err )
1603
+ // Ensure csvNewA is not installed
1604
+ _ , err = crClient .OperatorsV1alpha1 ().ClusterServiceVersions (testNamespace ).Get (context .Background (), csvNewA .Name , metav1.GetOptions {})
1605
+ require .Error (GinkgoT (), err )
1606
+ // Ensure csvA still exists
1607
+ _ , err = fetchCSV (GinkgoT (), crClient , csvA .Name , testNamespace , csvSucceededChecker )
1608
+ require .NoError (GinkgoT (), err )
1609
+
1610
+ // Update packagemanifest again
1611
+ manifests = []registry.PackageManifest {
1612
+ {
1613
+ PackageName : packageName1 ,
1614
+ Channels : []registry.PackageChannel {
1615
+ {Name : stableChannel , CurrentCSVName : csvNewA .GetName ()},
1616
+ },
1617
+ DefaultChannelName : stableChannel ,
1618
+ },
1619
+ {
1620
+ PackageName : packageName2 ,
1621
+ Channels : []registry.PackageChannel {
1622
+ {Name : stableChannel , CurrentCSVName : csvNewB .GetName ()},
1623
+ },
1624
+ DefaultChannelName : stableChannel ,
1625
+ },
1626
+ }
1627
+ updateInternalCatalog (GinkgoT (), kubeClient , crClient , catalogSourceName , testNamespace , []apiextensions.CustomResourceDefinition {crd , crd2 }, []v1alpha1.ClusterServiceVersion {csvA , csvB , csvNewA , csvNewB }, manifests )
1628
+ _ , err = fetchSubscription (crClient , testNamespace , subscriptionName , subscriptionStateUpgradePendingChecker )
1629
+ require .NoError (GinkgoT (), err )
1630
+ // Ensure csvNewA is installed
1631
+ _ , err = fetchCSV (GinkgoT (), crClient , csvNewA .Name , testNamespace , csvSucceededChecker )
1632
+ require .NoError (GinkgoT (), err )
1633
+ // Ensure csvNewB is installed
1634
+ _ , err = fetchCSV (GinkgoT (), crClient , csvNewB .Name , testNamespace , csvSucceededChecker )
1635
+ require .NoError (GinkgoT (), err )
1636
+ })
1438
1637
})
1439
1638
1440
1639
const (
0 commit comments