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 <lburgazz...@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