Skip to content

Commit e995f4c

Browse files
committed
NodeSet: add special notation @@source to expand group names
This change allows access to all group names of a specific source in node set expressions. The special operator `@@` optionally followed by a source expands group names that can then be manipulated as a set. The default group source is used when `@@` is used alone. Note: In that case, group names are not prefixed with @ and as such, not further expanded into nodes by NodeSet.
1 parent c421133 commit e995f4c

File tree

7 files changed

+136
-12
lines changed

7 files changed

+136
-12
lines changed

doc/man/man1/cluset.1

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.\" Man page generated from reStructuredText.
22
.
3-
.TH CLUSET 1 "2019-12-01" "1.8.3" "ClusterShell User Manual"
3+
.TH CLUSET 1 "2022-03-19" "1.8.4" "ClusterShell User Manual"
44
.SH NAME
55
cluset \- compute advanced cluster node set operations
66
.
@@ -225,7 +225,7 @@ node[0\-4,11\-13]
225225
.sp
226226
This computes a folded nodeset containing nodes found in group @gpu and @slurm:bigmem, but not in both, minus the nodes found in odd chassis groups from 1 to 9.
227227
.TP
228-
.B "All nodes" extension (v1.7+)
228+
.B "All nodes" extension
229229
The \fB@*\fP and \fB@SOURCE:*\fP special notations may be used in extended patterns to represent all nodes (in SOURCE) according to the \fIall\fP external shell command (see \fBgroups.conf\fP(5)) and are equivalent to:
230230
.INDENT 7.0
231231
.INDENT 3.5
@@ -235,6 +235,21 @@ The \fB@*\fP and \fB@SOURCE:*\fP special notations may be used in extended patte
235235
.UNINDENT
236236
.UNINDENT
237237
.UNINDENT
238+
.TP
239+
.B Group names in expressions
240+
The \fB@@SOURCE\fP notation may be used to access all group names from the specified SOURCE (or from the default group source when just \fB@@\fP is used) in node set expressions; this works with either file\-based group sources or with external group sources that have the \fIlist\fP upcall defined (see \fBgroups.conf\fP(5)):
241+
.INDENT 7.0
242+
.INDENT 3.5
243+
.INDENT 0.0
244+
.TP
245+
.B $ cluset \-f @@rack
246+
.UNINDENT
247+
.nf
248+
J[1\-3]
249+
.fi
250+
.sp
251+
.UNINDENT
252+
.UNINDENT
238253
.UNINDENT
239254
.SH NODE WILDCARDS
240255
.sp

doc/man/man1/nodeset.1

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.\" Man page generated from reStructuredText.
22
.
3-
.TH NODESET 1 "2021-11-03" "1.8.4" "ClusterShell User Manual"
3+
.TH NODESET 1 "2022-03-19" "1.8.4" "ClusterShell User Manual"
44
.SH NAME
55
nodeset \- compute advanced nodeset operations
66
.
@@ -225,7 +225,7 @@ node[0\-4,11\-13]
225225
.sp
226226
This computes a folded nodeset containing nodes found in group @gpu and @slurm:bigmem, but not in both, minus the nodes found in odd chassis groups from 1 to 9.
227227
.TP
228-
.B "All nodes" extension (v1.7+)
228+
.B "All nodes" extension
229229
The \fB@*\fP and \fB@SOURCE:*\fP special notations may be used in extended patterns to represent all nodes (in SOURCE) according to the \fIall\fP external shell command (see \fBgroups.conf\fP(5)) and are equivalent to:
230230
.INDENT 7.0
231231
.INDENT 3.5
@@ -235,6 +235,21 @@ The \fB@*\fP and \fB@SOURCE:*\fP special notations may be used in extended patte
235235
.UNINDENT
236236
.UNINDENT
237237
.UNINDENT
238+
.TP
239+
.B Group names in expressions
240+
The \fB@@SOURCE\fP notation may be used to access all group names from the specified SOURCE (or from the default group source when just \fB@@\fP is used) in node set expressions; this works with either file\-based group sources or with external group sources that have the \fIlist\fP upcall defined (see \fBgroups.conf\fP(5)):
241+
.INDENT 7.0
242+
.INDENT 3.5
243+
.INDENT 0.0
244+
.TP
245+
.B $ nodeset \-f @@rack
246+
.UNINDENT
247+
.nf
248+
J[1\-3]
249+
.fi
250+
.sp
251+
.UNINDENT
252+
.UNINDENT
238253
.UNINDENT
239254
.SH NODE WILDCARDS
240255
.sp

