代码之家  ›  专栏  ›  技术社区  ›  Risadinha

shuil.copystat()在Azure上的Docker中失败

  •  0
  • Risadinha  · 技术社区  · 8 年前

    失败的代码在Docker容器中运行,基于 python:3.6-stretch 德比安。 Django将文件从一个Docker卷移动到另一个Docker卷时会发生这种情况。

    当我在MacOS 10上测试时,它工作正常。在这里,Docker容器以Docker compose启动,并使用本地计算机上的常规Docker卷。

    部署到Azure中(Azure上的AKS-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()从不返回失败。

    https://docs.python.org/3/library/shutil.html

    我的问题是:

    • 这是不是一个“bug”,因为文档中说它应该“永不返回失败”?
    • 我是否可以保存尝试/排除此错误,因为有问题的文件已被移动(稍后在尝试复制统计数据时失败)
    • 我可以更改一些关于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'
    >>> 
    
    1 回复  |  直到 8 年前
        1
  •  0
  •   Risadinha    8 年前

    以下解决方案是一个修补程序。它必须适用于 调用的方法 copystat 直接或间接地(或产生可忽略的 errno.ENOSYS

    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