diff --git a/cmd/identify_imagebuild_test.go b/cmd/identify_imagebuild_test.go index 39990adb..9878a805 100644 --- a/cmd/identify_imagebuild_test.go +++ b/cmd/identify_imagebuild_test.go @@ -563,6 +563,45 @@ func TestImageBuildConfigurationIdentification(t *testing.T) { }, }, }, + { + name: "test9 basic deployment with cache args", + args: testdata.GetSeedData( + testdata.TestData{ + Namespace: "example-project-main", + ProjectName: "example-project", + EnvironmentName: "main", + Branch: "main", + LagoonYAML: "internal/testdata/basic/lagoon.yml", + ImageCacheBuildArgsJSON: `[{"image":"harbor.example/example-project/main/node@sha256:e90daba405cbf33bab23fe8a021146811b2c258df5f2afe7dadc92c0778eef45","name":"node"}]`, + }, true), + want: imageBuild{ + BuildKit: false, + BuildArguments: map[string]string{ + "LAGOON_BUILD_NAME": "lagoon-build-abcdefg", + "LAGOON_PROJECT": "example-project", + "LAGOON_ENVIRONMENT": "main", + "LAGOON_ENVIRONMENT_TYPE": "production", + "LAGOON_BUILD_TYPE": "branch", + "LAGOON_GIT_SOURCE_REPOSITORY": "ssh://git@example.com/lagoon-demo.git", + "LAGOON_KUBERNETES": "remote-cluster1", + "LAGOON_GIT_SHA": "abcdefg123456", + "LAGOON_GIT_BRANCH": "main", + "NODE_IMAGE": "example-project-main-node", + "LAGOON_CACHE_node": "harbor.example/example-project/main/node@sha256:e90daba405cbf33bab23fe8a021146811b2c258df5f2afe7dadc92c0778eef45", + }, + Images: []imageBuilds{ + { + Name: "node", + ImageBuild: generator.ImageBuild{ + BuildImage: "harbor.example/example-project/main/node:latest", + Context: "internal/testdata/basic/docker", + DockerFile: "basic.dockerfile", + TemporaryImage: "example-project-main-node", + }, + }, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/generator/build_data.go b/internal/generator/build_data.go index 15012b4a..433939ff 100644 --- a/internal/generator/build_data.go +++ b/internal/generator/build_data.go @@ -81,5 +81,9 @@ func collectImageBuildArguments(buildValues BuildValues) map[string]string { buildArgs[fmt.Sprintf("%s_IMAGE", strings.ToUpper(service.Name))] = service.ImageBuild.TemporaryImage } } + // add lagoon image cache build arguments + for _, icba := range buildValues.ImageCacheBuildArguments { + buildArgs[fmt.Sprintf("LAGOON_CACHE_%s", icba.Name)] = icba.Image + } return buildArgs } diff --git a/internal/generator/buildvalues.go b/internal/generator/buildvalues.go index af79ebae..9063ffd3 100644 --- a/internal/generator/buildvalues.go +++ b/internal/generator/buildvalues.go @@ -77,6 +77,7 @@ type BuildValues struct { RoutesAutogeneratePrefixes []string `json:"routesAutogeneratePrefixes"` BackupsEnabled bool `json:"backupsEnabled"` RouteQuota *int `json:"routeQuota"` + ImageCacheBuildArguments []ImageCacheBuildArguments `json:"imageCacheBuildArgs"` } type Resources struct { @@ -138,6 +139,11 @@ type DynamicSecret struct { Optional bool `json:"optional"` } +type ImageCacheBuildArguments struct { + Image string `json:"image"` + Name string `json:"name"` +} + // ServiceValues is the values for a specific service used by a lagoon build type ServiceValues struct { Name string `json:"name"` // the actual compose service name diff --git a/internal/generator/generator.go b/internal/generator/generator.go index e6437580..5dabae92 100644 --- a/internal/generator/generator.go +++ b/internal/generator/generator.go @@ -64,6 +64,7 @@ type GeneratorInput struct { CI bool DynamicSecrets []string DynamicDBaaSSecrets []string + ImageCacheBuildArgsJSON string } func NewGenerator( @@ -108,6 +109,7 @@ func NewGenerator( prBaseSHA := helpers.GetEnv("PR_BASE_SHA", generator.PRBaseSHA, generator.Debug) dynamicSecrets := helpers.GetEnv("DYNAMIC_SECRETS", strings.Join(generator.DynamicSecrets, ","), generator.Debug) dynamicDBaaSSecrets := helpers.GetEnv("DYNAMIC_DBAAS_SECRETS", strings.Join(generator.DynamicDBaaSSecrets, ","), generator.Debug) + imageCacheBuildArgsJSON := helpers.GetEnv("LAGOON_CACHE_BUILD_ARGS", generator.ImageCacheBuildArgsJSON, generator.Debug) // this is used by CI systems to influence builds, it is rarely used and should probably be abandoned buildValues.IsCI = helpers.GetEnvBool("CI", generator.CI, generator.Debug) @@ -408,6 +410,13 @@ func NewGenerator( if err != nil { return nil, err } + + if imageCacheBuildArgsJSON != "" { + err = json.Unmarshal([]byte(imageCacheBuildArgsJSON), &buildValues.ImageCacheBuildArguments) + if err != nil { + return nil, err + } + } buildValues.ImageBuildArguments = collectImageBuildArguments(buildValues) /* end compose->service configuration */ diff --git a/internal/testdata/testdata.go b/internal/testdata/testdata.go index 26051aa2..37ef18d4 100644 --- a/internal/testdata/testdata.go +++ b/internal/testdata/testdata.go @@ -57,6 +57,7 @@ type TestData struct { PrivateRegistryURLS []string DynamicSecrets []string DynamicDBaaSSecrets []string + ImageCacheBuildArgsJSON string } // helper function to set up all the environment variables from provided testdata @@ -187,6 +188,10 @@ func SetupEnvironment(rootCmd cobra.Command, templatePath string, t TestData) (g if err != nil { return generator.GeneratorInput{}, err } + err = os.Setenv("LAGOON_CACHE_BUILD_ARGS", t.ImageCacheBuildArgsJSON) + if err != nil { + return generator.GeneratorInput{}, err + } generator, err := generator.GenerateInput(rootCmd, false) if err != nil { @@ -327,5 +332,8 @@ func GetSeedData(t TestData, defaultProjectVariables bool) TestData { if t.DynamicDBaaSSecrets != nil { rt.DynamicDBaaSSecrets = t.DynamicDBaaSSecrets } + if t.ImageCacheBuildArgsJSON != "" { + rt.ImageCacheBuildArgsJSON = t.ImageCacheBuildArgsJSON + } return rt } diff --git a/legacy/build-deploy-docker-compose.sh b/legacy/build-deploy-docker-compose.sh index 1cc01c4e..894b37d4 100755 --- a/legacy/build-deploy-docker-compose.sh +++ b/legacy/build-deploy-docker-compose.sh @@ -350,6 +350,14 @@ DEPLOY_TYPE=$(cat .lagoon.yml | shyaml get-value environments.${BRANCH//./\\.}.d # Load all Services that are defined COMPOSE_SERVICES=($(cat $DOCKER_COMPOSE_YAML | shyaml keys services)) +############################################## +### CACHE IMAGE LIST GENERATION +############################################## + +# get a list of the images in the deployments for seeing image cache if required +export LAGOON_CACHE_BUILD_ARGS=$(kubectl -n ${NAMESPACE} get deployments -o yaml -l 'lagoon.sh/service' \ + | yq -o json e '.items[].spec.template.spec.containers[].image | capture("^(?P.+\/.+\/.+\/(?P.+)\@.*)$")' \ + | jq -sMrc) # Figure out which services should we handle SERVICE_TYPES=() @@ -578,13 +586,6 @@ patchBuildStep "${buildStartTime}" "${buildStartTime}" "${currentStepEnd}" "${NA previousStepEnd=${currentStepEnd} beginBuildStep "Image Builds" "buildingImages" -############################################## -### CACHE IMAGE LIST GENERATION -############################################## - -LAGOON_CACHE_BUILD_ARGS=() -readarray LAGOON_CACHE_BUILD_ARGS < <(kubectl -n ${NAMESPACE} get deployments -o yaml -l 'lagoon.sh/service' | yq e '.items[].spec.template.spec.containers[].image | capture("^(?P.+\/.+\/.+\/(?P.+)\@.*)$") | "LAGOON_CACHE_" + .name + "=" + .image' -) - ############################################## ### BUILD IMAGES