15
0

Accepting request 1033892 from devel:languages:python

OBS-URL: https://build.opensuse.org/request/show/1033892
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-parallax?expand=0&rev=20
This commit is contained in:
2022-11-07 12:51:26 +00:00
committed by Git OBS Bridge
9 changed files with 21 additions and 383 deletions

View File

@@ -1,80 +0,0 @@
From f5ccee901d346873adbe5d979b5b70d0ba029570 Mon Sep 17 00:00:00 2001
From: liangxin1300 <XLiang@suse.com>
Date: Fri, 24 Apr 2020 07:05:13 +0800
Subject: [PATCH] Add ssh_key option used by -i option of ssh/scp
---
parallax/__init__.py | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/parallax/__init__.py b/parallax/__init__.py
index fc1a6e7..1008ca2 100644
--- a/parallax/__init__.py
+++ b/parallax/__init__.py
@@ -87,6 +87,7 @@ class Options(object):
askpass = False # Ask for a password
outdir = None # Write stdout to a file per host in this directory
errdir = None # Write stderr to a file per host in this directory
+ ssh_key = None # Specific ssh key used by ssh/scp -i option
ssh_options = [] # Extra options to pass to SSH
ssh_extra = [] # Extra arguments to pass to SSH
verbose = False # Warning and diagnostic messages
@@ -138,19 +139,21 @@ class _CallOutputBuilder(object):
return ret
-def _build_call_cmd(host, port, user, cmdline, options, extra):
+def _build_call_cmd(host, port, user, cmdline, opts):
cmd = ['ssh', host,
'-o', 'NumberOfPasswordPrompts=1',
'-o', 'SendEnv=PARALLAX_NODENUM PARALLAX_HOST']
- if options:
- for opt in options:
+ if opts.ssh_options:
+ for opt in opts.ssh_options:
cmd += ['-o', opt]
if user:
cmd += ['-l', user]
if port:
cmd += ['-p', port]
- if extra:
- cmd.extend(extra)
+ if opts.ssh_key:
+ cmd += ['-i', opts.ssh_key]
+ if opts.ssh_extra:
+ cmd.extend(opts.ssh_extra)
if cmdline:
cmd.append(cmdline)
return cmd
@@ -173,9 +176,7 @@ def call(hosts, cmdline, opts=Options()):
warn_message=opts.warn_message,
callbacks=_CallOutputBuilder())
for host, port, user in _expand_host_port_user(hosts):
- cmd = _build_call_cmd(host, port, user, cmdline,
- options=opts.ssh_options,
- extra=opts.ssh_extra)
+ cmd = _build_call_cmd(host, port, user, cmdline, opts)
t = Task(host, port, user, cmd,
stdin=opts.input_stream,
verbose=opts.verbose,
@@ -219,6 +220,8 @@ def _build_copy_cmd(host, port, user, src, dst, opts):
cmd += ['-P', port]
if opts.recursive:
cmd.append('-r')
+ if opts.ssh_key:
+ cmd += ['-i', opts.ssh_key]
if opts.ssh_extra:
cmd.extend(opts.ssh_extra)
cmd.append(src)
@@ -312,6 +315,8 @@ def _build_slurp_cmd(host, port, user, src, dst, opts):
cmd += ['-P', port]
if opts.recursive:
cmd.append('-r')
+ if opts.ssh_key:
+ cmd += ['-i', opts.ssh_key]
if opts.ssh_extra:
cmd.extend(opts.ssh_extra)
if user:
--
2.21.1

View File

@@ -1,40 +0,0 @@
From 1b253513291fe6022b7b832547e43b372886059c Mon Sep 17 00:00:00 2001
From: liangxin1300 <XLiang@suse.com>
Date: Thu, 16 Jul 2020 00:19:26 +0800
Subject: [PATCH] Change format of scp command for ipv6 compatible
---
parallax/__init__.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/parallax/__init__.py b/parallax/__init__.py
index 1008ca2..50a2268 100644
--- a/parallax/__init__.py
+++ b/parallax/__init__.py
@@ -226,9 +226,9 @@ def _build_copy_cmd(host, port, user, src, dst, opts):
cmd.extend(opts.ssh_extra)
cmd.append(src)
if user:
- cmd.append('%s@%s:%s' % (user, host, dst))
+ cmd.append('%s@[%s]:%s' % (user, host, dst))
else:
- cmd.append('%s:%s' % (host, dst))
+ cmd.append('[%s]:%s' % (host, dst))
return cmd
@@ -320,9 +320,9 @@ def _build_slurp_cmd(host, port, user, src, dst, opts):
if opts.ssh_extra:
cmd.extend(opts.ssh_extra)
if user:
- cmd.append('%s@%s:%s' % (user, host, src))
+ cmd.append('%s@[%s]:%s' % (user, host, src))
else:
- cmd.append('%s:%s' % (host, src))
+ cmd.append('[%s]:%s' % (host, src))
cmd.append(dst)
return cmd
--
2.21.1

View File

@@ -1,100 +0,0 @@
From 22cd571ceb360c66279512af3690347e1d6a768d Mon Sep 17 00:00:00 2001
From: liangxin1300 <XLiang@suse.com>
Date: Tue, 12 Jul 2022 10:06:06 +0800
Subject: [PATCH] Fix: task: Don't use ssh if command running on local
(bsc#1200833)
** Problem
When a command is running on local, it will failed if local ssh service stopped
** Solution
Run this command directly, without ssh
---
parallax/__init__.py | 22 ++++++++++++++++++++--
parallax/task.py | 6 ++++--
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/parallax/__init__.py b/parallax/__init__.py
index 50a2268..aa6ebd9 100644
--- a/parallax/__init__.py
+++ b/parallax/__init__.py
@@ -27,6 +27,7 @@
import os
import sys
+import socket
DEFAULT_PARALLELISM = 32
DEFAULT_TIMEOUT = 0 # "infinity" by default
@@ -176,7 +177,11 @@ def call(hosts, cmdline, opts=Options()):
warn_message=opts.warn_message,
callbacks=_CallOutputBuilder())
for host, port, user in _expand_host_port_user(hosts):
- cmd = _build_call_cmd(host, port, user, cmdline, opts)
+ is_local = is_local_host(host)
+ if is_local:
+ cmd = [cmdline]
+ else:
+ cmd = _build_call_cmd(host, port, user, cmdline, opts)
t = Task(host, port, user, cmd,
stdin=opts.input_stream,
verbose=opts.verbose,
@@ -184,7 +189,8 @@ def call(hosts, cmdline, opts=Options()):
print_out=opts.print_out,
inline=opts.inline,
inline_stdout=opts.inline_stdout,
- default_user=opts.default_user)
+ default_user=opts.default_user,
+ is_local=is_local)
manager.add_task(t)
try:
return manager.run()
@@ -366,3 +372,15 @@ def slurp(hosts, src, dst, opts=Options()):
return manager.run()
except FatalError as err:
raise IOError(str(err))
+
+
+def is_local_host(host):
+ """
+ Check if the host is local
+ """
+ try:
+ socket.inet_aton(host)
+ hostname = socket.gethostbyaddr(host)[0]
+ except:
+ hostname = host
+ return hostname == socket.gethostname()
diff --git a/parallax/task.py b/parallax/task.py
index 5e05f30..5307b06 100644
--- a/parallax/task.py
+++ b/parallax/task.py
@@ -39,7 +39,8 @@ class Task(object):
print_out=False,
inline=False,
inline_stdout=False,
- default_user=None):
+ default_user=None,
+ is_local=False):
# Backwards compatibility:
if not isinstance(verbose, bool):
@@ -66,6 +67,7 @@ class Task(object):
self.pretty_host = host
self.port = port
self.cmd = cmd
+ self.is_local = is_local
if user and user != default_user:
self.pretty_host = '@'.join((user, self.pretty_host))
@@ -126,7 +128,7 @@ class Task(object):
close_fds=False, preexec_fn=os.setsid, env=environ)
else:
self.proc = Popen(self.cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE,
- close_fds=False, start_new_session=True, env=environ)
+ close_fds=False, start_new_session=True, env=environ, shell=self.is_local)
self.timestamp = time.time()
if self.inputbuffer:
--
2.34.1

