From adc5513693274a82183f6b41d03d5de284b37400 Mon Sep 17 00:00:00 2001 From: Yolanda Robla Date: Tue, 16 Jul 2019 12:28:24 +0200 Subject: [PATCH] Create wrapper to execute commands In order to have a standard way of executing shell commands, and show the proper output/error, i have created a wrapper that is called on each system call, and controls the behaviour of it. Signed-off-by: Yolanda Robla Change-Id: I0a40a126677a5f7ec878e34e657399d696dd5ee9 --- pkg/requirements/requirements.go | 35 +++++---------------- pkg/site/site.go | 18 ++--------- pkg/utils/utils.go | 66 +++++++++++++++++++++++++--------------- 3 files changed, 51 insertions(+), 68 deletions(-) diff --git a/pkg/requirements/requirements.go b/pkg/requirements/requirements.go index 80947a1..f9c6ada 100644 --- a/pkg/requirements/requirements.go +++ b/pkg/requirements/requirements.go @@ -1,16 +1,14 @@ package requirements import ( - "bytes" "fmt" - "io" "log" "os" - "os/exec" "path" "path/filepath" "strings" + "gerrit.akraino.org/kni/installer/pkg/utils" getter "github.com/hashicorp/go-getter" ) @@ -45,9 +43,9 @@ func (r Requirement) FetchRequirementFolder() { err = filepath.Walk(extractDir, func(path string, info os.FileInfo, err error) error { if (info.Name() == r.binaryName || info.Name() == alternativeBinaryName) && !info.IsDir() { // we found the binary, move it. Give exec perms as well - finalBinary := fmt.Sprintf("%s/%s", r.buildPath, r.binaryName) + finalBinary := fmt.Sprintf("%s/%s", r.buildPath, r.binaryName) os.Rename(path, finalBinary) - os.Chmod(finalBinary, 0755) + os.Chmod(finalBinary, 0755) os.RemoveAll(extractDir) return nil } @@ -66,31 +64,12 @@ func (r Requirement) BuildOpenshiftBinary() { } // build the openshift binary - cmd := exec.Command("hack/build.sh") - cmd.Dir = extractDir - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, "TAGS=libvirt") - cmd.Env = append(cmd.Env, fmt.Sprintf("GOPATH=%s", r.buildPath)) - - var stdBuffer bytes.Buffer - mw := io.MultiWriter(os.Stdout, &stdBuffer) - cmd.Stdout = mw - cmd.Stderr = mw - - err = cmd.Run() - if err != nil { - log.Fatal(fmt.Sprintf("Error building binary: %s - %s", err, stdBuffer.String())) - os.Exit(1) - } - log.Println(stdBuffer.String()) + envVars := []string{"TAGS=libvirt", fmt.Sprintf("GOPATH=%s", r.buildPath)} + utils.ExecuteCommand(extractDir, envVars, true, true, "hack/build.sh") // copy the generated binary to the build directory - cmd = exec.Command("cp", fmt.Sprintf("%s/bin/openshift-install", extractDir), r.buildPath) - err = cmd.Run() - if err != nil { - log.Fatal(fmt.Sprintf("Error copying installer to buid path: %s", err)) - os.Exit(1) - } + var cpEnvVars []string + utils.ExecuteCommand("", cpEnvVars, true, true, "cp", fmt.Sprintf("%s/bin/openshift-install", extractDir), r.buildPath) log.Println(fmt.Sprintf("Installer is available on %s/openshift-install", r.buildPath)) } diff --git a/pkg/site/site.go b/pkg/site/site.go index c07f509..01eebc4 100644 --- a/pkg/site/site.go +++ b/pkg/site/site.go @@ -6,7 +6,6 @@ import ( "io/ioutil" "log" "os" - "os/exec" "path" "path/filepath" "strings" @@ -212,12 +211,8 @@ func (s Site) PrepareManifests() { } // and now copy site inside the sites folder, replacing the absolute references to relative - cmd := exec.Command("cp", "-R", fmt.Sprintf("%s/site", sitePath), fmt.Sprintf("%s/blueprint/sites/site", sitePath)) - err = cmd.Run() - if err != nil { - log.Fatal(fmt.Sprintf("Error copying site into blueprint: %s", err)) - os.Exit(1) - } + var envVars []string + utils.ExecuteCommand("", envVars, true, false, "cp", "-R", fmt.Sprintf("%s/site", sitePath), fmt.Sprintf("%s/blueprint/sites/site", sitePath)) err = filepath.Walk(fmt.Sprintf("%s/blueprint/sites/site", sitePath), func(path string, info os.FileInfo, err error) error { if err == nil { @@ -264,14 +259,7 @@ func (s Site) PrepareManifests() { } // now generate the manifests - cmd = exec.Command(fmt.Sprintf("%s/openshift-install", binariesPath), "create", "manifests", fmt.Sprintf("--dir=%s", assetsPath), "--log-level", "debug") - out, err = cmd.Output() - if err != nil { - log.Fatal(fmt.Sprintf("Error creating manifests: %s", err)) - log.Println(out) - os.Exit(1) - } - + utils.ExecuteCommand("", envVars, true, true, fmt.Sprintf("%s/openshift-install", binariesPath), "create", "manifests", fmt.Sprintf("--dir=%s", assetsPath), "--log-level", "debug") // iterate over all the generated files and create a kustomization file f, err := os.Create(fmt.Sprintf("%s/kustomization.yaml", assetsPath)) if err != nil { diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index b7587cf..2e25c20 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -1,6 +1,7 @@ package utils import ( + "bytes" "fmt" "io/ioutil" "log" @@ -22,12 +23,8 @@ func ValidateRequirements(buildPath string, siteName string) { if _, err := os.Stat(fmt.Sprintf("%s/id_rsa.pub", buildPath)); os.IsNotExist(err) { log.Println(fmt.Sprintf("No SSH public key (id_rsa.pub) found in %s. Generating keypair.", buildPath)) - cmd := exec.Command("/bin/bash", "-c", fmt.Sprintf("ssh-keygen -b 2048 -q -N '' -f %s/id_rsa -C user@example.com", buildPath)) - err = cmd.Run() - if err != nil { - log.Fatal(fmt.Sprintf("Error generating ssh keypair: %s", err)) - os.Exit(1) - } + var envVars []string + ExecuteCommand("", envVars, true, true, "/bin/bash", "-c", fmt.Sprintf("ssh-keygen -b 2048 -q -N '' -f %s/id_rsa -C user@example.com", buildPath)) } // check if requirements folder exist @@ -49,23 +46,14 @@ func ApplyKustomize(kustomizeBinary string, kustomizePath string) []byte { } exPath := filepath.Dir(ex) - cmd := exec.Command(kustomizeBinary, "build", "--enable_alpha_plugins", "--reorder", "none", kustomizePath) - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, fmt.Sprintf("XDG_CONFIG_HOME=%s/plugins", exPath)) - out, err := cmd.Output() - - if err != nil { - log.Fatal(fmt.Sprintf("Error kustomizing manifests for %s: %s", kustomizePath, err)) - os.Exit(1) - } + envVars := []string{fmt.Sprintf("XDG_CONFIG_HOME=%s/plugins", exPath)} + out, _ := ExecuteCommand("", envVars, true, false, kustomizeBinary, "build", "--enable_alpha_plugins", "--reorder", "none", kustomizePath) return out } // utility to apply kubectl for a given output func ApplyKubectl(kubectlBinary string, kubectlContent []byte, kubeconfigPath string) { - var out []byte - // write content to be applied to temporary file tmpFile, err := ioutil.TempFile(os.TempDir(), "kubectl-") if err != nil { @@ -80,15 +68,9 @@ func ApplyKubectl(kubectlBinary string, kubectlContent []byte, kubeconfigPath st os.Exit(1) } + envVars := []string{fmt.Sprintf("KUBECONFIG_PATH=%s", kubeconfigPath)} for i := 1; i <= 10; i++ { - cmd := exec.Command(kubectlBinary, "apply", "-f", tmpFile.Name()) - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, fmt.Sprintf("KUBECONFIG_PATH=%s", kubeconfigPath)) - - out, err = cmd.Output() - - // show output for user to see progress - log.Println(string(out)) + _, err := ExecuteCommand("", envVars, false, true, kubectlBinary, "apply", "-f", tmpFile.Name()) if err == nil { // it is ok, stop the loop @@ -100,3 +82,37 @@ func ApplyKubectl(kubectlBinary string, kubectlContent []byte, kubeconfigPath st } } } + +// utility to execute a command and show the stdout and stderr output +func ExecuteCommand(directory string, envVars []string, failFatal bool, showOutput bool, name string, arg ...string) ([]byte, []byte) { + cmd := exec.Command(name, arg...) + + // set additional modifiers + if directory != "" { + cmd.Dir = directory + } + cmd.Env = os.Environ() + for _, envVar := range envVars { + cmd.Env = append(cmd.Env, envVar) + + } + var outb, errb bytes.Buffer + cmd.Stdout = &outb + cmd.Stderr = &errb + err := cmd.Run() + + // show output of command + if showOutput { + log.Println(outb.String()) + } + + if err != nil { + if failFatal { + log.Fatal(fmt.Sprintf("Error applying command: %s - %s", err, errb.String())) + os.Exit(1) + } else { + log.Println(fmt.Sprintf("Error applying command: %s - %s", err, errb.String())) + } + } + return outb.Bytes(), errb.Bytes() +} -- 2.16.6