@@ -4,22 +4,21 @@ import (
4
4
"context"
5
5
"fmt"
6
6
7
- "k8s.io/client-go/dynamic"
8
- "k8s.io/client-go/tools/cache"
9
-
10
- "github.com/operator-framework/api/pkg/operators/v1alpha1"
11
- crdlib "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/crd"
12
- index "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/index"
13
- "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
14
- errorwrap "github.com/pkg/errors"
15
7
logger "github.com/sirupsen/logrus"
16
8
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
17
9
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
18
10
apiextensionsv1client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
19
11
apiextensionsv1beta1client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1"
20
-
21
12
k8serrors "k8s.io/apimachinery/pkg/api/errors"
22
13
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14
+ "k8s.io/client-go/dynamic"
15
+ "k8s.io/client-go/tools/cache"
16
+ "k8s.io/client-go/util/retry"
17
+
18
+ "github.com/operator-framework/api/pkg/operators/v1alpha1"
19
+ crdlib "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/crd"
20
+ index "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/index"
21
+ "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
23
22
)
24
23
25
24
// Stepper manages cluster interactions based on the step.
@@ -99,7 +98,7 @@ func (b *builder) NewCRDV1Step(client apiextensionsv1client.ApiextensionsV1Inter
99
98
if k8serrors .IsNotFound (err ) {
100
99
return v1alpha1 .StepStatusNotPresent , nil
101
100
} else {
102
- return v1alpha1 .StepStatusNotPresent , errorwrap . Wrapf ( err , "error finding the %s CRD" , crd .Name )
101
+ return v1alpha1 .StepStatusNotPresent , fmt . Errorf ( "error finding the %q CRD: %w " , crd .Name , err )
103
102
}
104
103
}
105
104
established , namesAccepted := false , false
@@ -126,39 +125,45 @@ func (b *builder) NewCRDV1Step(client apiextensionsv1client.ApiextensionsV1Inter
126
125
127
126
_ , createError := client .CustomResourceDefinitions ().Create (context .TODO (), crd , metav1.CreateOptions {})
128
127
if k8serrors .IsAlreadyExists (createError ) {
129
- currentCRD , _ := client .CustomResourceDefinitions ().Get (context .TODO (), crd .GetName (), metav1.GetOptions {})
130
- // Verify CRD ownership, only attempt to update if
131
- // CRD has only one owner
132
- // Example: provided=database.coreos.com/v1alpha1/EtcdCluster
133
- matchedCSV , err := index .V1CRDProviderNames (b .csvToProvidedAPIs , crd )
134
- if err != nil {
135
- return v1alpha1 .StepStatusUnknown , errorwrap .Wrapf (err , "error find matched CSV: %s" , step .Resource .Name )
136
- }
137
- crd .SetResourceVersion (currentCRD .GetResourceVersion ())
138
- if len (matchedCSV ) == 1 {
139
- logger .Debugf ("Found one owner for CRD %v" , crd )
140
- } else if len (matchedCSV ) > 1 {
141
- logger .Debugf ("Found multiple owners for CRD %v" , crd )
128
+ err := retry .RetryOnConflict (retry .DefaultRetry , func () error {
129
+ currentCRD , _ := client .CustomResourceDefinitions ().Get (context .TODO (), crd .GetName (), metav1.GetOptions {})
130
+ // Verify CRD ownership, only attempt to update if
131
+ // CRD has only one owner
132
+ // Example: provided=database.coreos.com/v1alpha1/EtcdCluster
133
+ matchedCSV , err := index .V1CRDProviderNames (b .csvToProvidedAPIs , crd )
134
+ if err != nil {
135
+ return fmt .Errorf ("error finding matched CSV %q: %w" , step .Resource .Name , err )
136
+ }
137
+ crd .SetResourceVersion (currentCRD .GetResourceVersion ())
138
+ if len (matchedCSV ) == 1 {
139
+ logger .Debugf ("Found one owner for CRD %v" , crd )
140
+ } else if len (matchedCSV ) > 1 {
141
+ logger .Debugf ("Found multiple owners for CRD %v" , crd )
142
142
143
- if err = validateV1CRDCompatibility (b .dynamicClient , currentCRD , crd ); err != nil {
144
- return v1alpha1 .StepStatusUnknown , errorwrap .Wrapf (err , "error validating existing CRs against new CRD's schema: %s" , step .Resource .Name )
143
+ if err = validateV1CRDCompatibility (b .dynamicClient , currentCRD , crd ); err != nil {
144
+ return fmt .Errorf ("error validating existing CRs against new CRD's schema for %q: %w" , step .Resource .Name , err )
145
+ }
145
146
}
146
- }
147
147
148
- // check to see if stored versions changed and whether the upgrade could cause potential data loss
149
- safe , err := crdlib .SafeStorageVersionUpgrade (currentCRD , crd )
150
- if ! safe {
151
- b .logger .Errorf ("risk of data loss updating %s: %s" , step .Resource .Name , err )
152
- return v1alpha1 . StepStatusUnknown , errorwrap . Wrapf ( err , "risk of data loss updating %s " , step .Resource .Name )
153
- }
154
- if err != nil {
155
- return v1alpha1 . StepStatusUnknown , errorwrap . Wrapf ( err , "checking CRD for potential data loss updating %s " , step .Resource .Name )
156
- }
148
+ // check to see if stored versions changed and whether the upgrade could cause potential data loss
149
+ safe , err := crdlib .SafeStorageVersionUpgrade (currentCRD , crd )
150
+ if ! safe {
151
+ b .logger .Errorf ("risk of data loss updating %s: %s" , step .Resource .Name , err )
152
+ return fmt . Errorf ( "risk of data loss updating %q: %w " , step .Resource .Name , err )
153
+ }
154
+ if err != nil {
155
+ return fmt . Errorf ( "checking CRD for potential data loss updating %q: %w " , step .Resource .Name , err )
156
+ }
157
157
158
- // Update CRD to new version
159
- _ , err = client .CustomResourceDefinitions ().Update (context .TODO (), crd , metav1.UpdateOptions {})
158
+ // Update CRD to new version
159
+ _ , err = client .CustomResourceDefinitions ().Update (context .TODO (), crd , metav1.UpdateOptions {})
160
+ if err != nil {
161
+ return fmt .Errorf ("error updating CRD %q: %w" , step .Resource .Name , err )
162
+ }
163
+ return nil
164
+ })
160
165
if err != nil {
161
- return v1alpha1 .StepStatusUnknown , errorwrap . Wrapf ( err , "error updating CRD: %s" , step . Resource . Name )
166
+ return v1alpha1 .StepStatusUnknown , err
162
167
}
163
168
// If it already existed, mark the step as Present.
164
169
// they were equal - mark CRD as present
@@ -187,7 +192,7 @@ func (b *builder) NewCRDV1Beta1Step(client apiextensionsv1beta1client.Apiextensi
187
192
if k8serrors .IsNotFound (err ) {
188
193
return v1alpha1 .StepStatusNotPresent , nil
189
194
} else {
190
- return v1alpha1 .StepStatusNotPresent , errorwrap . Wrapf ( err , "error finding the %s CRD" , crd .Name )
195
+ return v1alpha1 .StepStatusNotPresent , fmt . Errorf ( "error finding the %q CRD: %w " , crd .Name , err )
191
196
}
192
197
}
193
198
established , namesAccepted := false , false
@@ -214,39 +219,45 @@ func (b *builder) NewCRDV1Beta1Step(client apiextensionsv1beta1client.Apiextensi
214
219
215
220
_ , createError := client .CustomResourceDefinitions ().Create (context .TODO (), crd , metav1.CreateOptions {})
216
221
if k8serrors .IsAlreadyExists (createError ) {
217
- currentCRD , _ := client .CustomResourceDefinitions ().Get (context .TODO (), crd .GetName (), metav1.GetOptions {})
218
- // Verify CRD ownership, only attempt to update if
219
- // CRD has only one owner
220
- // Example: provided=database.coreos.com/v1alpha1/EtcdCluster
221
- matchedCSV , err := index .V1Beta1CRDProviderNames (b .csvToProvidedAPIs , crd )
222
- if err != nil {
223
- return v1alpha1 .StepStatusUnknown , errorwrap .Wrapf (err , "error find matched CSV: %s" , step .Resource .Name )
224
- }
225
- crd .SetResourceVersion (currentCRD .GetResourceVersion ())
226
- if len (matchedCSV ) == 1 {
227
- logger .Debugf ("Found one owner for CRD %v" , crd )
228
- } else if len (matchedCSV ) > 1 {
229
- logger .Debugf ("Found multiple owners for CRD %v" , crd )
222
+ err := retry .RetryOnConflict (retry .DefaultRetry , func () error {
223
+ currentCRD , _ := client .CustomResourceDefinitions ().Get (context .TODO (), crd .GetName (), metav1.GetOptions {})
224
+ // Verify CRD ownership, only attempt to update if
225
+ // CRD has only one owner
226
+ // Example: provided=database.coreos.com/v1alpha1/EtcdCluster
227
+ matchedCSV , err := index .V1Beta1CRDProviderNames (b .csvToProvidedAPIs , crd )
228
+ if err != nil {
229
+ return fmt .Errorf ("error finding matched CSV %q: %w" , step .Resource .Name , err )
230
+ }
231
+ crd .SetResourceVersion (currentCRD .GetResourceVersion ())
232
+ if len (matchedCSV ) == 1 {
233
+ logger .Debugf ("Found one owner for CRD %v" , crd )
234
+ } else if len (matchedCSV ) > 1 {
235
+ logger .Debugf ("Found multiple owners for CRD %v" , crd )
230
236
231
- if err = validateV1Beta1CRDCompatibility (b .dynamicClient , currentCRD , crd ); err != nil {
232
- return v1alpha1 .StepStatusUnknown , errorwrap .Wrapf (err , "error validating existing CRs against new CRD's schema: %s" , step .Resource .Name )
237
+ if err = validateV1Beta1CRDCompatibility (b .dynamicClient , currentCRD , crd ); err != nil {
238
+ return fmt .Errorf ("error validating existing CRs against new CRD's schema for %q: %w" , step .Resource .Name , err )
239
+ }
233
240
}
234
- }
235
241
236
- // check to see if stored versions changed and whether the upgrade could cause potential data loss
237
- safe , err := crdlib .SafeStorageVersionUpgrade (currentCRD , crd )
238
- if ! safe {
239
- b .logger .Errorf ("risk of data loss updating %s: %s" , step .Resource .Name , err )
240
- return v1alpha1 . StepStatusUnknown , errorwrap . Wrapf ( err , "risk of data loss updating %s " , step .Resource .Name )
241
- }
242
- if err != nil {
243
- return v1alpha1 . StepStatusUnknown , errorwrap . Wrapf ( err , "checking CRD for potential data loss updating %s " , step .Resource .Name )
244
- }
242
+ // check to see if stored versions changed and whether the upgrade could cause potential data loss
243
+ safe , err := crdlib .SafeStorageVersionUpgrade (currentCRD , crd )
244
+ if ! safe {
245
+ b .logger .Errorf ("risk of data loss updating %s: %s" , step .Resource .Name , err )
246
+ return fmt . Errorf ( "risk of data loss updating %q: %w " , step .Resource .Name , err )
247
+ }
248
+ if err != nil {
249
+ return fmt . Errorf ( "checking CRD for potential data loss updating %q: %w " , step .Resource .Name , err )
250
+ }
245
251
246
- // Update CRD to new version
247
- _ , err = client .CustomResourceDefinitions ().Update (context .TODO (), crd , metav1.UpdateOptions {})
252
+ // Update CRD to new version
253
+ _ , err = client .CustomResourceDefinitions ().Update (context .TODO (), crd , metav1.UpdateOptions {})
254
+ if err != nil {
255
+ return fmt .Errorf ("error updating CRD %q: %w" , step .Resource .Name , err )
256
+ }
257
+ return nil
258
+ })
248
259
if err != nil {
249
- return v1alpha1 .StepStatusUnknown , errorwrap . Wrapf ( err , "error updating CRD: %s" , step . Resource . Name )
260
+ return v1alpha1 .StepStatusUnknown , err
250
261
}
251
262
// If it already existed, mark the step as Present.
252
263
// they were equal - mark CRD as present
0 commit comments