summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--gnu/local.mk1
-rw-r--r--gnu/packages/patches/python-execnet-read-only-fix.patch77
-rw-r--r--gnu/packages/python-xyz.scm26
3 files changed, 92 insertions, 12 deletions
diff --git a/gnu/local.mk b/gnu/local.mk
index 14cd1cc6ad..ebcb4c82f5 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1635,6 +1635,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/python-cross-compile.patch		\
   %D%/packages/patches/python2-larch-coverage-4.0a6-compatibility.patch \
   %D%/packages/patches/python-configobj-setuptools.patch	\
+  %D%/packages/patches/python-execnet-read-only-fix.patch	\
   %D%/packages/patches/python-flask-restful-werkzeug-compat.patch	\
   %D%/packages/patches/python-keras-integration-test.patch	\
   %D%/packages/patches/python-pep8-stdlib-tokenize-compat.patch \
diff --git a/gnu/packages/patches/python-execnet-read-only-fix.patch b/gnu/packages/patches/python-execnet-read-only-fix.patch
new file mode 100644
index 0000000000..58a4b129a7
--- /dev/null
+++ b/gnu/packages/patches/python-execnet-read-only-fix.patch
@@ -0,0 +1,77 @@
+From 0d6562a20b0610c5a83d1c66ac879223b84a2746 Mon Sep 17 00:00:00 2001
+From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
+Date: Thu, 26 Aug 2021 00:43:26 -0400
+Subject: [PATCH] rsync_remote: Fix a problem when receiving read-only
+ directories.
+
+Before this change, when the source directories hierarchy was
+read-only, the read-only mode would be preserved at the destination,
+preventing child directories to be recreated by a normal user (a
+permission denied error, EACCES would be raised).
+
+* execnet/rsync_remote.py (serve_rsync.receive_directory_structure):
+Bitwise OR to ensure the write bit is set on received directories.
+* testing/test_rsync.py (TestRSync)
+<test_read_only_directories>: New test.
+---
+ execnet/rsync_remote.py |  8 ++++++--
+ testing/test_rsync.py   | 17 +++++++++++++++++
+ 2 files changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/execnet/rsync_remote.py b/execnet/rsync_remote.py
+index cd5e765..55d154c 100644
+--- a/execnet/rsync_remote.py
++++ b/execnet/rsync_remote.py
+@@ -35,7 +35,11 @@ def serve_rsync(channel):
+                 os.makedirs(path)
+             mode = msg.pop(0)
+             if mode:
+-                os.chmod(path, mode)
++                # Ensure directories are writable, otherwise a
++                # permission denied error (EACCES) would be raised
++                # when attempting to receive read-only directory
++                # structures.
++                os.chmod(path, mode | 0o700)
+             entrynames = {}
+             for entryname in msg:
+                 destpath = os.path.join(path, entryname)
+@@ -59,7 +63,7 @@ def serve_rsync(channel):
+                         checksum = md5(f.read()).digest()
+                         f.close()
+                     elif msg_mode and msg_mode != st.st_mode:
+-                        os.chmod(path, msg_mode)
++                        os.chmod(path, msg_mode | 0o700)
+                         return
+                     else:
+                         return  # already fine
+diff --git a/testing/test_rsync.py b/testing/test_rsync.py
+index 995f229..1d6c30c 100644
+--- a/testing/test_rsync.py
++++ b/testing/test_rsync.py
+@@ -157,6 +157,23 @@ class TestRSync:
+         mode = destdir.stat().mode
+         assert mode & 511 == 504
+ 
++    @py.test.mark.skipif("sys.platform == 'win32' or getattr(os, '_name', '') == 'nt'")
++    def test_read_only_directories(self, dirs, gw1):
++        source = dirs.source
++        dest = dirs.dest1
++        source.ensure("sub", "subsub", dir=True)
++        source.join("sub").chmod(0o500)
++        source.join("sub", "subsub").chmod(0o500)
++
++        # The destination directories should be created with the write
++        # permission forced, to avoid raising an EACCES error.
++        rsync = RSync(source)
++        rsync.add_target(gw1, dest)
++        rsync.send()
++
++        assert dest.join("sub").stat().mode & 0o700
++        assert dest.join("sub").join("subsub").stat().mode & 0o700
++
+     @needssymlink
+     def test_symlink_rsync(self, dirs, gw1):
+         source = dirs.source
+-- 
+2.32.0
+
diff --git a/gnu/packages/python-xyz.scm b/gnu/packages/python-xyz.scm
index beb70c9d84..dd1b741310 100644
--- a/gnu/packages/python-xyz.scm
+++ b/gnu/packages/python-xyz.scm
@@ -12193,24 +12193,26 @@ pure Python module that works on virtually all Python versions.")
 (define-public python-execnet
   (package
     (name "python-execnet")
-    (version "1.4.1")
+    (version "1.9.0")
     (source (origin
-             (method url-fetch)
-             (uri (pypi-uri "execnet" version))
-             (sha256
-              (base32
-               "1rpk1vyclhg911p3hql0m0nrpq7q7mysxnaaw6vs29cpa6kx8vgn"))))
+              (method url-fetch)
+              (uri (pypi-uri "execnet" version))
+              (sha256
+               (base32
+                "1ia7dvrh0gvzzpi758mx55f9flr16bzdqlmi12swm4ncm4xlyscg"))
+              (patches (search-patches "python-execnet-read-only-fix.patch"))))
     (build-system python-build-system)
     (arguments
-     `(;; 2 failed, 275 passed, 670 skipped, 4 xfailed
-       ;; The two test failures are caused by the lack of an `ssh` executable.
-       ;; The test suite can be run with pytest after the 'install' phase.
-       #:tests? #f))
+     `(#:phases
+       (modify-phases %standard-phases
+                  (replace 'check
+                    (lambda* (#:key inputs outputs tests? #:allow-other-keys)
+                      (when tests?
+                        (add-installed-pythonpath inputs outputs)
+                        (invoke "pytest" "-vv")))))))
     (native-inputs
      `(("python-pytest" ,python-pytest)
        ("python-setuptools-scm" ,python-setuptools-scm)))
-    (propagated-inputs
-     `(("python-apipkg" ,python-apipkg)))
     (synopsis "Rapid multi-Python deployment")
     (description "Execnet provides a share-nothing model with
 channel-send/receive communication for distributing execution across many