执行模式

  • 执行模式可以让你在多个主机上执行多个任务。

执行策略:

  • 默认fabric是单个有序地执行方法,其行为如下:

1. 创建一系列任务,通过fab任务执行要执行的任务;

2. 根据主机列表定义,去执行每一个任务;

3. 没有主机定义的任务,将在本地执行一次。

如:

from fabric.api import run, env

env.hosts = ['host1', 'host2']

def taskA():
run('ls') def taskB():
run('whoami') # 将在host1, host2都执行taskA, taskB
$ fab taskA taskB # 执行顺序如下
taskA executed on host1
taskA executed on host2
taskB executed on host1
taskB executed on host2

定义任务:

  • 如何定义任务,详情可见这里

定义主机列表:

  • 大多数时候你都需要根据目标,来定义多个远程主机,而不是仅在本地。

主机:

  • python定义的主机字符串为:
username@hostname:port #用户名和端口都可以省略
  • 主机定义也支持IPV6格式,如:
::1, [::1]:1222
user@2001:db8::1
user@[2001:db8::1]:1222

角色:

  • 角色提供了可以定义一个字符串对应于一组主机列表,而不是每次都针对的是整个主机列表,如:
from fabric.api import env
#假如www1, www2, www3是你的web服务器, 你可以指定任务由特定的角色来执行
env.roledefs['webservers'] = ['www1', 'www2', 'www3'] # 定义多个角色
env.roledefs = {
'web': ['www1', 'www2', 'www3'],
'dns': ['ns1', 'ns2']
}

怎么构建hosts:

  • 通过全局的env:
from fabric.api import env, run

env.hosts = ['host1', 'host2']

def mytask():
run('ls /var/www')
  • env配置会被每个任务检查,因此你完全可以在方法中设置env,如:
from fabric.api import env, run

def set_hosts():
env.hosts = ['host1', 'host2'] def mytask():
run('ls /var/www') # 调用
fab set_hosts mytask, set_hosts
  • 通过命令行参数指定:
$ fab -H host1,host2 mytask #会被env.hosts所重写,类似角色也可以通过-R role1, role2, ...来定义
  • 你也可以扩展命令行定义的主机,如:
from fabric.api import env, run

env.hosts.extend(['host3', 'host4'])

def mytask():
run('ls /var/www') # 那么执行主机将merge为host1,host2,host3,host4
fab -H host1, host2 mytask
NOTE: env.hosts是python的list对象,所以你可以用list.append()方法添加host,或者其他方法。
  • 针对每个任务的命令行参数:这是fabric提供一种更细粒度的定制:
from fabric.api import run

def mytask():
run('ls /var/www') # 该定义将重写其他任何hosts定义,mytask仅会在host1,host2上执行
fab mytask:hosts="host1;host2"
  • 针对每个任务进行修饰:
from fabric.api import hosts, run

@hosts('host1', 'host2')
def mytask():
run('ls /var/www') # 或者
my_hosts = ('host1', 'host2')
@hosts(my_hosts)
def mytask():
# ... # 这种修饰将重写env.hosts设置, 但不会重写上面通过命令行定义的任务。
  • 总结下上面这些host与task绑定定义的优先级:
# 由高到低
1. 命令行 fab mytask:host=host1
2. fabfile中修饰任务@hosts('host1')
3. 在fabfile中设置env.hosts = ['host1']
4. 在命令行中-H host1,host2,...
  • 主机列表组合
from fabric.api import env, hosts, roles, run

env.roledefs = {'role1': ['b', 'c']}

@hosts('a', 'b')
@roles('role1')
def mytask():
run('ls /var/www') # 若命令行不包含task定义,则上面的mytask家在a, b, c主机上执行
  • 排除特定的主机
# 若myrole被定义运行[host1, host2,...,host15], 则该命令将排除host2,host5
$ fab -R myrole -x host2,host5 mytask #该-x并不会修改env.hosts

用Execute智能地执行任务:

  • 看这么一个例子:
from fabric.api import run, roles

env.roledefs = {
'db': ['db1', 'db2'],
'web': ['web1', 'web2', 'web3'],
} @roles('db')
def migrate():
# Database stuff here.
pass @roles('web')
def update():
# Code updates here.
pass # 在fabric1.2之前,我们需要fab migrate update来执行这两个任务,
# 在fabric1.2之后,我们可以通过execute函数来执行这两个任务: from fabric.api import run, roles, execute def deploy():
execute(migrate)
execute(update)

