shutil.copystat() 在 Azure 上的 Docker 内失败
shutil.copystat() fails inside Docker on Azure
失败代码在基于 python:3.6-stretch
debian 的 Docker 容器中运行。
它发生在 Django 将文件从一个 Docker 卷移动到另一个卷时。
当我在 MacOS 10 上测试时,它没有错误。此处,Docker 容器以 docker-compose 启动,并在本地计算机上使用常规 Docker 卷。
已部署到 Azure(AKS - Azure 上的 Kubernetes),移动文件成功但复制统计信息失败并出现以下错误:
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'
Azure 上的卷是具有 ReadWriteMany
访问模式的持久卷声明。
现在,copystat
记录为:
copystat() never returns failure.
https://docs.python.org/3/library/shutil.html
我的问题是:
- 这是 "bug" 因为文档说它应该 "never return failure" 吗?
- 我可以避免 try/except 这个错误吗,因为有问题的文件被移动了(它只会在稍后尝试复制统计信息时失败)
- 我可以更改有关修复此问题的 Azure 设置吗? (可能不是)
这里在 Azure 本身的机器上进行一些小测试:
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.
>>> import shutil
>>> shutil.copystat('orig.pdf', 'testfile')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
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'
>>> shutil.copystat('orig.pdf', 'testfile', follow_symlinks=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
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'
>>>
以下解决方案是一个修补程序。它必须应用于直接或间接调用 copystat
的 any 方法(或任何产生可忽略的 errno.ENOSYS
的 shutil 方法)。
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)
file_field.save
是调用有问题的 shutil
代码的 Django 方法。这是我的代码中出现错误之前的最后一个位置。
失败代码在基于 python:3.6-stretch
debian 的 Docker 容器中运行。
它发生在 Django 将文件从一个 Docker 卷移动到另一个卷时。
当我在 MacOS 10 上测试时,它没有错误。此处,Docker 容器以 docker-compose 启动,并在本地计算机上使用常规 Docker 卷。
已部署到 Azure(AKS - Azure 上的 Kubernetes),移动文件成功但复制统计信息失败并出现以下错误:
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'
Azure 上的卷是具有 ReadWriteMany
访问模式的持久卷声明。
现在,copystat
记录为:
copystat() never returns failure.
https://docs.python.org/3/library/shutil.html
我的问题是:
- 这是 "bug" 因为文档说它应该 "never return failure" 吗?
- 我可以避免 try/except 这个错误吗,因为有问题的文件被移动了(它只会在稍后尝试复制统计信息时失败)
- 我可以更改有关修复此问题的 Azure 设置吗? (可能不是)
这里在 Azure 本身的机器上进行一些小测试:
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.
>>> import shutil
>>> shutil.copystat('orig.pdf', 'testfile')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
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'
>>> shutil.copystat('orig.pdf', 'testfile', follow_symlinks=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
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'
>>>
以下解决方案是一个修补程序。它必须应用于直接或间接调用 copystat
的 any 方法(或任何产生可忽略的 errno.ENOSYS
的 shutil 方法)。
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)
file_field.save
是调用有问题的 shutil
代码的 Django 方法。这是我的代码中出现错误之前的最后一个位置。