主要内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #1.定义主机列表 ##1.1 主机 ##1.2 角色 #2.如何构建主机列表(host lists) ? ##2.1 四种主机定义方式 ###(1)Globally, via env ###(2)Globally, via the command line ###(3)Per-task, via the command line ###(4)Per-task, via decorators ##2.2 主机定义的优先顺序 ##2.3 测试 #3. 其它 ##3.1 合并主机列表 ##3.2 重复的主机 ##3.3 不包含指定的主机 ##3.4 使用execute智能执行task
#1.定义主机列表 ##1.1 主机 主机的定义格式为: username@hostname:port
username和port是可选的(关联@和:),默认是本地用户,端口是22.
ip6格式同样是支持的。例如::1, [::1]:1222, user@2001:db8::1 or user@[2001:db8::1]:1222
##1.2 角色
有时候我们希望给主机分组,这样我们就能方便的控制它们。
1 2 3 from fabric.api import envenv.roledefs['webservers' ] = ['www1' , 'www2' , 'www3' ]
1 2 3 4 5 6 from fabric.api import envenv.roledefs = { 'web' : ['www1' , 'www2' , 'www3' ], 'dns' : ['ns1' , 'ns2' ] }
角色定义并是可必须的,它只是能让我们方便的管理同样功能的服务器组。
#2.如何构建主机列表(host lists) ?
##2.1 四种主机定义方式
###(1)Globally, via env 最常见的方式是通过设置 env: hosts and roles 。
hosts和roles的值会在运行时进行检测,为每个task构造主机列表。
####例子1: fabfile.py
1 2 3 4 5 6 from fabric.api import env, runenv.hosts = ['host1' , 'host2' ] def mytask (): run('ls /var/www' )
执行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # fab mytask [host1] Executing task 'mytask' [host1] run: ls /var/www [host1] out: cgi-bin error html icons [host1] out: [host2] Executing task 'mytask' [host2] run: ls /var/www [host2] out: cgi-bin error html icons [host2] out: Done. Disconnecting from host2... done. Disconnecting from host1... done.
####例子2: 动态设置env.hosts 我们可以在task中设置env.hosts, 它会影响接下来执行的tasks
1 2 3 4 5 6 7 from fabric.api import env, run def set_hosts(): env.hosts = ['host1', 'host2'] def mytask(): run('ls /var/www')
执行命令:
fab set_hosts mytask
跟例子1是一样的效果。
###(2)Globally, via the command line 你可在在模块中通过 env.hosts, env.roles, env.exclude_hosts 来定义主机,也可以通过命令行参数 hosts/-H 和 –roles/-R 来定义主机。
例如:
$ fab -H host1,host2 mytask
非常重要的一点是:
命令行参数会在fabfile文件载入方前被解释,所以fabfile文件中定义的env.hosts or env.roles会覆盖命令行参数。 如果你想合并它们,让在fabfile中使用 env.hosts.extend() 代替。
1 2 3 4 5 6 from fabric.api import env, runenv.hosts.extend(['host3' , 'host4' ]) def mytask (): run('ls /var/www' )
执行: fab -H host1,host2 mytask, 主机会包括: [‘host1’, ‘host2’, ‘host3’, ‘host4’]
###(3)Per-task, via the command line 对每个task, 使用命令行定义hosts。
1 2 3 4 from fabric.api import run def mytask(): run('ls /var/www')
为mytask定义主机
$ fab mytask:hosts="host1;host2"
这个会覆盖所有的主机列表,mytask只会在host1;host2中执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 $ cat fabfile.py from fabric.api import env, run def mytask(): run('ls /var/www' ) $ fab mytask:hosts="host1;host2" [host1] Executing task 'mytask' [host1] run: ls /var/www [host1] out: cgi-bin error html icons [host1] out: [host2] Executing task 'mytask' [host2] run: ls /var/www [host2] out: cgi-bin error html icons [host2] out: Done. Disconnecting from host2... done . Disconnecting from host1... done .
###(4)Per-task, via decorators
可以针对每一个task, 可以使用 hosts 或 roles decorators。
1 2 3 4 5 6 from fabric.api import hosts, run@hosts('host1' , 'host2' ) def mytask (): run('ls /var/www' )
或者这样定义
1 2 3 4 my_hosts = ('host1', 'host2') @hosts(my_hosts) def mytask(): run('ls /var/www')
##2.2 主机定义的优先顺序
官方说明: Order of precedence
Per-task, command-line host lists (fab mytask:host=host1) override absolutely everything else.
Per-task, decorator-specified host lists (@hosts(‘host1’)) override the env variables.
Globally specified host lists set in the fabfile (env.hosts = [‘host1’]) can override such lists set on the command-line, but only if you’re not careful (or want them to.)
Globally specified host lists set on the command-line (–hosts=host1) will initialize the env variables, but that’s it.
说明:
Per-task, command-line host lists (fab mytask:host=host1) 会绝对覆盖所有的hosts定义。
Per-task, decorator-specified host lists (@hosts(‘host1’)) 会覆盖 env 变量(env variables)。
Globally specified host lists set in the fabfile (env.hosts = [‘host1’]) 会覆盖command-lin定义的主机列表。
Globally specified host lists set on the command-line (–hosts=host1) 会初始化env 变量(env variables), 但仅仅如此。
##2.3 测试 ###2.3.1 测试1
1 2 3 4 5 6 from fabric.api import env, hosts, runenv.hosts = ['host1' ] def mytask (): run('ls /var/www' )
执行命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # fabfile定义的env.hosts会覆盖命令行的定义(-H) [root@fabserver fabric]# fab -H host2 mytask [host1] Executing task 'mytask' [host1] run: ls /var/www [host1] out: cgi-bin error html icons [host1] out: Done. Disconnecting from host1... done. # 命令行task里面的主机定义会覆盖掉"fabfile定义的env.hosts"及"命令行里的定义(-H)" [root@fabserver fabric]# fab -H host2 mytask:hosts=host3 [host3] Executing task 'mytask' [host3] run: ls /var/www [host3] out: cgi-bin error html icons [host3] out: Done. Disconnecting from host3... done.
###2.3.2 测试2
1 2 3 4 5 6 7 from fabric.api import env, hosts, run env.hosts = ['host1'] @hosts('host2') def mytask(): run('ls /var/www')
执行命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 [root@fabserver fabric] [host2] Executing task 'mytask' [host2] run: ls /var/www [host2] out: cgi-bin error html icons [host2] out: Done. Disconnecting from host2... done . [root@fabserver fabric] [host2] Executing task 'mytask' [host2] run: ls /var/www [host2] out: cgi-bin error html icons [host2] out: Done. Disconnecting from host2... done . [root@fabserver fabric] [host2] Executing task 'mytask' [host2] run: ls /var/www [host2] out: cgi-bin error html icons [host2] out: Done. Disconnecting from host2... done . [root@fabserver fabric] [host1] Executing task 'mytask' [host1] run: ls /var/www [host1] out: cgi-bin error html icons [host1] out: Done. Disconnecting from host1... done .
#3. 其它
##3.1 合并主机列表
1 2 3 4 5 6 7 8 9 from fabric.api import env, hosts, roles, runenv.roledefs = {'role1' : ['host2' , 'host3' ]} @hosts('host1' , 'host2' ) @roles('role1' ) def mytask (): run('ls /var/www' )
执行mytask时,[host1,host2,host3]都会执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [root@fabserver fabric] [host1] Executing task 'mytask' [host1] run: ls /var/www [host1] out: cgi-bin error html icons [host1] out: [host2] Executing task 'mytask' [host2] run: ls /var/www [host2] out: cgi-bin error html icons [host2] out: [host3] Executing task 'mytask' [host3] run: ls /var/www [host3] out: cgi-bin error html icons [host3] out: Done. Disconnecting from host2... done . Disconnecting from host3... done . Disconnecting from host1... done .
##3.2 重复的主机 fabric会删除重复的host, 所以对于每个task,每个host只会执行一次。 如果不需要删除重复的主机,请设置 env.dedupe_hosts 为 False.
例如,下面的host2会执行两次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 [root@fabserver fabric] from fabric.api import env, hosts, roles, run env.roledefs = {'role1' : ['host2' , 'host3' ]} env.dedupe_hosts = False @hosts('host1' , 'host2' ) @roles('role1' ) def mytask(): run('ls /var/www' ) [root@fabserver fabric] [host1] Executing task 'mytask' [host1] run: ls /var/www [host1] out: cgi-bin error html icons [host1] out: [host2] Executing task 'mytask' [host2] run: ls /var/www [host2] out: cgi-bin error html icons [host2] out: [host2] Executing task 'mytask' [host2] run: ls /var/www [host2] out: cgi-bin error html icons [host2] out: [host3] Executing task 'mytask' [host3] run: ls /var/www [host3] out: cgi-bin error html icons [host3] out: Done. Disconnecting from host2... done . Disconnecting from host3... done . Disconnecting from host1... done .
##3.3 不包含指定的主机 在命令行中使用 –exclude-hosts/-x 定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 [root@fabserver fabric] from fabric.api import env, hosts, roles, run env.roledefs = {'role1' : ['host2' , 'host3' ]} @hosts('host1' , 'host2' ) @roles('role1' ) def mytask(): run('ls /var/www' ) [root@fabserver fabric] [host1] Executing task 'mytask' [host1] run: ls /var/www [host1] out: cgi-bin error html icons [host1] out: [host2] Executing task 'mytask' [host2] run: ls /var/www [host2] out: cgi-bin error html icons [host2] out: [host3] Executing task 'mytask' [host3] run: ls /var/www [host3] out: cgi-bin error html icons [host3] out: Done. Disconnecting from host2... done . Disconnecting from host3... done . Disconnecting from host1... done . [root@fabserver fabric] [host2] Executing task 'mytask' [host2] run: ls /var/www [host2] out: cgi-bin error html icons [host2] out: [host3] Executing task 'mytask' [host3] run: ls /var/www [host3] out: cgi-bin error html icons [host3] out: Done. Disconnecting from host2... done . Disconnecting from host3... done .
注意: Host exclusion lists 跟 host lists 一样,是不能在不同的级别(level)合并在一起的。
例如:全局的 -x 选项不会影响到per-task host list 设置的。同样的per-task的exclude_hosts会影响全局的-H 定义的主机列表。
##3.4 使用execute智能执行task ###3.4.1 智能执行task
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from fabric.api import env, run, roles, execute env.roledefs = { 'db': ['host1', 'host2'], 'web': ['host3'], } @roles('db') def migrate(): # Database stuff here. pass @roles('web') def update(): # Code updates here. pass def deploy(): execute(migrate) execute(update)
执行 $ fab migrate update 和 $ fab deploy 是一样的效果。
1 2 3 4 5 6 7 8 9 10 11 12 [root@fabserver fabric] [host1] Executing task 'migrate' [host2] Executing task 'migrate' [host3] Executing task 'update' Done. [root@fabserver fabric] [host1] Executing task 'migrate' [host2] Executing task 'migrate' [host3] Executing task 'update' Done.
###3.4.2 动态设置主机列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from fabric.api import run, execute, taskfrom mylib import external_datastoredef do_work (): run("something interesting on a host" ) @task def deploy (lookup_param ): host_list = external_datastore.query(lookup_param) execute(do_work, hosts=host_list)
发布到app服务主机
$ fab deploy:app
发布到db服务主机
$ fab deploy:db