* gnu/packages/patches/python-execnet-read-only-fix.patch: New file. * gnu/local.mk (dist_patch_DATA): Register it. * gnu/packages/python-xyz.scm (python-execnet): Update to 1.9.0. [source]: Fix indentation. [arguments]: Enable tests, replacing the default check phase.
		
			
				
	
	
		
			77 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| 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
 | |
| 
 |