Skip to content

Commit 5080ebc

Browse files
committed
Adds dapr scheduler delete
Adds `dapr scheduler delete` which is a new CLI command to delete jobs and actor reminders which are stored in scheduler. You can delete multiple jobs at a time, or all jobs registered in a namespace. The target namespace is required. The given name encode the job target type in the string: ``` "job/<app-id>/<job-name>" for jobs "actorreinder/<actor-type>||<actor-id>||<reminder-name>" for actor reminders ``` ``` dapr delete -n foo job/foo/bar dapr delete -n foo actorreminder/MyActor||1234||reminder1 dapr delete -n foo --delete-all-yes-i-know-what-i-am-doing ``` Signed-off-by: joshvanl <[email protected]>
1 parent d248ea8 commit 5080ebc

File tree

8 files changed

+718
-336
lines changed

8 files changed

+718
-336
lines changed

cmd/scheduler.go

Lines changed: 6 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -13,112 +13,21 @@ limitations under the License.
1313

1414
package cmd
1515

16-
import (
17-
"os"
18-
"slices"
19-
20-
"github.com/gocarina/gocsv"
21-
"github.com/spf13/cobra"
22-
23-
"github.com/dapr/cli/pkg/print"
24-
"github.com/dapr/cli/pkg/scheduler"
25-
"github.com/dapr/cli/utils"
26-
"github.com/dapr/kit/ptr"
27-
"github.com/dapr/kit/signals"
28-
)
29-
30-
const (
31-
schedulerListJobsOutputFormatShort = "short"
32-
schedulerListJobsOutputFormatWide = "wide"
33-
schedulerListJobsOutputFormatYAML = "yaml"
34-
schedulerListJobsOutputFormatJSON = "json"
35-
)
16+
import "github.com/spf13/cobra"
3617

3718
var (
38-
schedulerSchedulerNamespace string
39-
schedulerNamespace string
40-
schedulerListJobsFilterType string
41-
schedulerListJobsOutputFormat string
19+
schedulerSchedulerNamespace string
20+
schedulerNamespace string
4221
)
4322

4423
var SchedulerCmd = &cobra.Command{
4524
Use: "scheduler",
4625
Short: "Scheduler management commands",
4726
}
4827

49-
var SchedulerListJobsCmd = &cobra.Command{
50-
Use: "list",
51-
Short: "List scheduled jobs in the Scheduler",
52-
Run: func(cmd *cobra.Command, args []string) {
53-
ctx := signals.Context()
54-
55-
if !slices.Contains([]string{
56-
scheduler.FilterJobsAll,
57-
scheduler.FilterJobsJob,
58-
scheduler.FilterJobsActor,
59-
}, schedulerListJobsFilterType) {
60-
print.FailureStatusEvent(os.Stderr, "invalid value for --filter-type. Supported values are 'all', 'jobs', 'actorreminder'")
61-
os.Exit(1)
62-
}
63-
64-
if !slices.Contains([]string{
65-
schedulerListJobsOutputFormatShort,
66-
schedulerListJobsOutputFormatWide,
67-
schedulerListJobsOutputFormatYAML,
68-
schedulerListJobsOutputFormatJSON,
69-
}, schedulerListJobsOutputFormat) {
70-
print.FailureStatusEvent(os.Stderr, "invalid value for --output. Supported values are 'table', 'wide', 'yaml', 'json'")
71-
os.Exit(1)
72-
}
73-
74-
opts := scheduler.ListJobsOptions{
75-
SchedulerNamespace: schedulerSchedulerNamespace,
76-
KubernetesMode: kubernetesMode,
77-
FilterJobType: schedulerListJobsFilterType,
78-
}
79-
if schedulerNamespace != "" {
80-
opts.DaprNamespace = ptr.Of(schedulerNamespace)
81-
}
82-
83-
var list any
84-
var err error
85-
if schedulerListJobsOutputFormat == schedulerListJobsOutputFormatShort {
86-
list, err = scheduler.ListJobsAsOutput(ctx, opts)
87-
} else {
88-
list, err = scheduler.ListJobsAsOutputWide(ctx, opts)
89-
}
90-
if err != nil {
91-
print.FailureStatusEvent(os.Stderr, "%s", err)
92-
os.Exit(1)
93-
}
94-
95-
switch schedulerListJobsOutputFormat {
96-
case schedulerListJobsOutputFormatYAML:
97-
err = utils.PrintDetail(os.Stdout, "yaml", list)
98-
case schedulerListJobsOutputFormatJSON:
99-
err = utils.PrintDetail(os.Stdout, "json", list)
100-
default:
101-
table, err := gocsv.MarshalString(list)
102-
if err != nil {
103-
break
104-
}
105-
106-
utils.PrintTable(table)
107-
}
108-
109-
if err != nil {
110-
print.FailureStatusEvent(os.Stdout, err.Error())
111-
os.Exit(1)
112-
}
113-
},
114-
}
115-
11628
func init() {
117-
SchedulerListJobsCmd.Flags().StringVar(&schedulerListJobsFilterType, "filter-type", scheduler.FilterJobsAll, "Filter jobs by type. Supported values are 'all', 'jobs', 'actorreminder'")
118-
SchedulerListJobsCmd.Flags().StringVarP(&schedulerListJobsOutputFormat, "output", "o", schedulerListJobsOutputFormatShort, "Output format. One of 'short', 'wide', 'yaml', 'json'")
119-
SchedulerListJobsCmd.Flags().StringVar(&schedulerSchedulerNamespace, "scheduler-namespace", "dapr-system", "Kubernetes namespace where the scheduler is deployed")
120-
SchedulerListJobsCmd.Flags().StringVarP(&schedulerNamespace, "namespace", "n", "", "Kubernetes namespace to list Dapr apps from. If not specified, uses all namespaces")
121-
SchedulerListJobsCmd.Flags().BoolVarP(&kubernetesMode, "kubernetes", "k", false, "List all Dapr pods in a Kubernetes cluster")
122-
SchedulerCmd.AddCommand(SchedulerListJobsCmd)
12329
RootCmd.AddCommand(SchedulerCmd)
30+
SchedulerCmd.PersistentFlags().BoolVarP(&kubernetesMode, "kubernetes", "k", false, "List all Dapr pods in a Kubernetes cluster")
31+
SchedulerCmd.PersistentFlags().StringVarP(&schedulerNamespace, "namespace", "n", "", "Kubernetes namespace to list Dapr apps from. If not specified, uses all namespaces")
32+
SchedulerCmd.PersistentFlags().StringVar(&schedulerSchedulerNamespace, "scheduler-namespace", "dapr-system", "Kubernetes namespace where the scheduler is deployed")
12433
}

