diff --git a/changelog/fragments/enable-run-bundle-cmd.yaml b/changelog/fragments/enable-run-bundle-cmd.yaml new file mode 100644 index 0000000000..b59d19eee3 --- /dev/null +++ b/changelog/fragments/enable-run-bundle-cmd.yaml @@ -0,0 +1,4 @@ +entries: + - description: > + Enable `run bundle` command and include e2e tests. + kind: addition diff --git a/internal/cmd/operator-sdk/run/cmd.go b/internal/cmd/operator-sdk/run/cmd.go index 5fb87cda1b..e44c78f294 100644 --- a/internal/cmd/operator-sdk/run/cmd.go +++ b/internal/cmd/operator-sdk/run/cmd.go @@ -17,6 +17,7 @@ package run import ( "github.com/spf13/cobra" + "github.com/operator-framework/operator-sdk/internal/cmd/operator-sdk/run/bundle" "github.com/operator-framework/operator-sdk/internal/cmd/operator-sdk/run/packagemanifests" "github.com/operator-framework/operator-sdk/internal/olm/operator" ) @@ -34,7 +35,7 @@ Currently only the package manifests format is supported via the 'packagemanifes cmd.AddCommand( // TODO(joelanford): enable bundle command when implementation is complete - // bundle.NewCmd(cfg), + bundle.NewCmd(cfg), packagemanifests.NewCmd(cfg), ) diff --git a/internal/cmd/operator-sdk/run/cmd_test.go b/internal/cmd/operator-sdk/run/cmd_test.go index c7784db851..12981ff5b9 100644 --- a/internal/cmd/operator-sdk/run/cmd_test.go +++ b/internal/cmd/operator-sdk/run/cmd_test.go @@ -29,8 +29,7 @@ var _ = Describe("Running a run command", func() { Expect(cmd.Long).NotTo(BeNil()) subcommands := cmd.Commands() - Expect(len(subcommands)).To(Equal(1)) - Expect(subcommands[0].Use).To(Equal("packagemanifests [packagemanifests-root-dir]")) + Expect(len(subcommands)).To(Equal(2)) }) }) }) diff --git a/test/e2e-ansible/e2e_ansible_olm_test.go b/test/e2e-ansible/e2e_ansible_olm_test.go index 3678d21b6d..0965488fee 100644 --- a/test/e2e-ansible/e2e_ansible_olm_test.go +++ b/test/e2e-ansible/e2e_ansible_olm_test.go @@ -61,12 +61,23 @@ var _ = Describe("Integrating ansible Projects with OLM", func() { err = tc.Make("bundle-build", "BUNDLE_IMG="+bundleImage) Expect(err).NotTo(HaveOccurred()) - if isRunningOnKind() { + if tc.IsRunningOnKind() { By("loading the bundle image into Kind cluster") err = tc.LoadImageToKindClusterWithName(bundleImage) Expect(err).NotTo(HaveOccurred()) } + By("running the operator bundle using `run bundle` command") + runBundleCmd := exec.Command(tc.BinaryName, "run", "bundle", bundleImage, "--namespace", tc.Kubectl.Namespace) + _, err = tc.Run(runBundleCmd) + Expect(err).NotTo(HaveOccurred()) + + By("destroying the Operator deployed with the 'run' subcommand") + cleanupPkgManCmd := exec.Command(tc.BinaryName, "cleanup", projectName, + "--timeout", "4m") + _, err = tc.Run(cleanupPkgManCmd) + Expect(err).NotTo(HaveOccurred()) + By("adding the 'packagemanifests' rule to the Makefile") err = tc.AddPackagemanifestsTarget() Expect(err).NotTo(HaveOccurred()) @@ -122,7 +133,7 @@ var _ = Describe("Integrating ansible Projects with OLM", func() { } By("destroying the deployed package manifests-formatted operator") - cleanupPkgManCmd := exec.Command(tc.BinaryName, "cleanup", projectName, + cleanupPkgManCmd = exec.Command(tc.BinaryName, "cleanup", projectName, "--timeout", "4m") _, err = tc.Run(cleanupPkgManCmd) Expect(err).NotTo(HaveOccurred()) diff --git a/test/e2e-ansible/e2e_ansible_suite_test.go b/test/e2e-ansible/e2e_ansible_suite_test.go index 8c0fe067b7..9c8669b819 100644 --- a/test/e2e-ansible/e2e_ansible_suite_test.go +++ b/test/e2e-ansible/e2e_ansible_suite_test.go @@ -42,8 +42,6 @@ var ( isPrometheusManagedBySuite = true // isOLMManagedBySuite is true when the suite tests is installing/uninstalling the OLM isOLMManagedBySuite = true - // kubectx stores the k8s context from where the tests are running - kubectx string // projectName is the name of the test project projectName string ) @@ -59,7 +57,7 @@ var _ = BeforeSuite(func(done Done) { projectName = filepath.Base(tc.Dir) By("checking the cluster type") - kubectx, err = tc.Kubectl.Command("config", "current-context") + tc.Kubectx, err = tc.Kubectl.Command("config", "current-context") Expect(err).NotTo(HaveOccurred()) By("checking API resources applied on Cluster") @@ -167,7 +165,7 @@ var _ = BeforeSuite(func(done Done) { err = tc.Make("docker-build", "IMG="+tc.ImageName) Expect(err).NotTo(HaveOccurred()) - if isRunningOnKind() { + if tc.IsRunningOnKind() { By("loading the project image into Kind cluster") err = tc.LoadImageToKindCluster() Expect(err).NotTo(HaveOccurred()) @@ -192,11 +190,6 @@ var _ = AfterSuite(func() { tc.Destroy() }) -// isRunningOnKind returns true when the tests are executed in a Kind Cluster -func isRunningOnKind() bool { - return strings.Contains(kubectx, "kind") -} - const memcachedWithBlackListTask = `- name: start memcached community.kubernetes.k8s: definition: diff --git a/test/e2e-go/e2e_go_olm_test.go b/test/e2e-go/e2e_go_olm_test.go index 5e63bd6400..749276291e 100644 --- a/test/e2e-go/e2e_go_olm_test.go +++ b/test/e2e-go/e2e_go_olm_test.go @@ -57,12 +57,23 @@ var _ = Describe("Integrating Go Projects with OLM", func() { err = tc.Make("bundle-build", "BUNDLE_IMG="+bundleImage) Expect(err).NotTo(HaveOccurred()) - if isRunningOnKind() { + if tc.IsRunningOnKind() { By("loading the bundle image into Kind cluster") err = tc.LoadImageToKindClusterWithName(bundleImage) Expect(err).NotTo(HaveOccurred()) } + By("running the operator bundle using `run bundle` command") + runBundleCmd := exec.Command(tc.BinaryName, "run", "bundle", bundleImage, "--namespace", tc.Kubectl.Namespace) + _, err = tc.Run(runBundleCmd) + Expect(err).NotTo(HaveOccurred()) + + By("destroying the Operator deployed with the 'run' subcommand") + cleanupPkgManCmd := exec.Command(tc.BinaryName, "cleanup", projectName, + "--timeout", "4m") + _, err = tc.Run(cleanupPkgManCmd) + Expect(err).NotTo(HaveOccurred()) + By("adding the 'packagemanifests' rule to the Makefile") err = tc.AddPackagemanifestsTarget() Expect(err).NotTo(HaveOccurred()) @@ -127,7 +138,7 @@ var _ = Describe("Integrating Go Projects with OLM", func() { } By("destroying the deployed package manifests-formatted operator") - cleanupPkgManCmd := exec.Command(tc.BinaryName, "cleanup", projectName, + cleanupPkgManCmd = exec.Command(tc.BinaryName, "cleanup", projectName, "--timeout", "4m") _, err = tc.Run(cleanupPkgManCmd) Expect(err).NotTo(HaveOccurred()) diff --git a/test/e2e-go/e2e_go_suite_test.go b/test/e2e-go/e2e_go_suite_test.go index 52103b1229..d7edc27cbd 100644 --- a/test/e2e-go/e2e_go_suite_test.go +++ b/test/e2e-go/e2e_go_suite_test.go @@ -44,8 +44,6 @@ var ( isPrometheusManagedBySuite = true // isOLMManagedBySuite is true when the suite tests is installing/uninstalling the OLM isOLMManagedBySuite = true - // kubectx stores the k8s context from where the tests are running - kubectx string // projectName is the name of the test project projectName string ) @@ -61,7 +59,7 @@ var _ = BeforeSuite(func(done Done) { projectName = filepath.Base(tc.Dir) By("checking the cluster type") - kubectx, err = tc.Kubectl.Command("config", "current-context") + tc.Kubectx, err = tc.Kubectl.Command("config", "current-context") Expect(err).NotTo(HaveOccurred()) By("checking API resources applied on Cluster") @@ -141,7 +139,7 @@ var _ = BeforeSuite(func(done Done) { err = tc.Make("docker-build", "IMG="+tc.ImageName) Expect(err).NotTo(HaveOccurred()) - if isRunningOnKind() { + if tc.IsRunningOnKind() { By("loading the project image into Kind cluster") err = tc.LoadImageToKindCluster() Expect(err).NotTo(HaveOccurred()) @@ -165,8 +163,3 @@ var _ = AfterSuite(func() { By("destroying container image and work dir") tc.Destroy() }) - -// isRunningOnKind returns true when the tests are executed in a Kind Cluster -func isRunningOnKind() bool { - return strings.Contains(kubectx, "kind") -} diff --git a/test/e2e-helm/e2e_helm_olm_test.go b/test/e2e-helm/e2e_helm_olm_test.go index a7c9cc44a3..b8325be7e4 100644 --- a/test/e2e-helm/e2e_helm_olm_test.go +++ b/test/e2e-helm/e2e_helm_olm_test.go @@ -61,12 +61,23 @@ var _ = Describe("Integrating Helm Projects with OLM", func() { err = tc.Make("bundle-build", "BUNDLE_IMG="+bundleImage) Expect(err).NotTo(HaveOccurred()) - if isRunningOnKind() { + if tc.IsRunningOnKind() { By("loading the bundle image into Kind cluster") err = tc.LoadImageToKindClusterWithName(bundleImage) Expect(err).NotTo(HaveOccurred()) } + By("running the operator bundle using `run bundle` command") + runBundleCmd := exec.Command(tc.BinaryName, "run", "bundle", bundleImage, "--namespace", tc.Kubectl.Namespace) + _, err = tc.Run(runBundleCmd) + Expect(err).NotTo(HaveOccurred()) + + By("destroying the Operator deployed with the 'run' subcommand") + cleanupPkgManCmd := exec.Command(tc.BinaryName, "cleanup", projectName, + "--timeout", "4m") + _, err = tc.Run(cleanupPkgManCmd) + Expect(err).NotTo(HaveOccurred()) + By("adding the 'packagemanifests' rule to the Makefile") err = tc.AddPackagemanifestsTarget() Expect(err).NotTo(HaveOccurred()) @@ -97,7 +108,7 @@ var _ = Describe("Integrating Helm Projects with OLM", func() { Expect(err).NotTo(HaveOccurred()) By("destroying the deployed package manifests-formatted operator") - cleanupPkgManCmd := exec.Command(tc.BinaryName, "cleanup", projectName, + cleanupPkgManCmd = exec.Command(tc.BinaryName, "cleanup", projectName, "--timeout", "4m") _, err = tc.Run(cleanupPkgManCmd) Expect(err).NotTo(HaveOccurred()) diff --git a/test/e2e-helm/e2e_helm_suite_test.go b/test/e2e-helm/e2e_helm_suite_test.go index 0f72d808cf..3e9d23f2d2 100644 --- a/test/e2e-helm/e2e_helm_suite_test.go +++ b/test/e2e-helm/e2e_helm_suite_test.go @@ -41,8 +41,6 @@ var ( isPrometheusManagedBySuite = true // isOLMManagedBySuite is true when the suite tests is installing/uninstalling the OLM isOLMManagedBySuite = true - // kubectx stores the k8s context from where the tests are running - kubectx string // projectName is the name of the test project projectName string ) @@ -58,7 +56,7 @@ var _ = BeforeSuite(func(done Done) { projectName = filepath.Base(tc.Dir) By("checking the cluster type") - kubectx, err = tc.Kubectl.Command("config", "current-context") + tc.Kubectx, err = tc.Kubectl.Command("config", "current-context") Expect(err).NotTo(HaveOccurred()) By("checking API resources applied on Cluster") @@ -117,7 +115,7 @@ var _ = BeforeSuite(func(done Done) { err = tc.Make("docker-build", "IMG="+tc.ImageName) Expect(err).NotTo(HaveOccurred()) - if isRunningOnKind() { + if tc.IsRunningOnKind() { By("loading the project image into Kind cluster") err = tc.LoadImageToKindCluster() Expect(err).NotTo(HaveOccurred()) @@ -141,8 +139,3 @@ var _ = AfterSuite(func() { By("destroying container image and work dir") tc.Destroy() }) - -// isRunningOnKind returns true when the tests are executed in a Kind Cluster -func isRunningOnKind() bool { - return strings.Contains(kubectx, "kind") -} diff --git a/test/internal/utils.go b/test/internal/utils.go index 3098958e08..ba3494385d 100644 --- a/test/internal/utils.go +++ b/test/internal/utils.go @@ -30,6 +30,9 @@ import ( // TestContext wraps kubebuilder's e2e TestContext. type TestContext struct { *kbtestutils.TestContext + + // kubectx stores the k8s context from where the tests are running + Kubectx string } // NewTestContext returns a TestContext containing a new kubebuilder TestContext. @@ -87,8 +90,17 @@ func ReplaceRegexInFile(path, match, replace string) { // LoadImageToKindCluster loads a local docker image with the name informed to the kind cluster func (tc TestContext) LoadImageToKindClusterWithName(image string) error { - kindOptions := []string{"load", "docker-image", image} + cluster := "kind" + if v, ok := os.LookupEnv("KIND_CLUSTER"); ok { + cluster = v + } + kindOptions := []string{"load", "docker-image", image, "--name", cluster} cmd := exec.Command("kind", kindOptions...) _, err := tc.Run(cmd) return err } + +// IsRunningOnKind returns true when the tests are executed in a Kind Cluster +func (tc TestContext) IsRunningOnKind() bool { + return strings.Contains(tc.Kubectx, "kind") +} diff --git a/website/content/en/docs/cli/operator-sdk_run.md b/website/content/en/docs/cli/operator-sdk_run.md index 414fccc760..1c7573ba5c 100644 --- a/website/content/en/docs/cli/operator-sdk_run.md +++ b/website/content/en/docs/cli/operator-sdk_run.md @@ -25,5 +25,6 @@ Currently only the package manifests format is supported via the 'packagemanifes ### SEE ALSO * [operator-sdk](../operator-sdk) - Development kit for building Kubernetes extensions and tools. +* [operator-sdk run bundle](../operator-sdk_run_bundle) - Deploy an Operator in the bundle format with OLM * [operator-sdk run packagemanifests](../operator-sdk_run_packagemanifests) - Deploy an Operator in the package manifests format with OLM diff --git a/website/content/en/docs/cli/operator-sdk_run_bundle.md b/website/content/en/docs/cli/operator-sdk_run_bundle.md new file mode 100644 index 0000000000..5708e29187 --- /dev/null +++ b/website/content/en/docs/cli/operator-sdk_run_bundle.md @@ -0,0 +1,36 @@ +--- +title: "operator-sdk run bundle" +--- +## operator-sdk run bundle + +Deploy an Operator in the bundle format with OLM + +### Synopsis + +Deploy an Operator in the bundle format with OLM + +``` +operator-sdk run bundle [flags] +``` + +### Options + +``` + --index-image string index image in which to inject bundle (default "quay.io/operator-framework/upstream-opm-builder:latest") + --install-mode InstallModeValue install mode + --timeout duration install timeout (default 2m0s) + --kubeconfig string Path to the kubeconfig file to use for CLI requests. + -n, --namespace string If present, namespace scope for this CLI request + -h, --help help for bundle +``` + +### Options inherited from parent commands + +``` + --verbose Enable verbose logging +``` + +### SEE ALSO + +* [operator-sdk run](../operator-sdk_run) - Run an Operator in a variety of environments +