@@ -3,12 +3,14 @@ package app
33import (
44 "fmt"
55 "os"
6+ "path"
67 "regexp"
78 "strings"
89 "sync"
910
1011 lla "github.com/emirpasic/gods/lists/arraylist"
1112 lls "github.com/emirpasic/gods/stacks/linkedliststack"
13+ "github.com/golang-module/carbon/v2"
1214 "github.com/stackup-app/stackup/lib/cache"
1315 "github.com/stackup-app/stackup/lib/checksums"
1416 "github.com/stackup-app/stackup/lib/downloader"
@@ -37,18 +39,22 @@ type StackupWorkflow struct {
3739}
3840
3941type WorkflowInclude struct {
40- Url string `yaml:"url"`
41- Headers []string `yaml:"headers"`
42- File string `yaml:"file"`
43- ChecksumUrl string `yaml:"checksum-url"`
44- VerifyChecksum * bool `yaml:"verify,omitempty"`
45- AccessKey string `yaml:"access-key"`
46- SecretKey string `yaml:"secret-key"`
47- Secure bool `yaml:"secure"`
48- ChecksumIsValid * bool
49- ValidationState string
50- Contents string
51- Hash string
42+ Url string `yaml:"url"`
43+ Headers []string `yaml:"headers"`
44+ File string `yaml:"file"`
45+ ChecksumUrl string `yaml:"checksum-url"`
46+ VerifyChecksum * bool `yaml:"verify,omitempty"`
47+ AccessKey string `yaml:"access-key"`
48+ SecretKey string `yaml:"secret-key"`
49+ Secure bool `yaml:"secure"`
50+ ChecksumIsValid * bool
51+ ValidationState string
52+ Contents string
53+ Hash string
54+ FoundChecksum string
55+ HashAlgorithm string
56+ ChecksumValidated bool
57+ FromCache bool
5258 //Workflow *StackupWorkflow
5359}
5460
@@ -137,63 +143,41 @@ func (wi *WorkflowInclude) getChecksumFromContents(contents string) string {
137143 return strings .TrimSpace (contents )
138144}
139145
140- func (wi * WorkflowInclude ) ValidateChecksum (contents string ) (bool , error ) {
146+ func (wi * WorkflowInclude ) ValidateChecksum (contents string ) (bool , string , error ) {
141147 if wi .VerifyChecksum != nil && * wi .VerifyChecksum == false {
142- return true , nil
148+ return true , "" , nil
143149 }
144150
145151 checksumUrls := []string {
152+ wi .FullUrlPath () + "/checksums.txt" ,
146153 wi .FullUrlPath () + "/checksums.sha256.txt" ,
147154 wi .FullUrlPath () + "/checksums.sha512.txt" ,
155+ wi .FullUrlPath () + "sha256sum" ,
156+ wi .FullUrlPath () + "sha512sum" ,
148157 wi .FullUrl () + ".sha256" ,
149158 wi .FullUrl () + ".sha512" ,
150159 }
151160
152- algorithm := ""
153- storedChecksum := ""
154- checksumContents := ""
155-
156161 for _ , url := range checksumUrls {
157-
158- if ! App .Workflow .Cache .IsExpired (url ) {
159- wi .ChecksumUrl = url
160- checksumContents = App .Workflow .Cache .Get (url )
161- // fmt.Printf("using cached checksum file %s\n", url)
162- break
163- }
164-
165162 checksumContents , err := utils .GetUrlContents (url )
166163 if err != nil {
167164 continue
168165 }
169166
170167 wi .ChecksumUrl = url
168+ wi .FoundChecksum = wi .getChecksumFromContents (checksumContents )
169+ wi .HashAlgorithm = wi .GetChecksumAlgorithm ()
171170
172- if checksumContents != "" {
173- // fmt.Printf("using checksum file %s\n", wi.ChecksumUrl)
174- App .Workflow .Cache .Set (url , checksumContents , 3 )
175- // fmt.Printf("using non-cached checksum file %s\n", url)
176- break
177- }
178- }
179-
180- if checksumContents != "" {
181- storedChecksum = wi .getChecksumFromContents (checksumContents )
182-
183- // wi.ChecksumUrl = hashUrl
184- // fmt.Println("checksum url: " + wi.ChecksumUrl)
185- algorithm = wi .GetChecksumAlgorithm ()
171+ break
186172 }
187173
188- // algorithm = "sha256"
189-
190- if algorithm == "unknown" || algorithm == "" {
191- return false , fmt .Errorf ("unable to find valid checksum file for %s" , wi .DisplayUrl ())
174+ if wi .HashAlgorithm == "unknown" || wi .HashAlgorithm == "" {
175+ return false , "" , fmt .Errorf ("unable to find valid checksum file for %s" , wi .DisplayUrl ())
192176 }
193177
194178 var hash string
195179
196- switch algorithm {
180+ switch wi . HashAlgorithm {
197181 case "sha256" :
198182 hash = checksums .CalculateSha256Hash (contents )
199183 break
@@ -202,16 +186,16 @@ func (wi *WorkflowInclude) ValidateChecksum(contents string) (bool, error) {
202186 break
203187 default :
204188 wi .SetChecksumIsValid (false )
205- return false , fmt .Errorf ("unsupported algorithm: %s" , algorithm )
189+ return false , "" , fmt .Errorf ("unsupported algorithm: %s" , wi . HashAlgorithm )
206190 }
207191
208- if ! strings .EqualFold (hash , storedChecksum ) {
192+ if ! strings .EqualFold (hash , wi . FoundChecksum ) {
209193 wi .SetChecksumIsValid (false )
210- return false , nil
194+ return false , "" , nil
211195 }
212196
213197 wi .SetChecksumIsValid (true )
214- return true , nil
198+ return true , hash , nil
215199}
216200
217201func (wi * WorkflowInclude ) IsLocalFile () bool {
@@ -277,6 +261,37 @@ func (wi *WorkflowInclude) GetChecksumAlgorithm() string {
277261 return "sha512"
278262 }
279263
264+ if strings .EqualFold (path .Base (wi .ChecksumUrl ), "sha256sum" ) {
265+ return "sha256"
266+ }
267+
268+ if strings .EqualFold (path .Base (wi .ChecksumUrl ), "sha512sum" ) {
269+ return "sha512"
270+ }
271+
272+ // check for md4 hash length:
273+ if len (wi .FoundChecksum ) == 16 {
274+ return "md4"
275+ }
276+ if len (wi .FoundChecksum ) == 32 {
277+ return "md5"
278+ }
279+ if len (wi .FoundChecksum ) == 40 {
280+ return "sha1"
281+ }
282+ if len (wi .FoundChecksum ) == 48 {
283+ return "sha224"
284+ }
285+ if len (wi .FoundChecksum ) == 64 {
286+ return "sha256"
287+ }
288+ if len (wi .FoundChecksum ) == 96 {
289+ return "sha384"
290+ }
291+ if len (wi .FoundChecksum ) == 128 {
292+ return "sha512"
293+ }
294+
280295 return "unknown"
281296}
282297
@@ -413,12 +428,6 @@ func (workflow *StackupWorkflow) RemoveTasks(uuidsToRemove []string) {
413428 workflow .Tasks = newTasks
414429}
415430
416- // func (workflow *StackupWorkflow) ProcessIncludes() {
417- // for _, include := range workflow.Includes {
418- // workflow.ProcessInclude(include)
419- // }
420- // }
421-
422431func (workflow * StackupWorkflow ) ProcessIncludes () {
423432 var wg sync.WaitGroup
424433 for _ , include := range workflow .Includes {
@@ -438,14 +447,16 @@ func (workflow *StackupWorkflow) ProcessInclude(include *WorkflowInclude) bool {
438447
439448 var err error
440449
441- if workflow .Cache .Has (include .DisplayName ()) && ! workflow .Cache .IsExpired (include .DisplayName ()) {
442- include .Contents = workflow .Cache .Get (include .DisplayName ())
443- include .Hash = workflow .Cache .GetHash (include .DisplayName ())
444- // fmt.Println("loaded from cache")
450+ data , found := workflow .Cache .Get (include .DisplayName ())
451+ include .FromCache = found
452+
453+ if found {
454+ include .Hash = data .Hash
455+ include .HashAlgorithm = data .Hash
456+ include .Contents = data .Value
445457 }
446458
447- if ! workflow .Cache .Has (include .DisplayName ()) || workflow .Cache .IsExpired (include .DisplayName ()) {
448- // fmt.Println("not loaded from cache")
459+ if ! found || data .IsExpired () {
449460 if include .IsLocalFile () {
450461 include .Contents , err = utils .GetFileContents (include .Filename ())
451462 } else if include .IsRemoteUrl () {
@@ -455,58 +466,61 @@ func (workflow *StackupWorkflow) ProcessInclude(include *WorkflowInclude) bool {
455466 include .SecretKey = os .ExpandEnv (include .SecretKey )
456467 include .Contents = downloader .ReadS3FileContents (include .FullUrl (), include .AccessKey , include .SecretKey , include .Secure )
457468 } else {
469+ fmt .Printf ("unknown include type: %s\n " , include .DisplayName ())
458470 return false
459471 }
460472
461473 include .Hash = checksums .CalculateSha256Hash (include .Contents )
462- workflow . Cache . Set ( include . DisplayName (), include . Contents , 3 )
463- }
474+ expires := carbon . Now (). AddMinutes ( App . Workflow . Settings . Cache . TtlMinutes )
475+ now := carbon . Now ()
464476
465- // fmt.Printf("value: %v\n", workflow.Cache.Get(include.DisplayName()))
466- // fmt.Printf("expires: %v\n", workflow.Cache.GetExpiresAt(include.DisplayName()))
467- // fmt.Printf("hash: %v\n", workflow.Cache.GetHash(include.DisplayName()))
477+ item := cache .CreateCacheEntry (
478+ include .DisplayName (),
479+ include .Contents ,
480+ & expires ,
481+ include .Hash ,
482+ include .HashAlgorithm ,
483+ & now ,
484+ )
485+
486+ workflow .Cache .Set (include .DisplayName (), item , App .Workflow .Settings .Cache .TtlMinutes )
487+ }
468488
469- // fmt.Printf("include: %s\n", include.DisplayName())
470- // fmt.Printf("include: %s\n", include.FullUrl())
471- // fmt.Printf("contents: %s\n", include.Contents)
489+ include .ChecksumValidated , include .FoundChecksum , _ = include .ValidateChecksum (include .Contents )
472490
473491 if err != nil {
474492 fmt .Println (err )
475493 return false
476494 }
477495
478- include .ValidationState = "checksum not validated "
496+ include .ValidationState = "verification skipped "
479497
480498 if include .IsRemoteUrl () {
481499 if * include .VerifyChecksum == true || include .VerifyChecksum == nil {
482- // support.StatusMessage("Validating checksum for remote include: "+include.DisplayUrl(), false)
483- validated , _ := include .ValidateChecksum (include .Contents )
484-
485- if include .ChecksumIsValid != nil && * include .ChecksumIsValid == true {
486- include .ValidationState = "checksum validated"
500+ if include .ChecksumValidated {
501+ include .ValidationState = "verified"
487502 }
488503
489- if include .ChecksumIsValid != nil && * include .ChecksumIsValid == false {
490- include .ValidationState = "checksum mismatch "
504+ if ! include .ChecksumValidated && include .FoundChecksum != "" {
505+ include .ValidationState = "verification failed "
491506 }
492507
493508 // if err != nil {
494509 // fmt.Println(err)
495510 // return false
496511 // }
497512
498- if ! validated {
499- if App .Workflow .Settings .ExitOnChecksumMismatch {
500- support .FailureMessageWithXMark ("Exiting due to checksum mismatch." )
501- App .exitApp ()
502- return false
503- }
513+ if ! include .ChecksumValidated && App .Workflow .Settings .ExitOnChecksumMismatch {
514+ support .FailureMessageWithXMark ("Exiting due to checksum mismatch." )
515+ App .exitApp ()
516+ return false
504517 }
505518 }
506519 }
507520
508- template := & IncludedTemplate {}
509- err = yaml .Unmarshal ([]byte (include .Contents ), template )
521+ // if strings.HasPrefix(include.Contents, "template:") {
522+ var template IncludedTemplate
523+ err = yaml .Unmarshal ([]byte (include .Contents ), & template )
510524
511525 if err != nil {
512526 fmt .Println (err )
@@ -536,7 +550,13 @@ func (workflow *StackupWorkflow) ProcessInclude(include *WorkflowInclude) bool {
536550 App .Workflow .Tasks = append (App .Workflow .Tasks , t )
537551 }
538552
539- support .SuccessMessageWithCheck ("Included file (" + include .ValidationState + "): " + include .DisplayName ())
553+ cachedText := ""
554+
555+ if include .FromCache {
556+ cachedText = ", cached"
557+ }
558+
559+ support .SuccessMessageWithCheck ("Included file (" + include .ValidationState + cachedText + "): " + include .DisplayName ())
540560
541561 return true
542562}
0 commit comments