cmd/schedulerdelete.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
Copyright 2025 The Dapr Authors
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package cmd
15+
16+
import (
17+
"errors"
18+
"fmt"
19+
"os"
20+
21+
"github.com/dapr/cli/pkg/print"
22+
"github.com/dapr/cli/pkg/scheduler"
23+
"github.com/dapr/kit/signals"
24+
"github.com/spf13/cobra"
25+
)
26+
27+
var (
28+
schedulerDeleteAll bool
29+
)
30+
31+
var SchedulerDeleteCmd = &cobra.Command{
32+
Use: "delete",
33+
Short: "Delete jobs or actor reminders which are scheduled in Scheduler.",
34+
Long: `Delete jobs or actor reminders which are scheduled in Scheduler.
35+
Namespace (-n) is required.
36+
Job names are formatted by their type, app ID, then identifier.
37+
Actor reminders require the actor type, actor ID, then reminder name, separated by ||.
38+
Accepts multiple job names or actor reminders to delete.
39+
40+
dapr scheduler delete -n foo job/my-app-id/my-job-name
41+
dapr scheduler delete -n foo "actorreminder/my-actor-type||my-actor-id||my-reminder-name"
42+
`,
43+
RunE: func(cmd *cobra.Command, args []string) error {
44+
ctx := signals.Context()
45+
46+
if !cmd.Flag("namespace").Changed {
47+
return errors.New(`required flag(s) "--namespace" not set`)
48+
}
49+
50+
if schedulerDeleteAll {
51+
if err := scheduler.DeleteAll(ctx, scheduler.DeleteOptions{
52+
SchedulerNamespace: schedulerSchedulerNamespace,
53+
DaprNamespace: schedulerNamespace,
54+
KubernetesMode: kubernetesMode,
55+
}); err != nil {
56+
return fmt.Errorf("Failed to delete jobs: %s", err)
57+
}
58+
return nil
59+
}
60+
61+
if len(args) < 1 {
62+
return errors.New(`Qualifier and job name are required.
63+
Example: dapr scheduler delete -n foo job/my-app-id/my-job-name
64+
Example: dapr scheduler delete -n foo "actorreminder/my-actor-type||my-actor-id||my-reminder-name"`)
65+
}
66+
67+
for _, name := range args {
68+
if err := scheduler.Delete(ctx, name, scheduler.DeleteOptions{
69+
SchedulerNamespace: schedulerSchedulerNamespace,
70+
DaprNamespace: schedulerNamespace,
71+
KubernetesMode: kubernetesMode,
72+
}); err != nil {
73+
return fmt.Errorf("Failed to delete job: %s", err)
74+
}
75+
print.InfoStatusEvent(os.Stdout, "Deleted job '%s' in namespace '%s'.", name, schedulerNamespace)
76+
}
77+
78+
return nil
79+
},
80+
}
81+
82+
func init() {
83+
SchedulerDeleteCmd.Flags().BoolVar(&schedulerDeleteAll, "delete-all-yes-i-know-what-i-am-doing", false, "Deletes all jobs and actor reminders in the given namespace.")
84+
SchedulerCmd.AddCommand(SchedulerDeleteCmd)
85+
}

