diff --git a/docs/modules/ROOT/pages/configuration/runtime-resources.adoc b/docs/modules/ROOT/pages/configuration/runtime-resources.adoc index a5aef8c923..4ed6c9eb4b 100644 --- a/docs/modules/ROOT/pages/configuration/runtime-resources.adoc +++ b/docs/modules/ROOT/pages/configuration/runtime-resources.adoc @@ -24,14 +24,14 @@ We want to use the materialized file in an integration: .resource-configmap-route.yaml ---- - from: - uri: "file:/etc/camel/resources/my-cm/?fileName=my-configmap-key&noop=true&idempotent=false" + uri: "file:/etc/camel/resources.d/_configmaps/my-cm/?fileName=my-configmap-key&noop=true&idempotent=false" steps: - setBody: simple: "resource file content is: ${body}" - to: "log:info" ---- -You can see that we're expecting to use a _my-configmap-key_ file stored in the default resource location (_/etc/camel/resources/_). In order to materialize the `Configmap` will be as easy as running the `--resource` _configmap_ syntax: +You can see that we're expecting to use a _my-configmap-key_ file stored in the default resource location (_/etc/camel/resources.d/_configmaps/_). In order to materialize the `Configmap` will be as easy as running the `--resource` _configmap_ syntax: ---- kamel run --resource configmap:my-cm resource-configmap-route.yaml @@ -58,14 +58,14 @@ We want to use the materialized secret file in an integration: .resource-secret-route.yaml ---- - from: - uri: "file:/etc/camel/resources/my-sec/?fileName=my-secret-key&noop=true&idempotent=false" + uri: "file:/etc/camel/resources.d/_secrets/my-sec/?fileName=my-secret-key&noop=true&idempotent=false" steps: - setBody: simple: "secret file content is: ${body}" - to: "log:info" ---- -You can see that we're expecting to use a _my-secret-key_ file stored in the default resource location (_/etc/camel/resources/_). In order to materialize the `Secret` will be as easy as running the `--resource` _secret_ syntax: +You can see that we're expecting to use a _my-secret-key_ file stored in the default resource location (_/etc/camel/resources.d/_secrets/_). In order to materialize the `Secret` will be as easy as running the `--resource` _secret_ syntax: ---- kamel run --resource secret:my-sec resource-secret-route.yaml diff --git a/e2e/common/config/files/resource-configmap-route.yaml b/e2e/common/config/files/resource-configmap-route.yaml index 3c90b8923f..7ffbc8e976 100644 --- a/e2e/common/config/files/resource-configmap-route.yaml +++ b/e2e/common/config/files/resource-configmap-route.yaml @@ -18,7 +18,7 @@ # --------------------------------------------------------------------------- - from: - uri: "file:/etc/camel/resources/my-cm/?fileName=my-configmap-key&noop=true&idempotent=false" + uri: "file:/etc/camel/resources.d/_configmaps/my-cm/?fileName=my-configmap-key&noop=true&idempotent=false" steps: - setBody: simple: "resource file content is: ${body}" diff --git a/e2e/common/config/files/resource-secret-route.yaml b/e2e/common/config/files/resource-secret-route.yaml index 024a4d7ec4..9ce6ac2162 100644 --- a/e2e/common/config/files/resource-secret-route.yaml +++ b/e2e/common/config/files/resource-secret-route.yaml @@ -18,7 +18,7 @@ # --------------------------------------------------------------------------- - from: - uri: "file:/etc/camel/resources/my-sec/?fileName=my-secret-key&noop=true&idempotent=false" + uri: "file:/etc/camel/resources.d/_secrets/my-sec/?fileName=my-secret-key&noop=true&idempotent=false" steps: - setBody: simple: "resource file content is: ${body}" diff --git a/e2e/common/traits/jvm_test.go b/e2e/common/traits/jvm_test.go index 958763f794..904f188a17 100644 --- a/e2e/common/traits/jvm_test.go +++ b/e2e/common/traits/jvm_test.go @@ -58,18 +58,75 @@ func TestJVMTrait(t *testing.T) { require.NoError(t, err) t.Run("JVM trait classpath", func(t *testing.T) { - g.Expect(KamelRunWithID(t, ctx, operatorID, ns, "./files/jvm/Classpath.java", "--resource", "configmap:my-deps", "-t", "jvm.classpath=/etc/camel/resources/my-deps/sample-1.0.jar").Execute()).To(Succeed()) - g.Eventually(IntegrationPodPhase(t, ctx, ns, "classpath"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) - g.Eventually(IntegrationConditionStatus(t, ctx, ns, "classpath", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) - g.Eventually(IntegrationLogs(t, ctx, ns, "classpath"), TestTimeoutShort).Should(ContainSubstring("Hello World!")) + name := RandomizedSuffixName("classpath") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, + "./files/jvm/Classpath.java", + "--name", name, + "--resource", "configmap:my-deps", + "-t", "jvm.classpath=/etc/camel/resources.d/_configmaps/my-deps/sample-1.0.jar").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Hello World!")) // check integration schema does not contains unwanted default trait value. - g.Eventually(UnstructuredIntegration(t, ctx, ns, "classpath")).ShouldNot(BeNil()) - unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, "classpath")() + g.Eventually(UnstructuredIntegration(t, ctx, ns, name)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name)() + jvmTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "jvm") + g.Expect(jvmTrait).ToNot(BeNil()) + g.Expect(len(jvmTrait)).To(Equal(1)) + g.Expect(jvmTrait["classpath"]).To(Equal("/etc/camel/resources.d/_configmaps/my-deps/sample-1.0.jar")) + mountTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "mount") + g.Expect(mountTrait).ToNot(BeNil()) + g.Expect(len(mountTrait)).To(Equal(1)) + + }) + + t.Run("JVM trait classpath on deprecated path", func(t *testing.T) { + name := RandomizedSuffixName("classpath") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, + "./files/jvm/Classpath.java", + "--name", name, + "-t", "mount.resources=configmap:my-deps/sample-1.0.jar@/etc/camel/resources", + "-t", "jvm.classpath=/etc/camel/resources/my-deps/sample-1.0.jar").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Hello World!")) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, name)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name)() jvmTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "jvm") g.Expect(jvmTrait).ToNot(BeNil()) g.Expect(len(jvmTrait)).To(Equal(1)) g.Expect(jvmTrait["classpath"]).To(Equal("/etc/camel/resources/my-deps/sample-1.0.jar")) + mountTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "mount") + g.Expect(mountTrait).ToNot(BeNil()) + g.Expect(len(mountTrait)).To(Equal(1)) + g.Expect(mountTrait["resources"]).To(ContainElements("configmap:my-deps/sample-1.0.jar@/etc/camel/resources")) + }) + + t.Run("JVM trait classpath on specific classpath", func(t *testing.T) { + name := RandomizedSuffixName("classpath") + g.Expect(KamelRunWithID(t, ctx, operatorID, ns, + "./files/jvm/Classpath.java", + "--name", name, + "-t", "mount.resources=configmap:my-deps/sample-1.0.jar@/etc/other/resources", + "-t", "jvm.classpath=/etc/other/resources/my-deps/sample-1.0.jar").Execute()).To(Succeed()) + g.Eventually(IntegrationPodPhase(t, ctx, ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + g.Eventually(IntegrationConditionStatus(t, ctx, ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + g.Eventually(IntegrationLogs(t, ctx, ns, name), TestTimeoutShort).Should(ContainSubstring("Hello World!")) + + // check integration schema does not contains unwanted default trait value. + g.Eventually(UnstructuredIntegration(t, ctx, ns, name)).ShouldNot(BeNil()) + unstructuredIntegration := UnstructuredIntegration(t, ctx, ns, name)() + jvmTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "jvm") + g.Expect(jvmTrait).ToNot(BeNil()) + g.Expect(len(jvmTrait)).To(Equal(1)) + g.Expect(jvmTrait["classpath"]).To(Equal("/etc/other/resources/my-deps/sample-1.0.jar")) + mountTrait, _, _ := unstructured.NestedMap(unstructuredIntegration.Object, "spec", "traits", "mount") + g.Expect(mountTrait).ToNot(BeNil()) + g.Expect(len(mountTrait)).To(Equal(1)) + g.Expect(mountTrait["resources"]).To(ContainElements("configmap:my-deps/sample-1.0.jar@/etc/other/resources")) }) g.Expect(Kamel(t, ctx, "delete", "--all", "-n", ns).Execute()).To(Succeed()) diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go index f79e03b837..7ca44edd49 100644 --- a/pkg/trait/jvm.go +++ b/pkg/trait/jvm.go @@ -205,8 +205,12 @@ func (t *jvmTrait) enableDebug(e *Environment) string { func (t *jvmTrait) prepareClasspathItems(container *corev1.Container) []string { classpath := sets.NewSet() + // Deprecated: replaced by /etc/camel/resources.d/[_configmaps/_secrets] (camel.ResourcesConfigmapsMountPath/camel.ResourcesSecretsMountPath). classpath.Add("./resources") - classpath.Add(filepath.ToSlash(camel.ConfigResourcesMountPath)) + classpath.Add(filepath.ToSlash(camel.ResourcesConfigmapsMountPath)) + classpath.Add(filepath.ToSlash(camel.ResourcesSecretsMountPath)) + // Deprecated: replaced by /etc/camel/resources.d/[_configmaps/_secrets] (camel.ResourcesConfigmapsMountPath/camel.ResourcesSecretsMountPath). + //nolint: staticcheck classpath.Add(filepath.ToSlash(camel.ResourcesDefaultMountPath)) if t.Classpath != "" { classpath.Add(strings.Split(t.Classpath, ":")...) diff --git a/pkg/trait/jvm_test.go b/pkg/trait/jvm_test.go index 9206e45148..13041de494 100644 --- a/pkg/trait/jvm_test.go +++ b/pkg/trait/jvm_test.go @@ -37,7 +37,9 @@ import ( ) var ( - crMountPath = filepath.ToSlash(camel.ConfigResourcesMountPath) + cmrMountPath = filepath.ToSlash(camel.ResourcesConfigmapsMountPath) + scrMountPath = filepath.ToSlash(camel.ResourcesSecretsMountPath) + // Deprecated. rdMountPath = filepath.ToSlash(camel.ResourcesDefaultMountPath) ) @@ -131,7 +133,7 @@ func TestConfigureJvmTraitExecutableSourcelessContainerWithJar(t *testing.T) { require.NoError(t, err) assert.Equal(t, []string{ "-cp", - fmt.Sprintf("./resources:%s:%s", crMountPath, rdMountPath), + fmt.Sprintf("./resources:%s:%s:%s", rdMountPath, cmrMountPath, scrMountPath), "-jar", "my-path/to/my-app.jar", }, d.Spec.Template.Spec.Containers[0].Args) } @@ -172,7 +174,7 @@ func TestConfigureJvmTraitExecutableSourcelessContainerWithJarAndOptions(t *test require.NoError(t, err) assert.Equal(t, []string{ "-Xmx1234M", "-Dmy-prop=abc", - "-cp", "./resources:/etc/camel/conf.d/_resources:/etc/camel/resources:deps/a.jar:deps/b.jar", + "-cp", "./resources:/etc/camel/resources:/etc/camel/resources.d/_configmaps:/etc/camel/resources.d/_secrets:deps/a.jar:deps/b.jar", "-jar", "my-path/to/my-app.jar", }, d.Spec.Template.Spec.Containers[0].Args) } @@ -206,7 +208,7 @@ func TestConfigureJvmTraitWithJar(t *testing.T) { require.NoError(t, err) assert.Equal(t, []string{ "-cp", - fmt.Sprintf("./resources:%s:%s", crMountPath, rdMountPath), + fmt.Sprintf("./resources:%s:%s:%s", rdMountPath, cmrMountPath, scrMountPath), "-jar", "my-path/to/my-app.jar", }, d.Spec.Template.Spec.Containers[0].Args) } @@ -246,7 +248,7 @@ func TestConfigureJvmTraitWithJarAndConfigs(t *testing.T) { require.NoError(t, err) assert.Equal(t, []string{ "-Xmx1234M", "-Dmy-prop=abc", - "-cp", "./resources:/etc/camel/conf.d/_resources:/etc/camel/resources:deps/a.jar:deps/b.jar", + "-cp", "./resources:/etc/camel/resources:/etc/camel/resources.d/_configmaps:/etc/camel/resources.d/_secrets:deps/a.jar:deps/b.jar", "-jar", "my-path/to/my-app.jar", }, d.Spec.Template.Spec.Containers[0].Args) } @@ -301,9 +303,10 @@ func TestApplyJvmTraitWithDeploymentResource(t *testing.T) { assert.Equal(t, []string{ "-cp", fmt.Sprintf( - "./resources:%s:%s:/mount/path:dependencies/*", - crMountPath, + "./resources:%s:%s:%s:/mount/path:dependencies/*", rdMountPath, + cmrMountPath, + scrMountPath, ), "io.quarkus.bootstrap.runner.QuarkusEntryPoint", }, d.Spec.Template.Spec.Containers[0].Args) @@ -335,7 +338,8 @@ func TestApplyJvmTraitWithKnativeResource(t *testing.T) { require.NoError(t, err) assert.Equal(t, []string{ "-cp", - fmt.Sprintf("./resources:%s:%s:/mount/path:dependencies/*", crMountPath, rdMountPath), + fmt.Sprintf("./resources:%s:%s:%s:/mount/path:dependencies/*", + rdMountPath, cmrMountPath, scrMountPath), "io.quarkus.bootstrap.runner.QuarkusEntryPoint", }, s.Spec.Template.Spec.Containers[0].Args) } @@ -402,7 +406,7 @@ func TestApplyJvmTraitWithExternalKitType(t *testing.T) { assert.Equal(t, []string{ "-cp", - fmt.Sprintf("./resources:%s:%s:dependencies/*", crMountPath, rdMountPath), + fmt.Sprintf("./resources:%s:%s:%s:dependencies/*", rdMountPath, cmrMountPath, scrMountPath), "io.quarkus.bootstrap.runner.QuarkusEntryPoint", }, d.Spec.Template.Spec.Containers[0].Args) } @@ -439,7 +443,9 @@ func TestApplyJvmTraitWithClasspath(t *testing.T) { require.NoError(t, err) assert.Equal(t, []string{ "-cp", - fmt.Sprintf("./resources:%s:%s:/mount/path:%s:%s:dependencies/*", crMountPath, rdMountPath, "/path/to/another/dep.jar", "/path/to/my-dep.jar"), + fmt.Sprintf("./resources:%s:%s:%s:/mount/path:%s:%s:dependencies/*", + rdMountPath, cmrMountPath, scrMountPath, + "/path/to/another/dep.jar", "/path/to/my-dep.jar"), "io.quarkus.bootstrap.runner.QuarkusEntryPoint", }, d.Spec.Template.Spec.Containers[0].Args) } diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go index bc9737f648..b05e405ce6 100644 --- a/pkg/trait/trait_types.go +++ b/pkg/trait/trait_types.go @@ -53,6 +53,10 @@ const ( // Knative does not want name=http, it only supports http1 (HTTP/1) and h2c (HTTP/2) // https://github.com/knative/specs/blob/main/specs/serving/runtime-contract.md#protocols-and-ports defaultKnativeContainerPortName = "h2c" + + secretStorageType = "secret" + configmapStorageType = "configmap" + pvcStorageType = "pvc" ) var capabilityDynamicProperty = regexp.MustCompile(`(\$\{([^}]*)\})`) @@ -569,8 +573,8 @@ func (e *Environment) configureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]c // User provided configmaps for _, configmaps := range e.collectConfigurations("configmap") { refName := kubernetes.SanitizeLabel(configmaps["value"]) - mountPath := getMountPoint(configmaps["value"], configmaps["resourceMountPoint"], "configmap", configmaps["resourceType"]) - vol := getVolume(refName, "configmap", configmaps["value"], configmaps["resourceKey"], configmaps["resourceKey"]) + mountPath := getMountPoint(configmaps["value"], configmaps["resourceMountPoint"], configmapStorageType, configmaps["resourceType"]) + vol := getVolume(refName, configmapStorageType, configmaps["value"], configmaps["resourceKey"], configmaps["resourceKey"]) mnt := getMount(refName, mountPath, "", true) *vols = append(*vols, *vol) @@ -581,8 +585,8 @@ func (e *Environment) configureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]c // User provided secrets for _, secret := range e.collectConfigurations("secret") { refName := kubernetes.SanitizeLabel(secret["value"]) - mountPath := getMountPoint(secret["value"], secret["resourceMountPoint"], "secret", secret["resourceType"]) - vol := getVolume(refName, "secret", secret["value"], secret["resourceKey"], secret["resourceKey"]) + mountPath := getMountPoint(secret["value"], secret["resourceMountPoint"], secretStorageType, secret["resourceType"]) + vol := getVolume(refName, secretStorageType, secret["value"], secret["resourceKey"], secret["resourceKey"]) mnt := getMount(refName, mountPath, "", true) *vols = append(*vols, *vol) @@ -601,7 +605,7 @@ func (e *Environment) configureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]c mountPath := configParts[1] volumeName := pvcName + "-data" - vol := getVolume(volumeName, "pvc", pvcName, "", "") + vol := getVolume(volumeName, pvcStorageType, pvcName, "", "") mnt := getMount(volumeName, mountPath, "", false) *vols = append(*vols, *vol) *mnts = append(*mnts, *mnt) @@ -615,19 +619,19 @@ func getVolume(volName, storageType, storageName, filterKey, filterValue string) VolumeSource: corev1.VolumeSource{}, } switch storageType { - case "configmap": + case configmapStorageType: volume.VolumeSource.ConfigMap = &corev1.ConfigMapVolumeSource{ LocalObjectReference: corev1.LocalObjectReference{ Name: storageName, }, Items: items, } - case "secret": + case secretStorageType: volume.VolumeSource.Secret = &corev1.SecretVolumeSource{ SecretName: storageName, Items: items, } - case "pvc": + case pvcStorageType: volume.VolumeSource.PersistentVolumeClaim = &corev1.PersistentVolumeClaimVolumeSource{ ClaimName: storageName, } @@ -671,10 +675,14 @@ func getMountPoint(resourceName string, mountPoint string, storagetype, resource return mountPoint } if resourceType == "data" { - return filepath.Join(camel.ResourcesDefaultMountPath, resourceName) + defaultResourceMountPoint := camel.ResourcesConfigmapsMountPath + if storagetype == secretStorageType { + defaultResourceMountPoint = camel.ResourcesSecretsMountPath + } + return filepath.Join(defaultResourceMountPoint, resourceName) } defaultMountPoint := camel.ConfigConfigmapsMountPath - if storagetype == "secret" { + if storagetype == secretStorageType { defaultMountPoint = camel.ConfigSecretsMountPath } diff --git a/pkg/util/camel/camel_util.go b/pkg/util/camel/camel_util.go index b5ef592e37..321ab9ad1b 100644 --- a/pkg/util/camel/camel_util.go +++ b/pkg/util/camel/camel_util.go @@ -29,14 +29,17 @@ import ( ) var ( - BasePath = "/etc/camel" - ConfDPath = filepath.Join(BasePath, "conf.d") - SourcesMountPath = filepath.Join(BasePath, "sources") - ResourcesDefaultMountPath = filepath.Join(BasePath, "resources") - ConfigResourcesMountPath = filepath.Join(ConfDPath, "_resources") - ConfigConfigmapsMountPath = filepath.Join(ConfDPath, "_configmaps") - ConfigSecretsMountPath = filepath.Join(ConfDPath, "_secrets") - ServiceBindingsMountPath = filepath.Join(ConfDPath, "_servicebindings") + BasePath = "/etc/camel" + ConfDPath = filepath.Join(BasePath, "conf.d") + ResourcesDPath = filepath.Join(BasePath, "resources.d") + SourcesMountPath = filepath.Join(BasePath, "sources") + // Deprecated: replaced by /etc/camel/resources.d/[_configmaps/_secrets] (ResourcesConfigmapsMountPath/ResourcesSecretsMountPath). + ResourcesDefaultMountPath = filepath.Join(BasePath, "resources") + ResourcesConfigmapsMountPath = filepath.Join(ResourcesDPath, "_configmaps") + ResourcesSecretsMountPath = filepath.Join(ResourcesDPath, "_secrets") + ConfigConfigmapsMountPath = filepath.Join(ConfDPath, "_configmaps") + ConfigSecretsMountPath = filepath.Join(ConfDPath, "_secrets") + ServiceBindingsMountPath = filepath.Join(ConfDPath, "_servicebindings") ) func findBestMatch(catalogs []v1.CamelCatalog, runtime v1.RuntimeSpec) (*RuntimeCatalog, error) { diff --git a/pkg/util/util.go b/pkg/util/util.go index 4ad0304c8e..2d72de0d1b 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -76,7 +76,7 @@ var ContainerPropertiesDirectory = "/etc/camel/conf.d" var ContainerRoutesDirectory = "/etc/camel/sources" // ContainerResourcesDirectory --. -var ContainerResourcesDirectory = "/etc/camel/resources" +var ContainerResourcesDirectory = "/etc/camel/resources.d" // ContainerQuarkusDirectoryName --. const ContainerQuarkusDirectoryName = "/quarkus"