Skip to content

Commit

Permalink
Add an option to wait for an instance uninstall (#1682)
Browse files Browse the repository at this point in the history
Similar to the 'wait' and 'wait-time' options for operator package installations, instance uninstalls can be waited upon to complete.

Signed-off-by: Jan Schlicht <jan@d2iq.com>
  • Loading branch information
Jan Schlicht committed Sep 15, 2020
1 parent 3c51361 commit 397aa37
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 8 deletions.
25 changes: 19 additions & 6 deletions pkg/kudoctl/cmd/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"fmt"
"time"

"github.com/spf13/cobra"

Expand All @@ -16,6 +17,8 @@ const (

type uninstallOptions struct {
InstanceName string
Wait bool
WaitTime int64
}

type uninstallCmd struct{}
Expand All @@ -28,25 +31,32 @@ func (cmd *uninstallCmd) run(options uninstallOptions, settings *env.Settings) e
return fmt.Errorf("failed to acquire kudo client: %w", err)
}

return cmd.uninstall(kc, options.InstanceName, settings)
return cmd.uninstall(kc, options, settings)
}

func (cmd *uninstallCmd) uninstall(kc *kudo.Client, instanceName string, settings *env.Settings) error {
instance, err := kc.GetInstance(instanceName, settings.Namespace)
func (cmd *uninstallCmd) uninstall(kc *kudo.Client, options uninstallOptions, settings *env.Settings) error {
instance, err := kc.GetInstance(options.InstanceName, settings.Namespace)
if err != nil {
return fmt.Errorf("failed to verify if instance already exists: %w", err)
}

if instance == nil {
return fmt.Errorf("instance %s in namespace %s does not exist in the cluster", instanceName, settings.Namespace)
return fmt.Errorf("instance %s in namespace %s does not exist in the cluster", options.InstanceName, settings.Namespace)
}

err = kc.DeleteInstance(instanceName, settings.Namespace)
err = kc.DeleteInstance(options.InstanceName, settings.Namespace)
if err != nil {
return err
}

clog.Printf("instance.%s/%s deleted\n", instance.APIVersion, instanceName)
if options.Wait {
waitDuration := time.Duration(options.WaitTime) * time.Second
if err := kc.WaitForInstanceDeleted(options.InstanceName, settings.Namespace, waitDuration); err != nil {
return err
}
}

clog.Printf("instance.%s/%s deleted\n", instance.APIVersion, options.InstanceName)
return nil
}

Expand Down Expand Up @@ -75,5 +85,8 @@ func newUninstallCmd() *cobra.Command {
panic(err)
}

uninstallCmd.Flags().BoolVar(&options.Wait, "wait", false, "Specify if the CLI should wait for the uninstall to complete before returning (default \"false\")")
uninstallCmd.Flags().Int64Var(&options.WaitTime, "wait-time", 300, "Specify the max wait time in seconds for CLI for the uninstall to complete before returning (default \"300\")")

return uninstallCmd
}
11 changes: 9 additions & 2 deletions pkg/kudoctl/cmd/uninstall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,12 @@ func TestUninstall(t *testing.T) {
t.Fatalf("failed to install instance: %v", err)
}

options := uninstallOptions{
InstanceName: "nonexisting-instance",
}

cmd := uninstallCmd{}
err = cmd.uninstall(kc, "nonexisting-instance", settings)
err = cmd.uninstall(kc, options, settings)
if err == nil {
t.Errorf("expected an error but got none")
}
Expand All @@ -56,7 +60,10 @@ func TestUninstall(t *testing.T) {
t.Errorf("expected error message '%s' but got '%v'", errMsg, err)
}

err = cmd.uninstall(kc, testInstance.Name, settings)
options.InstanceName = testInstance.Name
options.Wait = true

err = cmd.uninstall(kc, options, settings)
if err != nil {
t.Errorf("failed to uninstall instance: %v", err)
}
Expand Down
20 changes: 20 additions & 0 deletions pkg/kudoctl/util/kudo/kudo.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,26 @@ func (c *Client) WaitForInstance(name, namespace string, oldInstance *kudoapi.In
})
}

// WaitForInstanceDeleted waits for instance to be removed from the cluster.
func (c *Client) WaitForInstanceDeleted(name, namespace string, timeout time.Duration) error {
interval := 1 * time.Second

return wait.PollImmediate(interval, timeout, func() (done bool, err error) {
instance, err := c.GetInstance(name, namespace)
if err != nil {
return false, err
}

if instance == nil {
clog.V(2).Printf("instance %q was deleted\n", name)
return true, nil
}

clog.V(4).Printf("instance %q is still running\n", name)
return false, nil
})
}

// IsInstanceDone provides a check on instance to see if it is "finished" without retries
// oldInstance is nil if there is no previous instance
func (c *Client) IsInstanceDone(instance, oldInstance *kudoapi.Instance) (bool, error) {
Expand Down

0 comments on commit 397aa37

Please sign in to comment.