Skip to content

Commit

Permalink
Return maxrc properly for Rsh Worker
Browse files Browse the repository at this point in the history
The current version of the Rsh Worker does not properly return
the max error code with the -S option. This commit adds in a little
"magic" to the end of the rsh command to pass back the return code
when requested. Basically works exactly as pdsh does to extract the
return code.
  • Loading branch information
hawartens committed Sep 16, 2020
1 parent 3ec8632 commit 65223a7
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 2 deletions.
1 change: 1 addition & 0 deletions conf/clush.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ color: auto
fd_max: 8192
history_size: 100
node_count: yes
maxrc: no
verbosity: 1

# Add always all remote hosts to known_hosts without confirmation
Expand Down
2 changes: 1 addition & 1 deletion doc/extras/vim/syntax/clushconf.vim
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ syn match clushComment "#.*$"
syn match clushComment ";.*$"
syn match clushHeader "\[\w\+\]"

syn keyword clushKeys fanout command_timeout connect_timeout color fd_max history_size node_count verbosity
syn keyword clushKeys fanout command_timeout connect_timeout color fd_max history_size node_count maxrc verbosity
syn keyword clushKeys ssh_user ssh_path ssh_options
syn keyword clushKeys rsh_path rcp_path rcp_options

Expand Down
4 changes: 4 additions & 0 deletions doc/man/man5/clush.conf.5
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ list. Negative values imply unlimited history file size.
Should \fBclush\fP display additional (node count) information in buffer
header? (\fIyes\fP/\fIno\fP)
.TP
.B maxrc
Should \fBclush\fP return the largest of command return codes? (\fIyes\fP/\fIno\fP)
.TP
.B verbosity
Set the verbosity level: \fI0\fP (quiet), \fI1\fP (default), \fI2\fP (verbose) or more
(debug).
Expand Down Expand Up @@ -146,6 +149,7 @@ history_size: 100
color: auto
fd_max: 10240
node_count: yes
maxrc: no

.fi
.sp
Expand Down
3 changes: 3 additions & 0 deletions doc/sphinx/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ The following table describes available *clush* config file settings.
| node_count | Should *clush* display additional (node count) |
| | information in buffer header? (yes/no) |
+-----------------+----------------------------------------------------+
| maxrc | Should *clush* return the largest of command |
| | return codes? (yes/no) |
+-----------------+----------------------------------------------------+
| verbosity | Set the verbosity level: 0 (quiet), 1 (default), |
| | 2 (verbose) or more (debug). |
+-----------------+----------------------------------------------------+
Expand Down
3 changes: 3 additions & 0 deletions doc/txt/clush.conf.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ history_size
node_count
Should ``clush`` display additional (node count) information in buffer
header? (`yes`/`no`)
maxrc
Should ``clush`` return the largest of command return codes? (yes/no)
verbosity
Set the verbosity level: `0` (quiet), `1` (default), `2` (verbose) or more
(debug).
Expand Down Expand Up @@ -109,6 +111,7 @@ Simple configuration file.
| color: auto
| fd_max: 10240
| node_count: yes
| maxrc: no
|


Expand Down
3 changes: 3 additions & 0 deletions lib/ClusterShell/CLI/Clush.py
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,9 @@ def main():
task.set_info("connect_timeout", config.connect_timeout)
task.set_info("command_timeout", config.command_timeout)

# Return code handling
task.set_info("maxrc", config.maxrc)

# Enable stdout/stderr separation
task.set_default("stderr", not options.gatherall)

Expand Down
8 changes: 8 additions & 0 deletions lib/ClusterShell/CLI/Config.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class ClushConfig(configparser.ConfigParser, object):
"color": THREE_CHOICES[-1], # auto
"verbosity": "%d" % VERB_STD,
"node_count": "yes",
"maxrc": "no",
"fd_max": "8192"}

def __init__(self, options, filename=None):
Expand Down Expand Up @@ -94,6 +95,8 @@ def __init__(self, options, filename=None):
self._set_main("command_timeout", options.command_timeout)
if options.whencolor:
self._set_main("color", options.whencolor)
if options.maxrc:
self._set_main("maxrc", options.maxrc)

try:
# -O/--option KEY=VALUE
Expand Down Expand Up @@ -212,6 +215,11 @@ def node_count(self):
"""node_count value as a boolean"""
return self.getboolean("Main", "node_count")

@property
def maxrc(self):
"""maxrc value as a boolean"""
return self.getboolean("Main", "maxrc")

@property
def fd_max(self):
"""max number of open files (soft rlimit)"""
Expand Down
32 changes: 31 additions & 1 deletion lib/ClusterShell/Worker/Rsh.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import os
import shlex
import re

from ClusterShell.Worker.Exec import ExecClient, CopyClient, ExecWorker

Expand All @@ -45,6 +46,7 @@ def _build_cmd(self):
path = task.info("rsh_path") or "rsh"
user = task.info("rsh_user")
options = task.info("rsh_options")
maxrc = task.info("maxrc", False)

cmd_l = [os.path.expanduser(pathc) for pathc in shlex.split(path)]

Expand All @@ -59,8 +61,31 @@ def _build_cmd(self):
cmd_l.append("%s" % self.key) # key is the node
cmd_l.append("%s" % self.command)

# Save the return code from the command if required
if maxrc:
cmd_l.append("; echo XXRETCODE: $?")

return (cmd_l, None)

def _parse_line(self, line, sname):

# Read the return code from the command if required
task = self.worker.task
maxrc = task.info("maxrc", False)
if maxrc:
match = re.search("^XXRETCODE: (\d+)$", line.decode("utf-8"))
if match:
self.worker.current_rc = int(match.group(1))
else:
self.worker._on_node_msgline(self.key, line, sname)
else:
self.worker._on_node_msgline(self.key, line, sname)

def _handle_read(self, sname):
"""Engine is telling us a read is available."""
for msg in self._readlines(sname):
self._parse_line(msg, sname)


class RcpClient(CopyClient):
"""
Expand Down Expand Up @@ -122,13 +147,18 @@ class WorkerRsh(ExecWorker):
Remote Copy (rcp) usage example:
>>> worker = WorkerRsh(nodeset, handler=MyEventHandler(),
... source="/etc/my.conf",
... dest="/etc/my.conf")
... dest="/etc/my.conf.bak")
>>> task.schedule(worker) # schedule worker for execution
>>> task.resume() # run
connect_timeout option is ignored by this worker.
"""

def _on_node_close(self, node, rc):
if rc is None or self.current_rc > rc:
rc = self.current_rc
ExecWorker._on_close(self, node, rc)

SHELL_CLASS = RshClient
COPY_CLASS = RcpClient

Expand Down

0 comments on commit 65223a7

Please sign in to comment.