大约 36 小时以来,我一直在努力寻找解决方案,所以希望我不会重复问题或提出明显的问题。我正在构建一个 Web 应用程序,该应用程序必须操作我存储在 S3 中的文件,并使用“公共读取”acl 将新版本放回 S3 中。然后另一个页面允许您查看更新的文件。该应用程序存在于亚马逊 EC2 服务器上并连接到亚马逊 S3 存储桶。
我正在使用 django、celery 和 boto 来执行此操作。我设置了一个 celery 任务,它从我的一个视图中获取一些信息并进行处理,然后将新文件发布到 S3。我能够从 S3 获取原始文件,成功操作它,并将其重新发布到 S3。唯一似乎不起作用的是更改该文件的权限。所以一切正常,除了当你去查看页面时,我在尝试访问该文件时收到 403(禁止)错误。
如果我自己进入 S3 并更改该文件的权限以供所有人阅读,那么一切正常。在我继续之前,我在我的任务中使用的几乎可以工作的代码是:
name = 'filename.blah'
conn = boto.connect_s3()
b = conn.get_bucket(settings.AWS_STORAGE_BUCKET_NAME)
grab_from_S3(name,b) # grab file from S3
out_name = conv(name)
send_to_S3(out_name,b)
其中的功能是:
def grab_from_S3(file,bucket):
k = Key(bucket)
k.key = file
k.get_contents_to_filename(file)
def send_to_S3(file,bucket):
k = Key(bucket)
k.key = file
k.set_contents_from_filename(file)
k.set_acl('public-read')
而 conv(name) 只是做一些转换的东西。所以这几乎可以一直工作,除了文件的权限不是“公共读取”。我假设的所有 AWS 凭证和存储桶名称都是从环境中正确导入的,因为它能够将文件推入和拉出 S3。
最令人困惑的部分是,当我从我的 EC2 服务器上的 venv 或刚开始安装在其上的 python 打开一个 python 环境并运行上面显示的所有命令时,它确实有效。我可以毫无问题地更改权限。当任务运行时,它不会在 celery 日志中抛出任何错误,所以我认为任务实际上并没有遇到错误。它只是简单地不改变它应该改变的东西。
我尝试过的事情:
- 我尝试使用其他版本的权限功能,例如
k.set_contents_from_filename(file,policy='public-read')
ork.make_public()
或,b.set_acl('public-read',out_name)
但这些都不起作用。 - 我更改了存储桶的权限,说每个人都可以更改权限,但它仍然无法正常工作。
我尝试将存储桶策略更改为以下内容,但没有效果:
{ "Version": "2008-10-17", "Id": "whatever", "Statement": [ { "Sid": "whatever", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": [ "s3:PutObjectAcl", "s3:PutObject"], "Resource": [ "arn:aws:s3:::bucket_name", "arn:aws:s3:::bucket_name/*" ] } ] }
最后,我真的很困惑,因为我似乎可以在同一个 EC2 实例上的 python 环境中完成所有这些工作,而不是在该实例上运行的代码。我已经搜索和搜索,但无法找到任何有效的建议。另一个可能有用的信息(但可能与问题无关)是,如果我尝试通过执行上述类似命令在我的视图中连接到 S3,则会返回错误:
“没有处理程序准备好进行身份验证。检查了 1 个处理程序。['HmacAuthV1Handler'] 检查您的凭据”
即使在我的任务中运行这些命令时它仍然有效(我会假设它是错误的访问密钥或秘密访问密钥或其他东西,但它适用于其他所有内容)。我认为我在我需要的 boto 库部分的 python 代码中进行了正确的导入。
我最近刚刚设置了这个实例,所以它可能几乎有最新版本的 boto、celery、django 等。我大概忘记了什么。如果您需要更多信息来回答问题,请告诉我。我真的不确定发生了什么。
提前致谢。