From 4a990d783f9eaa96b75aad65a2543da0d749a5fb Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Thu, 30 Apr 2020 19:19:26 +0100 Subject: [PATCH 1/7] feat: allow kb layout works on operator-sdk run local command --- cmd/operator-sdk/run/local.go | 148 ++++++++++++++++--------- internal/util/kubebuilder/constants.go | 20 ++++ internal/util/projutil/project_util.go | 14 +++ 3 files changed, 130 insertions(+), 52 deletions(-) create mode 100644 internal/util/kubebuilder/constants.go diff --git a/cmd/operator-sdk/run/local.go b/cmd/operator-sdk/run/local.go index 8bd9753630..52b0008b49 100644 --- a/cmd/operator-sdk/run/local.go +++ b/cmd/operator-sdk/run/local.go @@ -25,7 +25,12 @@ import ( "strings" "syscall" + log "github.com/sirupsen/logrus" + "github.com/spf13/pflag" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "github.com/operator-framework/operator-sdk/internal/scaffold" + kbutil "github.com/operator-framework/operator-sdk/internal/util/kubebuilder" "github.com/operator-framework/operator-sdk/internal/util/projutil" "github.com/operator-framework/operator-sdk/pkg/ansible" aoflags "github.com/operator-framework/operator-sdk/pkg/ansible/flags" @@ -33,10 +38,6 @@ import ( hoflags "github.com/operator-framework/operator-sdk/pkg/helm/flags" "github.com/operator-framework/operator-sdk/pkg/k8sutil" "github.com/operator-framework/operator-sdk/pkg/log/zap" - - log "github.com/sirupsen/logrus" - "github.com/spf13/pflag" - logf "sigs.k8s.io/controller-runtime/pkg/log" ) type runLocalArgs struct { @@ -65,6 +66,8 @@ func (c *runLocalArgs) addToFlags(fs *pflag.FlagSet) { func (c runLocalArgs) run() error { log.Infof("Running the operator locally in namespace %s.", c.watchNamespace) + projutil.MustInProjectRoot() + switch t := projutil.GetOperatorType(); t { case projutil.OperatorTypeGo: return c.runGo() @@ -76,65 +79,48 @@ func (c runLocalArgs) run() error { return projutil.ErrUnknownOperatorType{} } +// runGo will run the project locally for the Go Type projects func (c runLocalArgs) runGo() error { - projutil.MustInProjectRoot() - absProjectPath := projutil.MustGetwd() - projectName := filepath.Base(absProjectPath) - outputBinName := filepath.Join(scaffold.BuildBinDir, projectName+"-local") - if runtime.GOOS == "windows" { - outputBinName += ".exe" - } - if err := c.buildLocal(outputBinName); err != nil { - return fmt.Errorf("failed to build operator to run locally: %v", err) - } - - args := []string{} - if c.operatorFlags != "" { - extraArgs := strings.Split(c.operatorFlags, " ") - args = append(args, extraArgs...) + // Build the project and generate binary that will be executed + binName, err := c.generateBinary() + if err != nil { + return err } - - var dc *exec.Cmd - + // Get the args that will be used to exec the binary. + // Users are allowed to use the flag operator-flags to pass any value that they may wish + args := c.buildArgsBasedOnOperatorFlag() + // Build the command + var cmd *exec.Cmd if c.enableDelve { - delveArgs := []string{"--listen=:2345", "--headless=true", "--api-version=2", "exec", outputBinName, "--"} - delveArgs = append(delveArgs, args...) - - dc = exec.Command("dlv", delveArgs...) - log.Infof("Delve debugger enabled with args %s", delveArgs) + cmd = getExecCmdWithDebugger(binName, args) } else { - dc = exec.Command(outputBinName, args...) + cmd = exec.Command(binName, args...) } - + // Kills the binary execution, if the exit signal be raised from the container ch := make(chan os.Signal) signal.Notify(ch, os.Interrupt, syscall.SIGTERM) go func() { <-ch - err := dc.Process.Kill() + err := cmd.Process.Kill() if err != nil { log.Fatalf("Failed to terminate the operator: (%v)", err) } os.Exit(0) }() - dc.Env = os.Environ() - dc.Env = append(dc.Env, fmt.Sprintf("%s=%s", k8sutil.ForceRunModeEnv, k8sutil.LocalRunMode)) - // only set env var if user explicitly specified a kubeconfig path - if c.kubeconfig != "" { - dc.Env = append(dc.Env, fmt.Sprintf("%v=%v", k8sutil.KubeConfigEnvVar, c.kubeconfig)) - } - dc.Env = append(dc.Env, fmt.Sprintf("%v=%v", k8sutil.WatchNamespaceEnvVar, c.watchNamespace)) - + // Add default env vars and values informed via flags + c.addEnvVars(cmd) + // todo: check if it should really be here. Shows that it should be part of AnsibleRun only. // Set the ANSIBLE_ROLES_PATH if c.ansibleOperatorFlags != nil && len(c.ansibleOperatorFlags.AnsibleRolesPath) > 0 { - log.Info(fmt.Sprintf("set the value %v for environment variable %v.", c.ansibleOperatorFlags.AnsibleRolesPath, - aoflags.AnsibleRolesPathEnvVar)) - dc.Env = append(dc.Env, fmt.Sprintf("%v=%v", aoflags.AnsibleRolesPathEnvVar, c.ansibleOperatorFlags.AnsibleRolesPath)) + log.Info(fmt.Sprintf("set the value %v for environment variable %v.", + c.ansibleOperatorFlags.AnsibleRolesPath, aoflags.AnsibleRolesPathEnvVar)) + cmd.Env = append(cmd.Env, fmt.Sprintf("%v=%v", aoflags.AnsibleRolesPathEnvVar, + c.ansibleOperatorFlags.AnsibleRolesPath)) } - - if err := projutil.ExecCmd(dc); err != nil { - return fmt.Errorf("failed to run operator locally: %v", err) + // Execute the command build above to exec the binary build with the project + if err := projutil.ExecCmd(cmd); err != nil { + return err } - return nil } @@ -154,6 +140,7 @@ func (c runLocalArgs) runHelm() error { return helm.Run(c.helmOperatorFlags) } +// setupOperatorEnv will add envvar for the kubeconfig and namespace informed func setupOperatorEnv(kubeconfig, namespace string) error { // Set the kubeconfig that the manager will be able to grab // only set env var if user explicitly specified a kubeconfig path @@ -168,8 +155,6 @@ func setupOperatorEnv(kubeconfig, namespace string) error { return fmt.Errorf("failed to set %s environment variable: %v", k8sutil.WatchNamespaceEnvVar, err) } } - // Set the operator name, if not already set - projutil.MustInProjectRoot() if _, err := k8sutil.GetOperatorName(); err != nil { operatorName := filepath.Base(projutil.MustGetwd()) if err := os.Setenv(k8sutil.OperatorNameEnvVar, operatorName); err != nil { @@ -179,7 +164,8 @@ func setupOperatorEnv(kubeconfig, namespace string) error { return nil } -func (c runLocalArgs) buildLocal(outputBinName string) error { +// getBuildRunLocalArgs will return the Args to buil the project based on the flags used +func (c runLocalArgs) getBuildRunLocalArgs() []string { var args []string if c.ldFlags != "" { args = []string{"-ldflags", c.ldFlags} @@ -187,10 +173,68 @@ func (c runLocalArgs) buildLocal(outputBinName string) error { if c.enableDelve { args = append(args, "-gcflags=\"all=-N -l\"") } + return args +} + +// generateBinary will build the Go project by running the command `go build -o bin/manager main.go` +func (c runLocalArgs) generateBinary() (string, error) { + // Define name of the bin and where is the main.go pkg for each layout + var name, packagePath string + if kbutil.HasProjectFile() { + name = filepath.Join(kbutil.BinBuildDir, projutil.GetProjectName()+"-local") + packagePath = kbutil.PkgPath + } else { + // todo: remove the if, else when the legacy code is no longer supported + packagePath = path.Join(projutil.GetGoPkg(), filepath.ToSlash(scaffold.ManagerDir)) + name = filepath.Join(scaffold.BuildBinDir, projutil.GetProjectName()+"-local") + } + // allow the command works in windows SO + if runtime.GOOS == "windows" { + name += ".exe" + } opts := projutil.GoCmdOptions{ - BinName: outputBinName, - PackagePath: path.Join(projutil.GetGoPkg(), filepath.ToSlash(scaffold.ManagerDir)), - Args: args, + BinName: name, + PackagePath: packagePath, + Args: c.getBuildRunLocalArgs(), + } + if err := projutil.GoBuild(opts); err != nil { + return name, err + } + return name, nil +} + +// execCmdForBinWithDebugger will exec the command with the delve required args +// Note that delve is a debugger for the Go programming language. +// More info: https://github.com/go-delve/delve +func getExecCmdWithDebugger(binName string, args []string) *exec.Cmd { + delveArgs := []string{"--listen=:2345", "--headless=true", "--api-version=2", "exec", binName, "--"} + delveArgs = append(delveArgs, args...) + log.Infof("Delve debugger enabled with args %s", delveArgs) + return exec.Command("dlv", delveArgs...) +} + +// addEnvVars will add the EnvVars to the command informed +func (c runLocalArgs) addEnvVars(cmd *exec.Cmd) { + cmd.Env = os.Environ() + + // Set EnvVar to let the project knows that it is running outside of the cluster + cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k8sutil.ForceRunModeEnv, k8sutil.LocalRunMode)) + + // only set env var if user explicitly specified a kubeconfig path + if c.kubeconfig != "" { + cmd.Env = append(cmd.Env, fmt.Sprintf("%v=%v", k8sutil.KubeConfigEnvVar, c.kubeconfig)) + } + + // Set WATCH_NAMESPACE with the value informed via flag + cmd.Env = append(cmd.Env, fmt.Sprintf("%v=%v", k8sutil.WatchNamespaceEnvVar, c.watchNamespace)) +} + +// buildArgsBasedOnOperatorFlag will return an array with all args used in the flags +func (c runLocalArgs) buildArgsBasedOnOperatorFlag() []string { + args := []string{} + if c.operatorFlags != "" { + extraArgs := strings.Split(c.operatorFlags, " ") + args = append(args, extraArgs...) } - return projutil.GoBuild(opts) + return args } diff --git a/internal/util/kubebuilder/constants.go b/internal/util/kubebuilder/constants.go new file mode 100644 index 0000000000..49e86888fa --- /dev/null +++ b/internal/util/kubebuilder/constants.go @@ -0,0 +1,20 @@ +// Copyright 2018 The Operator-SDK Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package kbutil + +const ( + BinBuildDir = "bin" + PkgPath = "main.go" +) diff --git a/internal/util/projutil/project_util.go b/internal/util/projutil/project_util.go index 5200e4085d..27f779f7ed 100644 --- a/internal/util/projutil/project_util.go +++ b/internal/util/projutil/project_util.go @@ -206,6 +206,14 @@ func GetOperatorType() OperatorType { } func IsOperatorGo() bool { + // todo: in the future we should check the plugin prefx to see if is or not a go type + // for now, we can assume that any project with the kubebuilder layout is Go Type + if kbutil.HasProjectFile() { + return true + } + + // todo: remove the following code when the legacy layout is no longer supported + // we can check it using the Project File _, err := os.Stat(managerMainFile) if err == nil || os.IsExist(err) { return true @@ -315,3 +323,9 @@ func PrintDeprecationWarning(msg string) { fmt.Printf(noticeColor, "[Deprecation Notice] "+msg+". Refer to the version upgrade guide "+ "for more information: https://operator-sdk.netlify.com/docs/migration/version-upgrade-guide\n\n") } + +// GetProjectName will return the name of the project +func GetProjectName() string { + absProjectPath := MustGetwd() + return filepath.Base(absProjectPath) +} From 4bde36633a921b13daa2e0d377df845ba2ed334e Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Fri, 1 May 2020 02:58:41 +0100 Subject: [PATCH 2/7] review and hidden flags --- cmd/operator-sdk/run/cmd.go | 15 +++++--- cmd/operator-sdk/run/local.go | 51 +++++++++++++++----------- internal/util/kubebuilder/constants.go | 2 +- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/cmd/operator-sdk/run/cmd.go b/cmd/operator-sdk/run/cmd.go index 8c5726af40..b63d29cce7 100644 --- a/cmd/operator-sdk/run/cmd.go +++ b/cmd/operator-sdk/run/cmd.go @@ -19,15 +19,16 @@ import ( "fmt" "path/filepath" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + olmcatalog "github.com/operator-framework/operator-sdk/internal/generate/olm-catalog" olmoperator "github.com/operator-framework/operator-sdk/internal/olm/operator" k8sinternal "github.com/operator-framework/operator-sdk/internal/util/k8sutil" + kbutil "github.com/operator-framework/operator-sdk/internal/util/kubebuilder" "github.com/operator-framework/operator-sdk/internal/util/projutil" aoflags "github.com/operator-framework/operator-sdk/pkg/ansible/flags" hoflags "github.com/operator-framework/operator-sdk/pkg/helm/flags" - - log "github.com/sirupsen/logrus" - "github.com/spf13/cobra" ) type runCmd struct { @@ -127,9 +128,11 @@ https://sdk.operatorframework.io/docs/olm-integration/cli-overview "specified by $KUBECONFIG, or to default file rules if not set") // Deprecated: namespace exists for historical compatibility. Use watch-namespace instead. //TODO: remove namespace flag before 1.0.0 - cmd.Flags().StringVar(&c.namespace, "namespace", "", - "(Deprecated: use --watch-namespace instead.)"+ - "The namespace where the operator watches for changes.") + if !kbutil.HasProjectFile() { // not show for the kb layout projects + cmd.Flags().StringVar(&c.namespace, "namespace", "", + "(Deprecated: use --watch-namespace instead.)"+ + "The namespace where the operator watches for changes.") + } // 'run --olm' and related flags. cmd.Flags().BoolVar(&c.olm, "olm", false, "The operator to be run will be managed by OLM in a cluster. "+ diff --git a/cmd/operator-sdk/run/local.go b/cmd/operator-sdk/run/local.go index 52b0008b49..7395db045e 100644 --- a/cmd/operator-sdk/run/local.go +++ b/cmd/operator-sdk/run/local.go @@ -53,9 +53,15 @@ type runLocalArgs struct { func (c *runLocalArgs) addToFlags(fs *pflag.FlagSet) { prefix := "[local only] " - fs.StringVar(&c.watchNamespace, "watch-namespace", "", - prefix+"The namespace where the operator watches for changes. Set \"\" for AllNamespaces, "+ - "set \"ns1,ns2\" for MultiNamespace") + // Currently (plugin phase 1), the new layout is not customized and has not the WATCH_NAMESPACE env var scaffolded + // by default into in; the main.go and manager.yaml as it is not importing sdk into go.mod. So, was decide that + // for now at least we would not allow the watch-namespace flag. + if !kbutil.HasProjectFile() { + fs.StringVar(&c.watchNamespace, "watch-namespace", "", + prefix+"The namespace where the operator watches for changes. Set \"\" for AllNamespaces, "+ + "set \"ns1,ns2\" for MultiNamespace") + } + fs.StringVar(&c.operatorFlags, "operator-flags", "", prefix+"The flags that the operator needs. Example: \"--flag1 value1 --flag2=value2\"") fs.StringVar(&c.ldFlags, "go-ldflags", "", prefix+"Set Go linker options") @@ -109,14 +115,6 @@ func (c runLocalArgs) runGo() error { }() // Add default env vars and values informed via flags c.addEnvVars(cmd) - // todo: check if it should really be here. Shows that it should be part of AnsibleRun only. - // Set the ANSIBLE_ROLES_PATH - if c.ansibleOperatorFlags != nil && len(c.ansibleOperatorFlags.AnsibleRolesPath) > 0 { - log.Info(fmt.Sprintf("set the value %v for environment variable %v.", - c.ansibleOperatorFlags.AnsibleRolesPath, aoflags.AnsibleRolesPathEnvVar)) - cmd.Env = append(cmd.Env, fmt.Sprintf("%v=%v", aoflags.AnsibleRolesPathEnvVar, - c.ansibleOperatorFlags.AnsibleRolesPath)) - } // Execute the command build above to exec the binary build with the project if err := projutil.ExecCmd(cmd); err != nil { return err @@ -179,28 +177,28 @@ func (c runLocalArgs) getBuildRunLocalArgs() []string { // generateBinary will build the Go project by running the command `go build -o bin/manager main.go` func (c runLocalArgs) generateBinary() (string, error) { // Define name of the bin and where is the main.go pkg for each layout - var name, packagePath string + var outputBinName, mainPath string if kbutil.HasProjectFile() { - name = filepath.Join(kbutil.BinBuildDir, projutil.GetProjectName()+"-local") - packagePath = kbutil.PkgPath + outputBinName = filepath.Join(kbutil.BinBuildDir, projutil.GetProjectName()+"-local") + mainPath = kbutil.MainPath } else { // todo: remove the if, else when the legacy code is no longer supported - packagePath = path.Join(projutil.GetGoPkg(), filepath.ToSlash(scaffold.ManagerDir)) - name = filepath.Join(scaffold.BuildBinDir, projutil.GetProjectName()+"-local") + mainPath = path.Join(projutil.GetGoPkg(), filepath.ToSlash(scaffold.ManagerDir)) + outputBinName = filepath.Join(scaffold.BuildBinDir, projutil.GetProjectName()+"-local") } // allow the command works in windows SO if runtime.GOOS == "windows" { - name += ".exe" + outputBinName += ".exe" } opts := projutil.GoCmdOptions{ - BinName: name, - PackagePath: packagePath, + BinName: outputBinName, + PackagePath: mainPath, Args: c.getBuildRunLocalArgs(), } if err := projutil.GoBuild(opts); err != nil { - return name, err + return outputBinName, err } - return name, nil + return outputBinName, nil } // execCmdForBinWithDebugger will exec the command with the delve required args @@ -220,13 +218,22 @@ func (c runLocalArgs) addEnvVars(cmd *exec.Cmd) { // Set EnvVar to let the project knows that it is running outside of the cluster cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k8sutil.ForceRunModeEnv, k8sutil.LocalRunMode)) - // only set env var if user explicitly specified a kubeconfig path + // Only set env var if user explicitly specified a kubeconfig path if c.kubeconfig != "" { cmd.Env = append(cmd.Env, fmt.Sprintf("%v=%v", k8sutil.KubeConfigEnvVar, c.kubeconfig)) } // Set WATCH_NAMESPACE with the value informed via flag cmd.Env = append(cmd.Env, fmt.Sprintf("%v=%v", k8sutil.WatchNamespaceEnvVar, c.watchNamespace)) + + // todo: check if it should really be here. Shows that it should be part of AnsibleRun only. + // Set the ANSIBLE_ROLES_PATH + if c.ansibleOperatorFlags != nil && len(c.ansibleOperatorFlags.AnsibleRolesPath) > 0 { + log.Info(fmt.Sprintf("set the value %v for environment variable %v.", + c.ansibleOperatorFlags.AnsibleRolesPath, aoflags.AnsibleRolesPathEnvVar)) + cmd.Env = append(cmd.Env, fmt.Sprintf("%v=%v", aoflags.AnsibleRolesPathEnvVar, + c.ansibleOperatorFlags.AnsibleRolesPath)) + } } // buildArgsBasedOnOperatorFlag will return an array with all args used in the flags diff --git a/internal/util/kubebuilder/constants.go b/internal/util/kubebuilder/constants.go index 49e86888fa..6c0a34faf6 100644 --- a/internal/util/kubebuilder/constants.go +++ b/internal/util/kubebuilder/constants.go @@ -16,5 +16,5 @@ package kbutil const ( BinBuildDir = "bin" - PkgPath = "main.go" + MainPath = "main.go" ) From 1a8eeadb050c871111c9a1192cf197d7690ff966 Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Tue, 5 May 2020 13:13:18 +0100 Subject: [PATCH 3/7] applying suggestions --- cmd/operator-sdk/run/local.go | 15 +++++++-------- internal/util/kubebuilder/constants.go | 2 +- internal/util/projutil/project_util.go | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/cmd/operator-sdk/run/local.go b/cmd/operator-sdk/run/local.go index 7395db045e..4722dc3437 100644 --- a/cmd/operator-sdk/run/local.go +++ b/cmd/operator-sdk/run/local.go @@ -53,9 +53,9 @@ type runLocalArgs struct { func (c *runLocalArgs) addToFlags(fs *pflag.FlagSet) { prefix := "[local only] " - // Currently (plugin phase 1), the new layout is not customized and has not the WATCH_NAMESPACE env var scaffolded - // by default into in; the main.go and manager.yaml as it is not importing sdk into go.mod. So, was decide that - // for now at least we would not allow the watch-namespace flag. + // The main.go and manager.yaml scaffolds in the new layout do not support the WATCH_NAMESPACE + // env var to configure the namespace that the operator watches. The default is all namespaces. + // So this flag is unsupported for the new layout. if !kbutil.HasProjectFile() { fs.StringVar(&c.watchNamespace, "watch-namespace", "", prefix+"The namespace where the operator watches for changes. Set \"\" for AllNamespaces, "+ @@ -94,7 +94,7 @@ func (c runLocalArgs) runGo() error { } // Get the args that will be used to exec the binary. // Users are allowed to use the flag operator-flags to pass any value that they may wish - args := c.buildArgsBasedOnOperatorFlag() + args := c.argsFromOperatorFlags() // Build the command var cmd *exec.Cmd if c.enableDelve { @@ -115,7 +115,6 @@ func (c runLocalArgs) runGo() error { }() // Add default env vars and values informed via flags c.addEnvVars(cmd) - // Execute the command build above to exec the binary build with the project if err := projutil.ExecCmd(cmd); err != nil { return err } @@ -162,7 +161,7 @@ func setupOperatorEnv(kubeconfig, namespace string) error { return nil } -// getBuildRunLocalArgs will return the Args to buil the project based on the flags used +// getBuildRunLocalArgs returns go build args for -ldflags and -gcflags func (c runLocalArgs) getBuildRunLocalArgs() []string { var args []string if c.ldFlags != "" { @@ -236,8 +235,8 @@ func (c runLocalArgs) addEnvVars(cmd *exec.Cmd) { } } -// buildArgsBasedOnOperatorFlag will return an array with all args used in the flags -func (c runLocalArgs) buildArgsBasedOnOperatorFlag() []string { +// argsFromOperatorFlags will return an array with all args used in the flags +func (c runLocalArgs) argsFromOperatorFlags() []string { args := []string{} if c.operatorFlags != "" { extraArgs := strings.Split(c.operatorFlags, " ") diff --git a/internal/util/kubebuilder/constants.go b/internal/util/kubebuilder/constants.go index 6c0a34faf6..78dd1a1da3 100644 --- a/internal/util/kubebuilder/constants.go +++ b/internal/util/kubebuilder/constants.go @@ -1,4 +1,4 @@ -// Copyright 2018 The Operator-SDK Authors +// Copyright 2020 The Operator-SDK Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/internal/util/projutil/project_util.go b/internal/util/projutil/project_util.go index 27f779f7ed..feef2a1c02 100644 --- a/internal/util/projutil/project_util.go +++ b/internal/util/projutil/project_util.go @@ -206,7 +206,7 @@ func GetOperatorType() OperatorType { } func IsOperatorGo() bool { - // todo: in the future we should check the plugin prefx to see if is or not a go type + // todo: in the future we should check the plugin prefix to ensure the operator type // for now, we can assume that any project with the kubebuilder layout is Go Type if kbutil.HasProjectFile() { return true From 0fb9c612be098ada2b7d3b708bd665aed64a0b99 Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Tue, 5 May 2020 15:32:37 +0100 Subject: [PATCH 4/7] apply jow suggestion over getprojectname --- cmd/operator-sdk/run/local.go | 10 ++++++++-- internal/util/projutil/project_util.go | 6 ------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cmd/operator-sdk/run/local.go b/cmd/operator-sdk/run/local.go index 4722dc3437..854f7a1e44 100644 --- a/cmd/operator-sdk/run/local.go +++ b/cmd/operator-sdk/run/local.go @@ -178,12 +178,12 @@ func (c runLocalArgs) generateBinary() (string, error) { // Define name of the bin and where is the main.go pkg for each layout var outputBinName, mainPath string if kbutil.HasProjectFile() { - outputBinName = filepath.Join(kbutil.BinBuildDir, projutil.GetProjectName()+"-local") + outputBinName = filepath.Join(kbutil.BinBuildDir, getProjectName()+"-local") mainPath = kbutil.MainPath } else { // todo: remove the if, else when the legacy code is no longer supported mainPath = path.Join(projutil.GetGoPkg(), filepath.ToSlash(scaffold.ManagerDir)) - outputBinName = filepath.Join(scaffold.BuildBinDir, projutil.GetProjectName()+"-local") + outputBinName = filepath.Join(scaffold.BuildBinDir, getProjectName()+"-local") } // allow the command works in windows SO if runtime.GOOS == "windows" { @@ -244,3 +244,9 @@ func (c runLocalArgs) argsFromOperatorFlags() []string { } return args } + +// GetProjectName will return the name of the project +func getProjectName() string { + absProjectPath := projutil.MustGetwd() + return filepath.Base(absProjectPath) +} \ No newline at end of file diff --git a/internal/util/projutil/project_util.go b/internal/util/projutil/project_util.go index feef2a1c02..5f8d6d5972 100644 --- a/internal/util/projutil/project_util.go +++ b/internal/util/projutil/project_util.go @@ -323,9 +323,3 @@ func PrintDeprecationWarning(msg string) { fmt.Printf(noticeColor, "[Deprecation Notice] "+msg+". Refer to the version upgrade guide "+ "for more information: https://operator-sdk.netlify.com/docs/migration/version-upgrade-guide\n\n") } - -// GetProjectName will return the name of the project -func GetProjectName() string { - absProjectPath := MustGetwd() - return filepath.Base(absProjectPath) -} From b399973b7a37bba65db7d5b7d2e2245deb0f4455 Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Tue, 5 May 2020 16:08:22 +0100 Subject: [PATCH 5/7] fix lint --- cmd/operator-sdk/run/local.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/operator-sdk/run/local.go b/cmd/operator-sdk/run/local.go index 854f7a1e44..69baf6b3dd 100644 --- a/cmd/operator-sdk/run/local.go +++ b/cmd/operator-sdk/run/local.go @@ -249,4 +249,4 @@ func (c runLocalArgs) argsFromOperatorFlags() []string { func getProjectName() string { absProjectPath := projutil.MustGetwd() return filepath.Base(absProjectPath) -} \ No newline at end of file +} From c709ffc21ec9ef3aac8d2603a1b00875026233c2 Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Wed, 6 May 2020 14:28:24 +0100 Subject: [PATCH 6/7] improvements suggestions --- cmd/operator-sdk/run/cmd.go | 36 ++++++++++++++++++++--------------- cmd/operator-sdk/run/local.go | 24 ++++++++++++----------- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/cmd/operator-sdk/run/cmd.go b/cmd/operator-sdk/run/cmd.go index b63d29cce7..0f331a4312 100644 --- a/cmd/operator-sdk/run/cmd.go +++ b/cmd/operator-sdk/run/cmd.go @@ -93,24 +93,30 @@ https://sdk.operatorframework.io/docs/olm-integration/cli-overview log.Fatalf("Failed to run operator using OLM: %v", err) } case c.local: - //TODO: remove namespace flag before 1.0.0 - // set --watch-namespace flag if the --namespace flag is set - // (only if --watch-namespace flag is not set) - if cmd.Flags().Changed("namespace") { - log.Info("--namespace is deprecated; use --watch-namespace instead.") - if !cmd.Flags().Changed("watch-namespace") { - err := cmd.Flags().Set("watch-namespace", c.namespace) - return err + // The main.go and manager.yaml scaffolds in the new layout do not support the WATCH_NAMESPACE + // env var to configure the namespace that the operator watches. The default is all namespaces. + // So this flag is unsupported for the new layout. + if !kbutil.HasProjectFile() { + //TODO: remove namespace flag before 1.0.0 + // set --watch-namespace flag if the --namespace flag is set + // (only if --watch-namespace flag is not set) + if cmd.Flags().Changed("namespace") { // not valid for te new layout + log.Info("--namespace is deprecated; use --watch-namespace instead.") + if !cmd.Flags().Changed("watch-namespace") { + err := cmd.Flags().Set("watch-namespace", c.namespace) + return err + } } - } - // Get default namespace to watch if unset. - if !cmd.Flags().Changed("watch-namespace") { - _, defaultNamespace, err := k8sinternal.GetKubeconfigAndNamespace(c.kubeconfig) - if err != nil { - return fmt.Errorf("error getting kubeconfig and default namespace: %v", err) + // Get default namespace to watch if unset. + if !cmd.Flags().Changed("watch-namespace") { + _, defaultNamespace, err := k8sinternal.GetKubeconfigAndNamespace(c.kubeconfig) + if err != nil { + return fmt.Errorf("error getting kubeconfig and default namespace: %v", err) + } + c.localArgs.watchNamespace = defaultNamespace } - c.localArgs.watchNamespace = defaultNamespace } + c.localArgs.kubeconfig = c.kubeconfig if err := c.localArgs.run(); err != nil { log.Fatalf("Failed to run operator locally: %v", err) diff --git a/cmd/operator-sdk/run/local.go b/cmd/operator-sdk/run/local.go index 69baf6b3dd..5f39e4485c 100644 --- a/cmd/operator-sdk/run/local.go +++ b/cmd/operator-sdk/run/local.go @@ -70,10 +70,12 @@ func (c *runLocalArgs) addToFlags(fs *pflag.FlagSet) { } func (c runLocalArgs) run() error { - log.Infof("Running the operator locally in namespace %s.", c.watchNamespace) - - projutil.MustInProjectRoot() - + // The new layout will not have c.watchNamespace + if kbutil.HasProjectFile() { + log.Infof("Running the operator locally ...") + } else { + log.Infof("Running the operator locally in namespace %v.", c.watchNamespace) + } switch t := projutil.GetOperatorType(); t { case projutil.OperatorTypeGo: return c.runGo() @@ -102,7 +104,7 @@ func (c runLocalArgs) runGo() error { } else { cmd = exec.Command(binName, args...) } - // Kills the binary execution, if the exit signal be raised from the container + // Kill the command if an exit signal is received. ch := make(chan os.Signal) signal.Notify(ch, os.Interrupt, syscall.SIGTERM) go func() { @@ -116,7 +118,7 @@ func (c runLocalArgs) runGo() error { // Add default env vars and values informed via flags c.addEnvVars(cmd) if err := projutil.ExecCmd(cmd); err != nil { - return err + return fmt.Errorf("failed to run operator locally: %v", err) } return nil } @@ -176,13 +178,13 @@ func (c runLocalArgs) getBuildRunLocalArgs() []string { // generateBinary will build the Go project by running the command `go build -o bin/manager main.go` func (c runLocalArgs) generateBinary() (string, error) { // Define name of the bin and where is the main.go pkg for each layout - var outputBinName, mainPath string + var outputBinName, packagePath string if kbutil.HasProjectFile() { outputBinName = filepath.Join(kbutil.BinBuildDir, getProjectName()+"-local") - mainPath = kbutil.MainPath + packagePath = projutil.GetGoPkg() } else { // todo: remove the if, else when the legacy code is no longer supported - mainPath = path.Join(projutil.GetGoPkg(), filepath.ToSlash(scaffold.ManagerDir)) + packagePath = path.Join(projutil.GetGoPkg(), filepath.ToSlash(scaffold.ManagerDir)) outputBinName = filepath.Join(scaffold.BuildBinDir, getProjectName()+"-local") } // allow the command works in windows SO @@ -191,11 +193,11 @@ func (c runLocalArgs) generateBinary() (string, error) { } opts := projutil.GoCmdOptions{ BinName: outputBinName, - PackagePath: mainPath, + PackagePath: packagePath, Args: c.getBuildRunLocalArgs(), } if err := projutil.GoBuild(opts); err != nil { - return outputBinName, err + return "", err } return outputBinName, nil } From 0e3808590977f4a447280690516276d4328158ad Mon Sep 17 00:00:00 2001 From: Camila Macedo Date: Wed, 6 May 2020 17:38:46 +0100 Subject: [PATCH 7/7] latest suggestions --- cmd/operator-sdk/run/local.go | 5 +++-- internal/util/kubebuilder/constants.go | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/operator-sdk/run/local.go b/cmd/operator-sdk/run/local.go index 5f39e4485c..22d53dcb37 100644 --- a/cmd/operator-sdk/run/local.go +++ b/cmd/operator-sdk/run/local.go @@ -74,7 +74,7 @@ func (c runLocalArgs) run() error { if kbutil.HasProjectFile() { log.Infof("Running the operator locally ...") } else { - log.Infof("Running the operator locally in namespace %v.", c.watchNamespace) + log.Infof("Running the operator locally; watching namespace %q", c.watchNamespace) } switch t := projutil.GetOperatorType(); t { case projutil.OperatorTypeGo: @@ -247,7 +247,8 @@ func (c runLocalArgs) argsFromOperatorFlags() []string { return args } -// GetProjectName will return the name of the project +// getProjectName will return the name of the project. This function only works if the current working directory +// is the project root. func getProjectName() string { absProjectPath := projutil.MustGetwd() return filepath.Base(absProjectPath) diff --git a/internal/util/kubebuilder/constants.go b/internal/util/kubebuilder/constants.go index 78dd1a1da3..3347144736 100644 --- a/internal/util/kubebuilder/constants.go +++ b/internal/util/kubebuilder/constants.go @@ -16,5 +16,4 @@ package kbutil const ( BinBuildDir = "bin" - MainPath = "main.go" )