Skip to content

Commit b478c9c

Browse files
committed
fix: argocd sync start/ finish validation
1 parent 0b76f83 commit b478c9c

File tree

3 files changed

+47
-27
lines changed

3 files changed

+47
-27
lines changed

pkg/app/AppService.go

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,14 @@ import (
7474
type AppServiceConfig struct {
7575
CdPipelineStatusCronTime string `env:"CD_PIPELINE_STATUS_CRON_TIME" envDefault:"*/2 * * * *" description:"Cron time for CD pipeline status"`
7676
CdHelmPipelineStatusCronTime string `env:"CD_HELM_PIPELINE_STATUS_CRON_TIME" envDefault:"*/2 * * * *" description:"Cron time to check the pipeline status "`
77-
CdPipelineStatusTimeoutDuration string `env:"CD_PIPELINE_STATUS_TIMEOUT_DURATION" envDefault:"20" description:"Timeout for CD pipeline to get healthy" ` // in minutes
78-
PipelineDegradedTime string `env:"PIPELINE_DEGRADED_TIME" envDefault:"10" description:"Time to mark a pipeline degraded if not healthy in defined time"` // in minutes
79-
GetPipelineDeployedWithinHours int `env:"DEPLOY_STATUS_CRON_GET_PIPELINE_DEPLOYED_WITHIN_HOURS" envDefault:"12" description:"This flag is used to fetch the deployment status of the application. It retrieves the status of deployments that occurred between 12 hours and 10 minutes prior to the current time. It fetches non-terminal statuses."` // in hours
80-
HelmPipelineStatusCheckEligibleTime string `env:"HELM_PIPELINE_STATUS_CHECK_ELIGIBLE_TIME" envDefault:"120" description:"eligible time for checking helm app status periodically and update in db, value is in seconds., default is 120, if wfr is updated within configured time i.e. HELM_PIPELINE_STATUS_CHECK_ELIGIBLE_TIME then do not include for this cron cycle."` // in seconds
77+
CdPipelineStatusTimeoutDuration string `env:"CD_PIPELINE_STATUS_TIMEOUT_DURATION" envDefault:"20" description:"Timeout for CD pipeline to get healthy" ` // in minutes
78+
PipelineDegradedTime string `env:"PIPELINE_DEGRADED_TIME" envDefault:"10" description:"Time to mark a pipeline degraded if not healthy in defined time"` // in minutes
79+
GetPipelineDeployedWithinHours int `env:"DEPLOY_STATUS_CRON_GET_PIPELINE_DEPLOYED_WITHIN_HOURS" envDefault:"12" description:"This flag is used to fetch the deployment status of the application. It retrieves the status of deployments that occurred between 12 hours and 10 minutes prior to the current time. It fetches non-terminal statuses."` // in hours
80+
HelmPipelineStatusCheckEligibleTime string `env:"HELM_PIPELINE_STATUS_CHECK_ELIGIBLE_TIME" envDefault:"120" description:"eligible time for checking helm app status periodically and update in db, value is in seconds., default is 120, if wfr is updated within configured time i.e. HELM_PIPELINE_STATUS_CHECK_ELIGIBLE_TIME then do not include for this cron cycle."` // in seconds
8181
ExposeCDMetrics bool `env:"EXPOSE_CD_METRICS" envDefault:"false"`
82-
DevtronChartHelmInstallRequestTimeout int `env:"DEVTRON_CHART_INSTALL_REQUEST_TIMEOUT" envDefault:"6" description:"Context timeout for no gitops concurrent async deployments"` // in minutes
83-
DevtronChartArgoCdInstallRequestTimeout int `env:"DEVTRON_CHART_ARGO_CD_INSTALL_REQUEST_TIMEOUT" envDefault:"1" description:"Context timeout for gitops concurrent async deployments"` // in minutes
84-
ArgoCdManualSyncCronPipelineDeployedBefore int `env:"ARGO_APP_MANUAL_SYNC_TIME" envDefault:"3" description:"retry argocd app manual sync if the timeline is stuck in ARGOCD_SYNC_INITIATED state for more than this defined time (in mins)"` // in minutes
82+
DevtronChartHelmInstallRequestTimeout int `env:"DEVTRON_CHART_INSTALL_REQUEST_TIMEOUT" envDefault:"6" description:"Context timeout for no gitops concurrent async deployments"` // in minutes
83+
DevtronChartArgoCdInstallRequestTimeout int `env:"DEVTRON_CHART_ARGO_CD_INSTALL_REQUEST_TIMEOUT" envDefault:"1" description:"Context timeout for gitops concurrent async deployments"` // in minutes
84+
ArgoCdManualSyncCronPipelineDeployedBefore int `env:"ARGO_APP_MANUAL_SYNC_TIME" envDefault:"3" description:"retry argocd app manual sync if the timeline is stuck in ARGOCD_SYNC_INITIATED state for more than this defined time (in mins)"` // in minutes
8585
}
8686

8787
func GetAppServiceConfig() (*AppServiceConfig, error) {
@@ -555,10 +555,15 @@ func (impl *AppServiceImpl) UpdatePipelineStatusTimelineForApplicationChanges(ap
555555
if err != nil {
556556
impl.logger.Errorw("error in save/update pipeline status fetch detail", "err", err, "cdWfrId", runnerHistoryId)
557557
}
558+
syncStartTime, found := helper.GetSyncStartTime(app)
559+
if !found {
560+
impl.logger.Warnw("sync operation not started yet", "app", app)
561+
return isTimelineUpdated, isTimelineTimedOut, kubectlApplySyncedTimeline, fmt.Errorf("sync operation not started yet")
562+
}
558563
// creating cd pipeline status timeline
559564
timeline := &pipelineConfig.PipelineStatusTimeline{
560565
CdWorkflowRunnerId: runnerHistoryId,
561-
StatusTime: helper.GetSyncStartTime(app, statusTime),
566+
StatusTime: syncStartTime,
562567
AuditLog: sql.AuditLog{
563568
CreatedBy: 1,
564569
CreatedOn: time.Now(),
@@ -591,7 +596,12 @@ func (impl *AppServiceImpl) UpdatePipelineStatusTimelineForApplicationChanges(ap
591596
timeline.Id = 0
592597
timeline.Status = timelineStatus.TIMELINE_STATUS_KUBECTL_APPLY_SYNCED
593598
timeline.StatusDetail = app.Status.OperationState.Message
594-
timeline.StatusTime = helper.GetSyncFinishTime(app, statusTime)
599+
syncFinishTime, found := helper.GetSyncFinishTime(app)
600+
if !found {
601+
impl.logger.Warnw("sync operation not found for the deployment", "app", app)
602+
return isTimelineUpdated, isTimelineTimedOut, kubectlApplySyncedTimeline, fmt.Errorf("sync operation not found for the deployment")
603+
}
604+
timeline.StatusTime = syncFinishTime
595605
// checking and saving if this timeline is present or not because kubewatch may stream same objects multiple times
596606
err = impl.pipelineStatusTimelineService.SaveTimeline(timeline, nil)
597607
if err != nil {
@@ -669,10 +679,15 @@ func (impl *AppServiceImpl) UpdatePipelineStatusTimelineForApplicationChanges(ap
669679
if err != nil {
670680
impl.logger.Errorw("error in save/update pipeline status fetch detail", "err", err, "installedAppVersionHistoryId", runnerHistoryId)
671681
}
682+
syncStartTime, found := helper.GetSyncStartTime(app)
683+
if !found {
684+
impl.logger.Warnw("sync operation not started yet", "app", app)
685+
return isTimelineUpdated, isTimelineTimedOut, kubectlApplySyncedTimeline, fmt.Errorf("sync operation not started yet")
686+
}
672687
// creating installedAppVersionHistory status timeline
673688
timeline := &pipelineConfig.PipelineStatusTimeline{
674689
InstalledAppVersionHistoryId: runnerHistoryId,
675-
StatusTime: helper.GetSyncStartTime(app, statusTime),
690+
StatusTime: syncStartTime,
676691
AuditLog: sql.AuditLog{
677692
CreatedBy: 1,
678693
CreatedOn: time.Now(),
@@ -705,7 +720,12 @@ func (impl *AppServiceImpl) UpdatePipelineStatusTimelineForApplicationChanges(ap
705720
timeline.Id = 0
706721
timeline.Status = timelineStatus.TIMELINE_STATUS_KUBECTL_APPLY_SYNCED
707722
timeline.StatusDetail = app.Status.OperationState.Message
708-
timeline.StatusTime = helper.GetSyncFinishTime(app, statusTime)
723+
syncFinishTime, found := helper.GetSyncFinishTime(app)
724+
if !found {
725+
impl.logger.Warnw("sync operation not found for the deployment", "app", app)
726+
return isTimelineUpdated, isTimelineTimedOut, kubectlApplySyncedTimeline, fmt.Errorf("sync operation not found for the deployment")
727+
}
728+
timeline.StatusTime = syncFinishTime
709729
// checking and saving if this timeline is present or not because kubewatch may stream same objects multiple times
710730
err = impl.pipelineStatusTimelineService.SaveTimeline(timeline, nil)
711731
if err != nil {

pkg/argoApplication/helper/deploymentStatusHelper.go

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,41 @@ package helper
22

33
import (
44
"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
5-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
65
"time"
76
)
87

98
// GetSyncStartTime assumes that it is always called for calculating start time of latest git hash
10-
func GetSyncStartTime(app *v1alpha1.Application, defaultStartTime time.Time) time.Time {
11-
startTime := metav1.NewTime(defaultStartTime)
9+
func GetSyncStartTime(app *v1alpha1.Application) (time.Time, bool) {
1210
gitHash := app.Status.Sync.Revision
1311
if app.Status.OperationState != nil &&
1412
app.Status.OperationState.Operation.Sync != nil &&
1513
app.Status.OperationState.Operation.Sync.Revision == gitHash {
16-
startTime = app.Status.OperationState.StartedAt
14+
return app.Status.OperationState.StartedAt.Time, true
1715
} else if len(app.Status.History) != 0 {
1816
if app.Status.History.LastRevisionHistory().Revision == gitHash &&
1917
app.Status.History.LastRevisionHistory().DeployStartedAt != nil {
20-
startTime = *app.Status.History.LastRevisionHistory().DeployStartedAt
18+
startTime := *app.Status.History.LastRevisionHistory().DeployStartedAt
19+
return startTime.Time, true
2120
}
2221
}
23-
return startTime.Time
22+
return time.Time{}, false
2423
}
2524

2625
// GetSyncFinishTime assumes that it is always called for calculating finish time of latest git hash
27-
func GetSyncFinishTime(app *v1alpha1.Application, defaultEndTime time.Time) time.Time {
28-
finishTime := metav1.NewTime(defaultEndTime)
26+
func GetSyncFinishTime(app *v1alpha1.Application) (time.Time, bool) {
2927
gitHash := app.Status.Sync.Revision
3028
if app.Status.OperationState != nil &&
3129
app.Status.OperationState.Operation.Sync != nil &&
3230
app.Status.OperationState.Operation.Sync.Revision == gitHash &&
3331
app.Status.OperationState.FinishedAt != nil {
34-
finishTime = *app.Status.OperationState.FinishedAt
35-
} else if app.Status.History != nil {
36-
for _, history := range app.Status.History {
37-
if history.Revision == gitHash {
38-
finishTime = history.DeployedAt
39-
}
32+
finishTime := *app.Status.OperationState.FinishedAt
33+
return finishTime.Time, true
34+
} else if len(app.Status.History) != 0 {
35+
if app.Status.History.LastRevisionHistory().Revision == gitHash &&
36+
app.Status.History.LastRevisionHistory().DeployStartedAt != nil {
37+
finishTime := *app.Status.History.LastRevisionHistory().DeployStartedAt
38+
return finishTime.Time, true
4039
}
4140
}
42-
return finishTime.Time
41+
return time.Time{}, false
4342
}

pkg/workflow/status/WorkflowStatusService.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,8 @@ func (impl *WorkflowStatusServiceImpl) CheckAndSendArgoPipelineStatusSyncEventIf
455455
}
456456

457457
// pipelineId can be cdPipelineId or installedAppVersionId, using isAppStoreApplication flag to identify between them
458-
if lastSyncTime.IsZero() || (!lastSyncTime.IsZero() && time.Since(lastSyncTime) > 5*time.Second) { // create new nats event
458+
if lastSyncTime.IsZero() || (!lastSyncTime.IsZero() && time.Since(lastSyncTime) > 5*time.Second) {
459+
// create new nats event
459460
err = impl.cdPipelineEventPublishService.PublishArgoTypePipelineSyncEvent(pipelineId, installedAppVersionId, userId, isAppStoreApplication)
460461
if err != nil {
461462
impl.logger.Errorw("error, PublishArgoTypePipelineSyncEvent", "err", err)

0 commit comments

Comments
 (0)