diff --git a/pkg/kev/kev_reconcile_test.go b/pkg/kev/kev_reconcile_test.go index f007c2ca..35fd82af 100644 --- a/pkg/kev/kev_reconcile_test.go +++ b/pkg/kev/kev_reconcile_test.go @@ -512,6 +512,48 @@ var _ = Describe("Reconcile", func() { }) }) + Context("when compose image name is overridden in an environment", func() { + BeforeEach(func() { + workingDir = "testdata/reconcile-image-name-override" + overrideFiles = []string{ + workingDir + "/docker-compose.env.dev.yaml", + workingDir + "/docker-compose.env.stage.yaml", + } + }) + + It("confirms the overridden image name pre-reconciliation", func() { + s, err := override.GetService("db") + Expect(err).NotTo(HaveOccurred()) + Expect(s.Image).To(Equal("mysql:latest")) + }) + + It("should keep the appropriate image in the environment override", func() { + testCases := []struct { + env string + expectedImage string + }{ + {env: "dev", expectedImage: "mysql:latest"}, + {env: "stage", expectedImage: ""}, + } + for _, tc := range testCases { + env, err := manifest.GetEnvironment(tc.env) + Expect(err).NotTo(HaveOccurred()) + + svc, err := env.GetService("db") + Expect(err).NotTo(HaveOccurred()) + Expect(svc.Image).To(Equal(tc.expectedImage)) + } + }) + + It("should log the change summary using the debug level", func() { + Expect(testutil.GetLoggedLevel(hook)).To(Equal("debug")) + }) + + It("should not error", func() { + Expect(mErr).NotTo(HaveOccurred()) + }) + }) + Context("when healthcheck is overridden by overlay", func() { Context("liveness tcp", func() { BeforeEach(func() { diff --git a/pkg/kev/override.go b/pkg/kev/override.go index 9812d01a..c888b162 100644 --- a/pkg/kev/override.go +++ b/pkg/kev/override.go @@ -18,6 +18,7 @@ package kev import ( "fmt" + "strings" "github.com/appvia/kev/pkg/kev/log" kmd "github.com/appvia/komando" @@ -314,6 +315,13 @@ func (o *composeOverride) mergeServicesInto(p *ComposeProject) error { envVarsFromNilToBlankInService(base) + // Copy over image name if one has bee defined in the override. In + // future this may expand to invlude other fields. + trimmed := strings.TrimSpace(override.Image) + if trimmed != "" && trimmed != base.Image { + base.Image = override.Image + } + if err := mergo.Merge(&base.Extensions, &override.Extensions, mergo.WithOverride); err != nil { return errors.Wrapf(err, "cannot merge extensions for service %s", override.Name) } diff --git a/pkg/kev/services.go b/pkg/kev/services.go index fc6881d1..b1fceaa3 100644 --- a/pkg/kev/services.go +++ b/pkg/kev/services.go @@ -25,7 +25,12 @@ import ( ) func newServiceConfig(s composego.ServiceConfig) (ServiceConfig, error) { - config := ServiceConfig{Name: s.Name, Environment: s.Environment, Extensions: s.Extensions} + config := ServiceConfig{ + Name: s.Name, + Image: s.Image, + Environment: s.Environment, + Extensions: s.Extensions, + } return config, nil } diff --git a/pkg/kev/testdata/reconcile-image-name-override/appmeta.yaml b/pkg/kev/testdata/reconcile-image-name-override/appmeta.yaml new file mode 100644 index 00000000..c1d72b61 --- /dev/null +++ b/pkg/kev/testdata/reconcile-image-name-override/appmeta.yaml @@ -0,0 +1,6 @@ +id: 10b5c35d-8b9a-42af-a16e-ed758a06c231 +compose: + - testdata/reconcile-image-name-override/docker-compose.yaml +environments: + dev: testdata/reconcile-image-name-override/docker-compose.env.dev.yaml + stage: testdata/reconcile-image-name-override/docker-compose.env.stage.yaml diff --git a/pkg/kev/testdata/reconcile-image-name-override/docker-compose.env.dev.yaml b/pkg/kev/testdata/reconcile-image-name-override/docker-compose.env.dev.yaml new file mode 100644 index 00000000..4f22422b --- /dev/null +++ b/pkg/kev/testdata/reconcile-image-name-override/docker-compose.env.dev.yaml @@ -0,0 +1,24 @@ +version: "3.9" +services: + db: + image: mysql:latest + x-k8s: + workload: + replicas: 1 + livenessProbe: + type: exec + exec: + command: ["echo", "Define healthcheck command for service db"] + initialDelay: 1m0s + period: 1m0s + failureThreashold: 3 + timeout: 10s + service: + type: None + environment: + - TO_OVERRIDE=value +volumes: + db_data: + x-k8s: + size: 100Mi + storageClass: standard diff --git a/pkg/kev/testdata/reconcile-image-name-override/docker-compose.env.stage.yaml b/pkg/kev/testdata/reconcile-image-name-override/docker-compose.env.stage.yaml new file mode 100644 index 00000000..0e348f35 --- /dev/null +++ b/pkg/kev/testdata/reconcile-image-name-override/docker-compose.env.stage.yaml @@ -0,0 +1,23 @@ +version: "3.9" +services: + db: + x-k8s: + workload: + replicas: 1 + livenessProbe: + type: exec + exec: + command: ["echo", "Define healthcheck command for service db"] + initialDelay: 1m0s + period: 1m0s + failureThreashold: 3 + timeout: 10s + service: + type: None + environment: + - TO_OVERRIDE=value +volumes: + db_data: + x-k8s: + size: 100Mi + storageClass: standard diff --git a/pkg/kev/testdata/reconcile-image-name-override/docker-compose.yaml b/pkg/kev/testdata/reconcile-image-name-override/docker-compose.yaml new file mode 100644 index 00000000..2916de7e --- /dev/null +++ b/pkg/kev/testdata/reconcile-image-name-override/docker-compose.yaml @@ -0,0 +1,17 @@ +version: '3.9' +services: + db: + image: mysql:8.0.19 + command: '--default-authentication-plugin=mysql_native_password' + restart: always + volumes: + - db_data:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=somewordpress + - MYSQL_DATABASE=wordpress + - MYSQL_USER=wordpress + - MYSQL_PASSWORD=wordpress + - TO_OVERRIDE=value +volumes: + db_data: + diff --git a/pkg/kev/types.go b/pkg/kev/types.go index f88f3b48..95110fe1 100644 --- a/pkg/kev/types.go +++ b/pkg/kev/types.go @@ -137,6 +137,7 @@ type ComposeProject struct { // ServiceConfig is a shallow version of a compose-go ServiceConfig type ServiceConfig struct { Name string `yaml:"-" json:"-" diff:"name"` + Image string `yaml:"image,omitempty" json:"-" diff:"image"` Environment composego.MappingWithEquals `yaml:",omitempty" json:"environment,omitempty" diff:"environment"` Extensions map[string]interface{} `yaml:",inline" json:"-"` }