@@ -12,6 +12,7 @@ import (
1212 "github.com/devtron-labs/devtron/client/argocdServer/application"
1313 "github.com/devtron-labs/devtron/client/argocdServer/bean"
1414 "github.com/devtron-labs/devtron/client/argocdServer/repository"
15+ "github.com/devtron-labs/devtron/internal/util"
1516 "github.com/devtron-labs/devtron/pkg/deployment/gitOps/config"
1617 "github.com/devtron-labs/devtron/pkg/deployment/gitOps/git"
1718 "github.com/devtron-labs/devtron/util/retryFunc"
@@ -25,6 +26,14 @@ type ACDConfig struct {
2526 ArgoCDAutoSyncEnabled bool `env:"ARGO_AUTO_SYNC_ENABLED" envDefault:"true"` // will gradually switch this flag to false in enterprise
2627}
2728
29+ func (config * ACDConfig ) IsManualSyncEnabled () bool {
30+ return config .ArgoCDAutoSyncEnabled == false
31+ }
32+
33+ func (config * ACDConfig ) IsAutoSyncEnabled () bool {
34+ return config .ArgoCDAutoSyncEnabled == true
35+ }
36+
2837func GetACDDeploymentConfig () (* ACDConfig , error ) {
2938 cfg := & ACDConfig {}
3039 err := env .Parse (cfg )
@@ -34,6 +43,10 @@ func GetACDDeploymentConfig() (*ACDConfig, error) {
3443 return cfg , err
3544}
3645
46+ const (
47+ ErrorOperationAlreadyInProgress = "another operation is already in progress" // this string is returned from argocd
48+ )
49+
3750type ArgoClientWrapperService interface {
3851
3952 // GetArgoAppWithNormalRefresh - refresh app at argocd side
@@ -96,17 +109,45 @@ func (impl *ArgoClientWrapperServiceImpl) GetArgoAppWithNormalRefresh(context co
96109}
97110
98111func (impl * ArgoClientWrapperServiceImpl ) SyncArgoCDApplicationIfNeededAndRefresh (context context.Context , argoAppName string ) error {
112+
99113 impl .logger .Info ("argocd manual sync for app started" , "argoAppName" , argoAppName )
100- if ! impl .ACDConfig .ArgoCDAutoSyncEnabled {
114+ if impl .ACDConfig .IsManualSyncEnabled () {
115+
101116 impl .logger .Debugw ("syncing argocd app as manual sync is enabled" , "argoAppName" , argoAppName )
102117 revision := "master"
103118 pruneResources := true
104- _ , syncErr := impl .acdClient .Sync (context , & application2.ApplicationSyncRequest {Name : & argoAppName , Revision : & revision , Prune : & pruneResources })
119+ _ , syncErr := impl .acdClient .Sync (context , & application2.ApplicationSyncRequest {Name : & argoAppName ,
120+ Revision : & revision ,
121+ Prune : & pruneResources ,
122+ })
105123 if syncErr != nil {
106- impl .logger .Errorw ("cannot get application with refresh" , "app" , argoAppName )
107- return syncErr
124+ impl .logger .Errorw ("error in syncing argoCD app" , "app" , argoAppName , "err" , syncErr )
125+ statusCode , msg := util .GetClientDetailedError (syncErr )
126+ if statusCode .IsFailedPreconditionCode () && msg == ErrorOperationAlreadyInProgress {
127+ impl .logger .Info ("terminating ongoing sync operation and retrying manual sync" , "argoAppName" , argoAppName )
128+ _ , terminationErr := impl .acdClient .TerminateOperation (context , & application2.OperationTerminateRequest {
129+ Name : & argoAppName ,
130+ })
131+ if terminationErr != nil {
132+ impl .logger .Errorw ("error in terminating sync operation" )
133+ return fmt .Errorf ("error in terminating existing sync, err: %w" , terminationErr )
134+ }
135+ _ , syncErr = impl .acdClient .Sync (context , & application2.ApplicationSyncRequest {Name : & argoAppName ,
136+ Revision : & revision ,
137+ Prune : & pruneResources ,
138+ RetryStrategy : & v1alpha1.RetryStrategy {
139+ Limit : 1 ,
140+ },
141+ })
142+ if syncErr != nil {
143+ impl .logger .Errorw ("error in syncing argoCD app" , "app" , argoAppName , "err" , syncErr )
144+ return syncErr
145+ }
146+ } else {
147+ return syncErr
148+ }
108149 }
109- impl .logger .Debugw ("argocd sync completed" , "argoAppName" , argoAppName )
150+ impl .logger .Infow ("argocd sync completed" , "argoAppName" , argoAppName )
110151 }
111152 refreshErr := impl .GetArgoAppWithNormalRefresh (context , argoAppName )
112153 if refreshErr != nil {
@@ -129,10 +170,9 @@ func (impl *ArgoClientWrapperServiceImpl) UpdateArgoCDSyncModeIfNeeded(ctx conte
129170}
130171
131172func (impl * ArgoClientWrapperServiceImpl ) isArgoAppSyncModeMigrationNeeded (argoApplication * v1alpha1.Application ) bool {
132- if ! impl .ACDConfig .ArgoCDAutoSyncEnabled && argoApplication .Spec .SyncPolicy .Automated != nil {
173+ if impl .ACDConfig .IsManualSyncEnabled () && argoApplication .Spec .SyncPolicy .Automated != nil {
133174 return true
134- }
135- if impl .ACDConfig .ArgoCDAutoSyncEnabled && argoApplication .Spec .SyncPolicy .Automated == nil {
175+ } else if impl .ACDConfig .IsAutoSyncEnabled () && argoApplication .Spec .SyncPolicy .Automated == nil {
136176 return true
137177 }
138178 return false
@@ -141,7 +181,7 @@ func (impl *ArgoClientWrapperServiceImpl) isArgoAppSyncModeMigrationNeeded(argoA
141181func (impl * ArgoClientWrapperServiceImpl ) CreateRequestForArgoCDSyncModeUpdateRequest (argoApplication * v1alpha1.Application ) * v1alpha1.Application {
142182 // set automated field in update request
143183 var automated * v1alpha1.SyncPolicyAutomated
144- if impl .ACDConfig .ArgoCDAutoSyncEnabled {
184+ if impl .ACDConfig .IsAutoSyncEnabled () {
145185 automated = & v1alpha1.SyncPolicyAutomated {
146186 Prune : true ,
147187 }
0 commit comments