Skip to content

Commit

Permalink
refactor: just use one tag with variable replacement
Browse files Browse the repository at this point in the history
  • Loading branch information
shreddedbacon committed Oct 8, 2024
1 parent ba7d408 commit 2313c62
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 50 deletions.
37 changes: 21 additions & 16 deletions internal/generator/helpers_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
50 changes: 20 additions & 30 deletions internal/generator/helpers_generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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",
Expand All @@ -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)
}
})
Expand Down
13 changes: 9 additions & 4 deletions internal/generator/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down

0 comments on commit 2313c62

Please sign in to comment.