diff --git a/0001-Add-ssh_key-option-used-by-i-option-of-ssh-scp.patch b/0001-Add-ssh_key-option-used-by-i-option-of-ssh-scp.patch deleted file mode 100644 index 5e4c7f4..0000000 --- a/0001-Add-ssh_key-option-used-by-i-option-of-ssh-scp.patch +++ /dev/null @@ -1,80 +0,0 @@ -From f5ccee901d346873adbe5d979b5b70d0ba029570 Mon Sep 17 00:00:00 2001 -From: liangxin1300 -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 - diff --git a/0002-Change-format-of-scp-command-for-ipv6-compatible.patch b/0002-Change-format-of-scp-command-for-ipv6-compatible.patch deleted file mode 100644 index 16ac353..0000000 --- a/0002-Change-format-of-scp-command-for-ipv6-compatible.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 1b253513291fe6022b7b832547e43b372886059c Mon Sep 17 00:00:00 2001 -From: liangxin1300 -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 - diff --git a/0003-Fix-task-Don-t-use-ssh-if-command-running-on-local-b.patch b/0003-Fix-task-Don-t-use-ssh-if-command-running-on-local-b.patch deleted file mode 100644 index e25d9f5..0000000 --- a/0003-Fix-task-Don-t-use-ssh-if-command-running-on-local-b.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 22cd571ceb360c66279512af3690347e1d6a768d Mon Sep 17 00:00:00 2001 -From: liangxin1300 -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 - diff --git a/0004-Fix-Error-inherit-from-Exception-instead-of-BaseExce.patch b/0004-Fix-Error-inherit-from-Exception-instead-of-BaseExce.patch deleted file mode 100644 index fa032fb..0000000 --- a/0004-Fix-Error-inherit-from-Exception-instead-of-BaseExce.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 31024ba3eafebbf73b188b6a102c4d8f00669705 Mon Sep 17 00:00:00 2001 -From: nicholasyang -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 - diff --git a/0005-Dev-add-parallax.run-to-return-non-zero-rc-without-r.patch b/0005-Dev-add-parallax.run-to-return-non-zero-rc-without-r.patch deleted file mode 100644 index bf8364d..0000000 --- a/0005-Dev-add-parallax.run-to-return-non-zero-rc-without-r.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 38bac0eb3cb20e9df8cbbf585cf9353793ffdba2 Mon Sep 17 00:00:00 2001 -From: nicholasyang -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 - diff --git a/parallax-1.0.6.tar.gz b/parallax-1.0.6.tar.gz deleted file mode 100644 index d3e0ef5..0000000 --- a/parallax-1.0.6.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c16703202ff67aed4740c0727df304abe9f3e7851e653533b24de21b338d9081 -size 17371 diff --git a/parallax-1.0.8.tar.gz b/parallax-1.0.8.tar.gz new file mode 100644 index 0000000..ab8e174 --- /dev/null +++ b/parallax-1.0.8.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:071f4413a0d49838af19359f10dca161aabbbece81175ddae72a51618321f046 +size 15921 diff --git a/python-parallax.changes b/python-parallax.changes index cfc0e14..550880d 100644 --- a/python-parallax.changes +++ b/python-parallax.changes @@ -1,3 +1,20 @@ +------------------------------------------------------------------- +Mon Nov 7 02:18:35 UTC 2022 - XinLiang + +- Fix: manager: file descriptor leakage +- Release 1.0.8 + +------------------------------------------------------------------- +Thu Nov 3 02:16:52 UTC 2022 - XinLiang + +- 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 diff --git a/python-parallax.spec b/python-parallax.spec index 02b3b83..3933d95 100644 --- a/python-parallax.spec +++ b/python-parallax.spec @@ -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