@@ -5,10 +5,12 @@ import (
55 "context"
66 "encoding/json"
77 "fmt"
8+ "io/ioutil"
89 "os"
910 "path/filepath"
1011 "strings"
1112
13+ "github.com/otiai10/copy"
1214 "github.com/pkg/errors"
1315 uuid "github.com/satori/go.uuid"
1416 "helm.sh/helm/v3/pkg/chart"
@@ -20,13 +22,14 @@ import (
2022
2123 "github.com/werf/lockgate"
2224 "github.com/werf/logboek"
25+ "github.com/werf/logboek/pkg/types"
2326 "github.com/werf/werf/pkg/deploy/helm/command_helpers"
2427 "github.com/werf/werf/pkg/util"
2528 "github.com/werf/werf/pkg/werf"
2629)
2730
28- func GetChartDependenciesCacheDir (lockChecksum string ) string {
29- return filepath .Join (werf .GetLocalCacheDir (), "helm_chart_dependencies" , "1" , lockChecksum )
31+ func GetChartDependenciesCacheDir () string {
32+ return filepath .Join (werf .GetLocalCacheDir (), "helm_chart_dependencies" , "1" )
3033}
3134
3235func LoadMetadata (files []* chart.ChartExtenderBufferedFile ) (* chart.Metadata , error ) {
@@ -60,14 +63,54 @@ func LoadMetadata(files []*chart.ChartExtenderBufferedFile) (*chart.Metadata, er
6063 return metadata , nil
6164}
6265
63- func GetPreparedChartDependenciesDir (ctx context.Context , metadataFile , metadataLockFile * chart.ChartExtenderBufferedFile , helmEnvSettings * cli.EnvSettings , registryClient * registry.Client , buildChartDependenciesOpts command_helpers.BuildChartDependenciesOptions ) (string , error ) {
64- depsDir := GetChartDependenciesCacheDir (util .Sha256Hash (string (metadataLockFile .Data )))
66+ func CopyChartDependenciesIntoCache (ctx context.Context , chartDir string , ch * chart.Chart ) error {
67+ metadataBytes , err := yaml .Marshal (ch .Metadata )
68+ if err != nil {
69+ return fmt .Errorf ("unable to marshal chart metadata into yaml: %w" , err )
70+ }
71+
72+ metadataLockBytes , err := yaml .Marshal (ch .Lock )
73+ if err != nil {
74+ return fmt .Errorf ("unable to marshal chart metadata lock into yaml: %w" , err )
75+ }
76+
77+ _ , err = prepareDependenciesDir (ctx , metadataBytes , metadataLockBytes , func (tmpDepsDir string ) error {
78+ var archivesDependencies []* chart.File
79+
80+ FindArchivesDependencies:
81+ for _ , f := range ch .Raw {
82+ if strings .HasPrefix (f .Name , "charts/" ) {
83+ for _ , depLock := range ch .Lock .Dependencies {
84+ if filepath .Base (f .Name ) == MakeDependencyArchiveName (depLock .Name , depLock .Version ) {
85+ archivesDependencies = append (archivesDependencies , f )
86+ continue FindArchivesDependencies
87+ }
88+ }
89+ }
90+ }
91+
92+ for _ , depArch := range archivesDependencies {
93+ srcPath := filepath .Join (chartDir , depArch .Name )
94+ destPath := filepath .Join (tmpDepsDir , depArch .Name )
95+ if err := copy .Copy (srcPath , destPath ); err != nil {
96+ return fmt .Errorf ("unable to copy %q into cache %q: %w" , srcPath , tmpDepsDir , err )
97+ }
98+ }
99+
100+ return nil
101+ }, logboek .Context (ctx ).Info ())
102+
103+ return err
104+ }
105+
106+ func prepareDependenciesDir (ctx context.Context , metadataBytes , metadataLockBytes []byte , prepareFunc func (tmpDepsDir string ) error , logger types.ManagerInterface ) (string , error ) {
107+ depsDir := filepath .Join (GetChartDependenciesCacheDir (), util .Sha256Hash (string (metadataLockBytes )))
65108
66109 _ , err := os .Stat (depsDir )
67110 switch {
68111 case os .IsNotExist (err ):
69- if err := logboek . Context ( ctx ). Default (). LogProcess ("Building chart dependencies" ).DoError (func () error {
70- logboek . Context ( ctx ). Default () .LogF ("Using chart dependencies directory: %s\n " , depsDir )
112+ if err := logger . LogProcess ("Preparing chart dependencies" ).DoError (func () error {
113+ logger .LogF ("Using chart dependencies directory: %s\n " , depsDir )
71114 _ , lock , err := werf .AcquireHostLock (ctx , depsDir , lockgate.AcquireOptions {})
72115 if err != nil {
73116 return fmt .Errorf ("error acquiring lock for %q: %w" , depsDir , err )
@@ -85,32 +128,67 @@ func GetPreparedChartDependenciesDir(ctx context.Context, metadataFile, metadata
85128
86129 tmpDepsDir := fmt .Sprintf ("%s.tmp.%s" , depsDir , uuid .NewV4 ().String ())
87130
88- buildChartDependenciesOpts .LoadOptions = & loader.LoadOptions {
89- ChartExtender : NewWerfChartStub (ctx , buildChartDependenciesOpts .IgnoreInvalidAnnotationsAndLabels ),
90- SubchartExtenderFactoryFunc : nil ,
131+ if err := createChartDependenciesDir (tmpDepsDir , metadataBytes , metadataLockBytes ); err != nil {
132+ return err
91133 }
92134
93- if err := command_helpers . BuildChartDependenciesInDir ( ctx , metadataFile , metadataLockFile , tmpDepsDir , helmEnvSettings , registryClient , buildChartDependenciesOpts ); err != nil {
94- return fmt . Errorf ( "error building chart dependencies: %w" , err )
135+ if err := prepareFunc ( tmpDepsDir ); err != nil {
136+ return err
95137 }
96138
97139 if err := os .Rename (tmpDepsDir , depsDir ); err != nil {
98140 return fmt .Errorf ("error renaming %q to %q: %w" , tmpDepsDir , depsDir , err )
99141 }
100-
101142 return nil
102143 }); err != nil {
103144 return "" , err
104145 }
105146 case err != nil :
106147 return "" , fmt .Errorf ("error accessing %q: %w" , depsDir , err )
107148 default :
108- logboek . Context ( ctx ). Default () .LogF ("Using cached chart dependencies directory: %s\n " , depsDir )
149+ logger .LogF ("Using cached chart dependencies directory: %s\n " , depsDir )
109150 }
110151
111152 return depsDir , nil
112153}
113154
155+ func createChartDependenciesDir (destDir string , metadataBytes , metadataLockBytes []byte ) error {
156+ if err := os .MkdirAll (destDir , os .ModePerm ); err != nil {
157+ return fmt .Errorf ("error creating dir %q: %w" , destDir , err )
158+ }
159+
160+ files := []* chart.ChartExtenderBufferedFile {
161+ {Name : "Chart.yaml" , Data : metadataBytes },
162+ {Name : "Chart.lock" , Data : metadataLockBytes },
163+ }
164+
165+ for _ , file := range files {
166+ if file == nil {
167+ continue
168+ }
169+
170+ path := filepath .Join (destDir , file .Name )
171+ if err := ioutil .WriteFile (path , file .Data , 0o644 ); err != nil {
172+ return fmt .Errorf ("error writing %q: %w" , path , err )
173+ }
174+ }
175+
176+ return nil
177+ }
178+
179+ func GetPreparedChartDependenciesDir (ctx context.Context , metadataFile , metadataLockFile * chart.ChartExtenderBufferedFile , helmEnvSettings * cli.EnvSettings , registryClient * registry.Client , buildChartDependenciesOpts command_helpers.BuildChartDependenciesOptions ) (string , error ) {
180+ return prepareDependenciesDir (ctx , metadataFile .Data , metadataLockFile .Data , func (tmpDepsDir string ) error {
181+ buildChartDependenciesOpts .LoadOptions = & loader.LoadOptions {
182+ ChartExtender : NewWerfChartStub (ctx , buildChartDependenciesOpts .IgnoreInvalidAnnotationsAndLabels ),
183+ SubchartExtenderFactoryFunc : nil ,
184+ }
185+ if err := command_helpers .BuildChartDependenciesInDir (ctx , tmpDepsDir , helmEnvSettings , registryClient , buildChartDependenciesOpts ); err != nil {
186+ return fmt .Errorf ("error building chart dependencies: %w" , err )
187+ }
188+ return nil
189+ }, logboek .Context (ctx ).Default ())
190+ }
191+
114192type ChartDependenciesConfiguration struct {
115193 ChartMetadata * chart.Metadata
116194 ChartMetadataLock * chart.Lock
@@ -142,7 +220,7 @@ func (conf *ChartDependenciesConfiguration) GetExternalDependenciesFiles(loadedC
142220 metadata .APIVersion = "v2"
143221
144222 var externalDependenciesNames []string
145- var isExternalDependency = func (depName string ) bool {
223+ isExternalDependency : = func (depName string ) bool {
146224 for _ , externalDepName := range externalDependenciesNames {
147225 if depName == externalDepName {
148226 return true
@@ -159,7 +237,7 @@ FindExternalDependencies:
159237
160238 for _ , loadedFile := range loadedChartFiles {
161239 if strings .HasPrefix (loadedFile .Name , "charts/" ) {
162- if filepath .Base (loadedFile .Name ) == fmt . Sprintf ( "%s-%s.tgz" , depLock .Name , depLock .Version ) {
240+ if filepath .Base (loadedFile .Name ) == MakeDependencyArchiveName ( depLock .Name , depLock .Version ) {
163241 continue FindExternalDependencies
164242 }
165243 }
@@ -343,3 +421,7 @@ func HashReq(req, lock []*chart.Dependency) (string, error) {
343421 s , err := provenance .Digest (bytes .NewBuffer (data ))
344422 return "sha256:" + s , err
345423}
424+
425+ func MakeDependencyArchiveName (depName , depVersion string ) string {
426+ return fmt .Sprintf ("%s-%s.tgz" , depName , depVersion )
427+ }
0 commit comments