Skip to content

Commit 7cb7f7e

Browse files
fix: hibernating status is not being updated in app listing page (#5294)
1 parent 796ed6f commit 7cb7f7e

File tree

8 files changed

+144
-41
lines changed

8 files changed

+144
-41
lines changed

cmd/external-app/wire_gen.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/sql/repository/pipelineConfig/CdWorfkflowRepository.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type CdWorkflowRepository interface {
5454
FindWorkflowRunnerById(wfrId int) (*CdWorkflowRunner, error)
5555
FindRetriedWorkflowCountByReferenceId(wfrId int) (int, error)
5656
FindLatestWfrByAppIdAndEnvironmentId(appId int, environmentId int) (*CdWorkflowRunner, error)
57+
FindLastUnFailedProcessedRunner(appId int, environmentId int) (*CdWorkflowRunner, error)
5758
IsLatestCDWfr(pipelineId, wfrId int) (bool, error)
5859
FindLatestCdWorkflowRunnerByEnvironmentIdAndRunnerType(appId int, environmentId int, runnerType bean.WorkflowType) (CdWorkflowRunner, error)
5960
FindAllTriggeredWorkflowCountInLast24Hour() (cdWorkflowCount int, err error)
@@ -490,6 +491,27 @@ func (impl *CdWorkflowRepositoryImpl) FindLatestWfrByAppIdAndEnvironmentId(appId
490491
return wfr, nil
491492
}
492493

494+
func (impl *CdWorkflowRepositoryImpl) FindLastUnFailedProcessedRunner(appId int, environmentId int) (*CdWorkflowRunner, error) {
495+
wfr := &CdWorkflowRunner{}
496+
err := impl.dbConnection.
497+
Model(wfr).
498+
Column("cd_workflow_runner.*", "CdWorkflow.Pipeline.id", "CdWorkflow.Pipeline.deployment_app_delete_request", "CdWorkflow.Pipeline.deployment_app_type").
499+
Where("p.environment_id = ?", environmentId).
500+
Where("p.app_id = ?", appId).
501+
Where("cd_workflow_runner.workflow_type = ?", bean.CD_WORKFLOW_TYPE_DEPLOY).
502+
Where("cd_workflow_runner.status NOT IN (?)", pg.In([]string{WorkflowInitiated, WorkflowInQueue, WorkflowFailed})).
503+
Order("cd_workflow_runner.id DESC").
504+
Join("inner join cd_workflow wf on wf.id = cd_workflow_runner.cd_workflow_id").
505+
Join("inner join pipeline p on p.id = wf.pipeline_id").
506+
Limit(1).
507+
Select()
508+
if err != nil {
509+
return wfr, err
510+
}
511+
return wfr, nil
512+
513+
}
514+
493515
func (impl *CdWorkflowRepositoryImpl) IsLatestCDWfr(pipelineId, wfrId int) (bool, error) {
494516
wfr := &CdWorkflowRunner{}
495517
ifAnySuccessorWfrExists, err := impl.dbConnection.

internal/sql/repository/pipelineConfig/PipelineRepository.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -722,13 +722,21 @@ func (impl PipelineRepositoryImpl) FindDeploymentTypeByPipelineIds(cdPipelineIds
722722
pipelineIdsMap := make(map[int]DeploymentObject)
723723

724724
var deploymentType []DeploymentObject
725-
query := "with pcos as(select max(id) as id from pipeline_config_override where pipeline_id in (?) " +
726-
"group by pipeline_id) select pco.deployment_type,pco.pipeline_id, aps.status from pipeline_config_override " +
725+
//query := "with pcos as(select max(id) as id from pipeline_config_override where pipeline_id in (?) " +
726+
// "group by pipeline_id) select pco.deployment_type,pco.pipeline_id, aps.status from pipeline_config_override " +
727+
// "pco inner join pcos on pcos.id=pco.id" +
728+
// " inner join pipeline p on p.id=pco.pipeline_id left join app_status aps on aps.app_id=p.app_id " +
729+
// "and aps.env_id=p.environment_id;"
730+
query := " WITH pcos AS " +
731+
" (SELECT max(p.id) AS id FROM pipeline_config_override p " +
732+
" INNER JOIN cd_workflow_runner cdwr ON cdwr.cd_workflow_id = p.cd_workflow_id " +
733+
// pipeline ids deploy type initiated,queued,failed
734+
" WHERE p.pipeline_id in (?) AND cdwr.workflow_type = ? AND cdwr.status NOT IN (?) " +
735+
" GROUP BY p.pipeline_id) select pco.deployment_type,pco.pipeline_id, aps.status from pipeline_config_override " +
727736
"pco inner join pcos on pcos.id=pco.id" +
728737
" inner join pipeline p on p.id=pco.pipeline_id left join app_status aps on aps.app_id=p.app_id " +
729738
"and aps.env_id=p.environment_id;"
730-
731-
_, err := impl.dbConnection.Query(&deploymentType, query, pg.In(cdPipelineIds), true)
739+
_, err := impl.dbConnection.Query(&deploymentType, query, pg.In(cdPipelineIds), bean.CD_WORKFLOW_TYPE_DEPLOY, pg.In([]string{WorkflowInitiated, WorkflowInQueue, WorkflowFailed}))
732740
if err != nil {
733741
return pipelineIdsMap, err
734742
}

pkg/app/AppService.go

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@ import (
2020
"context"
2121
"encoding/json"
2222
"fmt"
23+
health2 "github.com/argoproj/gitops-engine/pkg/health"
2324
argoApplication "github.com/devtron-labs/devtron/client/argocdServer/bean"
25+
"github.com/devtron-labs/devtron/internal/sql/models"
2426
commonBean "github.com/devtron-labs/devtron/pkg/deployment/gitOps/common/bean"
2527
"github.com/devtron-labs/devtron/pkg/deployment/gitOps/config"
2628
"github.com/devtron-labs/devtron/pkg/deployment/gitOps/git"
2729
"github.com/devtron-labs/devtron/pkg/deployment/manifest/deploymentTemplate"
2830
bean4 "github.com/devtron-labs/devtron/pkg/deployment/trigger/devtronApps/bean"
31+
"github.com/pkg/errors"
2932
"io/ioutil"
3033
"net/url"
3134
"path"
@@ -117,6 +120,7 @@ type AppServiceImpl struct {
117120
gitOpsConfigReadService config.GitOpsConfigReadService
118121
gitOperationService git.GitOperationService
119122
deploymentTemplateService deploymentTemplate.DeploymentTemplateService
123+
appListingService AppListingService
120124
}
121125

122126
type AppService interface {
@@ -139,6 +143,7 @@ type AppService interface {
139143
GetDeployedManifestByPipelineIdAndCDWorkflowId(appId int, envId int, cdWorkflowId int, ctx context.Context) ([]byte, error)
140144
//SetPipelineFieldsInOverrideRequest(overrideRequest *bean.ValuesOverrideRequest, pipeline *pipelineConfig.Pipeline)
141145
GetActiveCiCdAppsCount() (int, error)
146+
ComputeAppstatus(appId, envId int, status health2.HealthStatusCode) (string, error)
142147
}
143148

144149
func NewAppService(
@@ -162,7 +167,8 @@ func NewAppService(
162167
installedAppVersionHistoryRepository repository4.InstalledAppVersionHistoryRepository,
163168
scopedVariableManager variables.ScopedVariableCMCSManager, acdConfig *argocdServer.ACDConfig,
164169
gitOpsConfigReadService config.GitOpsConfigReadService, gitOperationService git.GitOperationService,
165-
deploymentTemplateService deploymentTemplate.DeploymentTemplateService) *AppServiceImpl {
170+
deploymentTemplateService deploymentTemplate.DeploymentTemplateService,
171+
appListingService AppListingService) *AppServiceImpl {
166172
appServiceImpl := &AppServiceImpl{
167173
environmentConfigRepository: environmentConfigRepository,
168174
mergeUtil: mergeUtil,
@@ -192,6 +198,7 @@ func NewAppService(
192198
gitOpsConfigReadService: gitOpsConfigReadService,
193199
gitOperationService: gitOperationService,
194200
deploymentTemplateService: deploymentTemplateService,
201+
appListingService: appListingService,
195202
}
196203
return appServiceImpl
197204
}
@@ -263,6 +270,42 @@ func (impl *AppServiceImpl) UpdateDeploymentStatusAndCheckIsSucceeded(app *v1alp
263270
return isSucceeded, pipelineOverride, nil
264271
}
265272

273+
func (impl *AppServiceImpl) ComputeAppstatus(appId, envId int, status health2.HealthStatusCode) (string, error) {
274+
appStatusInternal := string(status)
275+
276+
// get the last accepted deploy type workflow runner, accepted state -> not in (initiated/queued/failed)
277+
cdWfr, err := impl.cdWorkflowRepository.FindLastUnFailedProcessedRunner(appId, envId)
278+
if err != nil {
279+
impl.logger.Errorw("error in getting latest wfr by appId and envId", "err", err, "appId", appId, "envId", envId)
280+
return "", err
281+
}
282+
283+
override, err := impl.pipelineOverrideRepository.FindLatestByCdWorkflowId(cdWfr.CdWorkflowId)
284+
if err != nil {
285+
impl.logger.Errorw("error in getting latest wfr by pipelineId", "cdWorkflowId", cdWfr.CdWorkflowId, "err", err)
286+
return "", err
287+
}
288+
289+
if errors.Is(err, pg.ErrNoRows) {
290+
// not deployed
291+
return appStatusInternal, nil
292+
}
293+
294+
// this is not stop/start type
295+
if override.DeploymentType != models.DEPLOYMENTTYPE_STOP && override.DeploymentType != models.DEPLOYMENTTYPE_START {
296+
return appStatusInternal, nil
297+
}
298+
299+
// for stop, then user requested for hibernate, then check for hibernation.
300+
IslastAcceptedReleaseIsStopRequest := models.DEPLOYMENTTYPE_STOP == override.DeploymentType
301+
// request essentially means that the previous state of the release was hibernation/partial hibernation
302+
303+
if IslastAcceptedReleaseIsStopRequest {
304+
appStatusInternal = appStatus.GetHibernationStatus(status)
305+
}
306+
return appStatusInternal, nil
307+
}
308+
266309
func (impl *AppServiceImpl) UpdateDeploymentStatusForGitOpsPipelines(app *v1alpha1.Application, statusTime time.Time, isAppStore bool) (bool, bool, *chartConfig.PipelineOverride, error) {
267310
isSucceeded := false
268311
isTimelineUpdated := false
@@ -296,7 +339,13 @@ func (impl *AppServiceImpl) UpdateDeploymentStatusForGitOpsPipelines(app *v1alph
296339
impl.logger.Errorw("error in getting latest timeline before update", "err", err, "cdWfrId", cdWfr.Id)
297340
return isSucceeded, isTimelineUpdated, pipelineOverride, err
298341
}
299-
err = impl.appStatusService.UpdateStatusWithAppIdEnvId(cdPipeline.AppId, cdPipeline.EnvironmentId, string(app.Status.Health.Status))
342+
343+
appStatusInternal, err := impl.ComputeAppstatus(cdPipeline.AppId, cdPipeline.EnvironmentId, app.Status.Health.Status)
344+
if err != nil {
345+
impl.logger.Errorw("error in checking if last release is stop type", "err", err, cdPipeline.AppId, "envId", cdPipeline.EnvironmentId)
346+
return isSucceeded, isTimelineUpdated, pipelineOverride, err
347+
}
348+
err = impl.appStatusService.UpdateStatusWithAppIdEnvId(cdPipeline.AppId, cdPipeline.EnvironmentId, appStatusInternal)
300349
if err != nil {
301350
impl.logger.Errorw("error occurred while updating app status in app_status table", "error", err, "appId", cdPipeline.AppId, "envId", cdPipeline.EnvironmentId)
302351
}

pkg/appStatus/AppStatusService.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package appStatus
1818

1919
import (
20+
"github.com/argoproj/gitops-engine/pkg/health"
2021
"github.com/devtron-labs/devtron/internal/sql/repository/appStatus"
2122
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
2223
"github.com/devtron-labs/devtron/util/rbac"
@@ -103,3 +104,11 @@ func (impl *AppStatusServiceImpl) DeleteWithAppIdEnvId(tx *pg.Tx, appId, envId i
103104
}
104105
return nil
105106
}
107+
108+
func GetHibernationStatus(status health.HealthStatusCode) string {
109+
switch status {
110+
case health.HealthStatusHealthy:
111+
return HealthStatusHibernatingFilter
112+
}
113+
return string(status)
114+
}

pkg/deployment/deployedApp/DeployedAppService.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package deployedApp
1919
import (
2020
"context"
2121
"encoding/json"
22+
"errors"
2223
"fmt"
2324
util5 "github.com/devtron-labs/common-lib/utils/k8s"
2425
bean2 "github.com/devtron-labs/devtron/api/bean"
@@ -29,6 +30,7 @@ import (
2930
"github.com/devtron-labs/devtron/pkg/deployment/trigger/devtronApps"
3031
bean3 "github.com/devtron-labs/devtron/pkg/deployment/trigger/devtronApps/bean"
3132
"github.com/devtron-labs/devtron/pkg/k8s"
33+
"github.com/go-pg/pg"
3234
"go.uber.org/zap"
3335
)
3436

@@ -81,6 +83,9 @@ func (impl *DeployedAppServiceImpl) StopStartApp(ctx context.Context, stopReques
8183
//FIXME
8284
}
8385
wf, err := impl.cdWorkflowRepository.FindLatestCdWorkflowByPipelineId(pipelineIds)
86+
if errors.Is(err, pg.ErrNoRows) {
87+
return 0, errors.New("no deployment history found,this app was never deployed")
88+
}
8489
if err != nil {
8590
impl.logger.Errorw("error in fetching latest release", "err", err)
8691
return 0, err

pkg/workflow/status/WorkflowStatusService.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ type WorkflowStatusServiceImpl struct {
8282
installedAppRepository repository3.InstalledAppRepository
8383
pipelineStatusTimelineRepository pipelineConfig.PipelineStatusTimelineRepository
8484
pipelineRepository pipelineConfig.PipelineRepository
85+
appListingService app.AppListingService
8586

8687
application application.ServiceClient
8788
}
@@ -103,7 +104,9 @@ func NewWorkflowStatusServiceImpl(logger *zap.SugaredLogger,
103104
installedAppRepository repository3.InstalledAppRepository,
104105
pipelineStatusTimelineRepository pipelineConfig.PipelineStatusTimelineRepository,
105106
pipelineRepository pipelineConfig.PipelineRepository,
106-
application application.ServiceClient) (*WorkflowStatusServiceImpl, error) {
107+
application application.ServiceClient,
108+
appListingService app.AppListingService,
109+
) (*WorkflowStatusServiceImpl, error) {
107110
impl := &WorkflowStatusServiceImpl{
108111
logger: logger,
109112
workflowDagExecutor: workflowDagExecutor,
@@ -125,6 +128,7 @@ func NewWorkflowStatusServiceImpl(logger *zap.SugaredLogger,
125128
pipelineStatusTimelineRepository: pipelineStatusTimelineRepository,
126129
pipelineRepository: pipelineRepository,
127130
application: application,
131+
appListingService: appListingService,
128132
}
129133
config, err := types.GetCdConfig()
130134
if err != nil {
@@ -263,11 +267,17 @@ func (impl *WorkflowStatusServiceImpl) UpdatePipelineTimelineAndStatusByLiveAppl
263267
}
264268
isSucceeded, isTimelineUpdated, pipelineOverride, err = impl.appService.UpdateDeploymentStatusForGitOpsPipelines(app, time.Now(), isAppStore)
265269
if err != nil {
266-
impl.logger.Errorw("error in updating deployment status for gitOps cd pipelines", "app", app)
270+
impl.logger.Errorw("error in updating deployment status for gitOps cd pipelines", "app", app, "err", err)
267271
return err, isTimelineUpdated
268272
}
269-
appStatus := app.Status.Health.Status
270-
err = impl.appStatusService.UpdateStatusWithAppIdEnvId(pipeline.AppId, pipeline.EnvironmentId, string(appStatus))
273+
274+
appStatus, err := impl.appService.ComputeAppstatus(pipeline.AppId, pipeline.EnvironmentId, app.Status.Health.Status)
275+
if err != nil {
276+
impl.logger.Errorw("error in checking if last release is stop type", "err", err, pipeline.AppId, "envId", pipeline.EnvironmentId)
277+
return err, isTimelineUpdated
278+
}
279+
280+
err = impl.appStatusService.UpdateStatusWithAppIdEnvId(pipeline.AppId, pipeline.EnvironmentId, appStatus)
271281
if err != nil {
272282
impl.logger.Errorw("error occurred while updating app-status for cd pipeline", "err", err, "appId", pipeline.AppId, "envId", pipeline.EnvironmentId)
273283
impl.logger.Debugw("ignoring the error, UpdateStatusWithAppIdEnvId", "err", err, "appId", pipeline.AppId, "envId", pipeline.EnvironmentId)

0 commit comments

Comments
 (0)