将 collectstatic 与最新版本的 Boto、管道和存储一起使用时,x-amz-acl 设置不正确
x-amz-acl being set incorrectly when using collectstatic with latest version of Boto, Pipeline, and Storages
我正在更新我的应用程序的依赖项。我对 requirements.txt 进行了以下更改:
- boto:升级到 2.34.0
- django-pipeline: 升级到 1.4.2
- django-require: 升级到 1.0.6
- django-storages:最新 (1.1.8)
现在,当我尝试将 collectstatic 运行到我的 S3 存储桶中时,出现以下错误:
boto.exception.S3ResponseError: S3ResponseError: 400 Bad Request
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>InvalidArgument</Code>
x-amz-acl
/tmp/tmpDyVin1 xxx
yyy
并不奇怪,因为显然 /tmp/tmpDyVin1
是 not a valid value for x-amz-acl。
问题源于指定我自己的 class 来处理结合了 Boto、Require 和管道的静态文件:
settings.py
STATICFILES_STORAGE = 'myapp.storage.OptimizedS3BotoStorage'
storage.py
from pipeline.storage import PipelineMixin
from require.storage import OptimizedFilesMixin
from storages.backends.s3boto import S3BotoStorage
class ReleaseVersionCachedFilesMixin(CachedFilesMixin):
def hashed_name(self, name, content=None):
...
class OptimizedS3BotoStorage(PipelineMixin, OptimizedFilesMixin, ReleaseVersionCachedFilesMixin, S3BotoStorage):
pass
这与所有这些模块的旧版本完美一致。挖掘新代码,我发现问题出在与这三个的交互上:
- 调用
S3BotoStorage.__init__()
时,第一个参数acl
作为这个tmp目录的值传入。这会覆盖 public-read
的先前值并导致上述问题。
- 此
__init__()
例程由 CachedFilesMixin.__init__()
调用,后者接收 args = ('/tmp/tmpnNUVD9',)
。
__init__()
被 PipelineMixin.__init__()
调用,它这样做:
def __init__(self, location=None, *args, **kwargs):
if not settings.PIPELINE_ENABLED and location is None:
location = tempfile.mkdtemp()
super(PipelineMixin, self).__init__(location, *args, **kwargs)
所以,问题在于 Pipeline 传入 location
作为第一个参数,它向下传播并成为 acl
.
看起来这个看起来很讨厌的问题的解决方案只是将 PipelineMixin 移动到我的自定义存储 class 中参数列表的末尾,但这会破坏 r.js 优化器.解决方案是将此 PIPELINE_ENABLED
标志设置为 True
。
(文档说 this flag defaults to not settings.DEBUG
, but that may not be a meaningful dependency for your environment. The flag wasn't used this way in PipelineMixin
until 1.4, but it's not documented in the directives for upgrading to 1.4。)
我正在更新我的应用程序的依赖项。我对 requirements.txt 进行了以下更改:
- boto:升级到 2.34.0
- django-pipeline: 升级到 1.4.2
- django-require: 升级到 1.0.6
- django-storages:最新 (1.1.8)
现在,当我尝试将 collectstatic 运行到我的 S3 存储桶中时,出现以下错误:
boto.exception.S3ResponseError: S3ResponseError: 400 Bad Request <?xml version="1.0" encoding="UTF-8"?> <Error><Code>InvalidArgument</Code>
x-amz-acl /tmp/tmpDyVin1 xxx yyy
并不奇怪,因为显然 /tmp/tmpDyVin1
是 not a valid value for x-amz-acl。
问题源于指定我自己的 class 来处理结合了 Boto、Require 和管道的静态文件:
settings.py
STATICFILES_STORAGE = 'myapp.storage.OptimizedS3BotoStorage'
storage.py
from pipeline.storage import PipelineMixin
from require.storage import OptimizedFilesMixin
from storages.backends.s3boto import S3BotoStorage
class ReleaseVersionCachedFilesMixin(CachedFilesMixin):
def hashed_name(self, name, content=None):
...
class OptimizedS3BotoStorage(PipelineMixin, OptimizedFilesMixin, ReleaseVersionCachedFilesMixin, S3BotoStorage):
pass
这与所有这些模块的旧版本完美一致。挖掘新代码,我发现问题出在与这三个的交互上:
- 调用
S3BotoStorage.__init__()
时,第一个参数acl
作为这个tmp目录的值传入。这会覆盖public-read
的先前值并导致上述问题。 - 此
__init__()
例程由CachedFilesMixin.__init__()
调用,后者接收args = ('/tmp/tmpnNUVD9',)
。 __init__()
被PipelineMixin.__init__()
调用,它这样做:
def __init__(self, location=None, *args, **kwargs):
if not settings.PIPELINE_ENABLED and location is None:
location = tempfile.mkdtemp()
super(PipelineMixin, self).__init__(location, *args, **kwargs)
所以,问题在于 Pipeline 传入 location
作为第一个参数,它向下传播并成为 acl
.
看起来这个看起来很讨厌的问题的解决方案只是将 PipelineMixin 移动到我的自定义存储 class 中参数列表的末尾,但这会破坏 r.js 优化器.解决方案是将此 PIPELINE_ENABLED
标志设置为 True
。
(文档说 this flag defaults to not settings.DEBUG
, but that may not be a meaningful dependency for your environment. The flag wasn't used this way in PipelineMixin
until 1.4, but it's not documented in the directives for upgrading to 1.4。)