You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2019/06/21 12:10:36 UTC

[camel-k] branch master updated: Automatically create catalogs from maven #744

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

lburgazzoli 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 c04a393  Automatically create catalogs from maven #744
c04a393 is described below

commit c04a393d555d9836ec9e0a2eb1fe95efa8caf156
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Thu Jun 20 23:51:29 2019 +0200

    Automatically create catalogs from maven #744
---
 .../camel/v1alpha1/camelcatalog_types_support.go   |  29 ++++
 pkg/builder/builder_utils.go                       |   2 +-
 pkg/trait/camel.go                                 | 176 +++++++++++++++++----
 pkg/trait/environment_test.go                      |  10 ++
 pkg/trait/istio_test.go                            |   4 +
 pkg/trait/rest-dsl.go                              |  36 +++--
 pkg/trait/trait_types.go                           |  15 ++
 pkg/util/maven/maven_project_test.go               |   5 +-
 pkg/util/maven/maven_types.go                      |  35 ++--
 9 files changed, 243 insertions(+), 69 deletions(-)

diff --git a/pkg/apis/camel/v1alpha1/camelcatalog_types_support.go b/pkg/apis/camel/v1alpha1/camelcatalog_types_support.go
index fed3257..d30986f 100644
--- a/pkg/apis/camel/v1alpha1/camelcatalog_types_support.go
+++ b/pkg/apis/camel/v1alpha1/camelcatalog_types_support.go
@@ -19,6 +19,35 @@ package v1alpha1
 
 import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