doc/sphinx/tools/nodeset.rst

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -634,9 +634,13 @@ configured group sources and also display the default group source (unless
634634
Listing group names
635635
"""""""""""""""""""
636636

637-
If the **list** external shell command is configured (see
638-
:ref:`node groups configuration <groups-config>`), it is possible to list
639-
available groups *from the default source* with the following commands::
637+
It is always possible to list the groups from a group source if the source is
638+
:ref:`file-based <group-file-based>`.
639+
If the source is an :ref:`external group source <group-external-sources>`, the
640+
**list** upcall must be configured (see also:
641+
:ref:`node groups configuration <groups-config>`).
642+
643+
To list available groups *from the default source*, use the following command::
640644

641645
$ nodeset -l
642646
@mgnt
@@ -645,7 +649,7 @@ available groups *from the default source* with the following commands::
645649
@login
646650
@compute
647651

648-
Or, to list groups *from a specific group source*, use *-l* in conjunction
652+
To list groups *from a specific group source*, use *-l* in conjunction
649653
with *-s* (or *--groupsource*)::
650654

651655
$ nodeset -l -s slurm
@@ -667,6 +671,47 @@ Or, to list groups *from all available group sources*, use *-L* (or
667671
You can also use ``nodeset -ll`` or ``nodeset -LL`` to see each group's
668672
associated node sets.
669673

674+
Listing group names in expressions
675+
""""""""""""""""""""""""""""""""""
676+
677+
ClusterShell 1.8.5 introduces a new operator **@@** optionally followed by
678+
a source name (e.g. **@@source**) to access the list of *raw group names* of
679+
the source (without the **@** prefix). If no source is specified (as in *just*
680+
**@@**), the default group source is used (see :ref:`groups_config_conf`).
681+
The **@@** operator may be used in any node set expression to manipulate group
682+
names as a node set.
683+
684+
Example with the default group source::
685+
686+
$ nodeset -l
687+
@mgnt
688+
@mds
689+
@oss
690+
@login
691+
@compute
692+
693+
$ nodeset -e @@
694+
compute login mds mgnt oss
695+
696+
Example with a group source "rack" that defines group names from rack
697+
locations in a data center::
698+
699+
$ nodeset -l -s rack
700+
@rack:J1
701+
@rack:J2
702+
@rack:J3
703+
704+
$ nodeset -f @@rack
705+
J[1-3]
706+
707+
A set of valid, indexed group sources is also accepted by the **@@** operator
708+
(e.g. **@@dc[1-3]**).
709+
710+
711+
.. warning:: An error is generated when using **@@** in an expression if the
712+
source is not valid (e.g. invalid name, not configured or upcalls
713+
not currently working).
714+
670715

671716
Using node groups in basic commands
672717
"""""""""""""""""""""""""""""""""""

doc/txt/cluset.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ compute advanced cluster node set operations
77
--------------------------------------------
88

99
:Author: Stephane Thiell <[email protected]>
10-
:Date: 2021-11-03
10+
:Date: 2022-03-19
1111
:Copyright: GNU Lesser General Public License version 2.1 or later (LGPLv2.1+)
1212
:Version: 1.8.4
1313
:Manual section: 1
@@ -131,11 +131,19 @@ Example of advanced usage
131131

132132
This computes a folded nodeset containing nodes found in group @gpu and @slurm:bigmem, but not in both, minus the nodes found in odd chassis groups from 1 to 9.
133133

134-
"All nodes" extension (v1.7+)
134+
"All nodes" extension
135135
The ``@*`` and ``@SOURCE:*`` special notations may be used in extended patterns to represent all nodes (in SOURCE) according to the *all* external shell command (see ``groups.conf``\(5)) and are equivalent to:
136136

137137
:$ cluset [-s SOURCE] -a -f:
138138

139+
Group names in expressions
140+
The ``@@SOURCE`` notation may be used to access all group names from the specified SOURCE (or from the default group source when just ``@@`` is used) in node set expressions; this works with either file-based group sources or with external group sources that have the *list* upcall defined (see ``groups.conf``\(5)):
141+
142+
143+
:$ cluset -f @@rack:
144+
145+
| J[1-3]
146+
139147
NODE WILDCARDS
140148
==============
141149

doc/txt/nodeset.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ compute advanced nodeset operations
77
-----------------------------------
88

99
:Author: Stephane Thiell <[email protected]>
10-
:Date: 2021-11-03
10+
:Date: 2022-03-19
1111
:Copyright: GNU Lesser General Public License version 2.1 or later (LGPLv2.1+)
1212
:Version: 1.8.4
1313
:Manual section: 1
@@ -131,11 +131,19 @@ Example of advanced usage
131131

132132
This computes a folded nodeset containing nodes found in group @gpu and @slurm:bigmem, but not in both, minus the nodes found in odd chassis groups from 1 to 9.
133133

134-
"All nodes" extension (v1.7+)
134+
"All nodes" extension
135135
The ``@*`` and ``@SOURCE:*`` special notations may be used in extended patterns to represent all nodes (in SOURCE) according to the *all* external shell command (see ``groups.conf``\(5)) and are equivalent to:
136136

137137
:$ nodeset [-s SOURCE] -a -f:
138138

139+
Group names in expressions
140+
The ``@@SOURCE`` notation may be used to access all group names from the specified SOURCE (or from the default group source when just ``@@`` is used) in node set expressions; this works with either file-based group sources or with external group sources that have the *list* upcall defined (see ``groups.conf``\(5)):
141+
142+
:$ nodeset -f @@rack:
143+
144+
| J[1-3]
145+
146+
139147
NODE WILDCARDS
140148
==============
141149

lib/ClusterShell/NodeSet.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,8 @@ def parse_group_string(self, nodegroup, namespace=None):
916916
namespace, group = grpstr.split(':', 1)
917917
if group == '*': # @* or @source:* magic
918918
reslist = self.all_nodes(namespace)
919+
elif group.startswith('@'): # @@source group name list
920+
reslist = self.grouplist(grpstr[1:])
919921
else:
920922
reslist = self.group_resolver.group_nodes(group, namespace)
921923
return ','.join(reslist), namespace

tests/NodeSetGroupTest.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,11 @@ def testConfigListAllNDWithoutAll(self):
625625
self.assertEqual(str(NodeSet.fromall(resolver=res)), "rack[1-10]z[1-42]")
626626
self.assertEqual(res.grouplist(), ['x1y1', 'x1y2', 'x1y[3-4]']) # raw
627627
self.assertEqual(grouplist(resolver=res), ['x1y1', 'x1y2', 'x1y3', 'x1y4']) # cleaned
628+
# test "@@" group name set
629+
nodeset = NodeSet("@@", resolver=res)
630+
self.assertEqual(str(nodeset), "x1y[1-4]")
631+
nodeset = NodeSet("@@local", resolver=res)
632+
self.assertEqual(str(nodeset), "x1y[1-4]")
628633
# test "@*" magic group listing
629634
nodeset = NodeSet("@*", resolver=res)
630635
self.assertEqual(str(nodeset), "rack[1-10]z[1-42]")
@@ -1104,6 +1109,11 @@ def test_nodeset_wildcard_grouplist(self):
11041109
self.assertEqual(grouplist(resolver=res), ['a', 'b*', 'c', 'd', 'e'])
11051110
nodeset = NodeSet("*foo*", resolver=res)
11061111
self.assertEqual(str(nodeset), "foo[1-3],foobar,foobar1")
1112+
# currently @@ triggers group name wildcard expansion
1113+
nodeset = NodeSet("@@", resolver=res)
1114+
self.assertEqual(str(nodeset), "a,bar,bar[1-2],c,d,e")
1115+
nodeset = NodeSet("@@local", resolver=res)
1116+
self.assertEqual(str(nodeset), "a,bar,bar[1-2],c,d,e")
11071117

11081118
def test_nodeset_wildcard_support_ranges(self):
11091119
"""test NodeSet wildcard support with ranges"""
@@ -1228,6 +1238,16 @@ def testGroupListDefault(self):
12281238
self.assertEqual(len(all_nodes), len(nodes))
12291239
self.assertEqual(all_nodes, nodes)
12301240

1241+
# @@ special operator
1242+
gl_nodes = NodeSet("@@")
1243+
self.assertEqual(len(gl_nodes), 20)
1244+
self.assertEqual(str(gl_nodes),
1245+
"Uppercase,all,chassis[1-12],compute,gpu,gpuchassis,io,mds,oss")
1246+
gl_nodes = NodeSet("@@default")
1247+
self.assertEqual(len(gl_nodes), 20)
1248+
self.assertEqual(str(gl_nodes),
1249+
"Uppercase,all,chassis[1-12],compute,gpu,gpuchassis,io,mds,oss")
1250+
12311251
def testGroupListSource2(self):
12321252
"""test NodeSet group listing GroupResolver.grouplist(source)"""
12331253
groups = std_group_resolver().grouplist("source2")
@@ -1237,6 +1257,11 @@ def testGroupListSource2(self):
12371257
total += len(NodeSet("@source2:%s" % group))
12381258
self.assertEqual(total, 24)
12391259

1260+
# @@ special operator
1261+
gl_nodes = NodeSet("@@source2")
1262+
self.assertEqual(len(gl_nodes), 2)
1263+
self.assertEqual(str(gl_nodes), "gpu,para")
1264+
12401265
def testGroupNoPrefix(self):
12411266
"""test NodeSet group noprefix option"""
12421267
nodeset = NodeSet("montana[32-37,42-55]")
@@ -1641,6 +1666,12 @@ def test_yaml_basic(self):
16411666
nodeset = NodeSet("@unknown", resolver=res)
16421667
self.assertEqual(len(nodeset), 0)
16431668

1669+
# @@ grouplist operator
1670+
nodeset = NodeSet("@@", resolver=res)
1671+
self.assertEqual(str(nodeset), "bar,foo")
1672+
nodeset = NodeSet("@@yaml", resolver=res)
1673+
self.assertEqual(str(nodeset), "bar,foo")
1674+
16441675
# Regroup
16451676
nodeset = NodeSet("example[1-4,90-100]", resolver=res)
16461677
self.assertEqual(str(nodeset), "example[1-4,90-100]")

0 commit comments

Comments
 (0)