cmd: support type!=status in get --status-selector
`flux get --status-selector` only supported equality (`type=status`),
so finding objects that are not in a given state required multiple
invocations, e.g. listing everything that is not ready needed both
`Ready=False` and `Ready=Unknown`.
Add support for a negated selector `type!=status`. Since all resource
adapters delegate matching to the shared `statusMatches` helper and
filtering is centralised in `getRowsToPrint`, negation is implemented
purely in the parse/filter layer by inverting the match result. This
covers every resource type and the `--watch` path without touching the
per-resource adapters.
A missing condition is treated as not-matching by `statusMatches` (Flux
considers it "waiting to be reconciled"), so `Ready!=True` also surfaces
objects that have no Ready condition yet, i.e. the complete not-ready set:
flux get all -A --status-selector Ready!=True
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: 3uzbcqje <3uzbcqje@addy.to>
This commit is contained in:
+21
-6
@@ -78,7 +78,7 @@ func init() {
|
||||
getCmd.PersistentFlags().BoolVarP(&getArgs.noHeader, "no-header", "", false, "skip the header when printing the results")
|
||||
getCmd.PersistentFlags().BoolVarP(&getArgs.watch, "watch", "w", false, "After listing/getting the requested object, watch for changes.")
|
||||
getCmd.PersistentFlags().StringVar(&getArgs.statusSelector, "status-selector", "",
|
||||
"specify the status condition name and the desired state to filter the get result, e.g. ready=false")
|
||||
"specify the status condition name and the desired state to filter the get result, e.g. ready=false or ready!=true")
|
||||
getCmd.PersistentFlags().StringVarP(&getArgs.labelSelector, "label-selector", "l", "",
|
||||
"filter objects by label selector")
|
||||
rootCmd.AddCommand(getCmd)
|
||||
@@ -230,10 +230,18 @@ func namespaceNameOrAny(allNamespaces bool, namespaceName string) string {
|
||||
func getRowsToPrint(getAll bool, list summarisable) ([][]string, error) {
|
||||
noFilter := true
|
||||
var conditionType, conditionStatus string
|
||||
var negate bool
|
||||
if getArgs.statusSelector != "" {
|
||||
parts := strings.SplitN(getArgs.statusSelector, "=", 2)
|
||||
// Support both type=status (match) and type!=status (negated match).
|
||||
// "!=" must be checked first since it also contains "=".
|
||||
separator := "="
|
||||
if strings.Contains(getArgs.statusSelector, "!=") {
|
||||
separator = "!="
|
||||
negate = true
|
||||
}
|
||||
parts := strings.SplitN(getArgs.statusSelector, separator, 2)
|
||||
if len(parts) != 2 {
|
||||
return nil, fmt.Errorf("expected status selector in type=status format, but found: %s", getArgs.statusSelector)
|
||||
return nil, fmt.Errorf("expected status selector in type=status or type!=status format, but found: %s", getArgs.statusSelector)
|
||||
}
|
||||
conditionType = parts[0]
|
||||
conditionStatus = parts[1]
|
||||
@@ -241,10 +249,17 @@ func getRowsToPrint(getAll bool, list summarisable) ([][]string, error) {
|
||||
}
|
||||
var rows [][]string
|
||||
for i := 0; i < list.len(); i++ {
|
||||
if noFilter || list.statusSelectorMatches(i, conditionType, conditionStatus) {
|
||||
row := list.summariseItem(i, getArgs.allNamespaces, getAll)
|
||||
rows = append(rows, row)
|
||||
if !noFilter {
|
||||
matches := list.statusSelectorMatches(i, conditionType, conditionStatus)
|
||||
if negate {
|
||||
matches = !matches
|
||||
}
|
||||
if !matches {
|
||||
continue
|
||||
}
|
||||
}
|
||||
row := list.summariseItem(i, getArgs.allNamespaces, getAll)
|
||||
rows = append(rows, row)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user