diff --git a/pkg/deploy/deploy.go b/pkg/deploy/deploy.go index d342f8da2..7aa08a88a 100644 --- a/pkg/deploy/deploy.go +++ b/pkg/deploy/deploy.go @@ -39,6 +39,11 @@ func (o *DeployClient) Deploy(ctx context.Context) error { path = filepath.Dir(devfilePath) ) + _, err := libdevfile.ValidateAndGetCommand(*devfileObj, "", v1alpha2.DeployCommandGroupKind) + if err != nil { + return err + } + handler := component.NewRunHandler( ctx, o.kubeClient, @@ -52,7 +57,7 @@ func (o *DeployClient) Deploy(ctx context.Context) error { }, ) - err := o.buildPushAutoImageComponents(handler, *devfileObj) + err = o.buildPushAutoImageComponents(handler, *devfileObj) if err != nil { return err } diff --git a/tests/examples/source/devfiles/nodejs/devfile-autobuild-deploybydefault-no-deploy-cmd.yaml b/tests/examples/source/devfiles/nodejs/devfile-autobuild-deploybydefault-no-deploy-cmd.yaml new file mode 100644 index 000000000..552a8f540 --- /dev/null +++ b/tests/examples/source/devfiles/nodejs/devfile-autobuild-deploybydefault-no-deploy-cmd.yaml @@ -0,0 +1,151 @@ +commands: + - exec: + commandLine: npm install + component: runtime + group: + isDefault: true + kind: build + workingDir: ${PROJECT_SOURCE} + id: build + - exec: + commandLine: npm run start + component: runtime + group: + isDefault: true + kind: run + workingDir: ${PROJECT_SOURCE} + id: start-app + - exec: + commandLine: npm run debug + component: runtime + group: + isDefault: true + kind: debug + workingDir: ${PROJECT_SOURCE} + id: start-app-debug + +components: + - container: + command: [ 'tail' ] + args: [ '-f', '/dev/null' ] + endpoints: + - name: "3000-tcp" + targetPort: 3000 + - name: "debug" + targetPort: 5858 + exposure: none + env: + - name: DEBUG_PORT_PROJECT + value: "5858" + image: registry.access.redhat.com/ubi8/nodejs-12:1-36 + memoryLimit: 1024Mi + mountSources: true + name: runtime + + ####################### + # Kubernetes components + ####################### + + # deployByDefault true, not referenced in apply command => automatically created on startup + - kubernetes: + deployByDefault: true + inlined: | + apiVersion: v1 + kind: Pod + metadata: + name: k8s-deploybydefault-true-and-not-referenced + spec: + containers: + - name: main + image: busybox + command: ["/bin/sh", "-ec", "while :; do echo '.'; sleep 5 ; done"] + name: k8s-deploybydefault-true-and-not-referenced + + # deployByDefault not set, not referenced in apply command => automatically created on startup + - kubernetes: + inlined: | + apiVersion: v1 + kind: Pod + metadata: + name: k8s-deploybydefault-not-set-and-not-referenced + spec: + containers: + - name: main + image: busybox + command: ["/bin/sh", "-ec", "while :; do echo '.'; sleep 5 ; done"] + name: k8s-deploybydefault-not-set-and-not-referenced + + ####################### + # OpenShift components + ####################### + + # deployByDefault true, not referenced in apply command => automatically created on startup + - openshift: + deployByDefault: true + inlined: | + apiVersion: v1 + kind: Pod + metadata: + name: ocp-deploybydefault-true-and-not-referenced + spec: + containers: + - name: main + image: busybox + command: ["/bin/sh", "-ec", "while :; do echo '.'; sleep 5 ; done"] + name: ocp-deploybydefault-true-and-not-referenced + + # deployByDefault not set, not referenced in apply command => automatically created on startup + - openshift: + inlined: | + apiVersion: v1 + kind: Pod + metadata: + name: ocp-deploybydefault-not-set-and-not-referenced + spec: + containers: + - name: main + image: busybox + command: ["/bin/sh", "-ec", "while :; do echo '.'; sleep 5 ; done"] + name: ocp-deploybydefault-not-set-and-not-referenced + + ####################### + # Image components + ####################### + + # autoBuild true, not referenced in apply command => automatically created on startup + - image: + autoBuild: true + dockerfile: + buildContext: . + uri: Dockerfile + imageName: "{{ CONTAINER_IMAGE_REPO }}:autobuild-true-and-not-referenced" + name: autobuild-true-and-not-referenced + + # autoBuild not set, not referenced in apply command => automatically created on startup + - image: + dockerfile: + buildContext: . + uri: Dockerfile + imageName: "{{ CONTAINER_IMAGE_REPO }}:autobuild-not-set-and-not-referenced" + name: autobuild-not-set-and-not-referenced + +metadata: + description: Stack with Node.js 14 + displayName: Node.js Runtime + icon: https://nodejs.org/static/images/logos/nodejs-new-pantone-black.svg + language: javascript + name: my-node-app + projectType: nodejs + tags: + - NodeJS + - Express + - ubi8 + version: 1.0.0 +schemaVersion: 2.2.0 +starterProjects: + - git: + remotes: + origin: https://github.com/odo-devfiles/nodejs-ex.git + name: nodejs-starter +variables: + CONTAINER_IMAGE_REPO: localhost:5000/odo-dev/node diff --git a/tests/integration/cmd_devfile_deploy_test.go b/tests/integration/cmd_devfile_deploy_test.go index b3dedcc26..505202a6a 100644 --- a/tests/integration/cmd_devfile_deploy_test.go +++ b/tests/integration/cmd_devfile_deploy_test.go @@ -705,165 +705,194 @@ CMD ["npm", "start"] }) // More details on https://github.com/devfile/api/issues/852#issuecomment-1211928487 - When("starting with Devfile with autoBuild or deployByDefault components", func() { - BeforeEach(func() { - helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) - helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-autobuild-deploybydefault.yaml"), - filepath.Join(commonVar.Context, "devfile.yaml"), - cmpName) - }) - - When("running odo deploy with some components not referenced in the Devfile", func() { - var stdout string + Context("Devfile with autoBuild or deployByDefault components", func() { + When("starting with Devfile with Deploy commands", func() { BeforeEach(func() { - stdout = helper.Cmd("odo", "deploy").AddEnv("PODMAN_CMD=echo").ShouldPass().Out() + helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) + helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-autobuild-deploybydefault.yaml"), + filepath.Join(commonVar.Context, "devfile.yaml"), + cmpName) }) - It("should create the appropriate resources", func() { - By("automatically applying Kubernetes/OpenShift components with deployByDefault=true", func() { - for _, l := range []string{ - "k8s-deploybydefault-true-and-referenced", - "k8s-deploybydefault-true-and-not-referenced", - "ocp-deploybydefault-true-and-referenced", - "ocp-deploybydefault-true-and-not-referenced", - } { - Expect(stdout).Should(ContainSubstring("Creating resource Pod/%s", l)) - } - }) - By("automatically applying non-referenced Kubernetes/OpenShift components with deployByDefault not set", func() { - for _, l := range []string{ - "k8s-deploybydefault-not-set-and-not-referenced", - "ocp-deploybydefault-not-set-and-not-referenced", - } { - Expect(stdout).Should(ContainSubstring("Creating resource Pod/%s", l)) - } - }) - By("not applying Kubernetes/OpenShift components with deployByDefault=false", func() { - for _, l := range []string{ - "k8s-deploybydefault-false-and-referenced", - "k8s-deploybydefault-false-and-not-referenced", - "ocp-deploybydefault-false-and-referenced", - "ocp-deploybydefault-false-and-not-referenced", - } { - Expect(stdout).ShouldNot(ContainSubstring("Creating resource Pod/%s", l)) - } - }) - By("not applying referenced Kubernetes/OpenShift components with deployByDefault unset", func() { - Expect(stdout).ShouldNot(ContainSubstring("Creating resource Pod/k8s-deploybydefault-not-set-and-referenced")) + When("running odo deploy with some components not referenced in the Devfile", func() { + var stdout string + + BeforeEach(func() { + stdout = helper.Cmd("odo", "deploy").AddEnv("PODMAN_CMD=echo").ShouldPass().Out() }) - By("automatically applying image components with autoBuild=true", func() { - for _, tag := range []string{ - "autobuild-true-and-referenced", - "autobuild-true-and-not-referenced", - } { - Expect(stdout).Should(ContainSubstring("Building & Pushing Image: localhost:5000/odo-dev/node:%s", tag)) - } - }) - By("automatically applying non-referenced Image components with autoBuild not set", func() { - Expect(stdout).Should(ContainSubstring("Building & Pushing Image: localhost:5000/odo-dev/node:autobuild-not-set-and-not-referenced")) - }) - By("not applying image components with autoBuild=false", func() { - for _, tag := range []string{ - "autobuild-false-and-referenced", - "autobuild-false-and-not-referenced", - } { - Expect(stdout).ShouldNot(ContainSubstring("localhost:5000/odo-dev/node:%s", tag)) - } - }) - By("not applying referenced Image components with deployByDefault unset", func() { - Expect(stdout).ShouldNot(ContainSubstring("localhost:5000/odo-dev/node:autobuild-not-set-and-referenced")) + It("should create the appropriate resources", func() { + By("automatically applying Kubernetes/OpenShift components with deployByDefault=true", func() { + for _, l := range []string{ + "k8s-deploybydefault-true-and-referenced", + "k8s-deploybydefault-true-and-not-referenced", + "ocp-deploybydefault-true-and-referenced", + "ocp-deploybydefault-true-and-not-referenced", + } { + Expect(stdout).Should(ContainSubstring("Creating resource Pod/%s", l)) + } + }) + By("automatically applying non-referenced Kubernetes/OpenShift components with deployByDefault not set", func() { + for _, l := range []string{ + "k8s-deploybydefault-not-set-and-not-referenced", + "ocp-deploybydefault-not-set-and-not-referenced", + } { + Expect(stdout).Should(ContainSubstring("Creating resource Pod/%s", l)) + } + }) + By("not applying Kubernetes/OpenShift components with deployByDefault=false", func() { + for _, l := range []string{ + "k8s-deploybydefault-false-and-referenced", + "k8s-deploybydefault-false-and-not-referenced", + "ocp-deploybydefault-false-and-referenced", + "ocp-deploybydefault-false-and-not-referenced", + } { + Expect(stdout).ShouldNot(ContainSubstring("Creating resource Pod/%s", l)) + } + }) + By("not applying referenced Kubernetes/OpenShift components with deployByDefault unset", func() { + Expect(stdout).ShouldNot(ContainSubstring("Creating resource Pod/k8s-deploybydefault-not-set-and-referenced")) + }) + + By("automatically applying image components with autoBuild=true", func() { + for _, tag := range []string{ + "autobuild-true-and-referenced", + "autobuild-true-and-not-referenced", + } { + Expect(stdout).Should(ContainSubstring("Building & Pushing Image: localhost:5000/odo-dev/node:%s", tag)) + } + }) + By("automatically applying non-referenced Image components with autoBuild not set", func() { + Expect(stdout).Should(ContainSubstring("Building & Pushing Image: localhost:5000/odo-dev/node:autobuild-not-set-and-not-referenced")) + }) + By("not applying image components with autoBuild=false", func() { + for _, tag := range []string{ + "autobuild-false-and-referenced", + "autobuild-false-and-not-referenced", + } { + Expect(stdout).ShouldNot(ContainSubstring("localhost:5000/odo-dev/node:%s", tag)) + } + }) + By("not applying referenced Image components with deployByDefault unset", func() { + Expect(stdout).ShouldNot(ContainSubstring("localhost:5000/odo-dev/node:autobuild-not-set-and-referenced")) + }) }) }) + + When("running odo deploy with some components referenced in the Devfile", func() { + var stdout string + + BeforeEach(func() { + //TODO (rm3l): we do not support passing a custom deploy command yet. That's why we are manually updating the Devfile to set the default deploy command. + helper.UpdateDevfileContent(filepath.Join(commonVar.Context, "devfile.yaml"), []helper.DevfileUpdater{ + helper.DevfileCommandGroupUpdater("deploy", v1alpha2.CompositeCommandType, &v1alpha2.CommandGroup{ + Kind: v1alpha2.DeployCommandGroupKind, + IsDefault: pointer.Bool(false), + }), + helper.DevfileCommandGroupUpdater("deploy-with-referenced-components", v1alpha2.CompositeCommandType, &v1alpha2.CommandGroup{ + Kind: v1alpha2.DeployCommandGroupKind, + IsDefault: pointer.Bool(true), + }), + }) + + stdout = helper.Cmd("odo", "deploy").AddEnv("PODMAN_CMD=echo").ShouldPass().Out() + }) + + It("should create the appropriate resources", func() { + By("applying referenced Kubernetes/OpenShift components", func() { + for _, l := range []string{ + "k8s-deploybydefault-true-and-referenced", + "k8s-deploybydefault-false-and-referenced", + "k8s-deploybydefault-not-set-and-referenced", + "ocp-deploybydefault-true-and-referenced", + "ocp-deploybydefault-false-and-referenced", + "ocp-deploybydefault-not-set-and-referenced", + } { + Expect(stdout).Should(ContainSubstring("Creating resource Pod/%s", l)) + } + }) + + By("automatically applying Kubernetes/OpenShift components with deployByDefault=true", func() { + for _, l := range []string{ + "k8s-deploybydefault-true-and-referenced", + "k8s-deploybydefault-true-and-not-referenced", + "ocp-deploybydefault-true-and-referenced", + "ocp-deploybydefault-true-and-not-referenced", + } { + Expect(stdout).Should(ContainSubstring("Creating resource Pod/%s", l)) + } + }) + By("automatically applying non-referenced Kubernetes/OpenShift components with deployByDefault not set", func() { + for _, l := range []string{ + "k8s-deploybydefault-not-set-and-not-referenced", + "ocp-deploybydefault-not-set-and-not-referenced", + } { + Expect(stdout).Should(ContainSubstring("Creating resource Pod/%s", l)) + } + }) + + By("not applying non-referenced Kubernetes/OpenShift components with deployByDefault=false", func() { + for _, l := range []string{ + "k8s-deploybydefault-false-and-not-referenced", + "ocp-deploybydefault-false-and-not-referenced", + } { + Expect(stdout).ShouldNot(ContainSubstring("Creating resource Pod/%s", l)) + } + }) + + By("applying referenced image components", func() { + for _, tag := range []string{ + "autobuild-true-and-referenced", + "autobuild-false-and-referenced", + "autobuild-not-set-and-referenced", + } { + Expect(stdout).Should(ContainSubstring("Building & Pushing Image: localhost:5000/odo-dev/node:%s", tag)) + } + }) + By("automatically applying image components with autoBuild=true", func() { + for _, tag := range []string{ + "autobuild-true-and-referenced", + "autobuild-true-and-not-referenced", + } { + Expect(stdout).Should(ContainSubstring("Building & Pushing Image: localhost:5000/odo-dev/node:%s", tag)) + } + }) + By("automatically applying non-referenced Image components with autoBuild not set", func() { + Expect(stdout).Should(ContainSubstring("Building & Pushing Image: localhost:5000/odo-dev/node:autobuild-not-set-and-not-referenced")) + }) + By("not applying non-referenced image components with autoBuild=false", func() { + Expect(stdout).ShouldNot(ContainSubstring("localhost:5000/odo-dev/node:autobuild-false-and-not-referenced")) + }) + }) + }) + }) - When("running odo deploy with some components referenced in the Devfile", func() { - var stdout string - + When("starting with Devfile with no Deploy command", func() { BeforeEach(func() { - //TODO (rm3l): we do not support passing a custom deploy command yet. That's why we are manually updating the Devfile to set the default deploy command. - helper.UpdateDevfileContent(filepath.Join(commonVar.Context, "devfile.yaml"), []helper.DevfileUpdater{ - helper.DevfileCommandGroupUpdater("deploy", v1alpha2.CompositeCommandType, &v1alpha2.CommandGroup{ - Kind: v1alpha2.DeployCommandGroupKind, - IsDefault: pointer.Bool(false), - }), - helper.DevfileCommandGroupUpdater("deploy-with-referenced-components", v1alpha2.CompositeCommandType, &v1alpha2.CommandGroup{ - Kind: v1alpha2.DeployCommandGroupKind, - IsDefault: pointer.Bool(true), - }), - }) - - stdout = helper.Cmd("odo", "deploy").AddEnv("PODMAN_CMD=echo").ShouldPass().Out() + helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) + helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-autobuild-deploybydefault-no-deploy-cmd.yaml"), + filepath.Join(commonVar.Context, "devfile.yaml"), + cmpName) }) - It("should create the appropriate resources", func() { - By("applying referenced Kubernetes/OpenShift components", func() { - for _, l := range []string{ - "k8s-deploybydefault-true-and-referenced", - "k8s-deploybydefault-false-and-referenced", - "k8s-deploybydefault-not-set-and-referenced", - "ocp-deploybydefault-true-and-referenced", - "ocp-deploybydefault-false-and-referenced", - "ocp-deploybydefault-not-set-and-referenced", - } { - Expect(stdout).Should(ContainSubstring("Creating resource Pod/%s", l)) + It("should fail to run odo deploy", func() { + stdout, stderr := helper.Cmd("odo", "deploy").AddEnv("PODMAN_CMD=echo").ShouldFail().OutAndErr() + By("not automatically applying Kubernetes/OpenShift components ", func() { + for _, s := range []string{stdout, stderr} { + Expect(s).ShouldNot(ContainSubstring("Creating resource Pod/")) } }) - - By("automatically applying Kubernetes/OpenShift components with deployByDefault=true", func() { - for _, l := range []string{ - "k8s-deploybydefault-true-and-referenced", - "k8s-deploybydefault-true-and-not-referenced", - "ocp-deploybydefault-true-and-referenced", - "ocp-deploybydefault-true-and-not-referenced", - } { - Expect(stdout).Should(ContainSubstring("Creating resource Pod/%s", l)) + By("not automatically applying Image components ", func() { + for _, s := range []string{stdout, stderr} { + Expect(s).ShouldNot(ContainSubstring("Building & Pushing Image: localhost:5000/odo-dev/node:")) } }) - By("automatically applying non-referenced Kubernetes/OpenShift components with deployByDefault not set", func() { - for _, l := range []string{ - "k8s-deploybydefault-not-set-and-not-referenced", - "ocp-deploybydefault-not-set-and-not-referenced", - } { - Expect(stdout).Should(ContainSubstring("Creating resource Pod/%s", l)) - } - }) - - By("not applying non-referenced Kubernetes/OpenShift components with deployByDefault=false", func() { - for _, l := range []string{ - "k8s-deploybydefault-false-and-not-referenced", - "ocp-deploybydefault-false-and-not-referenced", - } { - Expect(stdout).ShouldNot(ContainSubstring("Creating resource Pod/%s", l)) - } - }) - - By("applying referenced image components", func() { - for _, tag := range []string{ - "autobuild-true-and-referenced", - "autobuild-false-and-referenced", - "autobuild-not-set-and-referenced", - } { - Expect(stdout).Should(ContainSubstring("Building & Pushing Image: localhost:5000/odo-dev/node:%s", tag)) - } - }) - By("automatically applying image components with autoBuild=true", func() { - for _, tag := range []string{ - "autobuild-true-and-referenced", - "autobuild-true-and-not-referenced", - } { - Expect(stdout).Should(ContainSubstring("Building & Pushing Image: localhost:5000/odo-dev/node:%s", tag)) - } - }) - By("automatically applying non-referenced Image components with autoBuild not set", func() { - Expect(stdout).Should(ContainSubstring("Building & Pushing Image: localhost:5000/odo-dev/node:autobuild-not-set-and-not-referenced")) - }) - By("not applying non-referenced image components with autoBuild=false", func() { - Expect(stdout).ShouldNot(ContainSubstring("localhost:5000/odo-dev/node:autobuild-false-and-not-referenced")) + By("displaying an error message", func() { + Expect(stderr).Should(ContainSubstring("no deploy command found in devfile")) }) }) }) - }) }) diff --git a/tests/integration/interactive_deploy_test.go b/tests/integration/interactive_deploy_test.go index 03f201573..d46b7374d 100644 --- a/tests/integration/interactive_deploy_test.go +++ b/tests/integration/interactive_deploy_test.go @@ -64,11 +64,11 @@ var _ = Describe("odo deploy interactive command tests", func() { helper.ExpectString(ctx, "Enter component name") helper.SendLine(ctx, "my-app") - helper.ExpectString(ctx, "no default deploy command found in devfile") + helper.ExpectString(ctx, "no deploy command found in devfile") }) Expect(err).To(Not(BeNil())) - Expect(output).To(ContainSubstring("no default deploy command found in devfile")) + Expect(output).To(ContainSubstring("no deploy command found in devfile")) Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) }) @@ -98,11 +98,11 @@ var _ = Describe("odo deploy interactive command tests", func() { helper.ExpectString(ctx, "Enter component name") helper.SendLine(ctx, "my-app") - helper.ExpectString(ctx, "no default deploy command found in devfile") + helper.ExpectString(ctx, "no deploy command found in devfile") }) Expect(err).To(Not(BeNil())) - Expect(output).To(ContainSubstring("no default deploy command found in devfile")) + Expect(output).To(ContainSubstring("no deploy command found in devfile")) Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) }) @@ -139,7 +139,7 @@ var _ = Describe("odo deploy interactive command tests", func() { helper.ExpectString(ctx, "Enter component name") helper.SendLine(ctx, "my-app") - helper.ExpectString(ctx, "no default deploy command found in devfile") + helper.ExpectString(ctx, "no deploy command found in devfile") }) Expect(err).To(Not(BeNil()))