cmd/schedulerlist.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
Copyright 2025 The Dapr Authors
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package cmd
15+
16+
import (
17+
"errors"
18+
"os"
19+
"slices"
20+
21+
"github.com/gocarina/gocsv"
22+
"github.com/spf13/cobra"
23+
24+
"github.com/dapr/cli/pkg/scheduler"
25+
"github.com/dapr/cli/utils"
26+
"github.com/dapr/kit/ptr"
27+
"github.com/dapr/kit/signals"
28+
)
29+
30+
const (
31+
schedulerListOutputFormatShort = "short"
32+
schedulerListOutputFormatWide = "wide"
33+
schedulerListOutputFormatYAML = "yaml"
34+
schedulerListOutputFormatJSON = "json"
35+
)
36+
37+
var (
38+
schedulerListFilterType string
39+
schedulerListOutputFormat string
40+
)
41+
42+
var SchedulerListCmd = &cobra.Command{
43+
Use: "list",
44+
Short: "List scheduled jobs in the Scheduler",
45+
RunE: func(cmd *cobra.Command, args []string) error {
46+
ctx := signals.Context()
47+
48+
if !slices.Contains([]string{
49+
scheduler.FilterJobsAll,
50+
scheduler.FilterJobsJob,
51+
scheduler.FilterJobsActor,
52+
}, schedulerListFilterType) {
53+
return errors.New("invalid value for --filter-type. Supported values are 'all', 'jobs', 'actorreminder'.")
54+
}
55+
56+
if !slices.Contains([]string{
57+
schedulerListOutputFormatShort,
58+
schedulerListOutputFormatWide,
59+
schedulerListOutputFormatYAML,
60+
schedulerListOutputFormatJSON,
61+
}, schedulerListOutputFormat) {
62+
return errors.New("invalid value for --output. Supported values are 'table', 'wide', 'yaml', 'json'.")
63+
}
64+
65+
opts := scheduler.ListJobsOptions{
66+
SchedulerNamespace: schedulerSchedulerNamespace,
67+
KubernetesMode: kubernetesMode,
68+
FilterJobType: schedulerListFilterType,
69+
}
70+
if schedulerNamespace != "" {
71+
opts.DaprNamespace = ptr.Of(schedulerNamespace)
72+
}
73+
74+
var list any
75+
var err error
76+
if schedulerListOutputFormat == schedulerListOutputFormatShort {
77+
list, err = scheduler.ListJobsAsOutput(ctx, opts)
78+
} else {
79+
list, err = scheduler.ListJobsAsOutputWide(ctx, opts)
80+
}
81+
if err != nil {
82+
return err
83+
}
84+
85+
switch schedulerListOutputFormat {
86+
case schedulerListOutputFormatYAML:
87+
err = utils.PrintDetail(os.Stdout, "yaml", list)
88+
case schedulerListOutputFormatJSON:
89+
err = utils.PrintDetail(os.Stdout, "json", list)
90+
default:
91+
table, err := gocsv.MarshalString(list)
92+
if err != nil {
93+
break
94+
}
95+
96+
utils.PrintTable(table)
97+
}
98+
99+
if err != nil {
100+
return err
101+
}
102+
103+
return nil
104+
},
105+
}
106+
107+
func init() {
108+
SchedulerListCmd.Flags().StringVar(&schedulerListFilterType, "filter-type", scheduler.FilterJobsAll, "Filter jobs by type. Supported values are 'all', 'jobs', 'actorreminder'")
109+
SchedulerListCmd.Flags().StringVarP(&schedulerListOutputFormat, "output", "o", schedulerListOutputFormatShort, "Output format. One of 'short', 'wide', 'yaml', 'json'")
110+
SchedulerCmd.AddCommand(SchedulerListCmd)
111+
}

0 commit comments

Comments
 (0)