Skip to content

Commit f0d6fee

Browse files
fix: restart workloads fix in app group (#5313)
1 parent 7de572f commit f0d6fee

File tree

5 files changed

+110
-46
lines changed

5 files changed

+110
-46
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module github.com/devtron-labs/devtron
22

33
go 1.21
44

5-
toolchain go1.21.8
5+
//toolchain go1.21.8
66

77
require (
88
github.com/Masterminds/semver v1.5.0

pkg/deployment/manifest/deploymentTemplate/chartRef/ChartRefService.go

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package chartRef
1818

1919
import (
2020
"bytes"
21+
"context"
2122
"encoding/json"
2223
"errors"
2324
"fmt"
@@ -29,8 +30,10 @@ import (
2930
util2 "github.com/devtron-labs/devtron/util"
3031
dirCopy "github.com/otiai10/copy"
3132
"go.uber.org/zap"
33+
"golang.org/x/exp/maps"
3234
"io/ioutil"
3335
"k8s.io/helm/pkg/chartutil"
36+
chart2 "k8s.io/helm/pkg/proto/hapi/chart"
3437
"os"
3538
"path"
3639
"path/filepath"
@@ -70,19 +73,21 @@ type ChartRefFileOpService interface {
7073
GetRefChart(chartRefId int) (string, string, string, string, error)
7174
ExtractChartIfMissing(chartData []byte, refChartDir string, location string) (*bean.ChartDataInfo, error)
7275
GetChartInBytes(chartRefId int, deleteChart bool) ([]byte, error)
73-
GetChartBytesInBulk(chartRefIds []int, deleteChart bool) (map[int][]byte, error)
76+
GetChartBytesForApps(ctx context.Context, appIdToAppName map[int]string) (map[int][]byte, error)
7477
}
7578

7679
type ChartRefServiceImpl struct {
7780
logger *zap.SugaredLogger
7881
chartRefRepository chartRepoRepository.ChartRefRepository
7982
chartTemplateService util.ChartTemplateService
8083
mergeUtil util.MergeUtil
84+
chartRepository chartRepoRepository.ChartRepository
8185
}
8286

8387
func NewChartRefServiceImpl(logger *zap.SugaredLogger,
8488
chartRefRepository chartRepoRepository.ChartRefRepository,
8589
chartTemplateService util.ChartTemplateService,
90+
chartRepository chartRepoRepository.ChartRepository,
8691
mergeUtil util.MergeUtil) *ChartRefServiceImpl {
8792
// cache devtron reference charts list
8893
devtronChartList, _ := chartRefRepository.FetchAllNonUserUploadedChartInfo()
@@ -92,6 +97,7 @@ func NewChartRefServiceImpl(logger *zap.SugaredLogger,
9297
chartRefRepository: chartRefRepository,
9398
chartTemplateService: chartTemplateService,
9499
mergeUtil: mergeUtil,
100+
chartRepository: chartRepository,
95101
}
96102
}
97103

@@ -309,23 +315,83 @@ func (impl *ChartRefServiceImpl) extractChartInBytes(chartRef *chartRepoReposito
309315
}
310316
return manifestByteArr, nil
311317
}
312-
func (impl *ChartRefServiceImpl) GetChartBytesInBulk(chartRefIds []int, performCleanup bool) (map[int][]byte, error) {
318+
319+
func (impl *ChartRefServiceImpl) getChartPath(chartRef *chartRepoRepository.ChartRef) (string, error) {
320+
refChartPath := filepath.Join(bean.RefChartDirPath, chartRef.Location)
321+
// For user uploaded charts ChartData will be retrieved from DB
322+
if chartRef.ChartData != nil {
323+
chartInfo, err := impl.ExtractChartIfMissing(chartRef.ChartData, bean.RefChartDirPath, chartRef.Location)
324+
if chartInfo != nil && chartInfo.TemporaryFolder != "" {
325+
err1 := os.RemoveAll(chartInfo.TemporaryFolder)
326+
if err1 != nil {
327+
impl.logger.Errorw("error in deleting temp dir ", "err", err)
328+
}
329+
}
330+
} else {
331+
// For Devtron reference charts the chart will be load from the directory location
332+
}
333+
return refChartPath, nil
334+
}
335+
336+
func (impl *ChartRefServiceImpl) GetChartBytesForApps(ctx context.Context, appIdToAppName map[int]string) (map[int][]byte, error) {
337+
338+
appIds := maps.Keys(appIdToAppName)
339+
charts, err := impl.chartRepository.FindLatestChartByAppIds(appIds)
340+
if err != nil {
341+
impl.logger.Errorw("error in fetching chart", "err", err, "appIds", appIds)
342+
return nil, err
343+
}
344+
345+
chartRefIdTOAppIds := make(map[int][]int)
346+
var chartRefIds []int
347+
chartRefToChartVersion := make(map[int]string)
348+
349+
for _, chart := range charts {
350+
chartRefIds = append(chartRefIds, chart.ChartRefId)
351+
chartRefToChartVersion[chart.ChartRefId] = chart.ChartVersion
352+
refAppIds, ok := chartRefIdTOAppIds[chart.ChartRefId]
353+
if !ok {
354+
refAppIds = make([]int, 0)
355+
}
356+
refAppIds = append(refAppIds, chart.AppId)
357+
chartRefIdTOAppIds[chart.ChartRefId] = refAppIds
358+
}
359+
313360
chartRefs, err := impl.chartRefRepository.FindByIds(chartRefIds)
314361
if err != nil {
315362
impl.logger.Errorw("error getting chart data", "chartRefIds", chartRefIds, "err", err)
316363
return nil, err
317364
}
318-
chartRefIdToBytes := make(map[int][]byte)
365+
366+
appIdToBytes := make(map[int][]byte)
367+
368+
// this loops run with O(len(apps)) T.C
319369
for _, chartRef := range chartRefs {
320-
chartInBytes, err := impl.extractChartInBytes(chartRef, performCleanup)
370+
refChartPath, err := impl.getChartPath(chartRef)
321371
if err != nil {
322372
impl.logger.Errorw("error in converting chart to bytes", "chartRefId", chartRef.Id, "err", err)
323373
return nil, err
324374
}
325-
chartRefIdToBytes[chartRef.Id] = chartInBytes
375+
376+
refAppIds := chartRefIdTOAppIds[chartRef.Id]
377+
for _, appId := range refAppIds {
378+
chartMetaData := &chart2.Metadata{
379+
Name: appIdToAppName[appId],
380+
Version: chartRefToChartVersion[chartRef.Id],
381+
}
382+
tempReferenceTemplateDir, err := impl.chartTemplateService.BuildChart(ctx, chartMetaData, refChartPath)
383+
if err != nil {
384+
impl.logger.Errorw("error in building chart", "chartMetaData", chartMetaData, "refChartPath", refChartPath)
385+
return nil, err
386+
}
387+
chartInBytes, err := impl.chartTemplateService.LoadChartInBytes(tempReferenceTemplateDir, true)
388+
appIdToBytes[appId] = chartInBytes
389+
}
390+
326391
}
327-
return chartRefIdToBytes, nil
392+
return appIdToBytes, nil
328393
}
394+
329395
func (impl *ChartRefServiceImpl) FetchCustomChartsInfo() ([]*bean.ChartDto, error) {
330396
resultsMetadata, err := impl.chartRefRepository.GetAllChartMetadata()
331397
if err != nil {

pkg/generateManifest/DeploymentTemplateService.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import (
4646
"github.com/gammazero/workerpool"
4747
"github.com/go-pg/pg"
4848
"go.uber.org/zap"
49+
"golang.org/x/exp/maps"
4950
"net/http"
5051
"os"
5152
"regexp"
@@ -422,6 +423,12 @@ func (impl DeploymentTemplateServiceImpl) GetRestartWorkloadData(ctx context.Con
422423
var finalError error
423424
for i, _ := range partitionedRequests {
424425
req := partitionedRequests[i]
426+
err = impl.setChartContent(ctx, req, appNameToId)
427+
if err != nil {
428+
impl.Logger.Errorw("error in setting chart content for apps", "appNames", maps.Keys(appNameToId), "err", err)
429+
// continue processing next batch
430+
continue
431+
}
425432
wp.Submit(func() {
426433
resp, err := impl.helmAppClient.TemplateChartBulk(ctx, &gRPC.BulkInstallReleaseRequest{BulkInstallReleaseRequest: req})
427434
if err != nil {

pkg/generateManifest/helper.go

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@
1717
package generateManifest
1818

1919
import (
20+
"context"
2021
"fmt"
2122
"github.com/devtron-labs/common-lib/utils/yaml"
2223
"github.com/devtron-labs/devtron/api/helm-app/bean"
2324
"github.com/devtron-labs/devtron/api/helm-app/gRPC"
2425
"github.com/devtron-labs/devtron/internal/sql/repository/app"
2526
"github.com/devtron-labs/devtron/pkg/cluster/repository"
27+
"go.opentelemetry.io/otel"
28+
"golang.org/x/exp/maps"
2629
)
2730

2831
func (impl DeploymentTemplateServiceImpl) constructRotatePodResponse(templateChartResponse []*gRPC.TemplateChartResponse, appNameToId map[string]int, environment *repository.Environment) (*RestartPodResponse, error) {
@@ -37,23 +40,15 @@ func (impl DeploymentTemplateServiceImpl) constructRotatePodResponse(templateCha
3740
for _, manifest := range manifests {
3841
gvk := manifest.GroupVersionKind()
3942
name := manifest.GetName()
40-
labels := manifest.GetLabels()
4143
switch gvk.Kind {
4244
case string(Deployment), string(StatefulSet), string(DemonSet), string(Rollout):
43-
if labels != nil && labels[LabelReleaseKey] != "" {
44-
resourceMeta = append(resourceMeta, &ResourceMetadata{
45-
Name: labels[LabelReleaseKey],
46-
GroupVersionKind: gvk,
47-
})
48-
} else {
49-
resourceMeta = append(resourceMeta, &ResourceMetadata{
50-
Name: name,
51-
GroupVersionKind: gvk,
52-
})
53-
}
54-
45+
resourceMeta = append(resourceMeta, &ResourceMetadata{
46+
Name: name,
47+
GroupVersionKind: gvk,
48+
})
5549
}
5650
}
51+
5752
appIdToResourceIdentifier[appNameToId[tcResp.AppName]] = &ResourceIdentifierResponse{
5853
ResourceMetaData: resourceMeta,
5954
AppName: appName,
@@ -91,10 +86,12 @@ func (impl DeploymentTemplateServiceImpl) constructInstallReleaseBulkReq(apps []
9186
if appIdToInstallReleaseRequest == nil || len(appIdToInstallReleaseRequest) == 0 {
9287
return nil, err
9388
}
94-
err = impl.setChartContent(applicationIds, appIdToInstallReleaseRequest)
95-
if err != nil {
96-
impl.Logger.Errorw("error in setting chart content", "appIds", applicationIds, "err", err)
97-
return nil, err
89+
90+
for _, app := range apps {
91+
if _, ok := appIdToInstallReleaseRequest[app.Id]; ok {
92+
appIdToInstallReleaseRequest[app.Id].AppName = app.AppName
93+
appIdToInstallReleaseRequest[app.Id].ChartRepository = ChartRepository
94+
}
9895
}
9996

10097
k8sServerVersion, err := impl.K8sUtil.GetKubeVersion()
@@ -111,8 +108,6 @@ func (impl DeploymentTemplateServiceImpl) constructInstallReleaseBulkReq(apps []
111108
if _, ok := appIdToInstallReleaseRequest[app.Id]; ok {
112109
appIdToInstallReleaseRequest[app.Id].ReleaseIdentifier = impl.getReleaseIdentifier(config, app, environment)
113110
appIdToInstallReleaseRequest[app.Id].K8SVersion = k8sServerVersion.String()
114-
appIdToInstallReleaseRequest[app.Id].AppName = app.AppName
115-
appIdToInstallReleaseRequest[app.Id].ChartRepository = ChartRepository
116111
}
117112
}
118113

@@ -122,30 +117,26 @@ func (impl DeploymentTemplateServiceImpl) constructInstallReleaseBulkReq(apps []
122117
return installReleaseRequests, nil
123118
}
124119

125-
func (impl DeploymentTemplateServiceImpl) setChartContent(appIds []int, appIdToInstallReleaseRequest map[int]*gRPC.InstallReleaseRequest) error {
126-
charts, err := impl.chartRepository.FindLatestChartByAppIds(appIds)
127-
if err != nil {
128-
impl.Logger.Errorw("error in fetching chart", "err", err, "appIds", appIds)
129-
return err
130-
}
131-
appIdToChartRefId := make(map[int]int)
132-
var chartRefIds []int
133-
for _, chart := range charts {
134-
appIdToChartRefId[chart.AppId] = chart.ChartRefId
135-
chartRefIds = append(chartRefIds, chart.ChartRefId)
120+
func (impl DeploymentTemplateServiceImpl) setChartContent(ctx context.Context, installReleaseRequests []*gRPC.InstallReleaseRequest, appNameToId map[string]int) error {
121+
appIdToInstallReleaseRequest := make(map[int]*gRPC.InstallReleaseRequest)
122+
requestAppNameToId := make(map[int]string)
123+
for _, req := range installReleaseRequests {
124+
appId := appNameToId[req.AppName]
125+
requestAppNameToId[appId] = req.AppName
126+
appIdToInstallReleaseRequest[appId] = req
136127
}
137-
chartRefIdToBytes, err := impl.chartRefService.GetChartBytesInBulk(chartRefIds, false)
128+
129+
_, span := otel.Tracer("orchestrator").Start(ctx, "chartRefService.GetChartBytesForApps")
130+
appIdToBytes, err := impl.chartRefService.GetChartBytesForApps(ctx, requestAppNameToId)
131+
span.End()
138132
if err != nil {
139-
impl.Logger.Errorw("error in fetching chartRefBean", "err", err, "chartRefIds", chartRefIds)
133+
impl.Logger.Errorw("error in fetching chartRefBean", "err", err, "appNames", maps.Keys(appNameToId))
140134
return err
141135
}
142-
for appId, chartRefId := range appIdToChartRefId {
143-
if bytes, ok := chartRefIdToBytes[chartRefId]; ok {
144-
if _, ok := appIdToInstallReleaseRequest[appId]; ok {
145-
appIdToInstallReleaseRequest[appId].ChartContent = &gRPC.ChartContent{Content: bytes}
146-
}
147-
}
136+
for appId, _ := range appIdToInstallReleaseRequest {
137+
appIdToInstallReleaseRequest[appId].ChartContent = &gRPC.ChartContent{Content: appIdToBytes[appId]}
148138
}
139+
149140
return err
150141
}
151142

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.

0 commit comments

Comments
 (0)