ClusterShell 1.9.3__tar.gz → 1.10.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ClusterShell-1.9.3 → clustershell-1.10.1}/ChangeLog +122 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/MANIFEST.in +1 -2
- clustershell-1.10.1/PKG-INFO +109 -0
- clustershell-1.10.1/README.md +149 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/bash_completion.d/cluset +5 -4
- clustershell-1.10.1/bash_completion.d/clush +159 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/groups.conf +1 -1
- clustershell-1.10.1/conf/groups.conf.d/ansible.conf.example +28 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/groups.conf.d/slurm.conf.example +7 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/groups.d/cluster.yaml.example +1 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/examples/check_nodes.py +16 -19
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/man/man1/clubak.1 +29 -11
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/man/man1/cluset.1 +24 -21
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/man/man1/clush.1 +31 -18
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/man/man1/nodeset.1 +21 -18
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/man/man5/clush.conf.5 +30 -13
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/man/man5/groups.conf.5 +56 -28
- clustershell-1.10.1/doc/sphinx/CHARTER.rst +233 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/_static/theme_overrides.css +6 -0
- clustershell-1.10.1/doc/sphinx/acknowledgments.rst +22 -0
- clustershell-1.10.1/doc/sphinx/api/EnginePort.rst +10 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/MsgTree.rst +3 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/NodeSet.rst +1 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/NodeUtils.rst +4 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/index.rst +1 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/conf.py +6 -11
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/config.rst +388 -97
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/further.rst +7 -12
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/guide/examples.rst +44 -39
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/guide/nodesets.rst +60 -51
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/guide/rangesets.rst +17 -10
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/guide/taskmgnt.rst +38 -35
- clustershell-1.10.1/doc/sphinx/index.rst +34 -0
- clustershell-1.10.1/doc/sphinx/install.rst +248 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/intro.rst +1 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/release.rst +171 -3
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/tools/clubak.rst +17 -9
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/tools/cluset.rst +111 -41
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/tools/clush.rst +63 -51
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/tools/nodeset.rst +114 -42
- clustershell-1.10.1/doc/txt/README +4 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/txt/clubak.txt +20 -11
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/txt/cluset.txt +47 -45
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/txt/clush.conf.txt +37 -20
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/txt/clush.txt +31 -20
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/txt/clustershell.rst +1 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/txt/groups.conf.txt +56 -31
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/txt/nodeset.txt +44 -42
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/CLI/Clubak.py +7 -3
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/CLI/Clush.py +14 -3
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/CLI/Display.py +9 -8
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/CLI/Nodeset.py +12 -8
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/CLI/OptionParser.py +8 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/CLI/Utils.py +12 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Communication.py +36 -12
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Defaults.py +1 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Engine/EPoll.py +1 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Engine/Engine.py +2 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Engine/Select.py +1 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Event.py +4 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Gateway.py +9 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/NodeSet.py +101 -5
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/NodeUtils.py +87 -15
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Propagation.py +70 -39
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/RangeSet.py +101 -12
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Task.py +45 -14
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Topology.py +3 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Worker/EngineClient.py +17 -4
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Worker/Tree.py +111 -31
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Worker/Worker.py +1 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/__init__.py +4 -4
- clustershell-1.10.1/lib/ClusterShell.egg-info/PKG-INFO +109 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell.egg-info/SOURCES.txt +9 -5
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell.egg-info/entry_points.txt +0 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/setup.cfg +0 -3
- {ClusterShell-1.9.3 → clustershell-1.10.1}/setup.py +6 -5
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/CLIClubakTest.py +33 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/CLIClushTest.py +67 -5
- clustershell-1.10.1/tests/CLICompletionTest.py +189 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/CLIConfigTest.py +1 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/CLINodesetTest.py +101 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/DefaultsTest.py +1 -1
- clustershell-1.10.1/tests/EngineErrorTest.py +51 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/MisusageTest.py +1 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/NodeSetGroupTest.py +270 -27
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/NodeSetTest.py +66 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/RangeSetNDTest.py +34 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/RangeSetTest.py +82 -3
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/StreamWorkerTest.py +98 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TLib.py +21 -2
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskDistantMixin.py +2 -2
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskDistantPdshMixin.py +1 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskDistantPdshTest.py +5 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskDistantTest.py +1 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskLocalMixin.py +2 -2
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskLocalTest.py +1 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskRLimitsTest.py +3 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskThreadJoinTest.py +35 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskTimerTest.py +1 -1
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TreeGatewayTest.py +145 -9
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TreeTaskTest.py +4 -4
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TreeTopologyTest.py +8 -2
- clustershell-1.10.1/tests/TreeWorkerTest.py +1200 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/WorkerExecTest.py +2 -2
- clustershell-1.10.1/tests/__init__.py +0 -0
- clustershell-1.10.1/tests/bin/hostname +4 -0
- ClusterShell-1.9.3/PKG-INFO +0 -96
- ClusterShell-1.9.3/README.md +0 -125
- ClusterShell-1.9.3/bash_completion.d/clush +0 -91
- ClusterShell-1.9.3/conf/groups.conf.d/ace.conf.example +0 -18
- ClusterShell-1.9.3/doc/epydoc/clustershell_epydoc.conf +0 -38
- ClusterShell-1.9.3/doc/sphinx/clustershell-nautilus-logo200.png +0 -0
- ClusterShell-1.9.3/doc/sphinx/index.rst +0 -25
- ClusterShell-1.9.3/doc/sphinx/install.rst +0 -302
- ClusterShell-1.9.3/doc/txt/README +0 -4
- ClusterShell-1.9.3/lib/ClusterShell.egg-info/PKG-INFO +0 -96
- ClusterShell-1.9.3/tests/TreeWorkerTest.py +0 -448
- {ClusterShell-1.9.3 → clustershell-1.10.1}/COPYING.LGPLv2.1 +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/clush.conf +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/clush.conf.d/README +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/clush.conf.d/sshpass.conf.example +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/clush.conf.d/sudo.conf.example +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/groups.conf.d/README +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/groups.conf.d/genders.conf.example +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/groups.conf.d/xcat.conf.example +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/groups.d/README +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/groups.d/local.cfg +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/conf/topology.conf.example +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/examples/defaults.conf-rsh +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/extras/vim/ftdetect/clustershell.vim +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/extras/vim/syntax/clushconf.vim +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/extras/vim/syntax/groupsconf.vim +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/Makefile +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/_static/clustershell-nautilus-logo200.png +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/Defaults.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/EngineTimer.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/Event.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/RangeSet.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/Task.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/workers/ExecWorker.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/workers/StreamWorker.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/workers/TreeWorker.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/workers/Worker.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/workers/WorkerPdsh.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/workers/WorkerPopen.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/workers/WorkerRsh.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/workers/WorkerSsh.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/api/workers/index.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/guide/index.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/doc/sphinx/tools/index.rst +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/CLI/Config.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/CLI/Error.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/CLI/__init__.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Engine/Factory.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Engine/Poll.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Engine/__init__.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/MsgTree.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Worker/Exec.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Worker/Pdsh.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Worker/Popen.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Worker/Rsh.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Worker/Ssh.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Worker/__init__.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell/Worker/fastsubprocess.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell.egg-info/dependency_links.txt +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell.egg-info/requires.txt +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/lib/ClusterShell.egg-info/top_level.txt +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/CLIDisplayTest.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/CLIOptionParserTest.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/MsgTreeTest.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskEventTest.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskMsgTreeTest.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskPortTest.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskThreadSuspendTest.py +0 -0
- {ClusterShell-1.9.3 → clustershell-1.10.1}/tests/TaskTimeoutTest.py +0 -0
|
@@ -1,3 +1,125 @@
|
|
|
1
|
+
2026-07-16 S. Thiell <stephane@thiell.com>
|
|
2
|
+
|
|
3
|
+
* Version 1.10.1 released. The main changes are listed below.
|
|
4
|
+
|
|
5
|
+
* setup: install the ansible.conf.example group source example, which
|
|
6
|
+
was missing from binary packages in 1.10 (#645)
|
|
7
|
+
|
|
8
|
+
* NodeSet: fix stepped slices across multiple patterns on Python 3 (#661)
|
|
9
|
+
|
|
10
|
+
* RangeSet: fix unpickling of empty sets (#658)
|
|
11
|
+
|
|
12
|
+
* Communication: pin the pickle protocol used for gateway messages, fixing
|
|
13
|
+
tree mode across mixed Python versions with Python 3.14 (#658)
|
|
14
|
+
|
|
15
|
+
* Communication: fix TypeError when reporting channel errors (#673)
|
|
16
|
+
|
|
17
|
+
* Tree: report gateway errors received before channel setup (#674)
|
|
18
|
+
|
|
19
|
+
* Tree: fix rcopy extraction error reporting (#663)
|
|
20
|
+
|
|
21
|
+
* EngineClient: remove stream on broken pipe, fixing a possible hang with
|
|
22
|
+
the select engine (#651, #652)
|
|
23
|
+
|
|
24
|
+
* Engine: fix error handling in the EPoll and Select event loops (#662)
|
|
25
|
+
|
|
26
|
+
* conf: remove the deprecated Cray ACE group source example (#644)
|
|
27
|
+
|
|
28
|
+
* packaging: remove the unmaintained in-repo RPM spec file; RPM packaging
|
|
29
|
+
is maintained in the Fedora and EPEL repositories (#643)
|
|
30
|
+
|
|
31
|
+
* doc: refresh the installation guide (#653)
|
|
32
|
+
|
|
33
|
+
* doc: port library examples to Python 3 (#654)
|
|
34
|
+
|
|
35
|
+
* doc: coverage, accuracy and rendering improvements across man pages and
|
|
36
|
+
Sphinx docs (#648, #655, #666, #671, #675)
|
|
37
|
+
|
|
38
|
+
* doc: modernize the Sphinx build: remove stale epydoc config, enable
|
|
39
|
+
viewcode, update build requirements; animate the tree mode diagram
|
|
40
|
+
(#667, #668, #669, #670)
|
|
41
|
+
|
|
42
|
+
* tests: add bash completion tests and improve test portability and
|
|
43
|
+
reliability (#650, #664, #665)
|
|
44
|
+
|
|
45
|
+
* CI: build the documentation with warnings as errors on every change (#649)
|
|
46
|
+
|
|
47
|
+
* CI: publish releases to PyPI with a GitHub Actions workflow using
|
|
48
|
+
Trusted Publishing (#646)
|
|
49
|
+
|
|
50
|
+
2026-07-04 S. Thiell <sthiell@stanford.edu>
|
|
51
|
+
|
|
52
|
+
* Version 1.10 released. The main changes are listed below.
|
|
53
|
+
|
|
54
|
+
* NodeUtils: add the 'mapall' group source upcall to retrieve all group
|
|
55
|
+
mappings in a single call, greatly speeding up group resolution on slow
|
|
56
|
+
sources (#612, #613)
|
|
57
|
+
|
|
58
|
+
* NodeUtils: do not pass stdin to group source upcalls (#581)
|
|
59
|
+
|
|
60
|
+
* NodeSet, RangeSet: add a list-like index() method returning the position
|
|
61
|
+
of a node or element, the inverse of [i] (#631, #633)
|
|
62
|
+
|
|
63
|
+
* cluset, nodeset: add a --index command to output a node's position in the
|
|
64
|
+
set, the reverse of -I/--slice (#637)
|
|
65
|
+
|
|
66
|
+
* groups.conf: add mapall upcalls to the Slurm group bindings (#623)
|
|
67
|
+
|
|
68
|
+
* groups.conf: add an Ansible inventory group source example (#610)
|
|
69
|
+
|
|
70
|
+
* clush, clubak: add --axis to fold nD node sets along selected axis only,
|
|
71
|
+
as already supported by nodeset and cluset (#356)
|
|
72
|
+
|
|
73
|
+
* Display: fix line buffering on Python 3.6 (#597)
|
|
74
|
+
|
|
75
|
+
* Tree: implement TreeWorker.abort() and per-gateway abort, with gateway
|
|
76
|
+
failover fixes (#229, #566)
|
|
77
|
+
|
|
78
|
+
* Tree: fire ev_pickup only once the command can no longer be rerouted and
|
|
79
|
+
improve reroute event reporting (#594)
|
|
80
|
+
|
|
81
|
+
* Tree: fix rcopy when a remote node closes (#545)
|
|
82
|
+
|
|
83
|
+
* Tree: improve handling of MessageProcessingError (#596)
|
|
84
|
+
|
|
85
|
+
* Tree: keep tar/scp errors on stderr instead of stdout during forward
|
|
86
|
+
copy (#622)
|
|
87
|
+
|
|
88
|
+
* Tree: pass filter='fully_trusted' to tarfile.extractall() (PEP 706) (#617)
|
|
89
|
+
|
|
90
|
+
* EngineClient: properly honor the abort flag on close (#591)
|
|
91
|
+
|
|
92
|
+
* Engine: fix set_events debug logging to identify the client and stream (#630)
|
|
93
|
+
|
|
94
|
+
* Task: only terminate a task once when killed, fixing a double termination
|
|
95
|
+
(#110, #640)
|
|
96
|
+
|
|
97
|
+
* NodeUtils, Topology: emit a DeprecationWarning for set_verbosity() and the
|
|
98
|
+
topology.conf [Main] section (#226, #639)
|
|
99
|
+
|
|
100
|
+
* Gateway: fix a Python 2 syntax error (#625)
|
|
101
|
+
|
|
102
|
+
* RangeSet: accept unicode strings on Python 2 (#635)
|
|
103
|
+
|
|
104
|
+
* completion: complete copy paths and command, and short options without
|
|
105
|
+
spaces (#585, #586)
|
|
106
|
+
|
|
107
|
+
* completion: treat -b/-B and clush's other no-arg options as flags (#598, #619)
|
|
108
|
+
|
|
109
|
+
* completion: fix cluset no-arg option lists (#620)
|
|
110
|
+
|
|
111
|
+
* doc: clarify the '*' all-nodes wildcard versus the literal 'all' group
|
|
112
|
+
source (#552)
|
|
113
|
+
|
|
114
|
+
* doc: HPSF onboarding (charter, DCO, governance) and misc doc fixes
|
|
115
|
+
(#577, #604)
|
|
116
|
+
|
|
117
|
+
* setup: clean up wheel packaging metadata (#634)
|
|
118
|
+
|
|
119
|
+
* CI: add Python 3.14 to the test matrix; run the test suite with the
|
|
120
|
+
standard library unittest instead of the abandoned nosetests runner
|
|
121
|
+
(#603, #618)
|
|
122
|
+
|
|
1
123
|
2025-01-23 S. Thiell <sthiell@stanford.edu>
|
|
2
124
|
|
|
3
125
|
* Version 1.9.3 released. The main changes are listed below.
|
|
@@ -18,7 +18,6 @@ include doc/man/man1/*.1
|
|
|
18
18
|
include doc/man/man5/*.5
|
|
19
19
|
include doc/sphinx/Makefile
|
|
20
20
|
include doc/sphinx/conf.py
|
|
21
|
-
include doc/sphinx/*.png
|
|
22
21
|
include doc/sphinx/*.rst
|
|
23
22
|
include doc/sphinx/_static/*.png
|
|
24
23
|
include doc/sphinx/_static/*.css
|
|
@@ -30,5 +29,5 @@ include doc/extras/vim/syntax/*.vim
|
|
|
30
29
|
include doc/extras/vim/ftdetect/*.vim
|
|
31
30
|
include doc/examples/*.py
|
|
32
31
|
include doc/examples/defaults.conf-rsh
|
|
33
|
-
include doc/epydoc/*.conf
|
|
34
32
|
include tests/*.py
|
|
33
|
+
include tests/bin/*
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ClusterShell
|
|
3
|
+
Version: 1.10.1
|
|
4
|
+
Summary: ClusterShell library and tools
|
|
5
|
+
Home-page: https://clustershell.readthedocs.io/
|
|
6
|
+
Download-URL: https://github.com/clustershell/clustershell/archive/refs/tags/v1.10.1.tar.gz
|
|
7
|
+
Author: Stephane Thiell
|
|
8
|
+
License: LGPLv2+
|
|
9
|
+
Keywords: clustershell,clush,clubak,nodeset
|
|
10
|
+
Platform: GNU/Linux
|
|
11
|
+
Platform: BSD
|
|
12
|
+
Platform: MacOSX
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: System Administrators
|
|
16
|
+
Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)
|
|
17
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
18
|
+
Classifier: Operating System :: POSIX :: BSD
|
|
19
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
20
|
+
Classifier: Programming Language :: Python
|
|
21
|
+
Classifier: Programming Language :: Python :: 2.7
|
|
22
|
+
Classifier: Programming Language :: Python :: 3
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: System :: Clustering
|
|
25
|
+
Classifier: Topic :: System :: Distributed Computing
|
|
26
|
+
Description-Content-Type: text/x-rst
|
|
27
|
+
License-File: COPYING.LGPLv2.1
|
|
28
|
+
Requires-Dist: PyYAML
|
|
29
|
+
Dynamic: author
|
|
30
|
+
Dynamic: classifier
|
|
31
|
+
Dynamic: description
|
|
32
|
+
Dynamic: description-content-type
|
|
33
|
+
Dynamic: download-url
|
|
34
|
+
Dynamic: home-page
|
|
35
|
+
Dynamic: keywords
|
|
36
|
+
Dynamic: license
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
Dynamic: platform
|
|
39
|
+
Dynamic: requires-dist
|
|
40
|
+
Dynamic: summary
|
|
41
|
+
|
|
42
|
+
ClusterShell is an event-driven open source Python framework, designed to run
|
|
43
|
+
local or distant commands in parallel on server farms or on large Linux
|
|
44
|
+
clusters. It will take care of common issues encountered on HPC clusters, such
|
|
45
|
+
as operating on groups of nodes, running distributed commands using optimized
|
|
46
|
+
execution algorithms, as well as gathering results and merging identical
|
|
47
|
+
outputs, or retrieving return codes. ClusterShell takes advantage of existing
|
|
48
|
+
remote shell facilities already installed on your systems, like SSH.
|
|
49
|
+
|
|
50
|
+
ClusterShell provides clush, clubak and cluset/nodeset, convenient command-line
|
|
51
|
+
tools that allow traditional shell scripts to benefit from some of the
|
|
52
|
+
library's features:
|
|
53
|
+
|
|
54
|
+
- **clush**: issue commands to cluster nodes and format output
|
|
55
|
+
|
|
56
|
+
Example of use:
|
|
57
|
+
|
|
58
|
+
::
|
|
59
|
+
|
|
60
|
+
$ clush -abL uname -r
|
|
61
|
+
node[32-49,51-71,80,82-150,156-159]: 2.6.18-164.11.1.el5
|
|
62
|
+
node[3-7,72-79]: 2.6.18-164.11.1.el5_lustre1.10.0.36
|
|
63
|
+
node[2,151-155]: 2.6.31.6-145.fc11.2.x86_64
|
|
64
|
+
|
|
65
|
+
See *man clush* for more details.
|
|
66
|
+
|
|
67
|
+
- **clubak**: improved dshbak to gather and sort dsh-like outputs
|
|
68
|
+
|
|
69
|
+
See *man clubak* for more details.
|
|
70
|
+
|
|
71
|
+
- **nodeset** (or **cluset**): compute advanced nodeset/nodegroup operations
|
|
72
|
+
|
|
73
|
+
Examples of use:
|
|
74
|
+
|
|
75
|
+
::
|
|
76
|
+
|
|
77
|
+
$ echo node160 node161 node162 node163 | nodeset -f
|
|
78
|
+
node[160-163]
|
|
79
|
+
|
|
80
|
+
$ nodeset -f node[0-7,32-159] node[160-163]
|
|
81
|
+
node[0-7,32-163]
|
|
82
|
+
|
|
83
|
+
$ nodeset -e node[160-163]
|
|
84
|
+
node160 node161 node162 node163
|
|
85
|
+
|
|
86
|
+
$ nodeset -f node[32-159] -x node33
|
|
87
|
+
node[32,34-159]
|
|
88
|
+
|
|
89
|
+
$ nodeset -f node[32-159] -i node[0-7,20-21,32,156-159]
|
|
90
|
+
node[32,156-159]
|
|
91
|
+
|
|
92
|
+
$ nodeset -f node[33-159] --xor node[32-33,156-159]
|
|
93
|
+
node[32,34-155]
|
|
94
|
+
|
|
95
|
+
$ nodeset -l
|
|
96
|
+
@oss
|
|
97
|
+
@mds
|
|
98
|
+
@io
|
|
99
|
+
@compute
|
|
100
|
+
|
|
101
|
+
$ nodeset -e @mds
|
|
102
|
+
node6 node7
|
|
103
|
+
|
|
104
|
+
See *man nodeset* (or *man cluset*) for more details.
|
|
105
|
+
|
|
106
|
+
Please visit the ClusterShell website_.
|
|
107
|
+
|
|
108
|
+
.. _website: https://clustershell.readthedocs.io/
|
|
109
|
+
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
ClusterShell Python Library and Tools
|
|
2
|
+
=====================================
|
|
3
|
+
|
|
4
|
+
[](https://hpsf.io)
|
|
5
|
+
|
|
6
|
+
This project adheres to a [Technical Charter](https://clustershell.readthedocs.io/en/latest/CHARTER.html), which defines its governance model, decision-making process, and long-term vision.
|
|
7
|
+
|
|
8
|
+
ClusterShell is an event-driven open source Python library designed to run
|
|
9
|
+
local or distant commands in parallel on server farms or on large Linux
|
|
10
|
+
clusters. It is an [HPSF Established](https://hpsf.io) project under
|
|
11
|
+
[LF Europe](https://linuxfoundation.eu/) stewardship.
|
|
12
|
+
|
|
13
|
+
ClusterShell handles typical HPC cluster administration tasks: operating on
|
|
14
|
+
groups of nodes, executing distributed commands with optimized algorithms,
|
|
15
|
+
gathering and merging output, and collecting return codes. It leverages remote
|
|
16
|
+
shell facilities already present on your systems, such as SSH.
|
|
17
|
+
|
|
18
|
+
ClusterShell's primary goal is to improve the administration of high-
|
|
19
|
+
performance clusters by providing a lightweight but scalable Python API for
|
|
20
|
+
developers. It also provides clush, clubak and cluset/nodeset, convenient
|
|
21
|
+
command-line tools that allow traditional shell scripts to benefit from some
|
|
22
|
+
of the library features.
|
|
23
|
+
|
|
24
|
+
Requirements
|
|
25
|
+
------------
|
|
26
|
+
|
|
27
|
+
* GNU/Linux, BSD, macOS
|
|
28
|
+
* OpenSSH (ssh/scp) or rsh
|
|
29
|
+
* Python 2.x (x >= 7) or Python 3.x (x >= 6)
|
|
30
|
+
* PyYAML
|
|
31
|
+
|
|
32
|
+
License
|
|
33
|
+
-------
|
|
34
|
+
|
|
35
|
+
ClusterShell is distributed under the GNU Lesser General Public License version
|
|
36
|
+
2.1 or later (LGPL v2.1+). Read the file `COPYING.LGPLv2.1` for details.
|
|
37
|
+
|
|
38
|
+
Documentation
|
|
39
|
+
-------------
|
|
40
|
+
|
|
41
|
+
Online documentation is available here:
|
|
42
|
+
|
|
43
|
+
https://clustershell.readthedocs.io/
|
|
44
|
+
|
|
45
|
+
The Sphinx documentation source is available under the doc/sphinx directory.
|
|
46
|
+
Type 'make' to see all available formats (you need the packages listed in
|
|
47
|
+
doc/sphinx/requirements.txt to build the documentation). For example, to
|
|
48
|
+
generate html docs, just type:
|
|
49
|
+
|
|
50
|
+
make html BUILDDIR=/dest/path
|
|
51
|
+
|
|
52
|
+
For local library API documentation, just type:
|
|
53
|
+
|
|
54
|
+
$ pydoc ClusterShell
|
|
55
|
+
|
|
56
|
+
The following man pages are also provided:
|
|
57
|
+
|
|
58
|
+
clush(1), clubak(1), cluset(1), nodeset(1), clush.conf(5), groups.conf(5)
|
|
59
|
+
|
|
60
|
+
Building
|
|
61
|
+
--------
|
|
62
|
+
|
|
63
|
+
To build the Python source distribution and wheel from a source checkout:
|
|
64
|
+
|
|
65
|
+
$ python -m build
|
|
66
|
+
|
|
67
|
+
The resulting tarball and wheel are written to the 'dist' directory.
|
|
68
|
+
|
|
69
|
+
RPM packaging is not maintained in this repository. RPM packages for Fedora,
|
|
70
|
+
RHEL and compatible distributions are maintained in the Fedora and EPEL
|
|
71
|
+
dist-git repositories:
|
|
72
|
+
|
|
73
|
+
https://src.fedoraproject.org/rpms/clustershell
|
|
74
|
+
|
|
75
|
+
To build RPMs locally, use that spec file, for example with 'fedpkg' or
|
|
76
|
+
'rpmbuild'.
|
|
77
|
+
|
|
78
|
+
Test Suite
|
|
79
|
+
----------
|
|
80
|
+
|
|
81
|
+
Regression testing scripts are available in the 'tests' directory. To run the
|
|
82
|
+
whole test suite from the source tree root:
|
|
83
|
+
|
|
84
|
+
$ python -m unittest discover -v -s tests -p '*Test.py' -t .
|
|
85
|
+
|
|
86
|
+
To run a single test module, narrow the discovery pattern, for example
|
|
87
|
+
`-p 'NodeSetTest.py'`.
|
|
88
|
+
|
|
89
|
+
You have to allow 'ssh localhost' and 'ssh $HOSTNAME' without any warnings for
|
|
90
|
+
"remote" tests to run as expected. $HOSTNAME should not be 127.0.0.1 nor ::1.
|
|
91
|
+
Also some tests use the 'bc' command.
|
|
92
|
+
|
|
93
|
+
Python code (simple example)
|
|
94
|
+
----------------------------
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
>>> from ClusterShell.Task import task_self
|
|
98
|
+
>>> from ClusterShell.NodeSet import NodeSet
|
|
99
|
+
>>> task = task_self()
|
|
100
|
+
>>> task.run("/bin/uname -r", nodes="linux[4-6,32-39]")
|
|
101
|
+
<ClusterShell.Worker.Ssh.WorkerSsh object at 0x7f45287db910>
|
|
102
|
+
>>> for buf, key in task.iter_buffers():
|
|
103
|
+
... print(NodeSet.fromlist(key), buf.message().decode())
|
|
104
|
+
...
|
|
105
|
+
linux[32-39] 6.14.9-300.fc42.x86_64
|
|
106
|
+
linux[4-6] 5.14.0-570.12.1.el9_6.x86_64
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Links
|
|
110
|
+
-----
|
|
111
|
+
|
|
112
|
+
Online documentation:
|
|
113
|
+
|
|
114
|
+
https://clustershell.readthedocs.io/
|
|
115
|
+
|
|
116
|
+
Github source repository:
|
|
117
|
+
|
|
118
|
+
https://github.com/clustershell/clustershell
|
|
119
|
+
|
|
120
|
+
Github Issue tracking system:
|
|
121
|
+
|
|
122
|
+
https://github.com/clustershell/clustershell/issues
|
|
123
|
+
|
|
124
|
+
Python Package Index (PyPI) links:
|
|
125
|
+
|
|
126
|
+
https://pypi.org/project/ClusterShell/
|
|
127
|
+
|
|
128
|
+
ClusterShell was born along with Shine, a scalable Lustre FS admin tool:
|
|
129
|
+
|
|
130
|
+
https://github.com/cea-hpc/shine
|
|
131
|
+
|
|
132
|
+
Core developers/reviewers
|
|
133
|
+
-------------------------
|
|
134
|
+
|
|
135
|
+
* Stephane Thiell
|
|
136
|
+
* Aurelien Degremont
|
|
137
|
+
* Dominique Martinet
|
|
138
|
+
|
|
139
|
+
Acknowledgments
|
|
140
|
+
---------------
|
|
141
|
+
|
|
142
|
+
We would like to express our gratitude to [CEA](https://www.cea.fr/english)
|
|
143
|
+
for the resources and funding provided to the project over the years.
|
|
144
|
+
|
|
145
|
+
We would also like to thank [Stanford University](https://srcc.stanford.edu)
|
|
146
|
+
(SRC) for their long-term support and resources provided to the project.
|
|
147
|
+
|
|
148
|
+
See the full [Acknowledgments](https://clustershell.readthedocs.io/en/latest/acknowledgments.html)
|
|
149
|
+
page for more details.
|
|
@@ -25,8 +25,9 @@ _cluset()
|
|
|
25
25
|
"") ;;
|
|
26
26
|
--) return;;
|
|
27
27
|
# no-arg options
|
|
28
|
-
--version|-h|--help|-
|
|
29
|
-
-
|
|
28
|
+
--version|-h|--help|-l|--list|-L|--list-all|-r|--regroup|\
|
|
29
|
+
--list-sources|--groupsources|-d|--debug|-q|--quiet|\
|
|
30
|
+
-R|--rangeset|-G|--groupbase|--contiguous|-a|--all|--completion) ;;
|
|
30
31
|
# get source separately...
|
|
31
32
|
--groupsource=*) groupsource="${word#*=}";;
|
|
32
33
|
-s|--groupsource) skip=groupsource;;
|
|
@@ -39,7 +40,7 @@ _cluset()
|
|
|
39
40
|
done
|
|
40
41
|
|
|
41
42
|
case "$prev" in
|
|
42
|
-
-c|--count|-e|--expand|-f|--fold|\
|
|
43
|
+
-c|--count|-e|--expand|-f|--fold|--index|\
|
|
43
44
|
-x|--exclude|-i|--intersection|-X|--xor)
|
|
44
45
|
case "$cur" in
|
|
45
46
|
*:*)
|
|
@@ -63,7 +64,7 @@ _cluset()
|
|
|
63
64
|
# no-arg options
|
|
64
65
|
--version|-h|--help|-l|--list|-L|--list-all|-r|--regroup|\
|
|
65
66
|
--list-sources|--groupsources|-d|--debug|-q|--quiet|\
|
|
66
|
-
-R|--rangeset|-G|--groupbase|--contiguous) ;;
|
|
67
|
+
-R|--rangeset|-G|--groupbase|--contiguous|-a|--all|--completion) ;;
|
|
67
68
|
# any other option: just ignore.
|
|
68
69
|
-*)
|
|
69
70
|
return;;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# clush bash completion
|
|
2
|
+
#
|
|
3
|
+
# to install in /usr/share/bash-completion/completions/ or ~/.local/share/bash-completion/completions/
|
|
4
|
+
_clush_command_or_file() {
|
|
5
|
+
# undo our nospace setting...
|
|
6
|
+
compopt +o nospace
|
|
7
|
+
|
|
8
|
+
# skip if shortopt is set -- these helpers cannot "restore" shortopt at start of
|
|
9
|
+
# the completions they provide easily
|
|
10
|
+
[ -n "$shortopt" ] && return
|
|
11
|
+
|
|
12
|
+
# complete either files (copy mode) or commands (if target set)
|
|
13
|
+
case "$target_set,$mode" in
|
|
14
|
+
*,copy)
|
|
15
|
+
# available since bash-completion 2.12
|
|
16
|
+
if declare -F _comp_compgen_filedir >/dev/null; then
|
|
17
|
+
_comp_compgen_filedir
|
|
18
|
+
else
|
|
19
|
+
_filedir
|
|
20
|
+
fi
|
|
21
|
+
;;
|
|
22
|
+
1,command)
|
|
23
|
+
# available since bash-completion 2.12
|
|
24
|
+
if declare -F _comp_command_offset >/dev/null; then
|
|
25
|
+
_comp_command_offset "$i"
|
|
26
|
+
else
|
|
27
|
+
_command_offset "$i"
|
|
28
|
+
fi
|
|
29
|
+
;;
|
|
30
|
+
esac
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
_clush()
|
|
34
|
+
{
|
|
35
|
+
# shellcheck disable=SC2034 # set/used by _init_completion
|
|
36
|
+
local cur prev words cword split
|
|
37
|
+
local i word options="" compopts="" skip=argv0 groupsource="" cleangroup=""
|
|
38
|
+
local mode=command target_set=""
|
|
39
|
+
local shortopt=""
|
|
40
|
+
|
|
41
|
+
_init_completion -s -n : || return
|
|
42
|
+
|
|
43
|
+
# stop parsing if there had been any non-option before (or --)
|
|
44
|
+
for i in "${!words[@]}"; do
|
|
45
|
+
word="${words[i]}"
|
|
46
|
+
case "$skip" in
|
|
47
|
+
"") ;;
|
|
48
|
+
groupsource)
|
|
49
|
+
groupsource="$word"
|
|
50
|
+
;& # fallthrough
|
|
51
|
+
*)
|
|
52
|
+
skip=""
|
|
53
|
+
continue
|
|
54
|
+
;;
|
|
55
|
+
esac
|
|
56
|
+
case "$word" in
|
|
57
|
+
"") ;;
|
|
58
|
+
--)
|
|
59
|
+
i=$((i+1)) # command from next word!
|
|
60
|
+
_clush_command_or_file
|
|
61
|
+
return
|
|
62
|
+
;;
|
|
63
|
+
-c|--copy|--rcopy) mode=copy;;
|
|
64
|
+
-w|-g|--group) target_set=1; skip=any;;
|
|
65
|
+
# no-arg options
|
|
66
|
+
--version|-h|--help|-n|--nostdin|-a|--all|-q|--quiet|\
|
|
67
|
+
-b|-B|--dshbak|-G|--groupbase|-L|-N|-P|--progress|\
|
|
68
|
+
-r|--regroup|-S|--maxrc|--diff|-p|-v|--verbose|-d|--debug) ;;
|
|
69
|
+
# get source separately...
|
|
70
|
+
--groupsource=*) groupsource="${word#*=}";;
|
|
71
|
+
-s|--groupsource) skip=groupsource;;
|
|
72
|
+
# assume all the rest as options...
|
|
73
|
+
# options with = included in word
|
|
74
|
+
--*=*) ;;
|
|
75
|
+
-*) skip=any;;
|
|
76
|
+
*)
|
|
77
|
+
# likely non-option, in copy mode options like -w can come
|
|
78
|
+
# later so just skip, otherwise likely start of command
|
|
79
|
+
[ "$mode" = copy ] && continue
|
|
80
|
+
_clush_command_or_file
|
|
81
|
+
return;;
|
|
82
|
+
esac
|
|
83
|
+
done
|
|
84
|
+
|
|
85
|
+
# split short opts without space...
|
|
86
|
+
case "$cur" in
|
|
87
|
+
-[a-z]*)
|
|
88
|
+
shortopt="${cur:0:2}"
|
|
89
|
+
prev="$shortopt"
|
|
90
|
+
cur="${cur:2}"
|
|
91
|
+
;;
|
|
92
|
+
esac
|
|
93
|
+
|
|
94
|
+
case "$prev" in
|
|
95
|
+
-w|-x|-g|--group|-X)
|
|
96
|
+
case "$cur" in
|
|
97
|
+
*:*)
|
|
98
|
+
groupsource="${cur%%:*}"
|
|
99
|
+
groupsource="${groupsource#@}"
|
|
100
|
+
;;
|
|
101
|
+
*)
|
|
102
|
+
if [ -n "$groupsource" ]; then
|
|
103
|
+
cleangroup=1
|
|
104
|
+
fi
|
|
105
|
+
;;
|
|
106
|
+
esac
|
|
107
|
+
if [ "$prev" = "-w" ]; then
|
|
108
|
+
compopts="@*" # include all nodes
|
|
109
|
+
fi
|
|
110
|
+
# shellcheck disable=SC2086 ## $compopts expanded on purpose
|
|
111
|
+
options="$(cluset ${groupsource:+-s "$groupsource"} --completion $compopts)"
|
|
112
|
+
if [ -n "$cleangroup" ]; then
|
|
113
|
+
options=${options//@"$groupsource":/@}
|
|
114
|
+
fi
|
|
115
|
+
case "$prev" in
|
|
116
|
+
-g|--group|-X)
|
|
117
|
+
options=${options//@/}
|
|
118
|
+
;;
|
|
119
|
+
esac
|
|
120
|
+
;;
|
|
121
|
+
-s|--groupsource)
|
|
122
|
+
options=$(cluset --groupsources --quiet)
|
|
123
|
+
;;
|
|
124
|
+
--color)
|
|
125
|
+
options="never always auto"
|
|
126
|
+
;;
|
|
127
|
+
-R|--worker)
|
|
128
|
+
options="ssh exec rsh"
|
|
129
|
+
;;
|
|
130
|
+
# no-arg options
|
|
131
|
+
--version|-h|--help|-n|--nostdin|-a|--all|-q|--quiet|\
|
|
132
|
+
-b|-B|--dshbak|-G|--groupbase|-L|-N|-P|--progress|\
|
|
133
|
+
-r|--regroup|-S|--maxrc|--diff|-p|-v|--verbose|-d|--debug|-c|--copy|--rcopy) ;;
|
|
134
|
+
# any other option: ignore next word (likely argument)
|
|
135
|
+
-*)
|
|
136
|
+
return;;
|
|
137
|
+
esac
|
|
138
|
+
# new option or no option:
|
|
139
|
+
if [ -z "$options" ]; then
|
|
140
|
+
case "$cur" in
|
|
141
|
+
-*)
|
|
142
|
+
# starts with dash - get all options from help text...
|
|
143
|
+
options="$(clush --help | grep -oP -- '(?<=[ \t])(-[a-z]|--[^= \t]*)')"
|
|
144
|
+
;;
|
|
145
|
+
*)
|
|
146
|
+
# otherwise complete command or file if appropriate and stop here
|
|
147
|
+
_clush_command_or_file
|
|
148
|
+
return
|
|
149
|
+
esac
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
# append space for everything that doesn't end in `:` (likely a groupsource)
|
|
153
|
+
mapfile -t COMPREPLY \
|
|
154
|
+
< <(compgen -W "$options" -- "$cur" \
|
|
155
|
+
| sed -e 's/[^:]$/& /' -e "s/^/$shortopt/")
|
|
156
|
+
# remove the prefix from COMPREPLY if $cur contains colons and
|
|
157
|
+
# COMP_WORDBREAKS splits on colons...
|
|
158
|
+
__ltrim_colon_completions "$cur"
|
|
159
|
+
} && complete -o nospace -F _clush "${BASH_SOURCE##*/}"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ClusterShell node groups main configuration file
|
|
2
2
|
#
|
|
3
3
|
# Please see `man 5 groups.conf` and
|
|
4
|
-
#
|
|
4
|
+
# https://clustershell.readthedocs.io/en/latest/config.html#node-groups
|
|
5
5
|
# for further details.
|
|
6
6
|
#
|
|
7
7
|
# NOTE: This is a simple group configuration example file, not a
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Additional ClusterShell group source config file
|
|
2
|
+
#
|
|
3
|
+
# Please see `man 5 groups.conf` for further details.
|
|
4
|
+
#
|
|
5
|
+
|
|
6
|
+
# Ansible inventory bindings
|
|
7
|
+
#
|
|
8
|
+
# Requirements: ansible-core (provides ansible-inventory), jq
|
|
9
|
+
#
|
|
10
|
+
# Replace /path/to/inventory with your inventory path or directory,
|
|
11
|
+
# or set ANSIBLE_INVENTORY in your environment to override it.
|
|
12
|
+
#
|
|
13
|
+
# Hostnames can be post-processed in jq, for instance to strip a DNS domain
|
|
14
|
+
# suffix; see the Ansible inventory bindings section of the online docs.
|
|
15
|
+
#
|
|
16
|
+
[ansible]
|
|
17
|
+
|
|
18
|
+
# Resolve group members, recursing into child groups
|
|
19
|
+
map: ANSIBLE_INVENTORY="${ANSIBLE_INVENTORY:-/path/to/inventory}" ansible-inventory --list 2>/dev/null | jq -r --arg g "$GROUP" 'def r(d;g): (d[g].hosts//[])[], ((d[g].children//[])[] as $c | r(d;$c)); r(.;$g)'
|
|
20
|
+
|
|
21
|
+
# Resolve all groups in a single call, recursing into child groups
|
|
22
|
+
mapall: ANSIBLE_INVENTORY="${ANSIBLE_INVENTORY:-/path/to/inventory}" ansible-inventory --list 2>/dev/null | jq -r 'def r(d;g): (d[g].hosts//[])[], ((d[g].children//[])[] as $c | r(d;$c)); . as $d | keys[] | select(. != "_meta" and . != "all" and (test("[[:space:]:]") | not)) | "\(.): \([r($d;.)] | join(" "))"'
|
|
23
|
+
|
|
24
|
+
# All inventory hosts
|
|
25
|
+
all: ANSIBLE_INVENTORY="${ANSIBLE_INVENTORY:-/path/to/inventory}" ansible-inventory --list 2>/dev/null | jq -r '.[].hosts // empty | .[]'
|
|
26
|
+
|
|
27
|
+
# All groups
|
|
28
|
+
list: ANSIBLE_INVENTORY="${ANSIBLE_INVENTORY:-/path/to/inventory}" ansible-inventory --list 2>/dev/null | jq -r 'keys[] | select(. != "_meta" and . != "all")'
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#
|
|
9
9
|
[slurmpart,sp]
|
|
10
10
|
map: sinfo -h -o "%N" -p $GROUP
|
|
11
|
+
mapall: sinfo -h -o "%R:%N"
|
|
11
12
|
all: sinfo -h -o "%N"
|
|
12
13
|
list: sinfo -h -o "%R"
|
|
13
14
|
reverse: sinfo -h -N -o "%R" -n $NODE
|
|
@@ -17,6 +18,7 @@ reverse: sinfo -h -N -o "%R" -n $NODE
|
|
|
17
18
|
#
|
|
18
19
|
[slurmresv,sr]
|
|
19
20
|
map: scontrol -o show reservation $GROUP | grep -Po 'Nodes=\K[^ ]+'
|
|
21
|
+
mapall: scontrol -o show reservation | sed -n 's/^ReservationName=\([^ :]*\) .* Nodes=\([^ ]*\).*/\1:\2/p'
|
|
20
22
|
all: scontrol -o show reservation | grep -Po 'Nodes=\K[^ ]+'
|
|
21
23
|
list: scontrol -o show reservation | grep -Po 'ReservationName=\K[^ ]+'
|
|
22
24
|
cache_time: 60
|
|
@@ -26,6 +28,7 @@ cache_time: 60
|
|
|
26
28
|
#
|
|
27
29
|
[slurmstate,st]
|
|
28
30
|
map: sinfo -h -o "%N" -t $GROUP
|
|
31
|
+
mapall: sinfo -h -o "%T:%N" | sed 's/[*~#!%$@+^-]*:/:/'
|
|
29
32
|
all: sinfo -h -o "%N"
|
|
30
33
|
list: sinfo -h -o "%T" | tr -d '*~#!%$@+^-'
|
|
31
34
|
reverse: sinfo -h -N -o "%T" -n $NODE | tr -d '*~#!%$@+^-'
|
|
@@ -36,6 +39,7 @@ cache_time: 60
|
|
|
36
39
|
#
|
|
37
40
|
[slurmjob,sj]
|
|
38
41
|
map: squeue -h -j $GROUP -o "%N"
|
|
42
|
+
mapall: squeue -h -o "%i:%N" -t R
|
|
39
43
|
list: squeue -h -o "%i" -t R
|
|
40
44
|
reverse: squeue -h -w $NODE -o "%i"
|
|
41
45
|
cache_time: 60
|
|
@@ -45,6 +49,7 @@ cache_time: 60
|
|
|
45
49
|
#
|
|
46
50
|
[slurmuser,su]
|
|
47
51
|
map: squeue -h -u $GROUP -o "%N" -t R
|
|
52
|
+
mapall: squeue -h -o "%u:%N" -t R
|
|
48
53
|
list: squeue -h -o "%u" -t R
|
|
49
54
|
reverse: squeue -h -w $NODE -o "%u"
|
|
50
55
|
cache_time: 60
|
|
@@ -54,6 +59,7 @@ cache_time: 60
|
|
|
54
59
|
#
|
|
55
60
|
[slurmaccount,sa]
|
|
56
61
|
map: squeue -h -A $GROUP -o "%N" -t R
|
|
62
|
+
mapall: squeue -h -o "%a:%N" -t R
|
|
57
63
|
list: squeue -h -o "%a" -t R
|
|
58
64
|
reverse: squeue -h -w $NODE -o "%a" 2>/dev/null || true
|
|
59
65
|
cache_time: 60
|
|
@@ -63,6 +69,7 @@ cache_time: 60
|
|
|
63
69
|
#
|
|
64
70
|
[slurmqos,sq]
|
|
65
71
|
map: squeue -h -q $GROUP -o "%N" -t R
|
|
72
|
+
mapall: squeue -h -o "%q:%N" -t R
|
|
66
73
|
list: squeue -h -o "%q" -t R
|
|
67
74
|
reverse: squeue -h -w $NODE -o "%q" 2>/dev/null || true
|
|
68
75
|
cache_time: 60
|
|
@@ -24,6 +24,7 @@ roles:
|
|
|
24
24
|
io: '@racks:rack2,example2'
|
|
25
25
|
compute: '@racks:rack[3-4]'
|
|
26
26
|
gpu: '@racks:rack4'
|
|
27
|
+
# '*' is the all-nodes wildcard, e.g. @roles:* or clush -a, not 'all'
|
|
27
28
|
# the 'all' special group is only needed if we don't want all nodes from
|
|
28
29
|
# this group source included, here we don't want example0 for clush -a
|
|
29
30
|
all: '@io,@compute'
|