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



我已经尝试找到这个问题的解决方案大约36个小时了,所以希望我不会重复一个问题或问一些明显的问题。我正在构建一个web应用程序,它必须操作我存储在S3中的文件,并使用"公共读取"acl将新版本放回S3中。然后通过另一个页面可以查看更新后的文件。该应用程序存在于amazonEC2服务器上,并连接到amazonS3存储桶。

我用django、芹菜和boto来做这个。我设置了一个芹菜任务,它从我的一个视图中获取一些信息并进行处理,然后将新文件发布到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凭据和bucket名称都是正确地从环境中导入的,因为它能够向S3推送和从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. 我更改了bucket上的权限,说每个人都可以更改权限,但它仍然不起作用
  3. 我试图将bucket策略更改为以下内容,但没有效果:

    { "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']检查您的凭据">

即使当这些命令在我的任务中运行时它也能工作(我认为它是错误的访问密钥或秘密访问密钥或其他什么,但它能处理其他一切)。我想我在python代码中正确导入了我需要的boto库的部分。

我最近刚刚设置了这个实例,所以它可能有最新版本的boto、芹菜、django等。我可能忘了什么。如果你需要更多信息来回答这个问题,请告诉我。我真的不确定发生了什么事。

提前感谢。

大约4天后,我自己解决了这个问题,答案一直在我眼皮底下。因此,为了可能发生在这件事上的其他人,我将揭露我的愚蠢。

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

答案是,我只需要重新启动守护进程,这样它就能看到我的命令。现在一切都好了。我去了,试图在芹菜文档或入门指南中搜索一行关于在进行更改或导入代码时记住这样做的内容,但没有看到任何明显的内容。我通过其他一些答案发现了这一点:

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

这对发展很有用。但我还没有看到任何明确的台词告诉新人要芹菜,以确保他们意识到需要重新启动工人。也许这是显而易见的,我只是太新了。如果有人知道哪里有关于它的一些信息的链接,那将是一个受欢迎的帖子,因为有人可能想在未来阅读它。很抱歉浪费了大家的时间。

相关内容

  • 没有找到相关文章