@@ -31,6 +31,7 @@ import (
31
31
repository2 "github.com/devtron-labs/devtron/pkg/cluster/environment/repository"
32
32
"github.com/devtron-labs/devtron/pkg/config/read"
33
33
v1 "github.com/devtron-labs/devtron/pkg/infraConfig/bean/v1"
34
+ infraConfigAudit "github.com/devtron-labs/devtron/pkg/infraConfig/service/audit"
34
35
k8s2 "github.com/devtron-labs/devtron/pkg/k8s"
35
36
"github.com/devtron-labs/devtron/pkg/pipeline"
36
37
bean3 "github.com/devtron-labs/devtron/pkg/pipeline/bean"
@@ -42,6 +43,7 @@ import (
42
43
"github.com/devtron-labs/devtron/pkg/workflow/trigger/audit/hook"
43
44
"go.uber.org/zap"
44
45
v12 "k8s.io/api/core/v1"
46
+ "k8s.io/apimachinery/pkg/api/resource"
45
47
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
46
48
"k8s.io/client-go/rest"
47
49
"net/http"
@@ -63,19 +65,20 @@ type WorkflowService interface {
63
65
}
64
66
65
67
type WorkflowServiceImpl struct {
66
- Logger * zap.SugaredLogger
67
- config * rest.Config
68
- ciCdConfig * types.CiCdConfig
69
- configMapService read.ConfigReadService
70
- envRepository repository2.EnvironmentRepository
71
- globalCMCSService pipeline.GlobalCMCSService
72
- argoWorkflowExecutor executors.ArgoWorkflowExecutor
73
- systemWorkflowExecutor executors.SystemWorkflowExecutor
74
- k8sCommonService k8s2.K8sCommonService
75
- infraProvider infraProviders.InfraProvider
76
- ucid ucid.Service
77
- k8sUtil * k8s.K8sServiceImpl
78
- triggerAuditHook hook.TriggerAuditHook
68
+ Logger * zap.SugaredLogger
69
+ config * rest.Config
70
+ ciCdConfig * types.CiCdConfig
71
+ configMapService read.ConfigReadService
72
+ envRepository repository2.EnvironmentRepository
73
+ globalCMCSService pipeline.GlobalCMCSService
74
+ argoWorkflowExecutor executors.ArgoWorkflowExecutor
75
+ systemWorkflowExecutor executors.SystemWorkflowExecutor
76
+ k8sCommonService k8s2.K8sCommonService
77
+ infraProvider infraProviders.InfraProvider
78
+ ucid ucid.Service
79
+ k8sUtil * k8s.K8sServiceImpl
80
+ triggerAuditHook hook.TriggerAuditHook
81
+ infraConfigAuditService infraConfigAudit.InfraConfigAuditService
79
82
}
80
83
81
84
// TODO: Move to bean
@@ -92,20 +95,22 @@ func NewWorkflowServiceImpl(Logger *zap.SugaredLogger,
92
95
ucid ucid.Service ,
93
96
k8sUtil * k8s.K8sServiceImpl ,
94
97
triggerAuditHook hook.TriggerAuditHook ,
98
+ infraConfigAuditService infraConfigAudit.InfraConfigAuditService ,
95
99
) (* WorkflowServiceImpl , error ) {
96
100
commonWorkflowService := & WorkflowServiceImpl {
97
- Logger : Logger ,
98
- ciCdConfig : ciCdConfig ,
99
- configMapService : configMapService ,
100
- envRepository : envRepository ,
101
- globalCMCSService : globalCMCSService ,
102
- argoWorkflowExecutor : argoWorkflowExecutor ,
103
- k8sUtil : k8sUtil ,
104
- systemWorkflowExecutor : systemWorkflowExecutor ,
105
- k8sCommonService : k8sCommonService ,
106
- infraProvider : infraProvider ,
107
- ucid : ucid ,
108
- triggerAuditHook : triggerAuditHook ,
101
+ Logger : Logger ,
102
+ ciCdConfig : ciCdConfig ,
103
+ configMapService : configMapService ,
104
+ envRepository : envRepository ,
105
+ globalCMCSService : globalCMCSService ,
106
+ argoWorkflowExecutor : argoWorkflowExecutor ,
107
+ k8sUtil : k8sUtil ,
108
+ systemWorkflowExecutor : systemWorkflowExecutor ,
109
+ k8sCommonService : k8sCommonService ,
110
+ infraProvider : infraProvider ,
111
+ ucid : ucid ,
112
+ triggerAuditHook : triggerAuditHook ,
113
+ infraConfigAuditService : infraConfigAuditService ,
109
114
}
110
115
restConfig , err := k8sUtil .GetK8sInClusterRestConfig ()
111
116
if err != nil {
@@ -255,6 +260,17 @@ func (impl *WorkflowServiceImpl) createWorkflowTemplateAndAuditTrigger(workflowR
255
260
return bean3.WorkflowTemplate {}, err
256
261
}
257
262
workflowTemplate .DevtronInstanceUID = devtronUCID
263
+
264
+ if workflowRequest .IsCiTypeWorkflowRequest () && workflowRequest .IsCiRetriggerType () {
265
+ // here we need to update the workflow template with cpu request and limit, memory limit and request and Build timeout (in oss this is applicable on all ci builds i.e. applied globally)
266
+ err = impl .updateWorkflowTemplateWithInfraConfigFromHistory (workflowRequest , & workflowTemplate )
267
+ if err != nil {
268
+ impl .Logger .Errorw ("error occurred while updating workflow template with infra config from history" , "err" , err )
269
+ return bean3.WorkflowTemplate {}, err
270
+ }
271
+
272
+ }
273
+
258
274
return workflowTemplate , nil
259
275
}
260
276
@@ -507,3 +523,99 @@ func (impl *WorkflowServiceImpl) getWfClient(environment *repository2.Environmen
507
523
}
508
524
return wfClient , nil
509
525
}
526
+
527
+ // updateWorkflowTemplateWithInfraConfigFromHistory updates the workflow template with CPU, memory limits/requests and timeout
528
+ // from the infra_config_trigger_history table based on previous workflow ID.
529
+ func (impl * WorkflowServiceImpl ) updateWorkflowTemplateWithInfraConfigFromHistory (workflowRequest * types.WorkflowRequest , workflowTemplate * bean3.WorkflowTemplate ) error {
530
+ // Skip if no previous workflow ID is available or if this is not a CI/Job workflow
531
+ if workflowRequest .ReferenceCiWorkflowId == 0 {
532
+ impl .Logger .Debugw ("skipping infra config history update" , "referenceWorkflowId" , workflowRequest .ReferenceCiWorkflowId , "workflowType" , workflowRequest .Type )
533
+ return nil
534
+ }
535
+
536
+ // Get infra config from history based on previous workflow ID
537
+ historicalInfraConfig , err := impl .infraConfigAuditService .GetInfraConfigByWorkflowId (workflowRequest .ReferenceCiWorkflowId , bean .CI_WORKFLOW_TYPE .String ())
538
+ if err != nil {
539
+ impl .Logger .Warnw ("could not retrieve infra config from history, using current config" , "referenceWorkflowId" , workflowRequest .ReferenceCiWorkflowId , "err" , err )
540
+ return nil // Don't fail the workflow, just use current config
541
+ }
542
+
543
+ if historicalInfraConfig == nil {
544
+ impl .Logger .Debugw ("no historical infra config found, using current config" , "referenceWorkflowId" , workflowRequest .ReferenceCiWorkflowId )
545
+ return nil
546
+ }
547
+
548
+ impl .Logger .Infow ("applying historical infra config to workflow template" , "referenceWorkflowId" , workflowRequest .ReferenceCiWorkflowId , "historicalConfig" , historicalInfraConfig )
549
+
550
+ // apply historical infra configurations to a workflow template
551
+ impl .applyInfraConfigToWorkflowTemplate (workflowRequest , workflowTemplate , historicalInfraConfig )
552
+
553
+ return nil
554
+ }
555
+
556
+ // applyInfraConfigToWorkflowTemplate applies the historical infra configuration to the workflow template.
557
+ // This function handles the core OSS functionality and can be extended in enterprise for additional fields.
558
+ func (impl * WorkflowServiceImpl ) applyInfraConfigToWorkflowTemplate (workflowRequest * types.WorkflowRequest , workflowTemplate * bean3.WorkflowTemplate , infraConfig * v1.InfraConfig ) {
559
+ // Apply timeout configuration
560
+ if infraConfig .GetCiDefaultTimeout () > 0 {
561
+ timeout := infraConfig .GetCiTimeoutInt ()
562
+ workflowTemplate .SetActiveDeadlineSeconds (timeout )
563
+ impl .Logger .Debugw ("applied historical timeout to workflow template" , "timeout" , timeout , "workflowId" , workflowRequest .WorkflowId )
564
+ }
565
+
566
+ // Apply CPU and memory resource configurations to the main container
567
+ if len (workflowTemplate .Containers ) > 0 {
568
+ container := & workflowTemplate .Containers [0 ]
569
+
570
+ // Initialize resources if not present
571
+ if container .Resources .Limits == nil {
572
+ container .Resources .Limits = make (v12.ResourceList )
573
+ }
574
+ if container .Resources .Requests == nil {
575
+ container .Resources .Requests = make (v12.ResourceList )
576
+ }
577
+
578
+ // Apply CPU limits and requests
579
+ if infraConfig .GetCiLimitCpu () != "" {
580
+ if cpuLimit , err := resource .ParseQuantity (infraConfig .GetCiLimitCpu ()); err == nil {
581
+ container .Resources .Limits [v12 .ResourceCPU ] = cpuLimit
582
+ impl .Logger .Debugw ("applied historical CPU limit to workflow template" , "cpuLimit" , infraConfig .GetCiLimitCpu (), "workflowId" , workflowRequest .WorkflowId )
583
+ } else {
584
+ impl .Logger .Warnw ("failed to parse CPU limit from historical config" , "cpuLimit" , infraConfig .GetCiLimitCpu (), "err" , err )
585
+ }
586
+ }
587
+ if infraConfig .GetCiReqCpu () != "" {
588
+ if cpuRequest , err := resource .ParseQuantity (infraConfig .GetCiReqCpu ()); err == nil {
589
+ container .Resources .Requests [v12 .ResourceCPU ] = cpuRequest
590
+ impl .Logger .Debugw ("applied historical CPU request to workflow template" , "cpuRequest" , infraConfig .GetCiReqCpu (), "workflowId" , workflowRequest .WorkflowId )
591
+ } else {
592
+ impl .Logger .Warnw ("failed to parse CPU request from historical config" , "cpuRequest" , infraConfig .GetCiReqCpu (), "err" , err )
593
+ }
594
+ }
595
+
596
+ // Apply memory limits and requests
597
+ if infraConfig .GetCiLimitMem () != "" {
598
+ if memoryLimit , err := resource .ParseQuantity (infraConfig .GetCiLimitMem ()); err == nil {
599
+ container .Resources .Limits [v12 .ResourceMemory ] = memoryLimit
600
+ impl .Logger .Debugw ("applied historical memory limit to workflow template" , "memoryLimit" , infraConfig .GetCiLimitMem (), "workflowId" , workflowRequest .WorkflowId )
601
+ } else {
602
+ impl .Logger .Warnw ("failed to parse memory limit from historical config" , "memoryLimit" , infraConfig .GetCiLimitMem (), "err" , err )
603
+ }
604
+ }
605
+ if infraConfig .GetCiReqMem () != "" {
606
+ if memoryRequest , err := resource .ParseQuantity (infraConfig .GetCiReqMem ()); err == nil {
607
+ container .Resources .Requests [v12 .ResourceMemory ] = memoryRequest
608
+ impl .Logger .Debugw ("applied historical memory request to workflow template" , "memoryRequest" , infraConfig .GetCiReqMem (), "workflowId" , workflowRequest .WorkflowId )
609
+ } else {
610
+ impl .Logger .Warnw ("failed to parse memory request from historical config" , "memoryRequest" , infraConfig .GetCiReqMem (), "err" , err )
611
+ }
612
+ }
613
+ }
614
+
615
+ impl .applyEnterpriseInfraConfigToWorkflowTemplate (workflowRequest , workflowTemplate , infraConfig )
616
+ }
617
+
618
+ // applyEnterpriseInfraConfigToWorkflowTemplate is a placeholder for enterprise-specific infra config application.
619
+ func (impl * WorkflowServiceImpl ) applyEnterpriseInfraConfigToWorkflowTemplate (workflowRequest * types.WorkflowRequest , workflowTemplate * bean3.WorkflowTemplate , infraConfig * v1.InfraConfig ) {
620
+ impl .Logger .Debugw ("enterprise infra config application (no-op in OSS)" , "workflowId" , workflowRequest .WorkflowId )
621
+ }
0 commit comments