Skip to content

Commit 524a3a2

Browse files
Dominique Martinetthiell
authored andcommitted
Clush/Nodeset: add --pick N option
These options will pick N nodes at random from the nodeset before doing the usual processing. Closes #311. Change-Id: I3a1fc87b7adc8bc4fe0d1a4041b02fd36529b1b5
1 parent 828dc3e commit 524a3a2

File tree

5 files changed

+43
-0
lines changed

5 files changed

+43
-0
lines changed

lib/ClusterShell/CLI/Clush.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import signal
5454
import time
5555
import threading
56+
import random
5657

5758
from ClusterShell.Defaults import DEFAULTS, _load_workerclass
5859
from ClusterShell.CLI.Config import ClushConfig, ClushConfigError
@@ -891,6 +892,15 @@ def main():
891892
if len(nodeset_base) < 1:
892893
parser.error('No node to run on.')
893894

895+
if options.pick and options.pick < len(nodeset_base):
896+
# convert to string for sample as nsiter() is slower for big
897+
# nodesets; and we assume options.pick will remain small-ish
898+
keep = random.sample(nodeset_base, options.pick)
899+
nodeset_base.intersection_update(','.join(keep))
900+
if config.verbosity >= VERB_VERB:
901+
msg = "Picked random nodes: %s" % nodeset_base
902+
print Display.COLOR_RESULT_FMT % msg
903+
894904
# Set open files limit.
895905
set_fdlimit(config.fd_max, display)
896906

lib/ClusterShell/CLI/Nodeset.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import logging
4343
import math
4444
import sys
45+
import random
4546

4647
from ClusterShell.CLI.Error import GENERIC_ERRORS, handle_generic_error
4748
from ClusterShell.CLI.OptionParser import OptionParser
@@ -290,6 +291,14 @@ def nodeset():
290291
# negative axis index (only single number supported)
291292
xset.fold_axis = [int(options.axis)]
292293

294+
if options.pick and options.pick < len(xset):
295+
# convert to string for sample as nsiter() is slower for big
296+
# nodesets; and we assume options.pick will remain small-ish
297+
keep = random.sample(xset, options.pick)
298+
# explicit class_set creation and str() convertion for RangeSet
299+
keep = class_set(','.join([str(x) for x in keep]))
300+
xset.intersection_update(keep)
301+
293302
fmt = options.output_format # default to '%s'
294303

295304
# Display result according to command choice

lib/ClusterShell/CLI/OptionParser.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ def install_nodes_options(self):
128128
default=None, metavar='FILE',
129129
help="topology configuration file to use for tree "
130130
"mode")
131+
optgrp.add_option("--pick", action="store", dest="pick",
132+
metavar="N", type="int",
133+
help="pick N node(s) at random in nodeset")
131134
self.add_option_group(optgrp)
132135

133136
def install_display_options(self,
@@ -335,4 +338,7 @@ def install_nodeset_options(self):
335338
optgrp.add_option("--axis", action="store", dest="axis",
336339
metavar="RANGESET", help="fold along these axis only "
337340
"(axis 1..n for nD nodeset)")
341+
optgrp.add_option("--pick", action="store", dest="pick",
342+
metavar="N", type="int",
343+
help="pick N node(s) at random in nodeset")
338344
self.add_option_group(optgrp)

tests/CLIClushTest.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,15 @@ def test_033_worker_pdsh_tty(self):
480480
finally:
481481
delattr(ClusterShell.CLI.Clush, '_f_user_interaction')
482482

483+
def test_034_pick(self):
484+
"""test clush --pick"""
485+
self._clush_t(["-w", "%s,localhost" % HOSTNAME, "--pick", "1",
486+
"echo foo"], None,
487+
re.compile(r"^(localhost|%s): foo\n$" % HOSTNAME))
488+
self._clush_t(["-w", "%s,localhost" % HOSTNAME, "--pick", "2",
489+
"echo foo"], None,
490+
re.compile(r"^((localhost|%s): foo\n){2}$" % HOSTNAME))
491+
483492

484493
class CLIClushTest_B_StdinFailure(unittest.TestCase):
485494
"""Unit test class for testing CLI/Clush.py and stdin failure"""

tests/CLINodesetTest.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,15 @@ def test_024_axis_stdin(self):
536536
self._nodeset_t(["--axis=2","-f"], '\n'.join(ndnodes) + '\n',
537537
','.join(exp_result) + '\n')
538538

539+
def test_025_pick(self):
540+
"""test nodeset --pick"""
541+
for num in range(1, 100):
542+
self._nodeset_t(["--count", "--pick", str(num), "foo[1-100]"],
543+
None, "%s\n" % num)
544+
self._nodeset_t(["--count", "--pick", str(num), "-R", "1-100"],
545+
None, "%s\n" % num)
546+
547+
539548

540549
class CLINodesetGroupResolverTest1(CLINodesetTestBase):
541550
"""Unit test class for testing CLI/Nodeset.py with custom Group Resolver"""

0 commit comments

Comments
 (0)