<p>The failing code runs inside a Docker container based on <code>python:3.6-stretch</code> debian.
It happens while Django moves a file from one Docker volume to another.</p>

<p>When I test on MacOS 10, it works without error. Here, the Docker containers are started with docker-compose and use regular Docker volumes on the local machine.</p>

<p>Deployed into Azure (AKS - Kubernetes on Azure), moving the file succeeds but copying the stats fails with the following error:</p>

<pre><code>  File "/usr/local/lib/python3.6/site-packages/django/core/files/move.py", line 70, in file_move_safe
    copystat(old_file_name, new_file_name)
  File "/usr/local/lib/python3.6/shutil.py", line 225, in copystat
    _copyxattr(src, dst, follow_symlinks=follow)
  File "/usr/local/lib/python3.6/shutil.py", line 157, in _copyxattr
    names = os.listxattr(src, follow_symlinks=follow_symlinks)
OSError: [Errno 38] Function not implemented: '/some/path/file.pdf'
</code></pre>

<p>The volumes on Azure are persistent volume claims with <code>ReadWriteMany</code> access mode.</p>

<p>Now, <code>copystat</code> is documented as:</p>

<blockquote>
  <p>copystat() never returns failure.</p>
</blockquote>

<p><a href="https://docs.python.org/3/library/shutil.html" rel="nofollow noreferrer">https://docs.python.org/3/library/shutil.html</a></p>

<p>My questions are:</p>

<ul>
<li>Is this a "bug" because the documentation says that it should "never return failure"?</li>
<li>Can I savely try/except this error because the file in question is moved (it only fails later on, while trying to copy the stats)</li>
<li>Can I change something about the Azure settings that fix this? (probably not)</li>
</ul>

<p>Here some small test on the machine in Azure itself:</p>

<pre><code>root:/media/documents# ls -al
insgesamt 267
drwxrwxrwx 2 1000 1000      0 Jul 31 15:29 .
drwxrwxrwx 2 1000 1000      0 Jul 31 15:29 ..
-rwxrwxrwx 1 1000 1000 136479 Jul 31 16:48 orig.pdf
-rwxrwxrwx 1 1000 1000 136479 Jul 31 15:29 testfile
root:/media/documents# lsattr 
--S-----c-jI------- ./orig.pdf
--S-----c-jI------- ./testfile
root:/media/documents# python
Python 3.6.6 (default, Jul 17 2018, 11:12:33) 
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; import shutil
&gt;&gt;&gt; shutil.copystat('orig.pdf', 'testfile')
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  File "/usr/local/lib/python3.6/shutil.py", line 225, in copystat
    _copyxattr(src, dst, follow_symlinks=follow)
  File "/usr/local/lib/python3.6/shutil.py", line 157, in _copyxattr
    names = os.listxattr(src, follow_symlinks=follow_symlinks)
OSError: [Errno 38] Function not implemented: 'orig.pdf'
&gt;&gt;&gt; shutil.copystat('orig.pdf', 'testfile', follow_symlinks=False)
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  File "/usr/local/lib/python3.6/shutil.py", line 225, in copystat
    _copyxattr(src, dst, follow_symlinks=follow)
  File "/usr/local/lib/python3.6/shutil.py", line 157, in _copyxattr
    names = os.listxattr(src, follow_symlinks=follow_symlinks)
OSError: [Errno 38] Function not implemented: 'orig.pdf'
&gt;&gt;&gt; 
</code></pre>

<p>The following solution is a hotfix. It would have to be applied to <em>any</em> method that calls <code>copystat</code> directly or indirectly (or any shutil method that produces an ignorable <code>errno.ENOSYS</code>).</p>

<pre><code>if hasattr(os, 'listxattr'):
    LOGGER.warning('patching listxattr to avoid ERROR 38 (errno.ENOSYS)')
    # avoid "ERROR 38 function not implemented on Azure"
    with mock.patch('os.listxattr', return_value=[]):
        file_field.save(name=name, content=GeneratedFile(fresh, content_type=content_type), save=True)
else:
    file_field.save(name=name, content=GeneratedFile(fresh, content_type=content_type), save=True)
</code></pre>

<p><code>file_field.save</code> is the Django method that calls the <code>shutil</code> code in question. It's the last location in my code before the error.</p>
