diff --git a/cmd/stop.go b/cmd/stop.go index dd76baf138..acf1de4851 100644 --- a/cmd/stop.go +++ b/cmd/stop.go @@ -61,19 +61,22 @@ dapr stop --run-file /path/to/directory -k err = executeStopWithRunFile(runFilePath) if err != nil { print.FailureStatusEvent(os.Stderr, "Failed to stop Dapr and app processes: %s", err) - } else { - print.SuccessStatusEvent(os.Stdout, "Dapr and app processes stopped successfully") + os.Exit(1) } + print.SuccessStatusEvent(os.Stdout, "Dapr and app processes stopped successfully") return } config, _, cErr := getRunConfigFromRunFile(runFilePath) if cErr != nil { print.FailureStatusEvent(os.Stderr, "Failed to parse run template file %q: %s", runFilePath, cErr.Error()) + os.Exit(1) } err = kubernetes.Stop(runFilePath, config) if err != nil { print.FailureStatusEvent(os.Stderr, "Error stopping deployments from multi-app run template: %v", err) + os.Exit(1) } + return } if stopAppID != "" { args = append(args, stopAppID) @@ -84,14 +87,19 @@ dapr stop --run-file /path/to/directory -k os.Exit(1) } cliPIDToNoOfApps := standalone.GetCLIPIDCountMap(apps) + stopFailed := false for _, appID := range args { err = standalone.Stop(appID, cliPIDToNoOfApps, apps) if err != nil { print.FailureStatusEvent(os.Stderr, "failed to stop app id %s: %s", appID, err) + stopFailed = true } else { print.SuccessStatusEvent(os.Stdout, "app stopped successfully: %s", appID) } } + if stopFailed { + os.Exit(1) + } }, } diff --git a/cmd/uninstall.go b/cmd/uninstall.go index 727e728ad8..7601bd05b3 100644 --- a/cmd/uninstall.go +++ b/cmd/uninstall.go @@ -90,9 +90,9 @@ dapr uninstall --runtime-path if err != nil { print.FailureStatusEvent(os.Stderr, fmt.Sprintf("Error removing Dapr: %s", err)) - } else { - print.SuccessStatusEvent(os.Stdout, "Dapr has been removed successfully") + os.Exit(1) } + print.SuccessStatusEvent(os.Stdout, "Dapr has been removed successfully") }, } diff --git a/pkg/kubernetes/run.go b/pkg/kubernetes/run.go index 9985e3406b..9360026093 100644 --- a/pkg/kubernetes/run.go +++ b/pkg/kubernetes/run.go @@ -391,13 +391,20 @@ func deployYamlToK8s(yamlToDeployPath string) error { return nil } -func deleteYamlK8s(yamlToDeletePath string) error { +func deleteYamlK8s(yamlToDeletePath string, ignoreNotFound bool) error { print.InfoStatusEvent(os.Stdout, "Deleting %q from Kubernetes", yamlToDeletePath) _, err := os.Stat(yamlToDeletePath) if os.IsNotExist(err) { return fmt.Errorf("error given file %q does not exist", yamlToDeletePath) } - _, err = utils.RunCmdAndWait("kubectl", "delete", "-f", yamlToDeletePath) + args := []string{"delete", "-f", yamlToDeletePath} + if ignoreNotFound { + // "dapr stop -f -k" races with the graceful shutdown performed by the + // "dapr run -f -k" process on receiving the stop signal; resources + // already deleted by the other process must not fail the stop. + args = append(args, "--ignore-not-found") + } + _, err = utils.RunCmdAndWait("kubectl", args...) if err != nil { return fmt.Errorf("error deleting the yaml %s from Kubernetes: %w", yamlToDeletePath, err) } @@ -412,9 +419,9 @@ func gracefullyShutdownK8sDeployment(runStates []runState, client k8s.Interface, errs := make([]error, 0, len(runStates)*4) for _, r := range runStates { if len(r.serviceFilePath) != 0 { - errs = append(errs, deleteYamlK8s(r.serviceFilePath)) + errs = append(errs, deleteYamlK8s(r.serviceFilePath, false)) } - errs = append(errs, deleteYamlK8s(r.deploymentFilePath)) + errs = append(errs, deleteYamlK8s(r.deploymentFilePath, false)) labelSelector := map[string]string{ daprAppIDKey: r.app.AppID, } diff --git a/pkg/kubernetes/stop.go b/pkg/kubernetes/stop.go index f2932bb7e2..993a021088 100644 --- a/pkg/kubernetes/stop.go +++ b/pkg/kubernetes/stop.go @@ -42,13 +42,13 @@ func Stop(runFilePath string, config runfileconfig.RunFileConfig) error { serviceFilePath := filepath.Join(deployDir, serviceFileName) deploymentFilePath := filepath.Join(deployDir, deploymentFileName) if app.CreateService { - err = deleteYamlK8s(serviceFilePath) + err = deleteYamlK8s(serviceFilePath, true) if err != nil { appError = true } errs = append(errs, err) } - err = deleteYamlK8s(deploymentFilePath) + err = deleteYamlK8s(deploymentFilePath, true) if err != nil { appError = true } diff --git a/tests/e2e/standalone/init_negative_test.go b/tests/e2e/standalone/init_negative_test.go index 9fe056852f..48f8dd1be3 100644 --- a/tests/e2e/standalone/init_negative_test.go +++ b/tests/e2e/standalone/init_negative_test.go @@ -54,7 +54,7 @@ func TestStandaloneInitNegatives(t *testing.T) { t.Run("stop without install", func(t *testing.T) { output, err := cmdStopWithAppID("test") - require.NoError(t, err, "expected no error on stop without install") + require.Error(t, err, "expected non-zero exit code on stop without install") require.Contains(t, output, "failed to stop app id test: couldn't find app id test", "expected output to match") })