Skip to content

Commit

Permalink
Feature - specify base images to refresh on deploy (#355)
Browse files Browse the repository at this point in the history
* Adds --pull to docker build to support updating base images

* adds REFRESH_BASE_IMAGES functionality

* Introduces labels for base image indicators

* debug

* readding docker pull

* Raw string jq

* Adding dockerfile reference regex check for validity

* Fixes comment

* Removes dupe test

---------

Co-authored-by: Blaize Kaye <[email protected]>
  • Loading branch information
bomoko and Blaize Kaye authored Aug 20, 2024
1 parent 54bb075 commit ad7dd3f
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 4 deletions.
2 changes: 2 additions & 0 deletions cmd/identify_imagebuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type imageBuild struct {
Images []imageBuilds `json:"images"`
BuildArguments map[string]string `json:"buildArguments"`
ContainerRegistries []generator.ContainerRegistry `json:"containerRegistries,omitempty"`
ForcePullImages []string `json:"forcePullImages"`
}

type imageBuilds struct {
Expand Down Expand Up @@ -69,6 +70,7 @@ func ImageBuildConfigurationIdentification(g generator.GeneratorInput) (imageBui
})
}
}
lServices.ForcePullImages = lagoonBuild.BuildValues.ForcePullImages
lServices.ContainerRegistries = lagoonBuild.BuildValues.ContainerRegistry
return lServices, nil
}
Expand Down
41 changes: 41 additions & 0 deletions cmd/identify_imagebuild_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,47 @@ func TestImageBuildConfigurationIdentification(t *testing.T) {
},
},
},
{
name: "test11 Force Pull Base Images",
args: testdata.GetSeedData(
testdata.TestData{
Namespace: "example-project-main",
ProjectName: "example-project",
EnvironmentName: "main",
Branch: "main",
LagoonYAML: "internal/testdata/basic/lagoon.forcebaseimagepull.yml",
}, 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://[email protected]/lagoon-demo.git",
"LAGOON_KUBERNETES": "remote-cluster1",
"LAGOON_GIT_SHA": "abcdefg123456",
"LAGOON_GIT_BRANCH": "main",
"NODE_IMAGE": "example-project-main-node",
"LAGOON_SSH_PRIVATE_KEY": "-----BEGIN OPENSSH PRIVATE KEY-----\nthisisafakekey\n-----END OPENSSH PRIVATE KEY-----",
},
ForcePullImages: []string{
"registry.com/namespace/imagename:latest",
},
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) {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e h1:n81KvOMrLZa+VWHwST7dun9f0G98X3zREHS1ztYzZKU=
github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e/go.mod h1:xpWTC2KnJMiDLkoawhsPQcXjvwATEBcbq0xevG2YR9M=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
Expand Down
1 change: 1 addition & 0 deletions internal/generator/buildvalues.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ type BuildValues struct {
ImageCacheBuildArguments []ImageCacheBuildArguments `json:"imageCacheBuildArgs"`
IgnoreImageCache bool `json:"ignoreImageCache"`
SSHPrivateKey string `json:"sshPrivateKey"`
ForcePullImages []string `json:"forcePullImages"`
}

type Resources struct {
Expand Down
10 changes: 10 additions & 0 deletions internal/generator/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/distribution/reference"
"os"
"reflect"
"regexp"
Expand Down Expand Up @@ -244,6 +245,15 @@ func composeToServiceValues(
}
}

baseimage := lagoon.CheckServiceLagoonLabel(composeServiceValues.Labels, "lagoon.base.image")
if baseimage != "" {
// First, let's ensure that the structure of the base image is valid
if !reference.ReferenceRegexp.MatchString(baseimage) {
return ServiceValues{}, 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]`", composeService, baseimage)
}
buildValues.ForcePullImages = append(buildValues.ForcePullImages, baseimage)
}

// if there are overrides defined in the lagoon API `LAGOON_SERVICE_TYPES`
// handle those here
if buildValues.ServiceTypeOverrides != nil {
Expand Down
42 changes: 38 additions & 4 deletions internal/generator/services_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ package generator

import (
"encoding/json"
"reflect"
"testing"
"time"

composetypes "github.com/compose-spec/compose-go/types"
"github.com/uselagoon/build-deploy-tool/internal/dbaasclient"
"github.com/uselagoon/build-deploy-tool/internal/helpers"
"github.com/uselagoon/build-deploy-tool/internal/lagoon"
"reflect"
"testing"
"time"
)

func Test_composeToServiceValues(t *testing.T) {
Expand Down Expand Up @@ -1163,6 +1162,41 @@ func Test_composeToServiceValues(t *testing.T) {
},
},
},
{
name: "test23 - failure on invalid baseimage label reference structure",
args: args{
buildValues: &BuildValues{
Namespace: "example-project-main",
Project: "example-project",
ImageRegistry: "harbor.example",
Environment: "main",
Branch: "main",
BuildType: "branch",
ServiceTypeOverrides: &lagoon.EnvironmentVariable{},
LagoonYAML: lagoon.YAML{
Environments: lagoon.Environments{
"main": lagoon.Environment{
Overrides: map[string]lagoon.Override{
"redis": {
Image: "uselagoon/fake-redis:7",
},
},
},
},
},
},
composeService: "redis",
composeServiceValues: composetypes.ServiceConfig{
Labels: composetypes.Labels{
"lagoon.type": "redis",
"lagoon.base.image": "this-is-an-invalid-reference!",
},
Image: "uselagoon/fake-redis:7",
},
},
want: ServiceValues{},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
23 changes: 23 additions & 0 deletions internal/testdata/basic/docker-compose.forcebaseimagepull.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: '2'
services:
node:
networks:
- amazeeio-network
- default
build:
context: internal/testdata/basic/docker
dockerfile: basic.dockerfile
labels:
lagoon.type: basic
lagoon.service.usecomposeports: true
lagoon.base.image: registry.com/namespace/imagename:latest
volumes:
- .:/app:delegated
ports:
- '1234'
- '8191'
- '9001/udp'

networks:
amazeeio-network:
external: true
10 changes: 10 additions & 0 deletions internal/testdata/basic/lagoon.forcebaseimagepull.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
docker-compose-yaml: internal/testdata/basic/docker-compose.forcebaseimagepull.yml

environment_variables:
git_sha: "true"

environments:
main:
routes:
- node:
- example.com
8 changes: 8 additions & 0 deletions legacy/build-deploy-docker-compose.sh
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,14 @@ if [[ "$BUILD_TYPE" == "pullrequest" || "$BUILD_TYPE" == "branch" ]]; then
BUILD_ARGS+=(--build-arg ${BUILD_ARG_NAME}="${BUILD_ARG_VALUE}")
done

# Here we iterate over any lagoon.base.image data that has been passed to us
# in order to explicitly pull the images to ensure they are current
for FPI in $(echo "$ENVIRONMENT_IMAGE_BUILD_DATA" | jq -rc '.forcePullImages[]?')
do
echo "Pulling Image: ${FPI}"
docker pull "${FPI}"
done

# now we loop through the images in the build data and determine if they need to be pulled or build
for IMAGE_BUILD_DATA in $(echo "$ENVIRONMENT_IMAGE_BUILD_DATA" | jq -c '.images[]')
do
Expand Down

0 comments on commit ad7dd3f

Please sign in to comment.