通过Execute访问多主机的结果:

  • 一个范例
from fabric.api import env, roles, task, execute, run, runs_once

env.roledefs = {
'zoo': ['zooserver'],
'mysql': ['mysqlmaster'],
} @task
def workhorse():
return run("uname -a") @roles('zoo')
@task
@runs_once
def go():
results = execute(workhorse)
print results #执行
fab go

用Execute动态设置host列表:

  • 我们可以通过传递参数,动态设置hosts,如:
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) # 调用
fab deploy:app
fab deploy:other
  • 一个替代的方法:
from fabric.api import run, task

from mylib import external_datastore

# Marked as a publicly visible task, but otherwise unchanged: still just
# "do the work, let somebody else worry about what hosts to run on".
@task
def do_work():
run("something interesting on a host") @task
def set_hosts(lookup_param):
# Update env.hosts instead of calling execute()
env.hosts = external_datastore.query(lookup_param) #调用
fab set_hosts:app do_work #相比上一种方法,该方法可以轻易替换其他任务,如
fab set_hosts:db snapshot
fab set_hosts:cassandra,cluster2 repair_ring
fab set_hosts:redis,environ=prod status

故障处理:

  • 故障处理也是一个比较实用的东西,fabric默认是"快速失败"的,一旦出现错误,就立即停止。
  • 我们可以通过settings上下文中的env.warn_only=True来临时指定,失败也继续执行。

连接:

  • fab本身是不对任何主机做远程连接的,她只会设置env.host_string的值(即当前的host)。
  • NOTE: 连接对象Connection会保存在fabric.state.connections中,并做缓存,以减少创建新连接的消耗。

懒连接:

  • fab在执行远程操作前,并不会事先去连接远程主机,如:
from fabric.api import *

@hosts('host1')
def clean_and_upload():
local('find assets/ -name "*.DS_Store" -exec rm '{}' \;')
local('tar czf /tmp/assets.tgz assets/')
put('/tmp/assets.tgz', '/tmp/assets.tgz') //这里才会开始进行远程连接相关的操作:cache.get() == null?new : cache.get()
with cd('/var/www/myapp/'):
run('tar xzf /tmp/assets.tgz')

关闭连接:

  • 连接缓存并不会关闭连接。fab工具会帮你管理连接,它会遍历所有连接,并在其退出前关闭连接。你也可以调用fabric.network.disconnect_all()来确保关闭所有连接。

多次连接尝试和跳过错误的主机:

密码管理:

  • Fabric在内存中维护了两层的密码缓存管理,会记住你登录的密码和sudo时的密码,以免以后再次输入。
  • 第一层密码由 env.password保存,其值为ssh默认密码或sudo提示输入密码。第二层密码保存在env.passwords中,主要用于缓存user/host/port:password。
  • Fabric还是建议使用密钥进行ssh访问,如无密登录。

使用本地的SSH配置文件:

  • 你可以为Fabric指定特定的ssh配置文件(--ssh-config-path/env.ssh_config_path.),但默认Fabric并没有开启加载配置文件,需要设置env.use_ssh_config为True。
  • 若开启了Fabric加载配置文件的选项,则Fabric为使用以下一些配置项:

User/Port ,HostName, IdentityFile, ForwardAgent, ProxyCommand。

具体参考可见:

http://docs.fabfile.org/en/1.9/usage/execution.html

