无法使用boto和django在S3中设置文件权限

时间:2013-09-30 01:01:13

标签: django amazon-s3 celery file-permissions boto

我一直试图找到一个解决方案大约36个小时,所以希望我不是重复问题或问一些明显的问题。我正在构建一个Web应用程序,它必须操作我存储在S3中的文件,并使用“public-read”acl将新版本放回S3中。然后,可以使用其他页面查看更新的文件。该应用程序存在于亚马逊EC2服务器上,并连接到亚马逊S3桶。

我正在使用django,celery和boto来做这件事。我有一个celery任务设置,从我的一个视图中获取一些信息并进行处理,然后将新文件发布到S3。我能够从S3获取原始文件,成功操作它,并将其重新发布到S3。唯一似乎不起作用的是更改该文件的权限。所以一切正常,除非你去查看页面,我在尝试访问该文件时收到403(Forbidden)错误。

如果我自己进入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开始时,我运行上面显示的所有命令,它就可以了。我可以毫无问题地更改权限。当任务运行时,它不会在芹菜日志中抛出任何错误,所以我不认为任务实际上遇到了错误。它只是不改变它应该改变的东西。

我尝试过的事情:

  1. 我尝试使用其他版本的权限功能,例如k.set_contents_from_filename(file,policy='public-read')k.make_public()b.set_acl('public-read',out_name),但这些功能都没有。
  2. 我更改了存储桶的权限,表示允许所有人更改权限,但它仍无法正常工作。
  3. 我尝试将存储桶策略更改为以下内容,但没有任何效果:

    { "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/*" ] } ] }

  4. 最后,我真的很困惑,因为我似乎可以在同一个EC2实例上的python环境中完成所有这些工作,但不是在该实例上运行的代码。我搜索并搜索过,但未能找到任何有效的建议。另一个可能有用的信息(但根据问题可能无关)是如果我尝试通过上面的类似命令在我的视图中连接到S3,则返回错误:

    “没有处理程序准备好进行身份验证。检查了1个处理程序。['HmacAuthV1Handler']检查您的凭据”

    即使它在我的任务中运行这些命令时也能工作(我认为它是错误的访问密钥或秘密访问密钥或其他东西,但它适用于其他所有东西)。我想我正在我需要的boto库部分的python代码中进行正确的导入。

    我刚刚设置了这个实例,所以它可能几乎是最新版本的boto,celery,django等。我可能忘记了什么。如果您需要更多信息来回答这个问题,请告诉我。我真的不确定发生了什么。

    提前感谢。

1 个答案:

答案 0 :(得分:7)

我在大约4天后自己解决了这个问题,答案一直在我的鼻子底下。因此,为了其他任何可能发生这种情况的人,我会暴露我的愚蠢。

我对芹菜非常新。我没有意识到的是,每次更改芹菜任务时,都需要重新启动工作人员以查看更改。这对我来说从来不是一个问题因为我每次开发时都会自己开始工作,但我最近改用芹菜作为守护进程。所以这是我做的第一次改变,其中芹菜一直在运行。

答案是我只需要重启守护进程就可以看到我的命令了。这一切现在都有效。我去尝试在芹菜文档中搜索一行,或者在您进行更改或者导入代码但没有看到任何明显的内容时,记得要记住这样做。我通过其他一些答案找到了这个:

http://docs.celeryproject.org/en/latest/internals/reference/celery.worker.autoreload.html

这对开发有用。但我没有看到任何明确的线路告诉新人芹菜,以确保他们知道需要重新启动工人。也许这很明显,我太新了。如果有人知道哪里有关于它的某些信息的链接,那将是一个受欢迎的帖子,因为有人可能希望将来阅读它。很抱歉浪费每个人的时间。