This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git


The following commit(s) were added to refs/heads/master by this push:
     new e5384b6  Option to create an Integration Context from an existing 
image #316
e5384b6 is described below

commit e5384b643712f904955fbbc0048ce90a5691facb
Author: lburgazzoli <[email protected]>
AuthorDate: Sat Dec 29 16:29:29 2018 +0100

    Option to create an Integration Context from an existing image #316
---
 .../camel/v1alpha1/integrationcontext_types.go     |  7 +++
 pkg/cmd/completion_bash.go                         |  9 +--
 pkg/cmd/context_create.go                          | 69 ++++++++++++++++++++--
 pkg/cmd/context_get.go                             |  9 ++-
 pkg/controller/integrationcontext/initialize.go    | 20 ++++---
 pkg/trait/classpath.go                             |  9 +++
 pkg/trait/springboot.go                            | 10 +++-
 7 files changed, 113 insertions(+), 20 deletions(-)

diff --git a/pkg/apis/camel/v1alpha1/integrationcontext_types.go 
b/pkg/apis/camel/v1alpha1/integrationcontext_types.go
index b85aa05..038da03 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 115f18e..3d7d5a7 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 7090d9b..5463f75 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 3fdab17..a0d88b1 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 20302ac..80b9452 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 2eec71a..ff50440 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 7c790e5..325a867 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, 
","))
        }

Reply via email to