Skip to content

Commit

Permalink
feat(build): add root image info
Browse files Browse the repository at this point in the history
* Useful to know from which image a kit hierarchy started
* added builder.base-image property trait to override easily the base image

Ref #2844
  • Loading branch information
squakez committed Oct 19, 2023
1 parent 07a6b15 commit 6159f9d
Show file tree
Hide file tree
Showing 16 changed files with 151 additions and 12 deletions.
4 changes: 4 additions & 0 deletions config/crd/bases/camel.apache.org_builds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1740,6 +1740,10 @@ spec:
phase:
description: describes the phase
type: string
rootImage:
description: root image (the first image from which the incremental
image has started)
type: string
startedAt:
description: the time when it started
format: date-time
Expand Down
10 changes: 9 additions & 1 deletion config/crd/bases/camel.apache.org_integrationkits.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ spec:
jsonPath: .status.image
name: Image
type: string
- description: The integration kit root image
jsonPath: .status.rootImage
name: Root
type: string
name: v1
schema:
openAPIV3Schema:
Expand Down Expand Up @@ -410,7 +414,7 @@ spec:
type: object
type: array
baseImage:
description: base image used by the kit
description: base image used by the kit (could be another IntegrationKit)
type: string
conditions:
description: a list of conditions which happened for the events related
Expand Down Expand Up @@ -495,6 +499,10 @@ spec:
platform:
description: the platform for which this kit was configured
type: string
rootImage:
description: root image used by the kit (the first image from which
the incremental image has started, typically a JDK/JRE base image)
type: string
runtimeProvider:
description: the runtime provider for which this kit was configured
type: string
Expand Down
16 changes: 15 additions & 1 deletion docs/modules/ROOT/partials/apis/camel-k-crds.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,13 @@ string
the digest from image
|`rootImage` +
string
|
root image (the first image from which the incremental image has started)
|`baseImage` +
string
|
Expand Down Expand Up @@ -2461,12 +2468,19 @@ ObservedGeneration is the most recent generation observed for this IntegrationKi
phase of the kit
|`rootImage` +
string
|
root image used by the kit (the first image from which the incremental image has started, typically a JDK/JRE base image)
|`baseImage` +
string
|
base image used by the kit
base image used by the kit (could be another IntegrationKit)
|`image` +
string
Expand Down
58 changes: 58 additions & 0 deletions e2e/commonwithcustominstall/incremental_build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func TestRunIncrementalBuildRoutine(t *testing.T) {
Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
integrationKitName := IntegrationKit(ns, name)()
Eventually(Kit(ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage()))
Eventually(Kit(ns, integrationKitName)().Status.RootImage).Should(Equal(defaults.BaseImage()))

t.Run("Reuse previous kit", func(t *testing.T) {
nameClone := "java-clone"
Expand Down Expand Up @@ -77,6 +78,7 @@ func TestRunIncrementalBuildRoutine(t *testing.T) {
// 10.108.177.66/test-d7cad110-bb1d-4e79-8a0e-ebd44f6fe5d4/camel-k-kit-c8357r4k5tp6fn1idm60@sha256:d49716f0429ad8b23a1b8d20a357d64b1aa42a67c1a2a534ebd4c54cd598a18d
// we should be save just to check the substring is contained
Eventually(Kit(ns, integrationIncrementalKitName)().Status.BaseImage).Should(ContainSubstring(integrationKitName))
Eventually(Kit(ns, integrationIncrementalKitName)().Status.RootImage).Should(Equal(defaults.BaseImage()))
})

Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
Expand All @@ -98,6 +100,7 @@ func TestRunIncrementalBuildPod(t *testing.T) {
Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
integrationKitName := IntegrationKit(ns, name)()
Eventually(Kit(ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage()))
Eventually(Kit(ns, integrationKitName)().Status.RootImage).Should(Equal(defaults.BaseImage()))
Eventually(BuilderPodsCount(ns)).Should(Equal(1))

t.Run("Reuse previous kit", func(t *testing.T) {
Expand Down Expand Up @@ -131,6 +134,7 @@ func TestRunIncrementalBuildPod(t *testing.T) {
// 10.108.177.66/test-d7cad110-bb1d-4e79-8a0e-ebd44f6fe5d4/camel-k-kit-c8357r4k5tp6fn1idm60@sha256:d49716f0429ad8b23a1b8d20a357d64b1aa42a67c1a2a534ebd4c54cd598a18d
// we should be save just to check the substring is contained
Eventually(Kit(ns, integrationIncrementalKitName)().Status.BaseImage).Should(ContainSubstring(integrationKitName))
Eventually(Kit(ns, integrationIncrementalKitName)().Status.RootImage).Should(Equal(defaults.BaseImage()))
Eventually(BuilderPodsCount(ns)).Should(Equal(2))
})

Expand Down Expand Up @@ -185,3 +189,57 @@ func TestRunIncrementalBuildOff(t *testing.T) {
Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
})
}

func TestRunIncrementalBuildWithDifferentBaseImages(t *testing.T) {
WithNewTestNamespace(t, func(ns string) {
operatorID := "camel-k-standard-build"
Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())

name := "java"
Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
"--name", name,
).Execute()).To(Succeed())
Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
integrationKitName := IntegrationKit(ns, name)()
Eventually(Kit(ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage()))
Eventually(Kit(ns, integrationKitName)().Status.RootImage).Should(Equal(defaults.BaseImage()))

t.Run("Create incremental kit", func(t *testing.T) {
// Another integration that should be built on top of the previous IntegrationKit
// just add a new random dependency
nameIncremental := "java-incremental"
Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
"--name", nameIncremental,
"-d", "camel:zipfile",
).Execute()).To(Succeed())
Eventually(IntegrationPodPhase(ns, nameIncremental), TestTimeoutLong).Should(Equal(corev1.PodRunning))
Eventually(IntegrationConditionStatus(ns, nameIncremental, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(IntegrationLogs(ns, nameIncremental), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
integrationIncrementalKitName := IntegrationKit(ns, nameIncremental)()
// the container comes in a format like
// 10.108.177.66/test-d7cad110-bb1d-4e79-8a0e-ebd44f6fe5d4/camel-k-kit-c8357r4k5tp6fn1idm60@sha256:d49716f0429ad8b23a1b8d20a357d64b1aa42a67c1a2a534ebd4c54cd598a18d
// we should be save just to check the substring is contained
Eventually(Kit(ns, integrationIncrementalKitName)().Status.BaseImage).Should(ContainSubstring(integrationKitName))
Eventually(Kit(ns, integrationIncrementalKitName)().Status.RootImage).Should(Equal(defaults.BaseImage()))
Eventually(BuilderPodsCount(ns)).Should(Equal(2))
})

newBaseImage := "eclipse-temurin:17.0.8.1_1-jdk-ubi9-minimal"
name := "java-new"
Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
"--name", name,
"-d", "camel:mongodb"
fmt.Sprintf("-t builder.base-image=%s", newBaseImage),
).Execute()).To(Succeed())
Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
integrationKitName = IntegrationKit(ns, name)()
Eventually(Kit(ns, integrationKitName)().Status.BaseImage).Should(Equal(newBaseImage))
Eventually(Kit(ns, integrationKitName)().Status.RootImage).Should(Equal(newBaseImage))

Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
})
}
4 changes: 4 additions & 0 deletions helm/camel-k/crds/crd-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1740,6 +1740,10 @@ spec:
phase:
description: describes the phase
type: string
rootImage:
description: root image (the first image from which the incremental
image has started)
type: string
startedAt:
description: the time when it started
format: date-time
Expand Down
10 changes: 9 additions & 1 deletion helm/camel-k/crds/crd-integration-kit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ spec:
jsonPath: .status.image
name: Image
type: string
- description: The integration kit root image
jsonPath: .status.rootImage
name: Root
type: string
name: v1
schema:
openAPIV3Schema:
Expand Down Expand Up @@ -410,7 +414,7 @@ spec:
type: object
type: array
baseImage:
description: base image used by the kit
description: base image used by the kit (could be another IntegrationKit)
type: string
conditions:
description: a list of conditions which happened for the events related
Expand Down Expand Up @@ -495,6 +499,10 @@ spec:
platform:
description: the platform for which this kit was configured
type: string
rootImage:
description: root image used by the kit (the first image from which
the incremental image has started, typically a JDK/JRE base image)
type: string
runtimeProvider:
description: the runtime provider for which this kit was configured
type: string
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/camel/v1/build_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ type BuildStatus struct {
Image string `json:"image,omitempty"`
// the digest from image
Digest string `json:"digest,omitempty"`
// root image (the first image from which the incremental image has started)
RootImage string `json:"rootImage,omitempty"`
// the base image used for this build
BaseImage string `json:"baseImage,omitempty"`
// a list of artifacts contained in the build
Expand Down
5 changes: 4 additions & 1 deletion pkg/apis/camel/v1/integrationkit_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
// +kubebuilder:printcolumn:name="Type",type=string,JSONPath=`.metadata.labels.camel\.apache\.org\/kit\.type`,description="The integration kit type"
// +kubebuilder:printcolumn:name="Layout",type=string,JSONPath=`.metadata.labels.camel\.apache\.org\/kit\.layout`,description="The integration kit layout"
// +kubebuilder:printcolumn:name="Image",type=string,JSONPath=`.status.image`,description="The integration kit image"
// +kubebuilder:printcolumn:name="Root",type=string,JSONPath=`.status.rootImage`,description="The integration kit root image"

// IntegrationKit defines a container image and additional configuration needed to run an `Integration`.
// An `IntegrationKit` is a generic image generally built from the requirements of an `Integration`, but agnostic to it,
Expand Down Expand Up @@ -97,7 +98,9 @@ type IntegrationKitStatus struct {
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
// phase of the kit
Phase IntegrationKitPhase `json:"phase,omitempty"`
// base image used by the kit
// root image used by the kit (the first image from which the incremental image has started, typically a JDK/JRE base image)
RootImage string `json:"rootImage,omitempty"`
// base image used by the kit (could be another IntegrationKit)
BaseImage string `json:"baseImage,omitempty"`
// actual image name of the kit
Image string `json:"image,omitempty"`
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/camel/v1/trait/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type BuilderTrait struct {
Properties []string `property:"properties" json:"properties,omitempty"`
// The strategy to use, either `pod` or `routine` (default routine)
Strategy string `property:"strategy" json:"strategy,omitempty"`
// Specify a base image
BaseImage string `property:"base-image" json:"baseImage,omitempty"`
// Use the incremental image build option, to reuse existing containers (default `true`)
IncrementalImageBuild *bool `property:"incremental-image-build" json:"incrementalImageBuild,omitempty"`
// The build order strategy to use, either `dependencies`, `fifo` or `sequential` (default sequential)
Expand Down
11 changes: 7 additions & 4 deletions pkg/builder/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ func incrementalImageContext(ctx *builderContext) error {

bestImage, commonLibs := findBestImage(images, ctx.Artifacts)
if bestImage.Image != "" {

ctx.BaseImage = bestImage.Image
ctx.SelectedArtifacts = make([]v1.Artifact, 0)

Expand Down Expand Up @@ -203,13 +204,15 @@ func listPublishedImages(context *builderContext) ([]v1.IntegrationKitStatus, er
}

images := make([]v1.IntegrationKitStatus, 0)
for _, item := range list.Items {
kit := item

for _, kit := range list.Items {
// Discard kits with a different root hierarchy
if kit.Status.RootImage != context.BaseImage {
continue
}
// Discard non ready kits
if kit.Status.Phase != v1.IntegrationKitPhaseReady {
continue
}

images = append(images, kit.Status)
}
return images, nil
Expand Down
7 changes: 6 additions & 1 deletion pkg/builder/jib.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,13 @@ func (t *jibTask) Do(ctx context.Context) v1.BuildStatus {
baseImage := t.build.Status.BaseImage
if baseImage == "" {
baseImage = t.task.BaseImage
status.BaseImage = baseImage
}
status.BaseImage = baseImage
rootImage := t.build.Status.RootImage
if rootImage == "" {
rootImage = t.task.BaseImage
}
status.RootImage = rootImage

contextDir := t.task.ContextDir
if contextDir == "" {
Expand Down
7 changes: 6 additions & 1 deletion pkg/builder/spectrum.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,13 @@ func (t *spectrumTask) Do(ctx context.Context) v1.BuildStatus {
baseImage := t.build.Status.BaseImage
if baseImage == "" {
baseImage = t.task.BaseImage
status.BaseImage = baseImage
}
status.BaseImage = baseImage
rootImage := t.build.Status.RootImage
if rootImage == "" {
rootImage = t.task.BaseImage
}
status.RootImage = rootImage

contextDir := t.task.ContextDir
if contextDir == "" {
Expand Down
9 changes: 9 additions & 0 deletions pkg/client/camel/applyconfiguration/camel/v1/buildstatus.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/controller/integrationkit/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ func (action *buildAction) handleBuildRunning(ctx context.Context, kit *v1.Integ
)
}

kit.Status.RootImage = build.Status.RootImage
kit.Status.BaseImage = build.Status.BaseImage
kit.Status.Image = build.Status.Image

Expand Down
8 changes: 6 additions & 2 deletions pkg/trait/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ func (t *builderTrait) Apply(e *Environment) error {
packageTask.Steps = make([]string, 0)
pipelineTasks = append(pipelineTasks, v1.Task{Package: packageTask})

baseImage := t.BaseImage
if baseImage == "" {
baseImage = e.Platform.Status.Build.BaseImage
}
// Publishing task
switch e.Platform.Status.Build.PublishStrategy {
case v1.IntegrationPlatformBuildPublishStrategySpectrum:
Expand All @@ -187,7 +191,7 @@ func (t *builderTrait) Apply(e *Environment) error {
Configuration: *taskConfOrDefault(tasksConf, "spectrum"),
},
PublishTask: v1.PublishTask{
BaseImage: e.Platform.Status.Build.BaseImage,
BaseImage: baseImage,
Image: getImageName(e),
Registry: e.Platform.Status.Build.Registry,
},
Expand All @@ -200,7 +204,7 @@ func (t *builderTrait) Apply(e *Environment) error {
Configuration: *taskConfOrDefault(tasksConf, "jib"),
},
PublishTask: v1.PublishTask{
BaseImage: e.Platform.Status.Build.BaseImage,
BaseImage: baseImage,
Image: getImageName(e),
Registry: e.Platform.Status.Build.Registry,
},
Expand Down

0 comments on commit 6159f9d

Please sign in to comment.