2012-09-19 25 views
3

在我的fabric腳本中,我遇到以下問題。我有一個稱爲autodeploy的主要任務。在這個任務中,我有一些任務,我只想在本地運行一次。所有遠程任務應該在主機列表的每個主機上運行。如何讓一些Fabric任務只在本地運行一次,而其他Fabric任務在所有主機上運行

env.roledefs ={ 
    'testing': ['t-server-01', 't-server-02'] 
    'staging': ['s-server-01', 's-server-02'] 
    'live': ['l-server-01', 'l-server-02'] 
} 

def localtask1(): 
    # download artifact 

def localtask2(): 
    # cleanup locally 

def remotetask(): 
    # deploy artifact to all hosts 

def autodeploy(): 
    localtask1() # run this task only once, locally 

    remotetask() # run this task on all hosts 

    localtask2() # run this task only once 

該通話如下。我想將角色作爲屬性傳遞給角色。

fab -R test autodeploy 

回答

6

使用wrapper函數autodeploy中的execute函數,並指定遠程任務的主機列表。

對於另外兩個,您可以使用execute來調用它們,如遠程任務或直接調用它們。使用它們中的本地函數,你會很好,並且不需要在本地主機上有ssh。

文檔是here如何最好的使用新的execute function

編輯

既然你提到在評論不同的使用情況下,我會嘲笑了你會怎麼做,從位已經給文檔中,加入param passing section

代碼:

#copy above 

#redefine this one 
def autodeploy(role_from_arg): 
    localtask1() 
    execute(remotetask, role=role_from_arg) 
    localtask2() 

#calls like fab autodeploy:testing 
+0

我改變了代碼在上面的問題,所以你可以看到我的嘗試。也許我錯過了一些事情,因爲它似乎沒有工作 –

+0

你做了倒退。執行(remotetask)是你真正需要的。我會編輯我的答案,使其更清楚。 – Morgan

+0

因爲我想將角色作爲屬性傳遞,所以我沒有看到此解決方案適用於我。如果我把@roles('testing')放在一個任務上面,它會一直運行這個任務,並且相應的宿主列表 –

3

使用裝飾器runs_once

@runs_once 
def localtask1(): 
    local('command') 
+0

防止'localtask1'被多次使用,當然,所以你不能再'fab localtask1 localtask1'。 – wodow

2

可以濫用hosts decorator迫使一個任務只運行一次,通過指定「localhost」作爲主機。

例子:

@fabric.decorators.hosts("localhost") 
def localtask1(): 
    # download artefact 
+2

我使用'@ fabric.decorators.hosts(「」)',因爲它與織物內部使用的內容相匹配。這個任務中的字符串並不重要,因爲它不應該被使用。如果你不小心把遠程命令放在這裏,它會失敗。 –

+0

@TimLudwinski有趣!我在https://github.com/fabric/fabric/search?q=local-only&type=Code查看使用的約定 – wodow

相關問題