From 2313c62e635748b3242d339f68384f428a309829 Mon Sep 17 00:00:00 2001 From: shreddedbacon Date: Tue, 8 Oct 2024 15:00:31 +1100 Subject: [PATCH] refactor: just use one tag with variable replacement --- internal/generator/helpers_generator.go | 37 ++++++++------- internal/generator/helpers_generator_test.go | 50 ++++++++------------ internal/generator/services.go | 13 +++-- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/internal/generator/helpers_generator.go b/internal/generator/helpers_generator.go index 9f6d3b5a..505f5be4 100644 --- a/internal/generator/helpers_generator.go +++ b/internal/generator/helpers_generator.go @@ -274,38 +274,43 @@ func getDBaasEnvironment( return exists, nil } -func determineRefreshImage(serviceName, imageName string, labels map[string]string, envVars []lagoon.EnvironmentVariable) (string, error) { - tagvalue := lagoon.CheckDockerComposeLagoonLabel(labels, "lagoon.base.image.tag") - if tagvalue != "" { +var exp = regexp.MustCompile(`(\\*)\$\{(.+?)(?:(\:\-)(.*?))?\}`) - // Regular expression to match VAR and defaulttag - re := regexp.MustCompile(`\$(\w+)(?::-(\w+))?`) - matches := re.FindStringSubmatch(tagvalue) - - if len(matches) > 0 { // we have an env var, and optionally a default +func determineRefreshImage(serviceName, imageName string, envVars []lagoon.EnvironmentVariable) (string, []error) { + errs := []error{} + parsed := exp.ReplaceAllStringFunc(string(imageName), func(match string) string { + tagvalue := "" + re := regexp.MustCompile(`\${?(\w+)?(?::-(\w+))?}?`) + matches := re.FindStringSubmatch(match) + if len(matches) > 0 { tv := "" envVarKey := matches[1] defaultVal := matches[2] //This could be empty for _, v := range envVars { if v.Name == envVarKey { - // we've found a matching env var - that becomes the tag tv = v.Value } } if tv == "" { if defaultVal != "" { tagvalue = defaultVal + } else { + errs = append(errs, fmt.Errorf("the 'lagoon.base.image' label defined on service %s in the docker-compose file is invalid ('%s') - no matching variable or fallback found to replace requested variable %s", serviceName, imageName, envVarKey)) } } else { tagvalue = tv } } - - imageName = fmt.Sprintf("%v:%v", imageName, tagvalue) - } - - if !reference.ReferenceRegexp.MatchString(imageName) { - return "", fmt.Errorf("the 'lagoon.base.image' label defined on service %s in the docker-compose file is invalid ('%s') - please ensure it conforms to the structure `[REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG|@DIGEST]`", serviceName, imageName) + return tagvalue + }) + if parsed == imageName { + if !reference.ReferenceRegexp.MatchString(parsed) { + if strings.Contains(parsed, "$") { + errs = append(errs, fmt.Errorf("the 'lagoon.base.image' label defined on service %s in the docker-compose file is invalid ('%s') - variables are defined incorrectly, must contain curly brackets (example: '${VARIABLE}')", serviceName, imageName)) + } else { + errs = append(errs, fmt.Errorf("the 'lagoon.base.image' label defined on service %s in the docker-compose file is invalid ('%s') - please ensure it conforms to the structure `[REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG|@DIGEST]`", serviceName, imageName)) + } + } } - return imageName, nil + return parsed, errs } diff --git a/internal/generator/helpers_generator_test.go b/internal/generator/helpers_generator_test.go index f388beb5..366a0970 100644 --- a/internal/generator/helpers_generator_test.go +++ b/internal/generator/helpers_generator_test.go @@ -86,7 +86,6 @@ func Test_determineRefreshImage(t *testing.T) { type args struct { serviceName string imageName string - labels map[string]string envVars []lagoon.EnvironmentVariable } tests := []struct { @@ -100,34 +99,27 @@ func Test_determineRefreshImage(t *testing.T) { args: args{ serviceName: "testservice", imageName: "image/name:latest", - labels: nil, envVars: nil, }, want: "image/name:latest", wantErr: false, }, { - name: "Adds simple tag", + name: "Fails with no matching variable in envvars", args: args{ serviceName: "testservice", - imageName: "image/name", - labels: map[string]string{ - "lagoon.base.image.tag": "sometag", - }, - envVars: nil, + imageName: "image/name:${NOENVVAR}", + envVars: nil, }, - want: "image/name:sometag", - wantErr: false, + want: "", + wantErr: true, }, { - name: "Fails with double tags", + name: "Fails with variable missing curly brackets", args: args{ serviceName: "testservice", - imageName: "image/name:latest", - labels: map[string]string{ - "lagoon.base.image.tag": "sometag", - }, - envVars: nil, + imageName: "image/name:$NOENVVAR", + envVars: nil, }, want: "", wantErr: true, @@ -136,11 +128,8 @@ func Test_determineRefreshImage(t *testing.T) { name: "Tag with simple arg - fallback to default", args: args{ serviceName: "testservice", - imageName: "image/name", - labels: map[string]string{ - "lagoon.base.image.tag": "$ENVVAR:-sometag", - }, - envVars: nil, + imageName: "image/name:${ENVVAR:-sometag}", + envVars: nil, }, want: "image/name:sometag", wantErr: false, @@ -149,10 +138,7 @@ func Test_determineRefreshImage(t *testing.T) { name: "Tag with env var that works", args: args{ serviceName: "testservice", - imageName: "image/name", - labels: map[string]string{ - "lagoon.base.image.tag": "$ENVVAR:-sometag", - }, + imageName: "image/name:${ENVVAR:-sometag}", envVars: []lagoon.EnvironmentVariable{ { Name: "ENVVAR", @@ -166,12 +152,16 @@ func Test_determineRefreshImage(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := determineRefreshImage(tt.args.serviceName, tt.args.imageName, tt.args.labels, tt.args.envVars) - if (err != nil) != tt.wantErr { - t.Errorf("determineRefreshImage() error = %v, wantErr %v", err, tt.wantErr) - return + got, errs := determineRefreshImage(tt.args.serviceName, tt.args.imageName, tt.args.envVars) + if len(errs) > 0 && !tt.wantErr { + for idx, err := range errs { + t.Errorf("determineRefreshImage() error = %v, wantErr %v", err, tt.wantErr) + if idx+1 == len(errs) { + return + } + } } - if got != tt.want { + if got != tt.want && !tt.wantErr { t.Errorf("determineRefreshImage() got = %v, want %v", got, tt.want) } }) diff --git a/internal/generator/services.go b/internal/generator/services.go index cc849e4f..1732e779 100644 --- a/internal/generator/services.go +++ b/internal/generator/services.go @@ -289,10 +289,15 @@ func composeToServiceValues( // may have an update without a change in tag (i.e. "latest" tagged images) baseimage := lagoon.CheckDockerComposeLagoonLabel(composeServiceValues.Labels, "lagoon.base.image") if baseimage != "" { - - baseImageWithTag, err := determineRefreshImage(composeService, baseimage, composeServiceValues.Labels, buildValues.EnvironmentVariables) - if err != nil { - return nil, err + baseImageWithTag, errs := determineRefreshImage(composeService, baseimage, buildValues.EnvironmentVariables) + if len(errs) > 0 { + for idx, err := range errs { + if idx+1 == len(errs) { + return nil, err + } else { + fmt.Println(err) + } + } } buildValues.ForcePullImages = append(buildValues.ForcePullImages, baseImageWithTag) }