View File

@@ -1,34 +0,0 @@
From 31024ba3eafebbf73b188b6a102c4d8f00669705 Mon Sep 17 00:00:00 2001
From: nicholasyang <nicholas.yang@suse.com>
Date: Tue, 27 Sep 2022 12:08:17 +0800
Subject: [PATCH 4/5] Fix: Error: inherit from Exception instead of
BaseExceptin
---
parallax/__init__.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/parallax/__init__.py b/parallax/__init__.py
index aa6ebd9..209c6f7 100644
--- a/parallax/__init__.py
+++ b/parallax/__init__.py
@@ -55,14 +55,14 @@ def to_ascii(s):
return s
-class Error(BaseException):
+class Error(Exception):
"""
Returned instead of a result for a host
in case of an error during the processing for
that host.
"""
def __init__(self, msg, task):
- super(BaseException, self).__init__()
+ super(Exception, self).__init__()
self.msg = msg
self.task = task
--
2.37.3

View File

@@ -1,115 +0,0 @@
From 38bac0eb3cb20e9df8cbbf585cf9353793ffdba2 Mon Sep 17 00:00:00 2001
From: nicholasyang <nicholas.yang@suse.com>
Date: Tue, 27 Sep 2022 12:08:17 +0800
Subject: [PATCH 5/5] Dev: add parallax.run() to return non-zero rc without
raising exceptions
---
README.md | 15 ++++++++---
parallax/__init__.py | 60 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 70 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index beb5620..268f6db 100644
--- a/README.md
+++ b/README.md
@@ -32,10 +32,17 @@ Share and enjoy!
Executes the given command on a set of hosts, collecting the output.
- Returns a dict mapping the hostname of
- each host either to a tuple containing a return code,
- stdout and stderr, or an `parallax.Error` instance
- describing the error.
+ Returns a dict mapping the hostname of each host either to a tuple containing
+ a return code, stdout and stderr when return code is 0, or an `parallax.Error`
+ instance describing the error when return code is not 0.
+
+* `parallax.run(hosts, cmdline, opts)`
+
+ Executes the given command on a set of hosts, collecting the output.
+
+ Returns a dict mapping the hostname of each host either to a tuple containing
+ a return code, stdout and stderr, or an `parallax.Error` instance describing
+ the error when ssh error occurred.
* `parallax.copy(hosts, src, dst, opts)`
diff --git a/parallax/__init__.py b/parallax/__init__.py
index 209c6f7..a3dc75e 100644
--- a/parallax/__init__.py
+++ b/parallax/__init__.py
@@ -162,7 +162,7 @@ def _build_call_cmd(host, port, user, cmdline, opts):
def call(hosts, cmdline, opts=Options()):
"""
- Executes the given command on a set of hosts, collecting the output
+ Executes the given command on a set of hosts, collecting the output. Return Error when exit status != 0.
Returns {host: (rc, stdout, stdin) | Error}
"""
if opts.outdir and not os.path.exists(opts.outdir):
@@ -384,3 +384,61 @@ def is_local_host(host):
except:
hostname = host
return hostname == socket.gethostname()
+
+def run(hosts, cmdline, opts=Options()):
+ """
+ Executes the given command on a set of hosts, collecting the output. Return Error when ssh error occurred.
+ Returns {host: (rc, stdout, stdin) | Error}
+ """
+ if opts.outdir and not os.path.exists(opts.outdir):
+ os.makedirs(opts.outdir)
+ if opts.errdir and not os.path.exists(opts.errdir):
+ os.makedirs(opts.errdir)
+ manager = Manager(limit=opts.limit,
+ timeout=opts.timeout,
+ askpass=opts.askpass,
+ outdir=opts.outdir,
+ errdir=opts.errdir,
+ warn_message=opts.warn_message,
+ callbacks=_RunOutputBuilder())
+ for host, port, user in _expand_host_port_user(hosts):
+ is_local = is_local_host(host)
+ if is_local:
+ cmd = [cmdline]
+ else:
+ cmd = _build_call_cmd(host, port, user, cmdline, opts)
+ t = Task(host, port, user, cmd,
+ stdin=opts.input_stream,
+ verbose=opts.verbose,
+ quiet=opts.quiet,
+ print_out=opts.print_out,
+ inline=opts.inline,
+ inline_stdout=opts.inline_stdout,
+ default_user=opts.default_user,
+ is_local=is_local)
+ manager.add_task(t)
+ try:
+ return manager.run()
+ except FatalError as err:
+ raise IOError(str(err))
+
+
+class _RunOutputBuilder(object):
+ def __init__(self):
+ self.finished_tasks = []
+
+ def finished(self, task, n):
+ """Called when Task is complete"""
+ self.finished_tasks.append(task)
+
+ def result(self, manager):
+ """Called when all Tasks are complete to generate result"""
+ ret = {}
+ for task in self.finished_tasks:
+ if task.exitstatus == 255:
+ ret[task.host] = Error(', '.join(task.failures), task)
+ else:
+ ret[task.host] = (task.exitstatus,
+ task.outputbuffer or manager.outdir,
+ task.errorbuffer or manager.errdir)
+ return ret
--
2.37.3

