github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/process/upgrade_kyma_operation.go (about) 1 package process 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/kyma-project/kyma-environment-broker/common/orchestration" 8 "github.com/kyma-project/kyma-environment-broker/internal" 9 "github.com/kyma-project/kyma-environment-broker/internal/storage" 10 "github.com/kyma-project/kyma-environment-broker/internal/storage/dberr" 11 12 "github.com/pivotal-cf/brokerapi/v8/domain" 13 "github.com/sirupsen/logrus" 14 ) 15 16 type UpgradeKymaOperationManager struct { 17 storage storage.UpgradeKyma 18 } 19 20 func NewUpgradeKymaOperationManager(storage storage.Operations) *UpgradeKymaOperationManager { 21 return &UpgradeKymaOperationManager{storage: storage} 22 } 23 24 // OperationSucceeded marks the operation as succeeded and only repeats it if there is a storage error 25 func (om *UpgradeKymaOperationManager) OperationSucceeded(operation internal.UpgradeKymaOperation, description string, log logrus.FieldLogger) (internal.UpgradeKymaOperation, time.Duration, error) { 26 updatedOperation, repeat, _ := om.update(operation, orchestration.Succeeded, description, log) 27 // repeat in case of storage error 28 if repeat != 0 { 29 return updatedOperation, repeat, nil 30 } 31 32 return updatedOperation, 0, nil 33 } 34 35 // OperationFailed marks the operation as failed and only repeats it if there is a storage error 36 func (om *UpgradeKymaOperationManager) OperationFailed(operation internal.UpgradeKymaOperation, description string, err error, log logrus.FieldLogger) (internal.UpgradeKymaOperation, time.Duration, error) { 37 updatedOperation, repeat, _ := om.update(operation, orchestration.Failed, description, log) 38 // repeat in case of storage error 39 if repeat != 0 { 40 return updatedOperation, repeat, nil 41 } 42 43 var retErr error 44 if err == nil { 45 // no exact err passed in 46 retErr = fmt.Errorf(description) 47 } else { 48 // keep the original err object for error categorizer 49 retErr = fmt.Errorf("%s: %w", description, err) 50 } 51 52 return updatedOperation, 0, retErr 53 } 54 55 // OperationSucceeded marks the operation as succeeded and only repeats it if there is a storage error 56 func (om *UpgradeKymaOperationManager) OperationCanceled(operation internal.UpgradeKymaOperation, description string, log logrus.FieldLogger) (internal.UpgradeKymaOperation, time.Duration, error) { 57 updatedOperation, repeat, _ := om.update(operation, orchestration.Canceled, description, log) 58 if repeat != 0 { 59 return updatedOperation, repeat, nil 60 } 61 62 return updatedOperation, 0, nil 63 } 64 65 // RetryOperation retries an operation for at maxTime in retryInterval steps and fails the operation if retrying failed 66 func (om *UpgradeKymaOperationManager) RetryOperation(operation internal.UpgradeKymaOperation, errorMessage string, err error, retryInterval time.Duration, maxTime time.Duration, log logrus.FieldLogger) (internal.UpgradeKymaOperation, time.Duration, error) { 67 since := time.Since(operation.UpdatedAt) 68 69 log.Infof("Retry Operation was triggered with message: %s", errorMessage) 70 log.Infof("Retrying for %s in %s steps", maxTime.String(), retryInterval.String()) 71 if since < maxTime { 72 return operation, retryInterval, nil 73 } 74 log.Errorf("Aborting after %s of failing retries", maxTime.String()) 75 return om.OperationFailed(operation, errorMessage, err, log) 76 } 77 78 // UpdateOperation updates a given operation and handles conflict situation 79 func (om *UpgradeKymaOperationManager) UpdateOperation(operation internal.UpgradeKymaOperation, update func(operation *internal.UpgradeKymaOperation), log logrus.FieldLogger) (internal.UpgradeKymaOperation, time.Duration, error) { 80 update(&operation) 81 updatedOperation, err := om.storage.UpdateUpgradeKymaOperation(operation) 82 switch { 83 case dberr.IsConflict(err): 84 { 85 op, err := om.storage.GetUpgradeKymaOperationByID(operation.Operation.ID) 86 if err != nil { 87 log.Errorf("while getting operation: %v", err) 88 return operation, 1 * time.Minute, err 89 } 90 update(op) 91 updatedOperation, err = om.storage.UpdateUpgradeKymaOperation(*op) 92 if err != nil { 93 log.Errorf("while updating operation after conflict: %v", err) 94 return operation, 1 * time.Minute, err 95 } 96 } 97 case err != nil: 98 log.Errorf("while updating operation: %v", err) 99 return operation, 1 * time.Minute, err 100 } 101 return *updatedOperation, 0, nil 102 } 103 104 // Deprecated: SimpleUpdateOperation updates a given operation without handling conflicts. Should be used when operation's data mutations are not clear 105 func (om *UpgradeKymaOperationManager) SimpleUpdateOperation(operation internal.UpgradeKymaOperation) (internal.UpgradeKymaOperation, time.Duration) { 106 updatedOperation, err := om.storage.UpdateUpgradeKymaOperation(operation) 107 if err != nil { 108 logrus.WithField("orchestrationID", operation.OrchestrationID). 109 WithField("instanceID", operation.InstanceID). 110 Errorf("Update provisioning operation failed: %s", err.Error()) 111 return operation, 1 * time.Minute 112 } 113 return *updatedOperation, 0 114 } 115 116 // RetryOperationWithoutFail retries an operation for at maxTime in retryInterval steps and omits the operation if retrying failed 117 func (om *UpgradeKymaOperationManager) RetryOperationWithoutFail(operation internal.UpgradeKymaOperation, description string, retryInterval, maxTime time.Duration, log logrus.FieldLogger) (internal.UpgradeKymaOperation, time.Duration, error) { 118 since := time.Since(operation.UpdatedAt) 119 120 log.Infof("Retry Operation was triggered with message: %s", description) 121 log.Infof("Retrying for %s in %s steps", maxTime.String(), retryInterval.String()) 122 if since < maxTime { 123 return operation, retryInterval, nil 124 } 125 // update description to track failed steps 126 updatedOperation, repeat, _ := om.update(operation, domain.InProgress, description, log) 127 if repeat != 0 { 128 return updatedOperation, repeat, nil 129 } 130 131 log.Errorf("Omitting after %s of failing retries", maxTime.String()) 132 return updatedOperation, 0, nil 133 } 134 135 func (om *UpgradeKymaOperationManager) update(operation internal.UpgradeKymaOperation, state domain.LastOperationState, description string, log logrus.FieldLogger) (internal.UpgradeKymaOperation, time.Duration, error) { 136 return om.UpdateOperation(operation, func(operation *internal.UpgradeKymaOperation) { 137 operation.State = state 138 operation.Description = description 139 }, log) 140 }