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:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to