@@ -18,9 +18,9 @@ import (
18
18
operatorcommon "github.com/openshift/assisted-service/internal/operators/common"
19
19
"github.com/openshift/assisted-service/internal/usage"
20
20
"github.com/openshift/assisted-service/models"
21
- "github.com/pkg/errors"
22
21
"github.com/sirupsen/logrus"
23
22
"github.com/thoas/go-funk"
23
+ "gorm.io/gorm"
24
24
)
25
25
26
26
type ValidationResult struct {
@@ -72,7 +72,7 @@ func (r *refreshPreprocessor) preprocess(ctx context.Context, c *clusterPreproce
72
72
if c .cluster != nil {
73
73
ignoredValidations , err = common .DeserializeJSONList (c .cluster .IgnoredClusterValidations )
74
74
if err != nil {
75
- return nil , nil , errors . Wrap ( err , fmt .Sprintf ( "Unable to deserialize ignored cluster validations for cluster %s" , string ( * c .cluster .ID )) )
75
+ return nil , nil , fmt .Errorf ( "unable to deserialize ignored cluster validations for cluster %s: %w " , c .cluster .ID . String (), err )
76
76
}
77
77
}
78
78
@@ -102,7 +102,7 @@ func (r *refreshPreprocessor) preprocess(ctx context.Context, c *clusterPreproce
102
102
// dependency, and then we will need to validate that secure boot is disabled.
103
103
err = r .recalculateOperatorDependencies (ctx , c )
104
104
if err != nil {
105
- err = errors . Wrapf ( err , "failed to recalculate operator dependencies for cluster '%s'" , c .clusterId )
105
+ err = fmt . Errorf ( "failed to recalculate operator dependencies for cluster '%s': %w " , c .clusterId , err )
106
106
return nil , nil , err
107
107
}
108
108
@@ -151,72 +151,87 @@ func (r *refreshPreprocessor) preprocess(ctx context.Context, c *clusterPreproce
151
151
func (r * refreshPreprocessor ) recalculateOperatorDependencies (ctx context.Context , c * clusterPreprocessContext ) error {
152
152
// Calculate and save the operators that have been added, updated or deleted:
153
153
operatorsBeforeResolve := c .cluster .MonitoredOperators
154
+
154
155
operatorsAfterResolve , err := r .operatorsAPI .ResolveDependencies (c .cluster , c .cluster .MonitoredOperators )
155
156
if err != nil {
156
- return errors .Wrapf (
157
- err ,
158
- "failed to resolve operator dependencies for cluster '%s'" ,
159
- c .clusterId ,
160
- )
157
+ return fmt .Errorf ("failed to resolve operator dependencies: %w" , err )
161
158
}
159
+
162
160
var addedOperators , updatedOperators , deletedOperators []* models.MonitoredOperator
161
+
163
162
for _ , operatorAfterResolve := range operatorsAfterResolve {
164
163
if operatorAfterResolve .ClusterID == "" {
165
164
operatorAfterResolve .ClusterID = c .clusterId
166
165
}
167
- operatorBeforeREsolve := operatorcommon .GetOperator (operatorsBeforeResolve , operatorAfterResolve .Name )
168
- if operatorBeforeREsolve != nil {
169
- if ! reflect .DeepEqual (operatorAfterResolve , operatorBeforeREsolve ) {
166
+
167
+ operatorBeforeResolve := operatorcommon .GetOperator (operatorsBeforeResolve , operatorAfterResolve .Name )
168
+ if operatorBeforeResolve != nil {
169
+ if ! reflect .DeepEqual (operatorAfterResolve , operatorBeforeResolve ) {
170
170
updatedOperators = append (updatedOperators , operatorAfterResolve )
171
171
}
172
172
} else {
173
173
addedOperators = append (addedOperators , operatorAfterResolve )
174
174
}
175
175
}
176
+
176
177
for _ , operatorBeforeResolve := range operatorsBeforeResolve {
177
178
if ! operatorcommon .HasOperator (operatorsAfterResolve , operatorBeforeResolve .Name ) {
178
179
deletedOperators = append (deletedOperators , operatorBeforeResolve )
179
180
}
180
181
}
181
- for _ , addedOperator := range addedOperators {
182
- err = c .db .Save (addedOperator ).Error
183
- if err != nil {
184
- return errors .Wrapf (
185
- err ,
186
- "failed to add operator '%s' to cluster '%s'" ,
187
- addedOperator .Name , * c .cluster .ID ,
188
- )
189
- }
182
+
183
+ // If nothing changed, nothing needs to be done
184
+ if len (addedOperators ) == 0 && len (deletedOperators ) == 0 && len (updatedOperators ) == 0 {
185
+ return nil
190
186
}
191
- for _ , updatedOperator := range updatedOperators {
192
- err = c .db .Save (updatedOperator ).Error
193
- if err != nil {
194
- return errors .Wrapf (
195
- err ,
196
- "failed to update operator '%s' for cluster '%s'" ,
197
- updatedOperator .Name , * c .cluster .ID ,
198
- )
199
- }
187
+
188
+ // Validate with cluster CPU architecture
189
+ err = r .operatorsAPI .EnsureOperatorPrerequisite (c .cluster , c .cluster .OpenshiftVersion , c .cluster .CPUArchitecture , operatorsAfterResolve )
190
+ if err != nil {
191
+ return fmt .Errorf ("failed to validate operator prerequisite: %w" , err )
200
192
}
201
- for _ , deletedOperator := range deletedOperators {
202
- err = c .db .Delete (deletedOperator ).Error
203
- if err != nil {
204
- return errors .Wrapf (
205
- err ,
206
- "failed to delete operator '%s' from cluster '%s'" ,
207
- deletedOperator .Name ,
208
- c .clusterId ,
209
- )
193
+
194
+ c .cluster .MonitoredOperators = operatorsAfterResolve
195
+
196
+ err = c .db .Transaction (func (tx * gorm.DB ) error {
197
+ for _ , addedOperator := range addedOperators {
198
+ err = tx .Save (addedOperator ).Error
199
+ if err != nil {
200
+ return fmt .Errorf ("failed to add operator '%s': %w" , addedOperator .Name , err )
201
+ }
202
+ }
203
+
204
+ for _ , updatedOperator := range updatedOperators {
205
+ err = tx .Save (updatedOperator ).Error
206
+ if err != nil {
207
+ return fmt .Errorf ("failed to update operator '%s': %w" , updatedOperator .Name , err )
208
+ }
209
+ }
210
+
211
+ for _ , deletedOperator := range deletedOperators {
212
+ err = tx .Delete (deletedOperator ).Error
213
+ if err != nil {
214
+ return fmt .Errorf ("failed to delete operator '%s': %w" , deletedOperator .Name , err )
215
+ }
210
216
}
217
+
218
+ // If any operator has been added or deleted then we need to update the corresponding feature usage
219
+ if len (addedOperators ) > 0 || len (deletedOperators ) > 0 {
220
+ err = r .recalculateOperatorFeatureUsage (c , tx , addedOperators , deletedOperators )
221
+ if err != nil {
222
+ return fmt .Errorf ("failed to recalculate operator feature usage: %w" , err )
223
+ }
224
+ }
225
+
226
+ return nil
227
+ })
228
+
229
+ if err != nil {
230
+ return fmt .Errorf ("transaction to update monitored operators, the associated usage and reset roles failed: %w" , err )
211
231
}
212
- c .cluster .MonitoredOperators = operatorsAfterResolve
213
232
214
- // If any operator has been added or deleted then we need to update the corresponding feature usage:
233
+ // If everything went smoothly, notify about the change
215
234
if len (addedOperators ) > 0 || len (deletedOperators ) > 0 {
216
- err = r .recalculateOperatorFeatureUsage (c , addedOperators , deletedOperators )
217
- if err != nil {
218
- return err
219
- }
220
235
err = r .notifyOperatorFeatureUsageChange (ctx , c , addedOperators , deletedOperators )
221
236
if err != nil {
222
237
return err
@@ -226,37 +241,35 @@ func (r *refreshPreprocessor) recalculateOperatorDependencies(ctx context.Contex
226
241
return nil
227
242
}
228
243
229
- func (r * refreshPreprocessor ) recalculateOperatorFeatureUsage (c * clusterPreprocessContext ,
244
+ func (r * refreshPreprocessor ) recalculateOperatorFeatureUsage (c * clusterPreprocessContext , db * gorm. DB ,
230
245
addedOperators , deletedOperators []* models.MonitoredOperator ) error {
231
246
if r .usageAPI == nil {
232
247
return nil
233
248
}
249
+
234
250
usages , err := usage .Unmarshal (c .cluster .FeatureUsage )
235
251
if err != nil {
236
- return errors .Wrapf (
237
- err ,
238
- "failed to read feature usage from cluster '%s'" ,
239
- c .clusterId ,
240
- )
252
+ return fmt .Errorf ("failed to read feature usage: %w" , err )
241
253
}
254
+
242
255
for _ , addedOperator := range addedOperators {
243
256
featureName := strings .ToUpper (addedOperator .Name )
244
257
r .usageAPI .Add (usages , featureName , nil )
245
258
}
259
+
246
260
for _ , deletedOperator := range deletedOperators {
247
261
featureName := strings .ToUpper (deletedOperator .Name )
248
262
r .usageAPI .Remove (usages , featureName )
249
263
}
264
+
250
265
data , err := json .Marshal (usages )
251
266
if err != nil {
252
- return errors .Wrapf (
253
- err ,
254
- "failed to write feature usage to cluster '%s'" ,
255
- c .clusterId ,
256
- )
267
+ return fmt .Errorf ("failed to write feature usage: %w" , err )
257
268
}
269
+
258
270
c .cluster .FeatureUsage = string (data )
259
- r .usageAPI .Save (c .db , c .clusterId , usages )
271
+ r .usageAPI .Save (db , c .clusterId , usages )
272
+
260
273
return nil
261
274
}
262
275
0 commit comments