View File

@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c16703202ff67aed4740c0727df304abe9f3e7851e653533b24de21b338d9081
size 17371

3
parallax-1.0.8.tar.gz Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:071f4413a0d49838af19359f10dca161aabbbece81175ddae72a51618321f046
size 15921

View File

@@ -1,3 +1,20 @@
-------------------------------------------------------------------
Mon Nov 7 02:18:35 UTC 2022 - XinLiang <XLiang@suse.com>
- Fix: manager: file descriptor leakage
- Release 1.0.8
-------------------------------------------------------------------
Thu Nov 3 02:16:52 UTC 2022 - XinLiang <XLiang@suse.com>
- Release 1.0.7
- Remove patches since already included:
Remove patch 0001-Add-ssh_key-option-used-by-i-option-of-ssh-scp.patch
Remove patch 0002-Change-format-of-scp-command-for-ipv6-compatible.patch
Remove patch 0003-Fix-task-Don-t-use-ssh-if-command-running-on-local-b.patch
Remove patch 0004-Fix-Error-inherit-from-Exception-instead-of-BaseExce.patch
Remove patch 0005-Dev-add-parallax.run-to-return-non-zero-rc-without-r.patch
-------------------------------------------------------------------
Wed Sep 28 02:34:51 UTC 2022 - Nicholas Yang <nicholas.yang@suse.com>

View File

@@ -18,18 +18,13 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-parallax
Version: 1.0.6
Version: 1.0.8
Release: 0
Summary: Python module for multi-node SSH command execution and file copy
License: BSD-3-Clause
Group: Development/Languages/Python
URL: https://github.com/krig/parallax/
Source: https://files.pythonhosted.org/packages/source/p/parallax/parallax-%{version}.tar.gz
Patch1: 0001-Add-ssh_key-option-used-by-i-option-of-ssh-scp.patch
Patch2: 0002-Change-format-of-scp-command-for-ipv6-compatible.patch
Patch3: 0003-Fix-task-Don-t-use-ssh-if-command-running-on-local-b.patch
Patch4: 0004-Fix-Error-inherit-from-Exception-instead-of-BaseExce.patch
Patch5: 0005-Dev-add-parallax.run-to-return-non-zero-rc-without-r.patch
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
@@ -54,11 +49,6 @@ multiple nodes using SCP.
%prep
%setup -q -n parallax-%{version}
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%build
%python_build