mirror of
https://github.com/siderolabs/omni.git
synced 2026-05-05 14:46:12 +02:00
fix: start watch before delete in omnictl delete
Start the watch before sending the destroy call to not miss events. Add support for passing more than a single resource to the call, e.g., `omnictl delete link link-1 link-2 link-3`. Additionally, bring back the "WatchKind" behavior when `--all` or `--selector` is used, or when the number of resources to be deleted is above a certain size. Signed-off-by: Utku Ozdemir <utku.ozdemir@siderolabs.com>
This commit is contained in:
parent
40033da998
commit
a32cb8a1f8
@ -31,7 +31,7 @@ var deleteCmd = &cobra.Command{
|
||||
Short: "Delete a specific resource by ID or all resources of the type.",
|
||||
Long: `Similar to 'kubectl delete', 'omnictl delete' initiates resource deletion and waits for the operation to complete.`,
|
||||
Example: "",
|
||||
Args: cobra.RangeArgs(1, 2),
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return access.WithClient(deleteResources(cmd, args))
|
||||
},
|
||||
@ -53,39 +53,55 @@ func deleteResources(cmd *cobra.Command, args []string) func(ctx context.Context
|
||||
deleteCmdFlags.namespace = rd.TypedSpec().DefaultNamespace
|
||||
}
|
||||
|
||||
var resourceIDs []resource.ID
|
||||
listMD := resource.NewMetadata(deleteCmdFlags.namespace, rd.TypedSpec().Type, "", resource.VersionUndefined)
|
||||
|
||||
var (
|
||||
resourceIDs []resource.ID
|
||||
useWatchKind bool
|
||||
watchKindOpts []state.WatchKindOption
|
||||
)
|
||||
|
||||
if len(args) > 1 {
|
||||
resourceIDs = []resource.ID{args[1]}
|
||||
resourceIDs = args[1:]
|
||||
useWatchKind = len(resourceIDs) > 10
|
||||
} else {
|
||||
var listOpts []state.ListOption
|
||||
useWatchKind = true
|
||||
|
||||
if !deleteCmdFlags.all && deleteCmdFlags.selector == "" {
|
||||
return fmt.Errorf("either resource ID or one of --all or --selector flags must be specified")
|
||||
}
|
||||
|
||||
if deleteCmdFlags.selector != "" {
|
||||
var query *resource.LabelQuery
|
||||
var listOpts []state.ListOption
|
||||
|
||||
query, err = labels.ParseQuery(deleteCmdFlags.selector)
|
||||
if deleteCmdFlags.selector != "" {
|
||||
var labelQuery resource.LabelQueryOption
|
||||
|
||||
labelQuery, err = labelQueryForSelector(deleteCmdFlags.selector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
listOpts = append(listOpts, state.WithLabelQuery(resource.RawLabelQuery(*query)))
|
||||
listOpts = append(listOpts, state.WithLabelQuery(labelQuery))
|
||||
watchKindOpts = append(watchKindOpts, state.WatchWithLabelQuery(labelQuery))
|
||||
}
|
||||
|
||||
var list resource.List
|
||||
|
||||
list, err = st.List(ctx, resource.NewMetadata(deleteCmdFlags.namespace, rd.TypedSpec().Type, "", resource.VersionUndefined), listOpts...)
|
||||
if err != nil {
|
||||
if resourceIDs, err = getResourceIDs(ctx, st, listMD, listOpts...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
resourceIDs = make([]resource.ID, 0, len(list.Items))
|
||||
watchCh := make(chan state.Event)
|
||||
|
||||
for _, item := range list.Items {
|
||||
resourceIDs = append(resourceIDs, item.Metadata().ID())
|
||||
if useWatchKind {
|
||||
if err = st.WatchKind(ctx, listMD, watchCh, watchKindOpts...); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
for _, resourceID := range resourceIDs {
|
||||
err = st.Watch(ctx, resource.NewMetadata(deleteCmdFlags.namespace, rd.TypedSpec().Type, resourceID, resource.VersionUndefined), watchCh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,16 +115,6 @@ func deleteResources(cmd *cobra.Command, args []string) func(ctx context.Context
|
||||
fmt.Printf("torn down %s %s\n", rd.TypedSpec().Type, resourceID)
|
||||
}
|
||||
|
||||
// set up a watch for all resources of kind
|
||||
watchCh := make(chan state.Event)
|
||||
|
||||
for _, resourceID := range resourceIDs {
|
||||
err = st.Watch(ctx, resource.NewMetadata(deleteCmdFlags.namespace, rd.TypedSpec().Type, resourceID, resource.VersionUndefined), watchCh)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
resourceIDsLeft := map[resource.ID]struct{}{}
|
||||
|
||||
for _, resourceID := range resourceIDs {
|
||||
@ -151,6 +157,30 @@ func deleteResources(cmd *cobra.Command, args []string) func(ctx context.Context
|
||||
}
|
||||
}
|
||||
|
||||
func labelQueryForSelector(selector string) (resource.LabelQueryOption, error) {
|
||||
query, err := labels.ParseQuery(selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resource.RawLabelQuery(*query), nil
|
||||
}
|
||||
|
||||
func getResourceIDs(ctx context.Context, st state.State, listMD resource.Metadata, listOpts ...state.ListOption) ([]resource.ID, error) {
|
||||
list, err := st.List(ctx, listMD, listOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resourceIDs := make([]resource.ID, 0, len(list.Items))
|
||||
|
||||
for _, item := range list.Items {
|
||||
resourceIDs = append(resourceIDs, item.Metadata().ID())
|
||||
}
|
||||
|
||||
return resourceIDs, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
deleteCmd.PersistentFlags().StringVarP(&deleteCmdFlags.namespace, "namespace", "n", resources.DefaultNamespace, "The resource namespace.")
|
||||
deleteCmd.PersistentFlags().BoolVar(&deleteCmdFlags.all, "all", false, "Delete all resources of the type.")
|
||||
|
||||
@ -132,7 +132,7 @@ func generate() (err error) {
|
||||
port = ""
|
||||
}
|
||||
|
||||
data := struct { //nolint:govet
|
||||
data := struct {
|
||||
ClientID string
|
||||
Auth0Domain string
|
||||
Host string
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user