1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
# Copyright (C) 2019 Xin Liang <XLiang@suse.com>
# See COPYING for license information.
import typing
from crmsh.sh import Utils
from crmsh.prun import prun
Error = prun.PRunError
def parallax_call(nodes, cmd, *, timeout_seconds: int = -1):
"""
Executes the given command on a set of hosts, collecting the output, and raise exception when error occurs
nodes: a set of hosts
cmd: command
timeout_seconds: the timeout in seconds.
Returns [(host, (rc, stdout, stdin)), ...], or raises ValueError when any one of the rc != 0
"""
results = prun.prun({node: cmd for node in nodes}, timeout_seconds=timeout_seconds)
for node, result in results.items():
if isinstance(result, prun.PRunError):
raise ValueError('Failed to run command {} on {}@{}: {}'.format(cmd, result.user, result.host, result))
elif result.returncode != 0:
raise ValueError("Failed on {}: {}".format(
node,
Utils.decode_str(result.stderr) if result.stderr is not None else None,
))
return [(node, (result.returncode, result.stdout, result.stderr)) for node, result in results.items()]
def parallax_slurp(nodes: typing.Sequence[str], localdir, filename) -> typing.List[typing.Tuple[str, typing.Union[str, Error]]]:
"""
Copies from the remote node to the local node
nodes: a set of hosts
localdir: localpath
filename: remote filename want to slurp
Returns [(host, localpath), ...] or raises ValueError when any one of hosts fails.
"""
results = prun.pfetch_from_remote(nodes, filename, localdir)
for node, result in results.items():
if isinstance(result, prun.PRunError):
raise ValueError("Failed on {}@{}: {}".format(result.user, node, result))
return [(k, v) for k, v in results.items()]
def parallax_copy(nodes, src, dst, recursive=False, *, timeout_seconds: int = -1):
"""
Copies from the local node to a set of remote hosts
nodes: a set of hosts
src: local path
dst: remote path
recursive: whether to copy directories recursively
timeout_seconds: the timeout in seconds.
Returns None, or raises ValueError when any one of hosts fails.
"""
results = prun.pcopy_to_remote(src, nodes, dst, recursive, timeout_seconds=timeout_seconds)
for node, exc in results.items():
if exc is not None:
raise ValueError("Failed on {}@{}: {}".format(exc.user, node, exc))
def parallax_run(nodes, cmd):
"""
Executes the given command on a set of hosts, collecting the output and any error
nodes: a set of hosts
cmd: command
Returns [(host, (rc, stdout, stdin)), ...], or raises ValueError when any one of the hosts fails to start running
the command.
"""
results = prun.prun({node: cmd for node in nodes})
for value in results.values():
if isinstance(value, prun.PRunError):
raise ValueError('Failed to run command {} on {}@{}: {}'.format(cmd, value.user, value.host, value))
return {node: (result.returncode, result.stdout, result.stderr) for node, result in results.items()}
|