diff --git a/pkg/builder/builder.go b/pkg/builder/builder.go index 7b2e58089b..1e120f6393 100644 --- a/pkg/builder/builder.go +++ b/pkg/builder/builder.go @@ -66,7 +66,7 @@ func (b *defaultBuilder) Submit(request Request) Result { go b.loop() } - result, present := b.request.Load(request.Identifier) + result, present := b.request.Load(request.Meta.Name) if !present || result == nil { result = Result{ Request: request, @@ -75,7 +75,7 @@ func (b *defaultBuilder) Submit(request Request) Result { b.log.Infof("submitting request: %+v", request) - b.request.Store(request.Identifier, result) + b.request.Store(request.Meta.Name, result) b.requests <- request } @@ -84,7 +84,7 @@ func (b *defaultBuilder) Submit(request Request) Result { // Purge -- func (b *defaultBuilder) Purge(request Request) { - b.request.Delete(request.Identifier) + b.request.Delete(request.Meta.Name) } // ******************************** @@ -113,9 +113,9 @@ func (b *defaultBuilder) loop() { } func (b *defaultBuilder) submit(request Request) { - result, present := b.request.Load(request.Identifier) + result, present := b.request.Load(request.Meta.Name) if !present || result == nil { - b.log.Panicf("no info found for: %+v", request.Identifier) + b.log.Panicf("no info found for: %+v", request.Meta.Name) } // update the status @@ -138,7 +138,7 @@ func (b *defaultBuilder) submit(request Request) { defer os.RemoveAll(builderPath) // update the cache - b.request.Store(request.Identifier, r) + b.request.Store(request.Meta.Name, r) c := Context{ C: b.ctx, @@ -164,7 +164,7 @@ func (b *defaultBuilder) submit(request Request) { l := b.log.WithFields(logrus.Fields{ "step": step.ID(), "phase": step.Phase(), - "request": request.Identifier.String(), + "context": request.Meta.Name, }) l.Infof("executing step") @@ -195,7 +195,7 @@ func (b *defaultBuilder) submit(request Request) { } // update the cache - b.request.Store(request.Identifier, r) + b.request.Store(request.Meta.Name, r) - b.log.Infof("request %s:%s executed in %f seconds", r.Request.Identifier.Name, r.Request.Identifier.Qualifier, r.Task.Elapsed().Seconds()) + b.log.Infof("request to build context %s executed in %f seconds", request.Meta.Name, r.Task.Elapsed().Seconds()) } diff --git a/pkg/builder/builder_steps.go b/pkg/builder/builder_steps.go index 975326ea95..b339d1d369 100644 --- a/pkg/builder/builder_steps.go +++ b/pkg/builder/builder_steps.go @@ -25,6 +25,8 @@ import ( "path" "strings" + "github.com/rs/xid" + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" "github.com/operator-framework/operator-sdk/pkg/sdk" @@ -294,3 +296,35 @@ func FindBestImage(images []PublishedImage, entries []v1alpha1.Artifact) (*Publi return &bestImage, bestImageCommonLibs } + +// Notify -- +func Notify(ctx *Context) error { + c := v1alpha1.IntegrationContext{ + TypeMeta: metav1.TypeMeta{ + Kind: v1alpha1.IntegrationContextKind, + APIVersion: v1alpha1.SchemeGroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: ctx.Namespace, + Name: ctx.Request.Meta.Name, + }, + } + + if err := sdk.Get(&c); err != nil { + return err + } + + t := c.DeepCopy() + if t.Annotations == nil { + t.Annotations = make(map[string]string) + } + + // Add a random ID to trigger update + t.Annotations["camel.apache.org/build.id"] = xid.New().String() + + if err := sdk.Update(t); err != nil { + return err + } + + return nil +} diff --git a/pkg/builder/builder_types.go b/pkg/builder/builder_types.go index 0cf38ed4b8..000425f8e4 100644 --- a/pkg/builder/builder_types.go +++ b/pkg/builder/builder_types.go @@ -20,8 +20,11 @@ package builder import ( "context" "fmt" + "math" "time" + "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/apache/camel-k/pkg/util/maven" "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" @@ -29,13 +32,15 @@ import ( const ( // ProjectGenerationPhase -- - ProjectGenerationPhase int = 10 + ProjectGenerationPhase int32 = 10 // ProjectBuildPhase -- - ProjectBuildPhase int = 20 + ProjectBuildPhase int32 = 20 // ApplicationPackagePhase -- - ApplicationPackagePhase int = 30 + ApplicationPackagePhase int32 = 30 // ApplicationPublishPhase -- - ApplicationPublishPhase int = 40 + ApplicationPublishPhase int32 = 40 + // NotifyPhase -- + NotifyPhase int32 = math.MaxInt32 ) // Builder -- @@ -47,13 +52,13 @@ type Builder interface { // Step -- type Step interface { ID() string - Phase() int + Phase() int32 Execute(*Context) error } type stepWrapper struct { id string - phase int + phase int32 task func(*Context) error } @@ -65,7 +70,7 @@ func (s *stepWrapper) ID() string { return s.id } -func (s *stepWrapper) Phase() int { +func (s *stepWrapper) Phase() int32 { return s.phase } @@ -74,7 +79,7 @@ func (s *stepWrapper) Execute(ctx *Context) error { } // NewStep -- -func NewStep(ID string, phase int, task func(*Context) error) Step { +func NewStep(ID string, phase int32, task func(*Context) error) Step { s := stepWrapper{ id: ID, phase: phase, @@ -84,27 +89,9 @@ func NewStep(ID string, phase int, task func(*Context) error) Step { return &s } -// NewIdentifierForContext -- -func NewIdentifierForContext(context *v1alpha1.IntegrationContext) Identifier { - return Identifier{ - Name: "context-" + context.Name, - Qualifier: context.ResourceVersion, - } -} - -// Identifier -- -type Identifier struct { - Name string - Qualifier string -} - -func (r *Identifier) String() string { - return r.Name + ":" + r.Qualifier -} - // Request -- type Request struct { - Identifier Identifier + Meta v1.ObjectMeta Platform v1alpha1.IntegrationPlatformSpec Code v1alpha1.SourceSpec Dependencies []string diff --git a/pkg/builder/kaniko/kaniko.go b/pkg/builder/kaniko/kaniko.go index 33d8e4fe5d..a9b4a0c278 100644 --- a/pkg/builder/kaniko/kaniko.go +++ b/pkg/builder/kaniko/kaniko.go @@ -27,6 +27,7 @@ var DefaultSteps = []builder.Step{ builder.NewStep("build/compute-dependencies", builder.ProjectBuildPhase, builder.ComputeDependencies), builder.NewStep("packager", builder.ApplicationPackagePhase, builder.StandardPackager), builder.NewStep("publisher/kaniko", builder.ApplicationPublishPhase, Publisher), + builder.NewStep("notify", builder.NotifyPhase, builder.Notify), } // BuildDir is the directory where to build artifacts (shared with the Kaniko pod) diff --git a/pkg/builder/kaniko/publisher.go b/pkg/builder/kaniko/publisher.go index 823d13c4d0..88ef68ab2a 100644 --- a/pkg/builder/kaniko/publisher.go +++ b/pkg/builder/kaniko/publisher.go @@ -38,7 +38,7 @@ func Publisher(ctx *builder.Context) error { if organization == "" { organization = ctx.Namespace } - image := ctx.Request.Platform.Build.Registry + "/" + organization + "/camel-k-" + ctx.Request.Identifier.Name + ":" + ctx.Request.Identifier.Qualifier + image := ctx.Request.Platform.Build.Registry + "/" + organization + "/camel-k-" + ctx.Request.Meta.Name + ":" + ctx.Request.Meta.ResourceVersion baseDir, _ := path.Split(ctx.Archive) contextDir := path.Join(baseDir, "context") if err := tar.Extract(ctx.Archive, contextDir); err != nil { @@ -88,7 +88,7 @@ func Publisher(ctx *builder.Context) error { }, }) volumeMounts = append(volumeMounts, v1.VolumeMount{ - Name: "kaniko-secret", + Name: "kaniko-secret", MountPath: "/secret", }) envs = append(envs, v1.EnvVar{ @@ -105,14 +105,14 @@ func Publisher(ctx *builder.Context) error { }, ObjectMeta: metav1.ObjectMeta{ Namespace: ctx.Namespace, - Name: "camel-k-" + ctx.Request.Identifier.Name, + Name: "camel-k-" + ctx.Request.Meta.Name, }, Spec: v1.PodSpec{ Containers: []v1.Container{ { - Name: "kaniko", - Image: "gcr.io/kaniko-project/executor@sha256:f29393d9c8d40296e1692417089aa2023494bce9afd632acac7dd0aea763e5bc", - Args: args, + Name: "kaniko", + Image: "gcr.io/kaniko-project/executor@sha256:f29393d9c8d40296e1692417089aa2023494bce9afd632acac7dd0aea763e5bc", + Args: args, Env: envs, VolumeMounts: volumeMounts, }, diff --git a/pkg/builder/s2i/publisher.go b/pkg/builder/s2i/publisher.go index e6b0d9219d..68cd60fdf8 100644 --- a/pkg/builder/s2i/publisher.go +++ b/pkg/builder/s2i/publisher.go @@ -45,7 +45,7 @@ func Publisher(ctx *builder.Context) error { Kind: "BuildConfig", }, ObjectMeta: metav1.ObjectMeta{ - Name: "camel-k-" + ctx.Request.Identifier.Name, + Name: "camel-k-" + ctx.Request.Meta.Name, Namespace: ctx.Namespace, }, Spec: buildv1.BuildConfigSpec{ @@ -64,7 +64,7 @@ func Publisher(ctx *builder.Context) error { Output: buildv1.BuildOutput{ To: &v1.ObjectReference{ Kind: "ImageStreamTag", - Name: "camel-k-" + ctx.Request.Identifier.Name + ":" + ctx.Request.Identifier.Qualifier, + Name: "camel-k-" + ctx.Request.Meta.Name + ":" + ctx.Request.Meta.ResourceVersion, }, }, }, @@ -83,7 +83,7 @@ func Publisher(ctx *builder.Context) error { Kind: "ImageStream", }, ObjectMeta: metav1.ObjectMeta{ - Name: "camel-k-" + ctx.Request.Identifier.Name, + Name: "camel-k-" + ctx.Request.Meta.Name, Namespace: ctx.Namespace, }, Spec: imagev1.ImageStreamSpec{ @@ -113,7 +113,7 @@ func Publisher(ctx *builder.Context) error { Namespace(ctx.Namespace). Body(resource). Resource("buildconfigs"). - Name("camel-k-" + ctx.Request.Identifier.Name). + Name("camel-k-" + ctx.Request.Meta.Name). SubResource("instantiatebinary"). Do() @@ -159,7 +159,7 @@ func Publisher(ctx *builder.Context) error { return errors.New("dockerImageRepository not available in ImageStream") } - ctx.Image = is.Status.DockerImageRepository + ":" + ctx.Request.Identifier.Qualifier + ctx.Image = is.Status.DockerImageRepository + ":" + ctx.Request.Meta.ResourceVersion return nil } diff --git a/pkg/builder/s2i/s2i.go b/pkg/builder/s2i/s2i.go index e8854fe223..4d5079784f 100644 --- a/pkg/builder/s2i/s2i.go +++ b/pkg/builder/s2i/s2i.go @@ -25,4 +25,5 @@ var DefaultSteps = []builder.Step{ builder.NewStep("build/compute-dependencies", builder.ProjectBuildPhase, builder.ComputeDependencies), builder.NewStep("packager/incremental", builder.ApplicationPackagePhase, builder.IncrementalPackager), builder.NewStep("publisher/s2i", builder.ApplicationPublishPhase, Publisher), + builder.NewStep("notify", builder.NotifyPhase, builder.Notify), } diff --git a/pkg/stub/action/context/build.go b/pkg/stub/action/context/build.go index d97cfce63b..2b85770c10 100644 --- a/pkg/stub/action/context/build.go +++ b/pkg/stub/action/context/build.go @@ -62,7 +62,7 @@ func (action *buildAction) Handle(context *v1alpha1.IntegrationContext) error { } r := builder.Request{ - Identifier: builder.NewIdentifierForContext(context), + Meta: context.ObjectMeta, Dependencies: context.Spec.Dependencies, Steps: env.Steps, Platform: env.Platform.Spec, diff --git a/pkg/trait/builder_test.go b/pkg/trait/builder_test.go index ef35e96c79..f26f010523 100644 --- a/pkg/trait/builder_test.go +++ b/pkg/trait/builder_test.go @@ -77,7 +77,7 @@ func TestS2IBuilderTrait(t *testing.T) { assert.NotEmpty(t, env.ExecutedTraits) assert.Contains(t, env.ExecutedTraits, ID("builder")) assert.NotEmpty(t, env.Steps) - assert.Len(t, env.Steps, 4) + assert.Len(t, env.Steps, 5) assert.Condition(t, func() bool { for _, s := range env.Steps { if s.ID() == "publisher/s2i" && s.Phase() == builder.ApplicationPublishPhase { @@ -97,7 +97,7 @@ func TestKanikoBuilderTrait(t *testing.T) { assert.NotEmpty(t, env.ExecutedTraits) assert.Contains(t, env.ExecutedTraits, ID("builder")) assert.NotEmpty(t, env.Steps) - assert.Len(t, env.Steps, 4) + assert.Len(t, env.Steps, 5) assert.Condition(t, func() bool { for _, s := range env.Steps { if s.ID() == "publisher/kaniko" && s.Phase() == builder.ApplicationPublishPhase { diff --git a/test/build_manager_integration_test.go b/test/build_manager_integration_test.go index 63fcc12a8d..09bc0e7584 100644 --- a/test/build_manager_integration_test.go +++ b/test/build_manager_integration_test.go @@ -26,11 +26,11 @@ import ( "testing" "time" + "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" "github.com/apache/camel-k/pkg/builder" "github.com/apache/camel-k/pkg/builder/s2i" - "github.com/apache/camel-k/pkg/util/digest" - "github.com/stretchr/testify/assert" ) @@ -40,9 +40,9 @@ func TestBuildManagerBuild(t *testing.T) { b := builder.New(ctx, namespace) r := builder.Request{ - Identifier: builder.Identifier{ - Name: "man-test", - Qualifier: digest.Random(), + Meta: v1.ObjectMeta{ + Name: "man-test", + ResourceVersion: "1", }, Code: v1alpha1.SourceSpec{ Content: createTimerToLogIntegrationCode(), @@ -51,7 +51,8 @@ func TestBuildManagerBuild(t *testing.T) { "mvn:org.apache.camel/camel-core", "camel:telegram", }, - Steps: s2i.DefaultSteps, + // to not include notify step + Steps: s2i.DefaultSteps[:len(s2i.DefaultSteps)-1], } b.Submit(r) @@ -78,9 +79,9 @@ func TestBuildManagerFailedBuild(t *testing.T) { b := builder.New(ctx, namespace) r := builder.Request{ - Identifier: builder.Identifier{ - Name: "man-test", - Qualifier: digest.Random(), + Meta: v1.ObjectMeta{ + Name: "man-test", + ResourceVersion: "1", }, Code: v1alpha1.SourceSpec{ Content: createTimerToLogIntegrationCode(), @@ -88,7 +89,8 @@ func TestBuildManagerFailedBuild(t *testing.T) { Dependencies: []string{ "mvn:org.apache.camel/camel-cippalippa", }, - Steps: s2i.DefaultSteps, + // to not include notify step + Steps: s2i.DefaultSteps[:len(s2i.DefaultSteps)-1], } b.Submit(r)