+// NewCamelCatalog --
+func NewCamelCatalog(namespace string, name string) CamelCatalog {
+	return CamelCatalog{
+		TypeMeta: metav1.TypeMeta{
+			APIVersion: SchemeGroupVersion.String(),
+			Kind:       CamelCatalogKind,
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Namespace: namespace,
+			Name:      name,
+		},
+	}
+}
+
+// NewCamelCatalogWithSpecs --
+func NewCamelCatalogWithSpecs(namespace string, name string, spec CamelCatalogSpec) CamelCatalog {
+	return CamelCatalog{
+		TypeMeta: metav1.TypeMeta{
+			APIVersion: SchemeGroupVersion.String(),
+			Kind:       CamelCatalogKind,
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Namespace: namespace,
+			Name:      name,
+		},
+		Spec: spec,
+	}
+}
+
 // NewCamelCatalogList --
 func NewCamelCatalogList() CamelCatalogList {
 	return CamelCatalogList{
diff --git a/pkg/builder/builder_utils.go b/pkg/builder/builder_utils.go
index 571bece..7a21beb 100644
--- a/pkg/builder/builder_utils.go
+++ b/pkg/builder/builder_utils.go
@@ -61,7 +61,7 @@ func NewMavenProject(ctx *Context) (maven.Project, error) {
 
 	p := maven.NewProjectWithGAV("org.apache.camel.k.integration", "camel-k-integration", defaults.Version)
 	p.Properties = ctx.Build.Platform.Build.Properties
-	p.DependencyManagement = maven.DependencyManagement{Dependencies: make([]maven.Dependency, 0)}
+	p.DependencyManagement = &maven.DependencyManagement{Dependencies: make([]maven.Dependency, 0)}
 	p.Dependencies = make([]maven.Dependency, 0)
 
 	//
diff --git a/pkg/trait/camel.go b/pkg/trait/camel.go
index 1881b2a..67c71da 100644
--- a/pkg/trait/camel.go
+++ b/pkg/trait/camel.go
@@ -19,8 +19,21 @@ package trait
 
 import (
 	"fmt"
+	"io/ioutil"
+	"os"
+	"path"
+	"regexp"
 
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
 	"github.com/apache/camel-k/pkg/util/camel"
+	"github.com/apache/camel-k/pkg/util/defaults"
+	"github.com/apache/camel-k/pkg/util/kubernetes"
+	"github.com/apache/camel-k/pkg/util/maven"
+	"github.com/pkg/errors"
+
+	"gopkg.in/yaml.v2"
+
+	k8serrors "k8s.io/apimachinery/pkg/api/errors"
 )
 
 type camelTrait struct {
@@ -44,56 +57,155 @@ func (t *camelTrait) Configure(e *Environment) (bool, error) {
 }
 
 func (t *camelTrait) Apply(e *Environment) error {
-	e.RuntimeVersion = e.DetermineRuntimeVersion()
-	if t.RuntimeVersion != "" {
-		e.RuntimeVersion = t.RuntimeVersion
+	ns := e.DetermineNamespace()
+	if ns == "" {
+		return errors.New("unable to determine namespace")
 	}
 
-	if e.Integration != nil {
-		if e.CamelCatalog == nil {
-			version := e.DetermineCamelVersion()
+	cv := e.DetermineCamelVersion()
+	rv := e.DetermineRuntimeVersion()
 
-			if t.Version != "" {
-				version = t.Version
-			}
+	if t.Version != "" {
+		cv = t.Version
+	}
+	if t.RuntimeVersion != "" {
+		rv = t.RuntimeVersion
+	}
 
-			c, err := camel.Catalog(e.C, e.Client, e.Integration.Namespace, version)
+	if e.CamelCatalog == nil {
+		c, err := camel.Catalog(e.C, e.Client, ns, cv)
+		if err != nil {
+			return err
+		}
+		if c == nil {
+			// if the catalog is not found in the cluster, try to create it if the
+			// required version is not set using semver constraints
+			matched, err := regexp.MatchString(`^(\d+)\.(\d+)\.([\w-\.]+)$`, cv)
 			if err != nil {
 				return err
 			}
-			if c == nil {
-				return fmt.Errorf("unable to find catalog for: %s", version)
+			if matched {
+				c, err = t.GenerateCatalog(e, cv)
+				if err != nil {
+					return err
+				}
+
+				cx := v1alpha1.NewCamelCatalogWithSpecs(ns, "camel-catalog-"+cv, c.CamelCatalogSpec)
+				cx.Labels = make(map[string]string)
+				cx.Labels["app"] = "camel-k"
+				cx.Labels["camel.apache.org/catalog.version"] = cv
+				cx.Labels["camel.apache.org/catalog.loader.version"] = cv
+				cx.Labels["camel.apache.org/catalog.generated"] = "true"
+
+				err = e.Client.Create(e.C, &cx)
+				if err != nil && !k8serrors.IsAlreadyExists(err) {
+					return err
+				}
 			}
+		}
 
-			e.CamelCatalog = c
+		if c == nil {
+			return fmt.Errorf("unable to find catalog for: %s", cv)
 		}
 
-		e.Integration.Status.CamelVersion = e.CamelCatalog.Version
-		e.Integration.Status.RuntimeVersion = e.RuntimeVersion
+		e.CamelCatalog = c
 	}
 
+	e.RuntimeVersion = rv
+
+	if e.Integration != nil {
+		e.Integration.Status.CamelVersion = e.CamelCatalog.Version
+	}
 	if e.IntegrationKit != nil {
-		if e.CamelCatalog == nil {
-			version := e.DetermineCamelVersion()
+		e.IntegrationKit.Status.CamelVersion = e.CamelCatalog.Version
+	}
 
-			if t.Version != "" {
-				version = t.Version
-			}
+	return nil
+}
 
-			c, err := camel.Catalog(e.C, e.Client, e.IntegrationKit.Namespace, version)
-			if err != nil {
-				return err
-			}
-			if c == nil {
-				return fmt.Errorf("unable to find catalog for: %s", version)
-			}
+// GenerateCatalog --
+func (t *camelTrait) GenerateCatalog(e *Environment, version string) (*camel.RuntimeCatalog, error) {
+	root := os.TempDir()
+	tmpDir, err := ioutil.TempDir(root, "camel-catalog")
+	if err != nil {
+		return nil, err
+	}
 
-			e.CamelCatalog = c
-		}
+	defer os.RemoveAll(tmpDir)
 
-		e.IntegrationKit.Status.CamelVersion = e.CamelCatalog.Version
-		e.IntegrationKit.Status.RuntimeVersion = e.RuntimeVersion
+	if err := os.MkdirAll(tmpDir, os.ModePerm); err != nil {
+		return nil, err
 	}
 
-	return nil
+	project, err := t.GenerateMavenProject(version)
+	if err != nil {
+		return nil, err
+	}
+
+	mc := maven.NewContext(tmpDir, project)
+	mc.AddArguments(maven.ExtraOptions(e.Platform.Spec.Build.LocalRepository)...)
+	mc.AddSystemProperty("catalog.path", tmpDir)
+	mc.AddSystemProperty("catalog.file", "catalog.yaml")
+
+	ns := e.DetermineNamespace()
+	if ns == "" {
+		return nil, errors.New("unable to determine namespace")
+	}
+
+	settings, err := kubernetes.ResolveValueSource(e.C, e.Client, ns, &e.Platform.Spec.Build.Maven.Settings)
+	if err != nil {
+		return nil, err
+	}
+	if settings != "" {
+		mc.SettingsData = []byte(settings)
+	}
+
+	err = maven.Run(mc)
+	if err != nil {
+		return nil, err
+	}
+
+	content, err := ioutil.ReadFile(path.Join(tmpDir, "catalog.yaml"))
+	if err != nil {
+		return nil, err
+	}
+
+	catalog := v1alpha1.CamelCatalog{}
+	if err := yaml.Unmarshal(content, &catalog); err != nil {
+		return nil, err
+	}
+
+	return camel.NewRuntimeCatalog(catalog.Spec), nil
+}
+
+// GenerateCatalogMavenProject --
+func (t *camelTrait) GenerateMavenProject(version string) (maven.Project, error) {
+	p := maven.NewProjectWithGAV("org.apache.camel.k.integration", "camel-k-catalog-generator", defaults.Version)
+	p.Build = &maven.Build{
+		DefaultGoal: "generate-resources",
+		Plugins: []maven.Plugin{
+			{
+				GroupID:    "org.apache.camel.k",
+				ArtifactID: "camel-k-maven-plugin",
+				Version:    defaults.RuntimeVersion,
+				Executions: []maven.Execution{
+					{
+						ID: "generate-catalog",
+						Goals: []string{
+							"generate-catalog",
+						},
+					},
+				},
+				Dependencies: []maven.Dependency{
+					{
+						GroupID:    "org.apache.camel",
+						ArtifactID: "camel-catalog",
+						Version:    version,
+					},
+				},
+			},
+		},
+	}
+
+	return p, nil
 }
diff --git a/pkg/trait/environment_test.go b/pkg/trait/environment_test.go
index a872868..ca5929d 100644
--- a/pkg/trait/environment_test.go
+++ b/pkg/trait/environment_test.go
@@ -31,6 +31,7 @@ import (
 
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
 func TestDefaultEnvironment(t *testing.T) {
@@ -54,6 +55,9 @@ func TestDefaultEnvironment(t *testing.T) {
 			},
 		},
 		Platform: &v1alpha1.IntegrationPlatform{
+			ObjectMeta: metav1.ObjectMeta{
+				Namespace: "ns",
+			},
 			Spec: v1alpha1.IntegrationPlatformSpec{
 				Cluster: v1alpha1.IntegrationPlatformClusterOpenShift,
 			},
@@ -119,6 +123,9 @@ func TestEnabledContainerMetaDataEnvVars(t *testing.T) {
 			},
 		},
 		Platform: &v1alpha1.IntegrationPlatform{
+			ObjectMeta: metav1.ObjectMeta{
+				Namespace: "ns",
+			},
 			Spec: v1alpha1.IntegrationPlatformSpec{
 				Cluster: v1alpha1.IntegrationPlatformClusterOpenShift,
 			},
@@ -184,6 +191,9 @@ func TestDisabledContainerMetaDataEnvVars(t *testing.T) {
 			},
 		},
 		Platform: &v1alpha1.IntegrationPlatform{
+			ObjectMeta: metav1.ObjectMeta{
+				Namespace: "ns",
+			},
 			Spec: v1alpha1.IntegrationPlatformSpec{
 				Cluster: v1alpha1.IntegrationPlatformClusterOpenShift,
 			},
diff --git a/pkg/trait/istio_test.go b/pkg/trait/istio_test.go
index 590aabe..b1ea483 100644
--- a/pkg/trait/istio_test.go
+++ b/pkg/trait/istio_test.go
@@ -29,6 +29,7 @@ import (
 	serving "github.com/knative/serving/pkg/apis/serving/v1alpha1"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
 func NewIstioTestEnv(t *testing.T, d *appsv1.Deployment, s *serving.Service) Environment {
@@ -53,6 +54,9 @@ func NewIstioTestEnv(t *testing.T, d *appsv1.Deployment, s *serving.Service) Env
 			},
 		},
 		Platform: &v1alpha1.IntegrationPlatform{
+			ObjectMeta: metav1.ObjectMeta{
+				Namespace: "ns",
+			},
 			Spec: v1alpha1.IntegrationPlatformSpec{
 				Cluster: v1alpha1.IntegrationPlatformClusterOpenShift,
 				Profile: v1alpha1.TraitProfileKnative,
diff --git a/pkg/trait/rest-dsl.go b/pkg/trait/rest-dsl.go
index 71cd6b7..6e9778d 100644
--- a/pkg/trait/rest-dsl.go
+++ b/pkg/trait/rest-dsl.go
@@ -212,25 +212,27 @@ func (t *restDslTrait) generateMavenProject(e *Environment) (maven.Project, erro
 	}
 
 	p := maven.NewProjectWithGAV("org.apache.camel.k.integration", "camel-k-rest-dsl-generator", defaults.Version)
-	p.Build.DefaultGoal = "generate-resources"
-	p.Build.Plugins = []maven.Plugin{
-		{
-			GroupID:    "org.apache.camel.k",
-			ArtifactID: "camel-k-maven-plugin",
-			Version:    e.RuntimeVersion,
-			Executions: []maven.Execution{
-				{
-					Phase: "generate-resources",
-					Goals: []string{
-						"generate-rest-xml",
+	p.Build = &maven.Build{
+		DefaultGoal: "generate-resources",
+		Plugins: []maven.Plugin{
+			{
+				GroupID:    "org.apache.camel.k",
+				ArtifactID: "camel-k-maven-plugin",
+				Version:    e.RuntimeVersion,
+				Executions: []maven.Execution{
+					{
+						Phase: "generate-resources",
+						Goals: []string{
+							"generate-rest-xml",
+						},
 					},
 				},
-			},
-			Dependencies: []maven.Dependency{
-				{
-					GroupID:    "org.apache.camel",
-					ArtifactID: "camel-swagger-rest-dsl-generator",
-					Version:    e.CamelCatalog.Version,
+				Dependencies: []maven.Dependency{
+					{
+						GroupID:    "org.apache.camel",
+						ArtifactID: "camel-swagger-rest-dsl-generator",
+						Version:    e.CamelCatalog.Version,
+					},
 				},
 			},
 		},
diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go
index 0f48b5c..63b55bb 100644
--- a/pkg/trait/trait_types.go
+++ b/pkg/trait/trait_types.go
@@ -260,6 +260,21 @@ func (e *Environment) DetermineRuntimeVersion() string {
 	return version
 }
 
+// DetermineNamespace --
+func (e *Environment) DetermineNamespace() string {
+	if e.Integration != nil && e.Integration.Namespace != "" {
+		return e.Integration.Namespace
+	}
+	if e.IntegrationKit != nil && e.IntegrationKit.Namespace != "" {
+		return e.IntegrationKit.Namespace
+	}
+	if e.Platform != nil && e.Platform.Namespace != "" {
+		return e.Platform.Namespace
+	}
+
+	return ""
+}
+
 // ComputeConfigMaps --
 func (e *Environment) ComputeConfigMaps() []runtime.Object {
 	sources := e.Integration.Sources()
diff --git a/pkg/util/maven/maven_project_test.go b/pkg/util/maven/maven_project_test.go
index cbb7daa..6c8e980 100644
--- a/pkg/util/maven/maven_project_test.go
+++ b/pkg/util/maven/maven_project_test.go
@@ -76,14 +76,11 @@ const expectedPom = `<?xml version="1.0" encoding="UTF-8"?>
       </releases>
     </pluginRepository>
   </pluginRepositories>
-  <build>
-    <plugins></plugins>
-  </build>
 </project>`
 
 func TestPomGeneration(t *testing.T) {
 	project := NewProjectWithGAV("org.apache.camel.k.integration", "camel-k-integration", "1.0.0")
-	project.DependencyManagement = DependencyManagement{
+	project.DependencyManagement = &DependencyManagement{
 		Dependencies: []Dependency{
 			{
 				GroupID:    "org.apache.camel",
diff --git a/pkg/util/maven/maven_types.go b/pkg/util/maven/maven_types.go
index 24ff0a3..c292b13 100644
--- a/pkg/util/maven/maven_types.go
+++ b/pkg/util/maven/maven_types.go
@@ -55,8 +55,8 @@ type Plugin struct {
 
 // Execution --
 type Execution struct {
-	ID    string   `xml:"id"`
-	Phase string   `xml:"phase"`
+	ID    string   `xml:"id,omitempty"`
+	Phase string   `xml:"phase,omitempty"`
 	Goals []string `xml:"goals>goal,omitempty"`
 }
 
@@ -132,6 +132,11 @@ func (c *Context) AddArguments(arguments ...string) {
 	c.AdditionalArguments = append(c.AdditionalArguments, arguments...)
 }
 
+// AddSystemProperty --
+func (c *Context) AddSystemProperty(name string, value string) {
+	c.AddArgumentf("-D%s=%s", name, value)
+}
+
 // Settings represent a maven settings
 type Settings struct {
 	XMLName           xml.Name
@@ -161,19 +166,19 @@ func (s Settings) MarshalBytes() ([]byte, error) {
 // Project represent a maven project
 type Project struct {
 	XMLName              xml.Name
-	XMLNs                string               `xml:"xmlns,attr"`
-	XMLNsXsi             string               `xml:"xmlns:xsi,attr"`
-	XsiSchemaLocation    string               `xml:"xsi:schemaLocation,attr"`
-	ModelVersion         string               `xml:"modelVersion"`
-	GroupID              string               `xml:"groupId"`
-	ArtifactID           string               `xml:"artifactId"`
-	Version              string               `xml:"version"`
-	Properties           Properties           `xml:"properties,omitempty"`
-	DependencyManagement DependencyManagement `xml:"dependencyManagement"`
-	Dependencies         []Dependency         `xml:"dependencies>dependency,omitempty"`
-	Repositories         []Repository         `xml:"repositories>repository,omitempty"`
-	PluginRepositories   []Repository         `xml:"pluginRepositories>pluginRepository,omitempty"`
-	Build                Build                `xml:"build,omitempty"`
+	XMLNs                string                `xml:"xmlns,attr"`
+	XMLNsXsi             string                `xml:"xmlns:xsi,attr"`
+	XsiSchemaLocation    string                `xml:"xsi:schemaLocation,attr"`
+	ModelVersion         string                `xml:"modelVersion"`
+	GroupID              string                `xml:"groupId"`
+	ArtifactID           string                `xml:"artifactId"`
+	Version              string                `xml:"version"`
+	Properties           Properties            `xml:"properties,omitempty"`
+	DependencyManagement *DependencyManagement `xml:"dependencyManagement"`
+	Dependencies         []Dependency          `xml:"dependencies>dependency,omitempty"`
+	Repositories         []Repository          `xml:"repositories>repository,omitempty"`
+	PluginRepositories   []Repository          `xml:"pluginRepositories>pluginRepository,omitempty"`
+	Build                *Build                `xml:"build,omitempty"`
 }
 
 // Exclusion represent a maven's dependency exlucsion