ssc*_*ssc 107 python host fabric
我想使用Fabric将我的Web应用程序代码部署到开发,登台和生产服务器.我的fabfile:
def deploy_2_dev():
deploy('dev')
def deploy_2_staging():
deploy('staging')
def deploy_2_prod():
deploy('prod')
def deploy(server):
print 'env.hosts:', env.hosts
env.hosts = [server]
print 'env.hosts:', env.hosts
Run Code Online (Sandbox Code Playgroud)
样本输出:
host:folder user$ fab deploy_2_dev
env.hosts: []
env.hosts: ['dev']
No hosts found. Please specify (single) host string for connection:
Run Code Online (Sandbox Code Playgroud)
当我创建Fabric文档中set_hosts()
显示的任务时,env.hosts设置正确.但是,这不是一个可行的选择,也不是装饰者.在命令行上传递主机最终会导致调用fabfile的某种shell脚本,我宁愿让一个工具正常工作.
它在Fabric文档中说'env.hosts只是一个Python列表对象'.根据我的观察,这根本不是真的.
谁能解释一下这里发生了什么?如何设置要部署的主机?
Zac*_*Zac 128
我这样做是通过声明每个环境的实际功能.例如:
def test():
env.user = 'testuser'
env.hosts = ['test.server.com']
def prod():
env.user = 'produser'
env.hosts = ['prod.server.com']
def deploy():
...
Run Code Online (Sandbox Code Playgroud)
使用上面的函数,我将键入以下内容以部署到我的测试环境:
fab test deploy
Run Code Online (Sandbox Code Playgroud)
...以及以下部署到生产:
fab prod deploy
Run Code Online (Sandbox Code Playgroud)
这样做的好处是可以在任何 fab函数之前使用test
和函数,而不仅仅是部署.它非常有用.prod
tho*_*mie 75
使用roledefs
from fabric.api import env, run
env.roledefs = {
'test': ['localhost'],
'dev': ['user@dev.example.com'],
'staging': ['user@staging.example.com'],
'production': ['user@production.example.com']
}
def deploy():
run('echo test')
Run Code Online (Sandbox Code Playgroud)
用-R选择角色:
$ fab -R test deploy
[localhost] Executing task 'deploy'
...
Run Code Online (Sandbox Code Playgroud)
tob*_*ych 49
这是一个更简单的serverhorrors版本答案:
from fabric.api import settings
def mystuff():
with settings(host_string='192.0.2.78'):
run("hostname -f")
Run Code Online (Sandbox Code Playgroud)
Gol*_*Boy 21
我自己也坚持了下来,但终于弄明白了.您无法在任务中设置env.hosts配置.每个任务执行N次,每个主机指定一次,因此该设置基本上在任务范围之外.
查看上面的代码,您可以简单地执行此操作:
@hosts('dev')
def deploy_dev():
deploy()
@hosts('staging')
def deploy_staging():
deploy()
def deploy():
# do stuff...
Run Code Online (Sandbox Code Playgroud)
这似乎会做你想要的.
或者,您可以在全局范围内编写一些自定义代码,手动解析参数,并在定义任务函数之前设置env.hosts.出于几个原因,这实际上就是我如何设置我的.
j-a*_*j-a 18
从fab 1.5开始,这是一种动态设置主机的文档化方法.
http://docs.fabfile.org/en/1.7/usage/execution.html#dynamic-hosts
引用来自下面的文档.
将execute与动态设置的主机列表一起使用
Fabric的常见中高级用例是在运行时参数化一个目标主机列表的查找(当使用Roles时不够).执行可以使这非常简单,如下所示:
from fabric.api import run, execute, task
# For example, code talking to an HTTP API, or a database, or ...
from mylib import external_datastore
# This is the actual algorithm involved. It does not care about host
# lists at all.
def do_work():
run("something interesting on a host")
# This is the user-facing task invoked on the command line.
@task
def deploy(lookup_param):
# This is the magic you don't get with @hosts or @roles.
# Even lazy-loading roles require you to declare available roles
# beforehand. Here, the sky is the limit.
host_list = external_datastore.query(lookup_param)
# Put this dynamically generated host list together with the work to be
# done.
execute(do_work, hosts=host_list)
Run Code Online (Sandbox Code Playgroud)
pzt*_*ick 10
相反,一些其他的答案,它是可以修改env
任务中的环境变量.但是,这env
仅用于使用该fabric.tasks.execute
功能执行的后续任务.
from fabric.api import task, roles, run, env
from fabric.tasks import execute
# Not a task, plain old Python to dynamically retrieve list of hosts
def get_stressors():
hosts = []
# logic ...
return hosts
@task
def stress_test():
# 1) Dynamically generate hosts/roles
stressors = get_stressors()
env.roledefs['stressors'] = map(lambda x: x.public_ip, stressors)
# 2) Wrap sub-tasks you want to execute on new env in execute(...)
execute(stress)
# 3) Note that sub-tasks not nested in execute(...) will use original env
clean_up()
@roles('stressors')
def stress():
# this function will see any changes to env, as it was wrapped in execute(..)
run('echo "Running stress test..."')
# ...
@task
def clean_up():
# this task will NOT see any dynamic changes to env
Run Code Online (Sandbox Code Playgroud)
如果不包含子任务execute(...)
,将使用模块级env
设置或从fab
CLI 传递的任何内容.
你需要设置host_string
一个例子:
from fabric.context_managers import settings as _settings
def _get_hardware_node(virtualized):
return "localhost"
def mystuff(virtualized):
real_host = _get_hardware_node(virtualized)
with _settings(
host_string=real_host):
run("echo I run on the host %s :: `hostname -f`" % (real_host, ))
Run Code Online (Sandbox Code Playgroud)
解释为什么它甚至是一个问题.命令fab正在利用结构库来运行主机列表上的任务.如果您尝试更改任务中的主机列表,那么在迭代它时,您实际上是在尝试更改列表.或者在没有定义主机的情况下,循环遍历一个空列表,其中从未执行将列表设置为循环的代码.
env.host_string的使用是解决此问题的唯一方法,因为它直接指定要连接的主机的功能.如果您想要执行多个主机,这会导致一些问题,即您将重新构建执行循环.
人们在运行时设置主机的最简单方法是将env作为一个独特的任务保持,设置所有主机字符串,用户等.然后他们运行部署任务.它看起来像这样:
fab production deploy
Run Code Online (Sandbox Code Playgroud)
要么
fab staging deploy
Run Code Online (Sandbox Code Playgroud)
升级和生产就像你给出的任务一样,但他们不会自己调用下一个任务.它有这样的工作的原因,是该任务已经完成,并打破循环(主机,在ENV的情况下无,但在这一点上是一个的循环),然后有遍历主机(现在由前面的任务定义)重新开始.
归档时间: |
|
查看次数: |
64452 次 |
最近记录: |