You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@camel.apache.org by GitBox <gi...@apache.org> on 2019/01/09 13:17:54 UTC

[GitHub] nicolaferraro closed pull request #317: Option to create an Integration Context from an existing image

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


With regards,
Apache Git Services