具有远程 (AWS S3) 目标的生成文件



我想创建一个生成文件,其中的目标和依赖项不是本地文件,而是存在于某个 AWS/S3 存储桶中。

考虑以下示例,该示例只需将"data_raw"文件复制到"obj1"中,然后复制到"obj2"中(在运行此文件之前,您需要将"存储桶"编辑为您拥有的某个存储桶并创建一些"data_raw"文件(:

# local, works fine
bucket = /tmp/test/
cp = cp
# remote, does not work
bucket = s3://bucket/test/
cp = s3cmd cp
all : $(bucket)obj2
$(bucket)obj2 : $(bucket)obj1
    $(cp) $(bucket)obj1 $(bucket)obj2
$(bucket)obj1 :
    $(cp) $(bucket)raw_data $(bucket)obj1

我得到的错误是:

makefile:9: *** target pattern contains no `%'.  Stop.

适用于:

all : $(bucket)obj2

我怀疑 make 根本不理解远程 URI("s3://xxx"(。

我能找到的所有示例/文档似乎都隐式引用了目标和依赖项的本地文件。广泛的谷歌搜索只产生了一些关于为 s3 创建 ant 任务的看似未完成的想法(http://code.google.com/p/awstasks/(。

这是在Python中运行几个复杂/复杂的MapReduce作业的上下文中。

我宁愿使用GNU make,但肯定会考虑替代方案。

我总是可以为远程目标创建一些轻型本地镜像,但肯定有更好的方法吗?

提前感谢!

网卡

一种有效的解决方法是在本地挂载 S3 存储桶。

在Linux上,可以使用fuse/s3fs。这可能也适用于MacOS,但安装起来似乎非常混乱。我改用商业软件传输(单击"挂载为磁盘"(。有了这个,上面的例子对我来说是有用的:

bucket = /Volumes/s3.amazonaws.com/bucket/test/
cp = cp

在这个例子中,我们使用'cp',因为's3cmd cp'拒绝本地uri。在一个(我的(现实生活中的例子中,该命令将被一些需要实际 s3 输入/输出 uri 的 python map-reduce 脚本替换。

为了保持整洁,本地挂载的文件可能应该有一个前缀变量("/Volumes/s3.amazonaws.com/"(和一个前缀变量("s3://"(用于构建命令指向实际数据(数据将由 EC2 实例通过 mapreduce,我们绝对不想在本地下载所有内容(。

请记住,S3 只是最终一致的。还要确保为了测试是否存在和最新性,整个文件不会在本地下载(在这种情况下,应使用一些虚拟文件(。

希望有帮助。

如果有人有更直接的方法(没有本地安装(,我很感兴趣。

网卡

我喜欢你要找的东西。 但是,如果它被内置到makefile中并make本身,我会感到惊讶;正如您正确指出的那样,"Linux"方法是找到一种方法将 S3 挂载为文件系统。

但是,如果你要包括"make-like",我建议从Ruby宇宙中rake。 自从我愤怒地使用它以来已经有一段时间了,但我记得它允许您编写自定义扩展,以便您的源和目标不需要在本地文件系统上。

我会将所有的制作文件切换到 rake-file,如果 Ruby 在我倾向于使用的系统类型(相当裸露的 EC2 和没有管理员权限的 ECS 系统(上更普遍一点。