2012-09-19 22 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

相关问题