2012-05-10 29 views
2

我想創建一個makefile,目標和依賴不會是本地文件,而是存在於某個AWS/S3存儲桶中。考慮下面的例子,它會簡單地將'data_raw'文件複製到'obj1'然後'obj2'(你需要編輯'bucket'到你擁有的某個桶並創建一些'data_raw'文件,然後再運行這個文件):遠程(AWS S3)目標的Makefile

# 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的螞蟻任務(http://code.google.com/p/awstasks/)。

這是在Python中運行幾個複雜/複雜的MapReduce作業的上下文。

我寧願使用GNU make,但肯定會考慮其他選擇。

我總是可以創建一些遠程目標的本地鏡像,但肯定有更好的方法嗎?

在此先感謝!

Nic

+0

Make最好在使用文件*有*來建立文件*在這裏*。但是這個makefile看起來不錯,你是否想要降低複雜性?你可以從桶內運行Make嗎? – Beta

+0

這裏的困難可能在於不接受遠程URI作爲目標或依賴關係。我錯過了一些愚蠢的東西(逃避?)?什麼樣的URI應該能夠處理?我會想象它最需要能夠測試存在並獲得S3應該支持的日期嗎? –

+0

我不知道AWS/S3,但是你可以使用幾個本地文件作爲代理,只是爲了'touch'來表明真實文件已被修改,並且可以使用'synch'目標來更新它們他們的初選? – Beta

回答

1

一種可行的解決方法是在本地安裝S3存儲桶。

在Linux上,可能使用fuse/s3fs。這可能也適用於MacOS,但似乎是非常麻煩的安裝。我使用了商業軟件transmit來代替(點擊'mount as disk')。就這樣,上面的例子是對我的功能:

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

在這個例子中,我們使用「CP」,因爲「s3cmd CP」拒絕本地的URI。在(我的)現實生活中,命令將被一些需要實際s3輸入/輸出uris的python map-reduce腳本取代。

爲了保持整潔,本地安裝的文件應該有一個前綴變量(「/Volumes/s3.amazonaws.com/」)(對於Make來測試是否存在/最新內容)和用於構建命令的一個前綴變量(「s3://」)指向實際數據(數據將通過mapreduce由EC2實例處理,我們絕對不希望本地下載所有內容)。

請記住,S3只是最終一致。還要確保爲了測試是否存在和最新內容,整個文件不會在本地下載(在這種情況下,應該使用一些虛擬文件)。

希望有所幫助。

如果有人有更直接的方法(沒有本地安裝),我很感興趣。

Nic