@@ -53,6 +53,7 @@ import (
53
53
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/scoped"
54
54
sharedtime "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/time"
55
55
"github.com/operator-framework/operator-lifecycle-manager/pkg/metrics"
56
+ "github.com/operator-framework/operator-registry/pkg/configmap"
56
57
)
57
58
58
59
const (
@@ -1105,6 +1106,16 @@ func (o *Operator) createInstallPlan(namespace string, gen int, subs []*v1alpha1
1105
1106
return reference .GetReference (res )
1106
1107
}
1107
1108
1109
+ type UnpackedBundleReference struct {
1110
+ kind string
1111
+ name string
1112
+ namespace string
1113
+ catalogSourceName string
1114
+ catalogSourceNamespace string
1115
+ replaces string
1116
+ }
1117
+
1118
+ // unpackBundles makes one walk through the bundlelookups and attempts to progress them
1108
1119
func (o * Operator ) unpackBundles (plan * v1alpha1.InstallPlan ) (bool , * v1alpha1.InstallPlan , error ) {
1109
1120
out := plan .DeepCopy ()
1110
1121
unpacked := true
@@ -1129,17 +1140,33 @@ func (o *Operator) unpackBundles(plan *v1alpha1.InstallPlan) (bool, *v1alpha1.In
1129
1140
continue
1130
1141
}
1131
1142
1143
+ // Ensure that bundle can be applied by the current version of OLM
1132
1144
steps , err := resolver .NewStepsFromBundle (res .Bundle (), out .GetNamespace (), res .Replaces , res .CatalogSourceRef .Name , res .CatalogSourceRef .Namespace )
1133
1145
if err != nil {
1134
- errs = append (errs , fmt .Errorf ("failed to turn bundle into steps: %s " , err . Error () ))
1146
+ errs = append (errs , fmt .Errorf ("failed to turn bundle into steps: %v " , err ))
1135
1147
unpacked = false
1136
1148
continue
1137
1149
}
1138
1150
1139
- // Add steps and remove resolved bundle lookup
1151
+ // step manifests are replaced with references to the configmap containing them
1152
+ for _ , s := range steps {
1153
+ ref := UnpackedBundleReference {
1154
+ kind : "ConfigMap" ,
1155
+ namespace : res .CatalogSourceRef .Namespace ,
1156
+ name : res .Name (),
1157
+ catalogSourceName : res .CatalogSourceRef .Name ,
1158
+ catalogSourceNamespace : res .CatalogSourceRef .Namespace ,
1159
+ replaces : res .Replaces ,
1160
+ }
1161
+ r , err := json .Marshal (ref )
1162
+ if err != nil {
1163
+ errs = append (errs , fmt .Errorf ("failed to generate reference for configmap: %v" , err ))
1164
+ unpacked = false
1165
+ continue
1166
+ }
1167
+ s .Resource .Manifest = string (r )
1168
+ }
1140
1169
out .Status .Plan = append (out .Status .Plan , steps ... )
1141
- out .Status .BundleLookups = append (out .Status .BundleLookups [:i ], out .Status .BundleLookups [i + 1 :]... )
1142
- i --
1143
1170
}
1144
1171
1145
1172
if err := utilerrors .NewAggregate (errs ); err != nil {
@@ -1418,9 +1445,70 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1418
1445
ensurer := newStepEnsurer (kubeclient , crclient , dynamicClient )
1419
1446
b := newBuilder (kubeclient , dynamicClient , o .csvProvidedAPIsIndexer , o .logger )
1420
1447
1448
+ refForStep := func (step * v1alpha1.Step ) (ref * UnpackedBundleReference ) {
1449
+ if err := json .Unmarshal ([]byte (step .Resource .Manifest ), & ref ); err != nil {
1450
+ return nil
1451
+ }
1452
+ if ref .kind != "ConfigMap" || ref .name == "" || ref .namespace == "" || ref .catalogSourceName == "" || ref .catalogSourceNamespace == "" {
1453
+ return nil
1454
+ }
1455
+ return ref
1456
+ }
1457
+
1458
+ // for each step that points to a configmap instead of holding the full step manifest, find the steps and cache them
1459
+ unpackedSteps := map [string ][]v1alpha1.StepResource {}
1460
+ loader := configmap .NewBundleLoader ()
1461
+ for _ , step := range plan .Status .Plan {
1462
+ ref := refForStep (step )
1463
+ if ref == nil {
1464
+ continue
1465
+ }
1466
+ cm , err := o .lister .CoreV1 ().ConfigMapLister ().ConfigMaps (ref .namespace ).Get (ref .name )
1467
+ if err != nil {
1468
+ return errorwrap .Wrapf (err , "error finding unpacked bundle configmap for ref %s" , step .Resource .Manifest )
1469
+ }
1470
+ b , err := loader .Load (cm )
1471
+ if err != nil {
1472
+ return errorwrap .Wrapf (err , "error loading unpacked bundle configmap for ref %s" , step .Resource .Manifest )
1473
+ }
1474
+ steps , err := resolver .NewStepResourceFromBundle (b , plan .GetNamespace (), ref .replaces , ref .catalogSourceName , ref .catalogSourceNamespace )
1475
+ if err != nil {
1476
+ return errorwrap .Wrapf (err , "error calculating steps for ref %s" , step .Resource .Manifest )
1477
+ }
1478
+ unpackedSteps [step .Resolving ] = steps
1479
+ }
1480
+
1481
+ manifestForStep := func (step * v1alpha1.Step ) (string , error ) {
1482
+ manifest := step .Resource .Manifest
1483
+ ref := refForStep (step )
1484
+ if ref != nil {
1485
+ if usteps , ok := unpackedSteps [step .Resolving ]; ok {
1486
+ // need to find the real manifest from the unpacked steps
1487
+ for _ , u := range usteps {
1488
+ if u .Name == step .Resource .Name &&
1489
+ u .Kind == step .Resource .Kind &&
1490
+ u .Version == step .Resource .Version &&
1491
+ u .Group == step .Resource .Group {
1492
+ manifest = u .Manifest
1493
+ }
1494
+ }
1495
+ }
1496
+ if manifest == step .Resource .Manifest {
1497
+ return "" , errorwrap .Wrapf (err , "couldn't find unpacked step for %v" , step )
1498
+ }
1499
+ }
1500
+ return manifest , nil
1501
+ }
1502
+
1421
1503
for i , step := range plan .Status .Plan {
1504
+ // TODO: should lazy load only when the manifest is actually needed
1505
+ manifest , err := manifestForStep (step )
1506
+ if err != nil {
1507
+ return err
1508
+ }
1509
+
1422
1510
doStep := true
1423
- s , err := b .create (step )
1511
+ s , err := b .create (step , manifest )
1424
1512
if err != nil {
1425
1513
if _ , ok := err .(notSupportedStepperErr ); ok {
1426
1514
// stepper not implemented for this type yet
@@ -1448,7 +1536,7 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1448
1536
case v1alpha1 .ClusterServiceVersionKind :
1449
1537
// Marshal the manifest into a CSV instance.
1450
1538
var csv v1alpha1.ClusterServiceVersion
1451
- err := json .Unmarshal ([]byte (step . Resource . Manifest ), & csv )
1539
+ err := json .Unmarshal ([]byte (manifest ), & csv )
1452
1540
if err != nil {
1453
1541
return errorwrap .Wrapf (err , "error parsing step manifest: %s" , step .Resource .Name )
1454
1542
}
@@ -1481,7 +1569,7 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1481
1569
case v1alpha1 .SubscriptionKind :
1482
1570
// Marshal the manifest into a subscription instance.
1483
1571
var sub v1alpha1.Subscription
1484
- err := json .Unmarshal ([]byte (step . Resource . Manifest ), & sub )
1572
+ err := json .Unmarshal ([]byte (manifest ), & sub )
1485
1573
if err != nil {
1486
1574
return errorwrap .Wrapf (err , "error parsing step manifest: %s" , step .Resource .Name )
1487
1575
}
@@ -1505,7 +1593,7 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1505
1593
1506
1594
case resolver .BundleSecretKind :
1507
1595
var s corev1.Secret
1508
- err := json .Unmarshal ([]byte (step . Resource . Manifest ), & s )
1596
+ err := json .Unmarshal ([]byte (manifest ), & s )
1509
1597
if err != nil {
1510
1598
return errorwrap .Wrapf (err , "error parsing step manifest: %s" , step .Resource .Name )
1511
1599
}
@@ -1544,7 +1632,7 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1544
1632
case clusterRoleKind :
1545
1633
// Marshal the manifest into a ClusterRole instance.
1546
1634
var cr rbacv1.ClusterRole
1547
- err := json .Unmarshal ([]byte (step . Resource . Manifest ), & cr )
1635
+ err := json .Unmarshal ([]byte (manifest ), & cr )
1548
1636
if err != nil {
1549
1637
return errorwrap .Wrapf (err , "error parsing step manifest: %s" , step .Resource .Name )
1550
1638
}
@@ -1559,7 +1647,7 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1559
1647
case clusterRoleBindingKind :
1560
1648
// Marshal the manifest into a RoleBinding instance.
1561
1649
var rb rbacv1.ClusterRoleBinding
1562
- err := json .Unmarshal ([]byte (step . Resource . Manifest ), & rb )
1650
+ err := json .Unmarshal ([]byte (manifest ), & rb )
1563
1651
if err != nil {
1564
1652
return errorwrap .Wrapf (err , "error parsing step manifest: %s" , step .Resource .Name )
1565
1653
}
@@ -1574,7 +1662,7 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1574
1662
case roleKind :
1575
1663
// Marshal the manifest into a Role instance.
1576
1664
var r rbacv1.Role
1577
- err := json .Unmarshal ([]byte (step . Resource . Manifest ), & r )
1665
+ err := json .Unmarshal ([]byte (manifest ), & r )
1578
1666
if err != nil {
1579
1667
return errorwrap .Wrapf (err , "error parsing step manifest: %s" , step .Resource .Name )
1580
1668
}
@@ -1597,7 +1685,7 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1597
1685
case roleBindingKind :
1598
1686
// Marshal the manifest into a RoleBinding instance.
1599
1687
var rb rbacv1.RoleBinding
1600
- err := json .Unmarshal ([]byte (step . Resource . Manifest ), & rb )
1688
+ err := json .Unmarshal ([]byte (manifest ), & rb )
1601
1689
if err != nil {
1602
1690
return errorwrap .Wrapf (err , "error parsing step manifest: %s" , step .Resource .Name )
1603
1691
}
@@ -1620,7 +1708,7 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1620
1708
case serviceAccountKind :
1621
1709
// Marshal the manifest into a ServiceAccount instance.
1622
1710
var sa corev1.ServiceAccount
1623
- err := json .Unmarshal ([]byte (step . Resource . Manifest ), & sa )
1711
+ err := json .Unmarshal ([]byte (manifest ), & sa )
1624
1712
if err != nil {
1625
1713
return errorwrap .Wrapf (err , "error parsing step manifest: %s" , step .Resource .Name )
1626
1714
}
@@ -1643,7 +1731,7 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1643
1731
case serviceKind :
1644
1732
// Marshal the manifest into a Service instance
1645
1733
var s corev1.Service
1646
- err := json .Unmarshal ([]byte (step . Resource . Manifest ), & s )
1734
+ err := json .Unmarshal ([]byte (manifest ), & s )
1647
1735
if err != nil {
1648
1736
return errorwrap .Wrapf (err , "error parsing step manifest: %s" , step .Resource .Name )
1649
1737
}
@@ -1673,7 +1761,7 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1673
1761
1674
1762
case configMapKind :
1675
1763
var cfg corev1.ConfigMap
1676
- err := json .Unmarshal ([]byte (step . Resource . Manifest ), & cfg )
1764
+ err := json .Unmarshal ([]byte (manifest ), & cfg )
1677
1765
if err != nil {
1678
1766
return errorwrap .Wrapf (err , "error parsing step manifest: %s" , step .Resource .Name )
1679
1767
}
@@ -1709,7 +1797,7 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
1709
1797
}
1710
1798
1711
1799
// Marshal the manifest into an unstructured object
1712
- dec := yaml .NewYAMLOrJSONDecoder (strings .NewReader (step . Resource . Manifest ), 10 )
1800
+ dec := yaml .NewYAMLOrJSONDecoder (strings .NewReader (manifest ), 10 )
1713
1801
unstructuredObject := & unstructured.Unstructured {}
1714
1802
if err := dec .Decode (unstructuredObject ); err != nil {
1715
1803
return errorwrap .Wrapf (err , "error decoding %s object to an unstructured object" , step .Resource .Name )
0 commit comments