Merge pull request #334 from StupidScience/windows-support
Get rid of shell-out and invoke command directly via exec
This commit is contained in:
@@ -150,15 +150,14 @@ func generateInstallManifests(targetPath, namespace, tmpDir string, localManifes
|
|||||||
}
|
}
|
||||||
|
|
||||||
func applyInstallManifests(ctx context.Context, manifestPath string, components []string) error {
|
func applyInstallManifests(ctx context.Context, manifestPath string, components []string) error {
|
||||||
command := fmt.Sprintf("kubectl apply -f %s", manifestPath)
|
kubectlArgs := []string{"apply", "-f", manifestPath}
|
||||||
if _, err := utils.execCommand(ctx, ModeOS, command); err != nil {
|
if _, err := utils.execKubectlCommand(ctx, ModeOS, kubectlArgs...); err != nil {
|
||||||
return fmt.Errorf("install failed")
|
return fmt.Errorf("install failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, deployment := range components {
|
for _, deployment := range components {
|
||||||
command = fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s",
|
kubectlArgs = []string{"-n", namespace, "rollout", "status", "deployment", deployment, "--timeout", timeout.String()}
|
||||||
namespace, deployment, timeout.String())
|
if _, err := utils.execKubectlCommand(ctx, ModeOS, kubectlArgs...); err != nil {
|
||||||
if _, err := utils.execCommand(ctx, ModeOS, command); err != nil {
|
|
||||||
return fmt.Errorf("install failed")
|
return fmt.Errorf("install failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,8 +238,8 @@ func generateSyncManifests(url, branch, name, namespace, targetPath, tmpDir stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
func applySyncManifests(ctx context.Context, kubeClient client.Client, name, namespace, targetPath, tmpDir string) error {
|
func applySyncManifests(ctx context.Context, kubeClient client.Client, name, namespace, targetPath, tmpDir string) error {
|
||||||
command := fmt.Sprintf("kubectl apply -k %s", filepath.Join(tmpDir, targetPath, namespace))
|
kubectlArgs := []string{"apply", "-k", filepath.Join(tmpDir, targetPath, namespace)}
|
||||||
if _, err := utils.execCommand(ctx, ModeStderrOS, command); err != nil {
|
if _, err := utils.execKubectlCommand(ctx, ModeStderrOS, kubectlArgs...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,14 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/blang/semver/v4"
|
"github.com/blang/semver/v4"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
apimachineryversion "k8s.io/apimachinery/pkg/version"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
)
|
)
|
||||||
@@ -48,6 +49,10 @@ var (
|
|||||||
checkComponents []string
|
checkComponents []string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type kubectlVersion struct {
|
||||||
|
ClientVersion *apimachineryversion.Info `json:"clientVersion"`
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
checkCmd.Flags().BoolVarP(&checkPre, "pre", "", false,
|
checkCmd.Flags().BoolVarP(&checkPre, "pre", "", false,
|
||||||
"only run pre-installation checks")
|
"only run pre-installation checks")
|
||||||
@@ -97,14 +102,20 @@ func kubectlCheck(ctx context.Context, version string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
command := "kubectl version --client --short | awk '{ print $3 }'"
|
kubectlArgs := []string{"version", "--client", "--output", "json"}
|
||||||
output, err := utils.execCommand(ctx, ModeCapture, command)
|
output, err := utils.execKubectlCommand(ctx, ModeCapture, kubectlArgs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Failuref("kubectl version can't be determined")
|
logger.Failuref("kubectl version can't be determined")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
v, err := semver.ParseTolerant(output)
|
kv := &kubectlVersion{}
|
||||||
|
if err = json.Unmarshal([]byte(output), kv); err != nil {
|
||||||
|
logger.Failuref("kubectl version output can't be unmarshaled")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
v, err := semver.ParseTolerant(kv.ClientVersion.GitVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Failuref("kubectl version can't be parsed")
|
logger.Failuref("kubectl version can't be parsed")
|
||||||
return false
|
return false
|
||||||
@@ -161,9 +172,8 @@ func componentsCheck() bool {
|
|||||||
|
|
||||||
ok := true
|
ok := true
|
||||||
for _, deployment := range checkComponents {
|
for _, deployment := range checkComponents {
|
||||||
command := fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s",
|
kubectlArgs := []string{"-n", namespace, "rollout", "status", "deployment", deployment, "--timeout", timeout.String()}
|
||||||
namespace, deployment, timeout.String())
|
if output, err := utils.execKubectlCommand(ctx, ModeCapture, kubectlArgs...); err != nil {
|
||||||
if output, err := utils.execCommand(ctx, ModeCapture, command); err != nil {
|
|
||||||
logger.Failuref("%s: %s", deployment, strings.TrimSuffix(output, "\n"))
|
logger.Failuref("%s: %s", deployment, strings.TrimSuffix(output, "\n"))
|
||||||
ok = false
|
ok = false
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -158,14 +158,13 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
if verbose {
|
if verbose {
|
||||||
applyOutput = ModeOS
|
applyOutput = ModeOS
|
||||||
}
|
}
|
||||||
dryRun := ""
|
|
||||||
|
kubectlArgs := []string{"apply", "-f", manifest}
|
||||||
if installDryRun {
|
if installDryRun {
|
||||||
dryRun = "--dry-run=client"
|
args = append(args, "--dry-run=client")
|
||||||
applyOutput = ModeOS
|
applyOutput = ModeOS
|
||||||
}
|
}
|
||||||
|
if _, err := utils.execKubectlCommand(ctx, applyOutput, kubectlArgs...); err != nil {
|
||||||
command := fmt.Sprintf("kubectl apply -f %s %s", manifest, dryRun)
|
|
||||||
if _, err := utils.execCommand(ctx, applyOutput, command); err != nil {
|
|
||||||
return fmt.Errorf("install failed")
|
return fmt.Errorf("install failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,9 +177,8 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
logger.Waitingf("verifying installation")
|
logger.Waitingf("verifying installation")
|
||||||
for _, deployment := range installComponents {
|
for _, deployment := range installComponents {
|
||||||
command = fmt.Sprintf("kubectl -n %s rollout status deployment %s --timeout=%s",
|
kubectlArgs = []string{"-n", namespace, "rollout", "status", "deployment", deployment, "--timeout", timeout.String()}
|
||||||
namespace, deployment, timeout.String())
|
if _, err := utils.execKubectlCommand(ctx, applyOutput, kubectlArgs...); err != nil {
|
||||||
if _, err := utils.execCommand(ctx, applyOutput, command); err != nil {
|
|
||||||
return fmt.Errorf("install failed")
|
return fmt.Errorf("install failed")
|
||||||
} else {
|
} else {
|
||||||
logger.Successf("%s ready", deployment)
|
logger.Successf("%s ready", deployment)
|
||||||
|
|||||||
@@ -71,10 +71,8 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dryRun := ""
|
dryRun := "--dry-run=server"
|
||||||
if uninstallDryRun {
|
if !uninstallDryRun && !uninstallSilent {
|
||||||
dryRun = "--dry-run=server"
|
|
||||||
} else if !uninstallSilent {
|
|
||||||
prompt := promptui.Prompt{
|
prompt := promptui.Prompt{
|
||||||
Label: fmt.Sprintf("Are you sure you want to delete the %s namespace", namespace),
|
Label: fmt.Sprintf("Are you sure you want to delete the %s namespace", namespace),
|
||||||
IsConfirm: true,
|
IsConfirm: true,
|
||||||
@@ -105,9 +103,15 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
sourcev1.HelmRepositoryKind,
|
sourcev1.HelmRepositoryKind,
|
||||||
helmv2.HelmReleaseKind,
|
helmv2.HelmReleaseKind,
|
||||||
} {
|
} {
|
||||||
command := fmt.Sprintf("kubectl -n %s delete %s --all --ignore-not-found --timeout=%s %s",
|
kubectlArgs := []string{
|
||||||
namespace, kind, timeout.String(), dryRun)
|
"-n", namespace,
|
||||||
if _, err := utils.execCommand(ctx, ModeOS, command); err != nil {
|
"delete", kind, "--all", "--ignore-not-found",
|
||||||
|
"--timeout", timeout.String(),
|
||||||
|
}
|
||||||
|
if uninstallDryRun {
|
||||||
|
kubectlArgs = append(kubectlArgs, dryRun)
|
||||||
|
}
|
||||||
|
if _, err := utils.execKubectlCommand(ctx, ModeOS, kubectlArgs...); err != nil {
|
||||||
return fmt.Errorf("uninstall failed: %w", err)
|
return fmt.Errorf("uninstall failed: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,9 +127,15 @@ func uninstallCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
logger.Actionf("uninstalling components")
|
logger.Actionf("uninstalling components")
|
||||||
|
|
||||||
for _, kind := range kinds {
|
for _, kind := range kinds {
|
||||||
command := fmt.Sprintf("kubectl delete %s -l app.kubernetes.io/instance=%s --ignore-not-found --timeout=%s %s",
|
kubectlArgs := []string{
|
||||||
kind, namespace, timeout.String(), dryRun)
|
"delete", kind,
|
||||||
if _, err := utils.execCommand(ctx, ModeOS, command); err != nil {
|
"-l", fmt.Sprintf("app.kubernetes.io/instance=%s", namespace),
|
||||||
|
"--ignore-not-found", "--timeout", timeout.String(),
|
||||||
|
}
|
||||||
|
if uninstallDryRun {
|
||||||
|
kubectlArgs = append(kubectlArgs, dryRun)
|
||||||
|
}
|
||||||
|
if _, err := utils.execKubectlCommand(ctx, ModeOS, kubectlArgs...); err != nil {
|
||||||
return fmt.Errorf("uninstall failed: %w", err)
|
return fmt.Errorf("uninstall failed: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,9 +60,10 @@ const (
|
|||||||
ModeCapture ExecMode = "capture.stderr|stdout"
|
ModeCapture ExecMode = "capture.stderr|stdout"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (*Utils) execCommand(ctx context.Context, mode ExecMode, command string) (string, error) {
|
func (*Utils) execKubectlCommand(ctx context.Context, mode ExecMode, args ...string) (string, error) {
|
||||||
var stdoutBuf, stderrBuf bytes.Buffer
|
var stdoutBuf, stderrBuf bytes.Buffer
|
||||||
c := exec.CommandContext(ctx, "/bin/sh", "-c", command)
|
|
||||||
|
c := exec.CommandContext(ctx, "kubectl", args...)
|
||||||
|
|
||||||
if mode == ModeStderrOS {
|
if mode == ModeStderrOS {
|
||||||
c.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
|
c.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
|
||||||
|
|||||||
Reference in New Issue
Block a user