Skip to content

Commit

Permalink
Support custom wait for ready timeout (#76)
Browse files Browse the repository at this point in the history
Signed-off-by: Prasad Ghangal <[email protected]>
  • Loading branch information
PrasadG193 authored May 26, 2021
1 parent 01935e1 commit 417649a
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 25 deletions.
17 changes: 16 additions & 1 deletion cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"strings"
"time"

"github.com/pkg/errors"
"github.com/spf13/cobra"
Expand All @@ -15,9 +16,12 @@ import (
"github.com/kbrew-dev/kbrew/pkg/version"
)

const defaultTimeout = "15m0s"

var (
configFile string
namespace string
timeout string

rootCmd = &cobra.Command{
Use: "kbrew",
Expand Down Expand Up @@ -108,6 +112,8 @@ func init() {
rootCmd.AddCommand(removeCmd)
rootCmd.AddCommand(searchCmd)
rootCmd.AddCommand(updateCmd)

installCmd.PersistentFlags().StringVarP(&timeout, "timeout", "t", "", "time to wait for app components to be in a ready state (default 15m0s)")
}

func main() {
Expand All @@ -128,6 +134,13 @@ func checkArgs(args []string) error {

func manageApp(m apps.Method, args []string) error {
ctx := context.Background()
if timeout == "" {
timeout = defaultTimeout
}
timeoutDur, err := time.ParseDuration(timeout)
if err != nil {
return err
}
for _, a := range args {
reg, err := registry.New(config.ConfigDir)
if err != nil {
Expand All @@ -137,7 +150,9 @@ func manageApp(m apps.Method, args []string) error {
if err != nil {
return err
}
if err := apps.Run(ctx, m, strings.ToLower(a), namespace, configFile); err != nil {
ctxTimeout, cancel := context.WithTimeout(ctx, timeoutDur)
defer cancel()
if err := apps.Run(ctxTimeout, m, strings.ToLower(a), namespace, configFile); err != nil {
return err
}
}
Expand Down
19 changes: 11 additions & 8 deletions pkg/apps/helm/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (ha *App) Install(ctx context.Context, name, namespace, version string, opt
return err
}

out, err := helmCommand(installMethod, name, version, namespace, fmt.Sprintf("%s/%s", ha.App.Repository.Name, name), ha.App.Args)
out, err := helmCommand(ctx, installMethod, name, version, namespace, fmt.Sprintf("%s/%s", ha.App.Repository.Name, name), ha.App.Args)
fmt.Println(out)
return err
}
Expand All @@ -58,7 +58,7 @@ func (ha *App) Uninstall(ctx context.Context, name, namespace string) error {
//TODO: Resolve Deps
// Validate and install chart
// TODO(@prasad): Use go sdks
out, err := helmCommand(uninstallMethod, name, "", namespace, "", nil)
out, err := helmCommand(ctx, uninstallMethod, name, "", namespace, "", nil)
fmt.Println(out)
return err
}
Expand Down Expand Up @@ -90,7 +90,7 @@ func (ha *App) resolveArgs() error {

func (ha *App) addRepo(ctx context.Context) (string, error) {
// Needs helm 3.2+
c := exec.Command("helm", "repo", "add", ha.App.Repository.Name, ha.App.Repository.URL)
c := exec.CommandContext(ctx, "helm", "repo", "add", ha.App.Repository.Name, ha.App.Repository.URL)
if out, err := c.CombinedOutput(); err != nil {
return string(out), err
}
Expand All @@ -99,7 +99,7 @@ func (ha *App) addRepo(ctx context.Context) (string, error) {

func (ha *App) updateRepo(ctx context.Context) (string, error) {
// Needs helm 3.2+
c := exec.Command("helm", "repo", "update")
c := exec.CommandContext(ctx, "helm", "repo", "update")
out, err := c.CombinedOutput()
return string(out), err
}
Expand All @@ -110,7 +110,7 @@ func (ha *App) Search(ctx context.Context, name string) (string, error) {
if out, err := ha.addRepo(ctx); err != nil {
return string(out), err
}
c := exec.Command("helm", "search", "repo", fmt.Sprintf("%s/%s", ha.App.Repository.Name, name))
c := exec.CommandContext(ctx, "helm", "search", "repo", fmt.Sprintf("%s/%s", ha.App.Repository.Name, name))
out, err := c.CombinedOutput()
if err != nil {
return string(out), err
Expand All @@ -121,17 +121,20 @@ func (ha *App) Search(ctx context.Context, name string) (string, error) {
return string(out), err
}

func helmCommand(m method, name, version, namespace, chart string, chartArgs map[string]interface{}) (string, error) {
func helmCommand(ctx context.Context, m method, name, version, namespace, chart string, chartArgs map[string]interface{}) (string, error) {
// Needs helm 3.2+
c := exec.Command("helm", string(m), name, "--namespace", namespace)
c := exec.CommandContext(ctx, "helm", string(m), name, "--namespace", namespace)
if chart != "" {
c.Args = append(c.Args, chart)
}
if version != "" {
c.Args = append(c.Args, "--version", version)
}
if m == installMethod {
c.Args = append(c.Args, "--wait", "--create-namespace")
// Add extra time to wait arg so that context will be timeout out before helm command failure
// This is for catching timeout through context instead of parsing helm command output
// This might change once we switch to SDKs
c.Args = append(c.Args, "--wait", "--timeout", "5h0m", "--create-namespace")
}

if chartArgs != nil && len(chartArgs) != 0 {
Expand Down
10 changes: 5 additions & 5 deletions pkg/apps/raw/raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (r *App) Install(ctx context.Context, name, namespace, version string, opti
}

// TODO(@prasad): Use go sdks
if err := kubectlCommand(install, name, namespace, patchedManifest); err != nil {
if err := kubectlCommand(ctx, install, name, namespace, patchedManifest); err != nil {
return err
}
return r.waitForReady(ctx, namespace)
Expand All @@ -100,23 +100,23 @@ func (r *App) Install(ctx context.Context, name, namespace, version string, opti
func (r *App) Uninstall(ctx context.Context, name, namespace string) error {
fmt.Printf("Unistalling raw app %s\n", name)
// TODO(@prasad): Use go sdks
return kubectlCommand(uninstall, name, namespace, r.App.Repository.URL)
return kubectlCommand(ctx, uninstall, name, namespace, r.App.Repository.URL)
}

// Search searches the app specified by name.
func (r *App) Search(ctx context.Context, name string) (string, error) {
return printList(r.App), nil
}

func kubectlCommand(m method, name, namespace, manifest string) error {
func kubectlCommand(ctx context.Context, m method, name, namespace, manifest string) error {
var c *exec.Cmd
switch m {
case install:
c = exec.Command("kubectl", string(m), "-f", "-")
c = exec.CommandContext(ctx, "kubectl", string(m), "-f", "-")
// Pass the manifest on STDIN
c.Stdin = strings.NewReader(manifest)
default:
c = exec.Command("kubectl", string(m), "-f", manifest)
c = exec.CommandContext(ctx, "kubectl", string(m), "-f", manifest)
}

if namespace != "" {
Expand Down
11 changes: 0 additions & 11 deletions pkg/kube/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,28 @@ package kube

import (
"context"
"time"

"github.com/kanisterio/kanister/pkg/kube"
osversioned "github.com/openshift/client-go/apps/clientset/versioned"
"k8s.io/client-go/kubernetes"
)

const workloadReadyTimeout = 15 * time.Minute

// WaitForPodReady waits till the pod gets ready
func WaitForPodReady(ctx context.Context, kubeCli kubernetes.Interface, namespace string, name string) error {
ctx, cancel := context.WithTimeout(ctx, workloadReadyTimeout)
defer cancel()
return kube.WaitForPodReady(ctx, kubeCli, namespace, name)
}

// WaitForDeploymentReady waits till the deployment gets ready
func WaitForDeploymentReady(ctx context.Context, kubeCli kubernetes.Interface, namespace string, name string) error {
ctx, cancel := context.WithTimeout(ctx, workloadReadyTimeout)
defer cancel()
return kube.WaitOnDeploymentReady(ctx, kubeCli, namespace, name)
}

// WaitForStatefulSetReady waits till the statefulset gets ready
func WaitForStatefulSetReady(ctx context.Context, kubeCli kubernetes.Interface, namespace string, name string) error {
ctx, cancel := context.WithTimeout(ctx, workloadReadyTimeout)
defer cancel()
return kube.WaitOnStatefulSetReady(ctx, kubeCli, namespace, name)
}

// WaitForDeploymentConfigReady waits till the deployment config gets ready
func WaitForDeploymentConfigReady(ctx context.Context, osCli osversioned.Interface, kubeCli kubernetes.Interface, namespace string, name string) error {
ctx, cancel := context.WithTimeout(ctx, workloadReadyTimeout)
defer cancel()
return kube.WaitOnDeploymentConfigReady(ctx, osCli, kubeCli, namespace, name)
}

0 comments on commit 417649a

Please sign in to comment.