nicolaferraro closed pull request #317: Option to create an Integration Context
from an existing image
URL: https://github.com/apache/camel-k/pull/317
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/pkg/apis/camel/v1alpha1/integrationcontext_types.go
b/pkg/apis/camel/v1alpha1/integrationcontext_types.go
index b85aa053..038da035 100644
--- a/pkg/apis/camel/v1alpha1/integrationcontext_types.go
+++ b/pkg/apis/camel/v1alpha1/integrationcontext_types.go
@@ -8,6 +8,7 @@ import (
// IntegrationContextSpec defines the desired state of IntegrationContext
type IntegrationContextSpec struct {
+ Image string `json:"image,omitempty"`
Dependencies []string
`json:"dependencies,omitempty"`
Profile TraitProfile `json:"profile,omitempty"`
Traits map[string]IntegrationTraitSpec `json:"traits,omitempty"`
@@ -55,6 +56,12 @@ const (
// IntegrationContextTypePlatform --
IntegrationContextTypePlatform = "platform"
+ // IntegrationContextTypeUser --
+ IntegrationContextTypeUser = "user"
+
+ // IntegrationContextTypeExternal --
+ IntegrationContextTypeExternal = "external"
+
// IntegrationContextPhaseBuilding --
IntegrationContextPhaseBuilding IntegrationContextPhase = "Building"
// IntegrationContextPhaseReady --
diff --git a/pkg/cmd/completion_bash.go b/pkg/cmd/completion_bash.go
index 115f18e3..3d7d5a77 100644
--- a/pkg/cmd/completion_bash.go
+++ b/pkg/cmd/completion_bash.go
@@ -132,13 +132,14 @@ __kamel_kubectl_get_integrationcontexts() {
fi
}
-__kamel_kubectl_get_user_integrationcontexts() {
+__kamel_kubectl_get_non_platform_integrationcontexts() {
local template
local kubectl_out
template="{{ range .items }}{{ .metadata.name }} {{ end }}"
+ label_condition="camel.apache.org/context.type!=platform"
- if kubectl_out=$(kubectl get -l camel.apache.org/context.type=user -o
template --template="${template}" integrationcontexts 2>/dev/null); then
+ if kubectl_out=$(kubectl get -l ${label_condition} -o template
--template="${template}" integrationcontexts 2>/dev/null); then
COMPREPLY=( $( compgen -W "${kubectl_out}" -- "$cur" ) )
fi
}
@@ -160,7 +161,7 @@ __custom_func() {
return
;;
kamel_context_delete)
- __kamel_kubectl_get_user_integrationcontexts
+ __kamel_kubectl_get_non_platform_integrationcontexts
return
;;
*)
@@ -215,7 +216,7 @@ func configureKnownBashCompletions(command *cobra.Command) {
command,
"context",
map[string][]string{
- cobra.BashCompCustom:
{"__kamel_kubectl_get_user_integrationcontexts"},
+ cobra.BashCompCustom:
{"__kamel_kubectl_get_non_platform_integrationcontexts"},
},
)
configureBashAnnotationForFlag(
diff --git a/pkg/cmd/context_create.go b/pkg/cmd/context_create.go
index 7090d9b8..5463f75b 100644
--- a/pkg/cmd/context_create.go
+++ b/pkg/cmd/context_create.go
@@ -23,6 +23,8 @@ import (
"strconv"
"strings"
+ "github.com/apache/camel-k/pkg/trait"
+
"github.com/apache/camel-k/pkg/util"
"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
@@ -48,11 +50,13 @@ func newContextCreateCmd(rootCmdOptions *RootCmdOptions)
*cobra.Command {
}
cmd.Flags().StringVarP(&impl.runtime, "runtime", "r", "jvm", "Runtime
provided by the context")
+ cmd.Flags().StringVar(&impl.image, "image", "", "Image used to create
the context")
cmd.Flags().StringSliceVarP(&impl.dependencies, "dependency", "d", nil,
"Add a dependency")
cmd.Flags().StringSliceVarP(&impl.properties, "property", "p", nil,
"Add a camel property")
cmd.Flags().StringSliceVar(&impl.configmaps, "configmap", nil, "Add a
ConfigMap")
cmd.Flags().StringSliceVar(&impl.secrets, "secret", nil, "Add a Secret")
- cmd.Flags().StringSliceVar(&impl.Repositories, "repository", nil, "Add
a maven repository")
+ cmd.Flags().StringSliceVar(&impl.repositories, "repository", nil, "Add
a maven repository")
+ cmd.Flags().StringSliceVarP(&impl.traits, "trait", "t", nil, "Configure
a trait. E.g. \"-t service.enabled=false\"")
// completion support
configureKnownCompletions(&cmd)
@@ -64,11 +68,13 @@ type contextCreateCommand struct {
*RootCmdOptions
runtime string
+ image string
dependencies []string
properties []string
configmaps []string
secrets []string
- Repositories []string
+ repositories []string
+ traits []string
}
func (command *contextCreateCommand) validateArgs(cmd *cobra.Command, args
[]string) error {
@@ -84,6 +90,18 @@ func (command *contextCreateCommand) run(cmd *cobra.Command,
args []string) erro
if err != nil {
return err
}
+
+ catalog := trait.NewCatalog(command.Context, c)
+ tp := catalog.ComputeTraitsProperties()
+ for _, t := range command.traits {
+ kv := strings.SplitN(t, "=", 2)
+
+ if !util.StringSliceExists(tp, kv[0]) {
+ fmt.Printf("Error: %s is not a valid trait property\n",
t)
+ return nil
+ }
+ }
+
ctx := v1alpha1.NewIntegrationContext(command.Namespace, args[0])
key := k8sclient.ObjectKey{
Namespace: command.Namespace,
@@ -101,14 +119,27 @@ func (command *contextCreateCommand) run(cmd
*cobra.Command, args []string) erro
ctx = v1alpha1.NewIntegrationContext(command.Namespace,
kubernetes.SanitizeName(args[0]))
ctx.Labels = map[string]string{
- "camel.apache.org/context.type": "user",
+ "camel.apache.org/context.type":
v1alpha1.IntegrationContextTypeUser,
}
ctx.Spec = v1alpha1.IntegrationContextSpec{
Dependencies: make([]string, 0, len(command.dependencies)),
Configuration: make([]v1alpha1.ConfigurationSpec, 0),
- Repositories: command.Repositories,
+ Repositories: command.repositories,
}
+ if command.image != "" {
+ //
+ // if the image is set, the context do not require any build but
+ // is be marked as external as the information about the
classpath
+ // is missing so it cannot be used as base for other contexts
+ //
+ ctx.Labels["camel.apache.org/context.type"] =
v1alpha1.IntegrationContextTypeExternal
+
+ //
+ // Set the image to be used by the context
+ //
+ ctx.Spec.Image = command.image
+ }
for _, item := range command.dependencies {
switch {
case strings.HasPrefix(item, "mvn:"):
@@ -145,6 +176,11 @@ func (command *contextCreateCommand) run(cmd
*cobra.Command, args []string) erro
Value: item,
})
}
+ for _, item := range command.traits {
+ if err := command.configureTrait(&ctx, item); err != nil {
+ return nil
+ }
+ }
existed := false
err = c.Create(command.Context, &ctx)
@@ -173,3 +209,28 @@ func (command *contextCreateCommand) run(cmd
*cobra.Command, args []string) erro
return nil
}
+
+func (*contextCreateCommand) configureTrait(ctx *v1alpha1.IntegrationContext,
config string) error {
+ if ctx.Spec.Traits == nil {
+ ctx.Spec.Traits = make(map[string]v1alpha1.IntegrationTraitSpec)
+ }
+
+ parts := traitConfigRegexp.FindStringSubmatch(config)
+ if len(parts) < 4 {
+ return errors.New("unrecognized config format (expected
\"<trait>.<prop>=<val>\"): " + config)
+ }
+ traitID := parts[1]
+ prop := parts[2][1:]
+ val := parts[3]
+
+ spec, ok := ctx.Spec.Traits[traitID]
+ if !ok {
+ spec = v1alpha1.IntegrationTraitSpec{
+ Configuration: make(map[string]string),
+ }
+ }
+
+ spec.Configuration[prop] = val
+ ctx.Spec.Traits[traitID] = spec
+ return nil
+}
diff --git a/pkg/cmd/context_get.go b/pkg/cmd/context_get.go
index 3fdab174..a0d88b10 100644
--- a/pkg/cmd/context_get.go
+++ b/pkg/cmd/context_get.go
@@ -49,7 +49,8 @@ func newContextGetCmd(rootCmdOptions *RootCmdOptions)
*cobra.Command {
},
}
- cmd.Flags().BoolVar(&impl.user, "user", true, "Includes user contexts")
+ cmd.Flags().BoolVar(&impl.user, v1alpha1.IntegrationContextTypeUser,
true, "Includes user contexts")
+ cmd.Flags().BoolVar(&impl.external,
v1alpha1.IntegrationContextTypeExternal, true, "Includes external contexts")
cmd.Flags().BoolVar(&impl.platform,
v1alpha1.IntegrationContextTypePlatform, true, "Includes platform contexts")
return &cmd
@@ -58,6 +59,7 @@ func newContextGetCmd(rootCmdOptions *RootCmdOptions)
*cobra.Command {
type contextGetCommand struct {
*RootCmdOptions
user bool
+ external bool
platform bool
}
@@ -80,10 +82,11 @@ func (command *contextGetCommand) run() error {
fmt.Fprintln(w, "NAME\tPHASE\tTYPE\tIMAGE")
for _, ctx := range ctxList.Items {
t := ctx.Labels["camel.apache.org/context.type"]
- u := command.user && t == "user"
+ u := command.user && t == v1alpha1.IntegrationContextTypeUser
+ e := command.external && t ==
v1alpha1.IntegrationContextTypeExternal
p := command.platform && t ==
v1alpha1.IntegrationContextTypePlatform
- if u || p {
+ if u || e || p {
fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", ctx.Name,
string(ctx.Status.Phase), t, ctx.Status.Image)
}
}
diff --git a/pkg/controller/integrationcontext/initialize.go
b/pkg/controller/integrationcontext/initialize.go
index 20302acd..80b9452a 100644
--- a/pkg/controller/integrationcontext/initialize.go
+++ b/pkg/controller/integrationcontext/initialize.go
@@ -52,15 +52,19 @@ func (action *initializeAction) Handle(ctx context.Context,
ictx *v1alpha1.Integ
target := ictx.DeepCopy()
- // execute custom initialization
- //if err := trait.apply(nil, context); err != nil {
- // return err
- //}
-
- // update the status
- logrus.Info("Context ", target.Name, " transitioning to state ",
v1alpha1.IntegrationContextPhaseBuilding)
+ // by default the context should be build
target.Status.Phase = v1alpha1.IntegrationContextPhaseBuilding
- dgst, err := digest.ComputeForIntegrationContext(ictx)
+
+ if target.Spec.Image != "" {
+ // but in case it has been created from an image, mark the
+ // context as ready
+ target.Status.Phase = v1alpha1.IntegrationContextPhaseReady
+
+ // and set the image to be used
+ target.Status.Image = target.Spec.Image
+ }
+
+ dgst, err := digest.ComputeForIntegrationContext(target)
if err != nil {
return err
}
diff --git a/pkg/trait/classpath.go b/pkg/trait/classpath.go
index 2eec71a9..ff50440a 100644
--- a/pkg/trait/classpath.go
+++ b/pkg/trait/classpath.go
@@ -81,6 +81,15 @@ func (t *classpathTrait) Apply(e *Environment) error {
deps = append(deps, artifact.Target)
}
+ if e.Context.Labels["camel.apache.org/context.type"] ==
v1alpha1.IntegrationContextTypeExternal {
+ //
+ // In case of an external created context. we do not have any
information about
+ // the classpath so we assume the all jars in
/deployments/dependencies/ have
+ // to be taken into account
+ //
+ deps = append(deps, "/deployments/dependencies/*")
+ }
+
envvar.SetVal(&e.EnvVars, "JAVA_CLASSPATH", strings.Join(deps, ":"))
return nil
diff --git a/pkg/trait/springboot.go b/pkg/trait/springboot.go
index 7c790e53..325a8673 100644
--- a/pkg/trait/springboot.go
+++ b/pkg/trait/springboot.go
@@ -78,7 +78,6 @@ func (t *springBootTrait) Apply(e *Environment) error {
// Override env vars
envvar.SetVal(&e.EnvVars, "JAVA_MAIN_CLASS",
"org.springframework.boot.loader.PropertiesLauncher")
- envvar.SetVal(&e.EnvVars, "LOADER_PATH",
"/deployments/dependencies/")
deps := make([]string, 0, 2+len(e.Context.Status.Artifacts))
deps = append(deps, "/etc/camel/resources")
@@ -97,6 +96,15 @@ func (t *springBootTrait) Apply(e *Environment) error {
deps = append(deps, artifact.Target)
}
+ if e.Context.Labels["camel.apache.org/context.type"] ==
v1alpha1.IntegrationContextTypeExternal {
+ //
+ // In case of an external created context. we do not
have any information about
+ // the classpath so we assume the all jars in
/deployments/dependencies/ have
+ // to be taken into account
+ //
+ deps = append(deps, "/deployments/dependencies/")
+ }
+
envvar.SetVal(&e.EnvVars, "LOADER_HOME", "/deployments")
envvar.SetVal(&e.EnvVars, "LOADER_PATH", strings.Join(deps,
","))
}
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services