cea-hpc/clustershell

In Groups, what's the best way to supply 'empty' group

Closed this issue · 3 comments

Somewhat of weird request, but I have a need to have empty group. I've been just using None to keep the library from getting a traceback, but we populate a group yaml file with something like:

x1000:
  c0: nid[0001-32]
  c0r3: nid[0001-16] 
  c0r7: nid[0017-32]
  c1: None
  ...

This is more for cluset type operations rather than clush operations specifically, but it's nice to provide some mechanism for empty set, but I don't know if there is a best mechanism for this or not. Leaving it empty gives a traceback. NULL also can't be used. I've thought maybe False, but still not great. So just looking how to mark an empty set as part of the configuration file. I'll continue scanning the docs, but I've not found anything (yet).

thiell commented

Hi @jbaksta – thanks for your report. I assume you're talking about the group definition in /etc/clustershell/groups.d/cluster.yaml ? I just tried to define an empty group c1 like this:

c1: ''

And it seems to work as it is empty but listed by cluset.

# cluset -f @roles:c1

# cluset -c @roles:c1
0
# cluset -s roles -l
@roles:adm
@roles:all
@roles:c1
@roles:compute
@roles:gpu
@roles:io
# cluset -s roles -ll
@roles:adm example0
@roles:all example[2,4-5,32-159]
@roles:c1 
@roles:compute example[32-159]
@roles:gpu example[156-159]
@roles:io example[2,4-5]

However, if I use just c1: , I see a traceback indeed, so we should fix this. The yaml file definition must be valid so I don't think you can just specify c1: without the quotes to define an empty node set, but I will double check.

# cluset -f @roles:c1
Traceback (most recent call last):
  File "/usr/bin/cluset", line 9, in <module>
    load_entry_point('ClusterShell==1.9.1', 'console_scripts', 'cluset')()
  File "/usr/lib/python2.7/site-packages/ClusterShell/CLI/Nodeset.py", line 337, in main
    nodeset()
  File "/usr/lib/python2.7/site-packages/ClusterShell/CLI/Nodeset.py", line 261, in nodeset
    compute_nodeset(xset, args, autostep)
  File "/usr/lib/python2.7/site-packages/ClusterShell/CLI/Nodeset.py", line 92, in compute_nodeset
    xset.update(class_set.fromlist(arg.splitlines(), autostep=autostep))
  File "/usr/lib/python2.7/site-packages/ClusterShell/NodeSet.py", line 1268, in fromlist
    inst.updaten(nodelist)
  File "/usr/lib/python2.7/site-packages/ClusterShell/NodeSet.py", line 550, in updaten
    self.update(other)
  File "/usr/lib/python2.7/site-packages/ClusterShell/NodeSet.py", line 1511, in update
    nodeset = self._parser.parse(other, self._autostep)
  File "/usr/lib/python2.7/site-packages/ClusterShell/NodeSet.py", line 803, in parse
    return self.parse_string(str(nsobj), autostep)
  File "/usr/lib/python2.7/site-packages/ClusterShell/NodeSet.py", line 829, in parse_string
    namespace)
  File "/usr/lib/python2.7/site-packages/ClusterShell/NodeSet.py", line 914, in parse_group_string
    reslist = self.group_resolver.group_nodes(group, namespace)
  File "/usr/lib/python2.7/site-packages/ClusterShell/NodeUtils.py", line 490, in group_nodes
    return self._list_nodes(source, 'map', group)
  File "/usr/lib/python2.7/site-packages/ClusterShell/NodeUtils.py", line 450, in _list_nodes
    for line in raw.splitlines():
AttributeError: 'NoneType' object has no attribute 'splitlines'

Thanks. Yeah, correct. I was just curious if maybe showing an empty set would be a good part of the docs as well. It wasn't an issue until I had collection of empty chassis or empty slots in our chassis, but I can see how an empty string would work, just didn't really cross my mind. I'll try this because I also want to see what happens when I do a clush on an empty set. I would like to see common ways to represent empty sets though just for YAML consistency:

null, NULL, ~, and possibly Python's None but that maybe limited by the underlying lib. Not sure. I would say a clearer message on the traceback rather than splitlines would be appreciated. Emitting a warning or error on yaml file parsing failure would be most excellent.

thiell commented

Sounds good. The underlying NodeSet classes does support either an empty string or None to instantiate an empty set, but for whatever reason there is an issue here if the field is "null" in the yaml file. We will try to fix that so we can support an empty yaml field, so using null or ~ would work to define an empty node set in there.

With the CLI tools, like cluset, the empty string can be used to define an empty set:

# cluset -f ""

# cluset -c ""
0

Union:

# cluset -f "" foo
foo
# cluset -c "" foo
1

Intersection:

# cluset -f foo -i ""

# cluset -c foo -i ""
0

Difference:

# cluset -f foo -x ""
foo
# cluset -c foo -x ""
1

The quotes are interpreted by the shell and the empty string is passed as command argument, which is supported to define an empty node set in that case.

What we don't have at this time is a representation of a generic empty node set to be used with in-line arithmetic operators like:

# a=foo[1-4]
# b=
# c=foo[3-6]

# echo cluset -f $a,$b,$c
cluset -f foo[1-4],,foo[3-6]

# cluset -f $a,$b,$c
cluset: Parse error: missing nodeset operand with ',' operator: "foo[3-6]"