python之fabric(二):执行模式(转)的更多相关文章

  1. 研磨设计模式解析及python代码实现——(二)外观模式(Facade)

    一.外观模式定义 为子系统中的一组接口提供一个一致的界面,使得此子系统更加容易使用. 二.书中python代码实现 class AModuleApi: def testA(self): pass cl ...

  2. jvm内存结构(二)(栈的变化,机器指令的格式/执行模式)

    栈的结构: <Java虚拟机原理图解>4.JVM机器指令集 局部变量表: 方法执行时,虚拟机会把字节码中方法数据区的code类型的属性中的局部变量放到栈的局部变量表中. 操作栈: jvm指 ...

  3. python设计模式之常用创建模式总结(二)

    前言 设计模式的创建模式终极目标是如何使用最少量最少需要修改的代码,传递最少的参数,消耗系统最少的资源创建可用的类的实例对象. 系列文章 python设计模式之单例模式(一) python设计模式之常 ...

  4. python使用Fabric模块实现自动化运维

    简介:Fabric是基于Python实现的SSH命令行工具,简化了SSH的应用程序部署及系统管理任务,它提供了系统基础的操作组件,可以实现本地或远程shell命令,包括:命令执行.文件上传.下载及完整 ...

  5. 编程语言与Python学习(二)

    1.1 流程控制之for循环 1 迭代式循环:for,语法如下 for i in range(10): 缩进的代码块 2 break与continue(同上) 3 循环嵌套 for i in rang ...

  6. Python进阶(十二)----re模块

    Python进阶(十二)----re模块 一丶re模块 ​ re模块是python将正则表达式封装之后的一个模块.正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行. #正则表达式: ...

  7. python排序之二冒泡排序法

    python排序之二冒泡排序法 如果你理解之前的插入排序法那冒泡排序法就很容易理解,冒泡排序是两个两个以向后位移的方式比较大小在互换的过程好了不多了先上代码吧如下: 首先还是一个无序列表lis,老规矩 ...

  8. CDC不同模式在ODI体现系列之二 异步模式

    CDC不同模式在ODI体现系列之二 异步模式 2 异步模式需要在数据库中做一些准备工作: 改数据为归档并启用logminer: SQL> shutdown immediate 数据库已经关闭. ...

  9. Python 数据分析(二 本实验将学习利用 Python 数据聚合与分组运算,时间序列,金融与经济数据应用等相关知识

    Python 数据分析(二) 本实验将学习利用 Python 数据聚合与分组运算,时间序列,金融与经济数据应用等相关知识 第1节 groupby 技术 第2节 数据聚合 第3节 分组级运算和转换 第4 ...

随机推荐

  1. RBL开发笔记一

    从这个系列开始  陆续记录整个RBL开发的过程   废话不多说   直入主题 10:54:53   2014-08-25 今天开发任务: RBL.h  的框架搭建出来   包括RBLServer RB ...

  2. 《深入浅出Node.js》第4章 异步编程

    @by Ruth92(转载请注明出处) 第4章 异步编程 Node 能够迅速成功并流行起来的原因: V8 和 异步 I/O 在性能上带来的提升: 前后端 JavaScript 编程风格一致 一.函数式 ...

  3. 如何快速编写Vim语法高亮文件

    这里有一份中文的入门文档,但是太长了,不想读,所以有本文 最快的办法,就是找一个语法相近的语法高亮文件,稍微改一下 自己从头写的话,首先搞定关键字: syntax case match "是 ...

  4. read.csv 把 "T" 读成 "TRUE" 的问题

    read.csv(text="A,B,T,T", header=FALSE) ## V1 V2 V3 V4 ## 1 A B TRUE TRUE RT, 有的时候R读取数据的时候容 ...

  5. 《Android深度探索》(卷1)HAL与驱动开发读后感

    第1章:安卓系统移植与驱动开发概述 这一章主要概括的介绍了安卓驱动开发和系统移植的主要内容,对安卓与Linux驱动做了一个总体的介绍.通过对第一章的学习,使我对Linux驱动开发有了一个感性的认识.在 ...

  6. 2015.12.29~2015.12.30真题回顾!-- HTML5学堂

    2015.12.29~2015.12.30真题回顾!-- HTML5学堂 吃饭,能够解决饥饿,提供身体运作机能.练习就像吃饭,强壮自己,提升编程技能,寻求编程技巧的最佳捷径!吃饭不能停,练习同样不能停 ...

  7. MFC 中编辑框数字限制范围

    http://www.cnblogs.com/ziwuge/archive/2011/11/15/2249541.html void CSAAlt::OnEnChangeSlocp()//样本盘号输入 ...

  8. SQL Server Profiler工具

    一.SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 图形化监视SQL Server查询: 在后台收集查询信息: 分析性能: 诊断像死锁之类的问 ...

  9. ASP.NET 下拉列表绑定枚举类型值,不用再新建一个枚举表

    public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArg ...

  10. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十四)之漏掉的客服消息

    前言 不知不觉已经十四篇了,其实已经没有什么可写了.但是突然发现layim中带的客服功能没有用到.于是乎,抽点时间完成吧.其实之前的工作已经把客服功能完成了一大半,剩下的我们稍微调整即可.今天的演示我 ...