5

大约 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 日志中抛出任何错误,所以我认为任务实际上并没有遇到错误。它只是简单地不改变它应该改变的东西。

我尝试过的事情:

  1. 我尝试使用其他版本的权限功能,例如k.set_contents_from_filename(file,policy='public-read')ork.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/*" ] } ] }

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

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

即使在我的任务中运行这些命令时它仍然有效(我会假设它是错误的访问密钥或秘密访问密钥或其他东西,但它适用于其他所有内容)。我认为我在我需要的 boto 库部分的 python 代码中进行了正确的导入。

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

提前致谢。

4

1 回答 1

7

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

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

答案是我只需要重新启动守护程序,它就会看到我的命令。现在一切正常。我去尝试在 celery 文档或入门指南中搜索有关在进行更改或导入代码但没有看到任何明显内容时记住执行此操作的行。我通过其他一些答案找到了这一点:

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

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

于 2013-10-01T18:42:43.507 回答