add timeout and force to kubectl command

pull/15985/head
Steven Powell 2023-03-01 13:07:46 -08:00
parent c5e359e0ab
commit 4e33f96173
3 changed files with 33 additions and 5 deletions

View File

@ -17,6 +17,7 @@ limitations under the License.
package addons
import (
"context"
"fmt"
"os/exec"
"path"
@ -433,11 +434,17 @@ func enableOrDisableAddonInternal(cc *config.ClusterConfig, addon *assets.Addon,
}
}
// on the first attempt try without force, but on subsuquent attempts use force
force := false
// Retry, because sometimes we race against an apiserver restart
apply := func() error {
_, err := runner.RunCmd(kubectlCommand(cc, deployFiles, enable))
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_, err := runner.RunCmd(kubectlCommand(ctx, cc, deployFiles, enable, force))
if err != nil {
klog.Warningf("apply failed, will retry: %v", err)
force = true
}
return err
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package addons
import (
"context"
"fmt"
"os/exec"
"path"
@ -27,7 +28,7 @@ import (
"k8s.io/minikube/pkg/minikube/vmpath"
)
func kubectlCommand(cc *config.ClusterConfig, files []string, enable bool) *exec.Cmd {
func kubectlCommand(ctx context.Context, cc *config.ClusterConfig, files []string, enable, force bool) *exec.Cmd {
v := constants.DefaultKubernetesVersion
if cc != nil {
v = cc.KubernetesConfig.KubernetesVersion
@ -41,6 +42,9 @@ func kubectlCommand(cc *config.ClusterConfig, files []string, enable bool) *exec
}
args := []string{fmt.Sprintf("KUBECONFIG=%s", path.Join(vmpath.GuestPersistentDir, "kubeconfig")), kubectlBinary, kubectlAction}
if force {
args = append(args, "--force")
}
if !enable {
// --ignore-not-found just ignores when we try to delete a resource that is already gone,
// like a completed job with a ttlSecondsAfterFinished
@ -50,5 +54,5 @@ func kubectlCommand(cc *config.ClusterConfig, files []string, enable bool) *exec
args = append(args, []string{"-f", f}...)
}
return exec.Command("sudo", args...)
return exec.CommandContext(ctx, "sudo", args...)
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package addons
import (
"context"
"strings"
"testing"
@ -28,6 +29,7 @@ func TestKubectlCommand(t *testing.T) {
description string
files []string
enable bool
force bool
expected string
}{
{
@ -35,12 +37,27 @@ func TestKubectlCommand(t *testing.T) {
files: []string{"a", "b"},
enable: true,
expected: "sudo KUBECONFIG=/var/lib/minikube/kubeconfig /var/lib/minikube/binaries/v1.17.0/kubectl apply -f a -f b",
}, {
},
{
description: "disable an addon",
files: []string{"a", "b"},
enable: false,
expected: "sudo KUBECONFIG=/var/lib/minikube/kubeconfig /var/lib/minikube/binaries/v1.17.0/kubectl delete --ignore-not-found -f a -f b",
},
{
description: "enable an addon",
files: []string{"a", "b"},
enable: true,
force: true,
expected: "sudo KUBECONFIG=/var/lib/minikube/kubeconfig /var/lib/minikube/binaries/v1.17.0/kubectl apply --force -f a -f b",
},
{
description: "disable an addon",
files: []string{"a", "b"},
enable: false,
force: true,
expected: "sudo KUBECONFIG=/var/lib/minikube/kubeconfig /var/lib/minikube/binaries/v1.17.0/kubectl delete --force --ignore-not-found -f a -f b",
},
}
cc := &config.ClusterConfig{
@ -51,7 +68,7 @@ func TestKubectlCommand(t *testing.T) {
for _, test := range tests {
t.Run(test.description, func(t *testing.T) {
command := kubectlCommand(cc, test.files, test.enable)
command := kubectlCommand(context.Background(), cc, test.files, test.enable, test.force)
actual := strings.Join(command.Args, " ")
if actual != test.expected {