推荐 远程部署 fabric
自己写的一个例子:
from fabric.api import run, env env.hosts = ['nanjing','hefei','haerbin','lanzhou','taiyuan','changchun']
env.user = 'lmdata'
env.password = 'lmdata' def uptime():
#run('ls -l /mnt/lustre/')
run('uptime')
可以监控各个集群的性能,当然他的功能远不止此,还有很多很强大的技能,原文: Python 远程部署利器 Fabric 详解
可以去原网址看,以下内容纯属备份,以防原文被删。
Python 远程部署利器 Fabric 详解
Fabric 是一个 Python 的库,它提供了丰富的同 SSH 交互的接口,可以用来在本地或远程机器上自动化、流水化地执行 Shell 命令。因此它非常适合用来做应用的远程部署及系统维护。其上手也极其简单,你需要的只是懂得基本的 Shell 命令。本文将为大家详细介绍 Fabric 的使用。
内容索引
安装 Fabric
首先 Python 的版本必须是 2.7 以上,可以通过下面的命令查看当前 Python 的版本:
$ python -V
Fabric 的官网是 www.fabfile.org,源码托管在 Github 上。你可以 clone 源码到本地,然后通过下面的命令来安装。
$ python setup.py develop
在执行源码安装前,你必须先将 Fabric 的依赖包 Paramiko 装上。所以,个人还是推荐使用 pip 安装,只需一条命令即可:
$ pip install fabric
第一个例子
万事从 Hello World 开始,我们创建一个”fabfile.py” 文件,然后写个 hello 函数:
|
1
2
|
def hello():
print "Hello Fabric!"
|
现在,让我们在”fabfile.py” 的目录下执行命令:
$ fab hello
你可以在终端看到”Hello Fabric!” 字样。
简单解释下,”fabfile.py” 文件中每个函数就是一个任务,任务名即函数名,上例中是”hello”。”fab” 命令就是用来执行”fabfile.py” 中定义的任务,它必须显式地指定任务名。你可以使用参数”-l” 来列出当前”fabfile.py” 文件中定义了哪些任务:
$ fab -l
任务可以带参数,比如我们将 hello 函数改为:
|
1
2
|
def hello(name, value):
print "Hello Fabric! %s=%s" % (name,value)
|
此时执行 hello 任务时,就要传入参数值:
$ fab hello:name=Year,value=2016
Fabric 的脚本建议写在”fabfile.py” 文件中,如果你想换文件名,那就要在”fab” 命令中用”-f” 指定。比如我们将脚本放在”script.py” 中,就要执行:
$ fab -f script.py hello
执行本地命令
“fabric.api” 包里的”local()” 方法可以用来执行本地 Shell 命令,比如让我们列出本地”/home/bjhee” 目录下的所有文件及目录:
|
1
2
3
4
|
from fabric.api import local
def hello():
local('ls -l /home/bjhee/')
|
“local()” 方法有一个”capture” 参数用来捕获标准输出,比如:
|
1
2
|
def hello():
output = local('echo Hello', capture=True)
|
这样,Hello 字样不会输出到屏幕上,而是保存在变量 output 里。”capture” 参数的默认值是 False。
执行远程命令
Fabric 真正强大之处不是在执行本地命令,而是可以方便的执行远程机器上的 Shell 命令。它通过 SSH 实现,你需要的是在脚本中配置远程机器地址及登录信息:
|
1
2
3
4
5
6
7
8
|
from fabric.api import run, env
env.hosts = ['example1.com', 'example2.com']
env.user = 'bjhee'
env.password = '111111'
def hello():
run('ls -l /home/bjhee/')
|
“fabric.api” 包里的”run()” 方法可以用来执行远程 Shell 命令。上面的任务会分别到两台服务器”example1.com” 和”example2.com” 上执行”ls -l /home/bjhee/” 命令。这里假设两台服务器的用户名都是”bjhee”,密码都是 6 个 1。你也可以把用户直接写在 hosts 里,比如:
|
1
|
env.hosts = ['bjhee@example1.com', 'bjhee@example2.com']
|
如果你的”env.hosts” 里没有配置某个服务器,但是你又想在这个服务器上执行任务,你可以在命令行中通过”-H” 指定远程服务器地址,多个服务器地址用逗号分隔:
$ fab -H bjhee@example3.com,bjhee@example4.com hello
另外,多台机器的任务是串行执行的,关于并行任务的执行我们在之后会介绍。
如果对于不同的服务器,我们想执行不同的任务,上面的方法似乎做不到,那怎么办?我们要对服务器定义角色:
|
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
|
from fabric.api import env, roles, run, execute, cd
env.roledefs = {
'staging': ['bjhee@example1.com','bjhee@example2.com'],
'build': ['build@example3.com']
}
env.passwords = {
'staging': '11111',
'build': '123456'
}
@roles('build')
def build():
with cd('/home/build/myapp/'):
run('git pull')
run('python setup.py')
@roles('staging')
def deploy():
run('tar xfz /tmp/myapp.tar.gz')
run('cp /tmp/myapp /home/bjhee/www/')
def task():
execute(build)
execute(deploy)
|
现在让我们执行:
$ fab task
这时 Fabric 会先在一台 build 服务器上执行 build 任务,然后在两台 staging 服务器上分别执行 deploy 任务。”@roles” 装饰器指定了它所装饰的任务会被哪个角色的服务器执行。
如果某一任务上没有指定某个角色,但是你又想让这个角色的服务器也能运行该任务,你可以通过”-R” 来指定角色名,多个角色用逗号分隔:
$ fab -R build deploy
这样”build” 和”staging” 角色的服务器都会运行”deploy” 任务了。注:”staging” 是装饰器默认的,因此不用通过”-R” 指定。
此外,上面的例子中,服务器的登录密码都是明文写在脚本里的。这样做不安全,推荐的方式是设置 SSH 自动登录,具体方法大家可以去网上搜搜。
SSH 功能函数
到目前为止,我们介绍了”local()” 和”run()” 函数分别用来执行本地和远程 Shell 命令。Fabric 还提供了其他丰富的功能函数来辅助执行命令,这里我们介绍几个常用的:
- sudo: 以超级用户权限执行远程命令
功能类似于”run()” 方法,区别是它相当于在 Shell 命令前加上了”sudo”,所以拥有超级用户的权限。使用此功能前,你需要将你的用户设为 sudoer,而且无需输密码。具体操作可参见我的这篇文章。
|
1
2
3
4
5
6
7
|
from fabric.api import env, sudo
env.hosts = ['bjhee@example1.com', 'bjhee@example2.com']
env.password = '111111'
def hello():
sudo('mkdir /var/www/myapp')
|
- get(remote, local): 从远程机器上下载文件到本地
它的工作原理是基于 scp 命令,使用的方法如下:
|
1
2
3
4
5
6
7
|
from fabric.api import env, get
env.hosts = ['bjhee@example.com',]
env.password = '111111'
def hello():
get('/var/log/myapp.log', 'myapp-0301.log')
|
上述任务将远程机上”/var/log/myapp.log” 文件下载到本地当前目录,并命名为”myapp-0301.log”。
- put(local, remote): 从本地上传文件到远程机器上
同 get 一样,put 方法也是基于 scp 命令,使用的方法如下:
|
1
2
3
4
5
6
7
|
from fabric.api import env, put
env.hosts = ['bjhee@example1.com', 'bjhee@example2.com']
env.password = '111111'
def hello():
put('/tmp/myapp-0301.tar.gz', '/var/www/myapp.tar.gz')
|
上述任务将本地”/tmp/myapp-0301.tar.gz” 文件分别上传到两台远程机的”/var/www/” 目录下,并命名为”myapp.tar.gz”。如果远程机上的目录需要超级用户权限才能放文件,可以在”put()” 方法里加上”use_sudo” 参数:
|
1
|
put('/tmp/myapp-0301.tar.gz', '/var/www/myapp.tar.gz', use_sudo=True)
|
- prompt: 提示输入
该方法类似于 Shell 中的”read” 命令,它会在终端显示一段文字来提示用户输入,并将用户的输入保存在变量里:
|
1
2
3
4
5
6
7
8
|
from fabric.api import env, get, prompt
env.hosts = ['bjhee@example.com',]
env.password = '111111'
def hello():
filename = prompt('Please input file name:')
get('/var/log/myapp.log', '%s.log' % filename)
|
现在下载后的文件名将由用户的输入来决定。我们还可以对用户输入给出默认值及类型检查:
|
1
|
port = prompt('Please input port number:', default=8080, validate=int)
|
执行任务后,终端会显示:
Please input port number: [8080]
如果你直接按回车,则 port 变量即为默认值 8080;如果你输入字符串,终端会提醒你类型验证失败,让你重新输入,直到正确为止。
- reboot: 重启服务器
看方法名就猜到了,有时候安装好环境后,需要重启服务器,这时就要用到”reboot()” 方法,你可以用”wait” 参数来控制其等待多少秒后重启,没有此参数则代表立即重启:
|
1
2
3
4
5
6
7
|
from fabric.api import env, reboot
env.hosts = ['bjhee@example.com',]
env.password = '111111'
def restart():
reboot(wait=60)
|
上面的 restart 任务将在一分钟后重启服务器。
上下文管理器
Fabric 的上下文管理器是一系列与 Python 的”with” 语句配合使用的方法,它可以在”with” 语句块内设置当前工作环境的上下文。让我们介绍几个常用的:
- cd: 设置远程机器的当前工作目录
“cd()” 方法在之前的范例中出现过,”with cd()” 语句块可以用来设置远程机的工作目录:
|
1
2
3
4
5
6
7
8
|
from fabric.api import env, cd, put
env.hosts = ['bjhee@example1.com', ]
env.password = '111111'
def hello():
with cd('/var/www/'):
put('/tmp/myapp-0301.tar.gz', 'myapp.tar.gz')
|
上例中的文件会上传到远程机的”/var/www/” 目录下。出了”with cd()” 语句块后,工作目录就回到初始的状态,也就是”bjhee” 用户的根目录。
- lcd: 设置本地工作目录
“lcd()” 就是”local cd” 的意思,用法同”cd()” 一样,区别是它设置的是本地的工作目录:
|
1
2
3
4
5
6
7
8
9
|
from fabric.api import env, cd, lcd, put
env.hosts = ['bjhee@example1.com', ]
env.password = '111111'
def hello():
with cd('/var/www/'):
with lcd('/tmp/'):
put('myapp-0301.tar.gz', 'myapp.tar.gz')
|
这个例子的执行效果跟上个例子一样。
- path: 添加远程机的 PATH 路径
|
1
2
3
4
5
6
7
8
9
|
from fabric.api import env, run, path
env.hosts = ['bjhee@example1.com', ]
env.password = '111111'
def hello():
with path('/home/bjhee/tmp'):
run('echo $PATH')
run('echo $PATH')
|
假设我们的 PATH 环境变量默认是”/sbin:/bin”,在上述”with path()” 语句块内 PATH 变量将变为”/sbin:/bin:/home/bjhee/tmp”。出了 with 语句块后,PATH 又回到原来的值。
- settings: 设置 Fabric 环境变量参数
Fabric 环境变量即是我们例子中一直出现的”fabric.api.env”,它支持的参数可以从官方文档中查到。
|
1
2
3
4
5
6
7
8
|
from fabric.api import env, run, settings
env.hosts = ['bjhee@example1.com', ]
env.password = '111111'
def hello():
with settings(warn_only=True):
run('echo $USER')
|
我们将环境参数”warn_only” 暂时设为 True,这样遇到错误时任务不会退出。
- shell_env: 设置 Shell 环境变量
可以用来临时设置远程和本地机上 Shell 的环境变量。
|
1
2
3
4
5
6
7
8
9
|
from fabric.api import env, run, local, shell_env
env.hosts = ['bjhee@example1.com', ]
env.password = '111111'
def hello():
with shell_env(JAVA_HOME='/opt/java'):
run('echo $JAVA_HOME')
local('echo $JAVA_HOME')
|
- prefix: 设置命令执行前缀
|
1
2
3
4
5
6
7
8
9
|
from fabric.api import env, run, local, prefix
env.hosts = ['bjhee@example1.com', ]
env.password = '111111'
def hello():
with prefix('echo Hi'):
run('pwd')
local('pwd')
|
在上述”with prefix()” 语句块内,所有的”run()” 或”local()” 方法的执行都会加上”echo Hi && “前缀,也就是效果等同于:
|
1
2
|
run('echo Hi && pwd')
local('echo Hi && pwd')
|
配合后一节我们会讲到的错误处理,它可以确保在”prefix()” 方法上的命令执行成功后才会执行语句块内的命令。
错误处理
默认情况下,Fabric 在任务遇到错误时就会退出,如果我们希望捕获这个错误而不是退出任务的话,就要开启”warn_only” 参数。在上面介绍”settings()” 上下文管理器时,我们已经看到了临时开启”warn_only” 的方法了,如果要全局开启,有两个办法:
- 在执行”fab” 命令时加上”-w” 参数
$ fab -w hello
- 设置”env.warn_only” 环境参数为 True
|
1
2
3
|
from fabric.api import env
env.warn_only = True
|
现在遇到错误时,控制台会打出一个警告信息,然后继续执行后续任务。那我们怎么捕获错误并处理呢?像”run()”, “local()”, “sudo()”, “get()”, “put()” 等 SSH 功能函数都有返回值。当返回值的”succeeded” 属性为 True 时,说明执行成功,反之就是失败。你也可以检查返回值的”failed” 属性,为 True 时就表示执行失败,有错误发生。在开启”warn_only” 后,你可以通过”failed” 属性检查捕获错误,并执行相应的操作。
|
1
2
3
4
5
6
7
8
9
10
11
|
from fabric.api import env, cd, put
env.hosts = ['bjhee@example1.com', ]
env.password = '111111'
def hello():
with cd('/var/www/'):
upload = put('/tmp/myapp-0301.tar.gz', 'myapp.tar.gz')
if upload.failed:
sudo('rm myapp.tar.gz')
put('/tmp/myapp-0301.tar.gz', 'myapp.tar.gz', use_sudo=True)
|
并行执行
我们在介绍执行远程命令时曾提到过多台机器的任务默认情况下是串行执行的。Fabric 支持并行任务,当服务器的任务之间没有依赖时,并行可以有效的加快执行速度。怎么开启并行执行呢?办法也是两个:
- 在执行”fab” 命令时加上”-P” 参数
$ fab -P hello
- 设置”env.parallel” 环境参数为 True
|
1
2
3
|
from fabric.api import env
env.parallel = True
|
如果,我们只想对某一任务做并行的话,我们可以在任务函数上加上”@parallel” 装饰器:
|
1
2
3
4
5
6
7
8
|
from fabric.api import parallel
@parallel
def runs_in_parallel():
pass
def runs_serially():
pass
|
这样即便并行未开启,”runs_in_parallel()” 任务也会并行执行。反过来,我们可以在任务函数上加上”@serial” 装饰器:
|
1
2
3
4
5
6
7
8
|
from fabric.api import serial
def runs_in_parallel():
pass
@serial
def runs_serially():
pass
|
这样即便并行已经开启,”runs_serially()” 任务也会串行执行。
补充
这个部分用来补充 Fabric 的一些特别功能:
- 终端输出带颜色
我们习惯上认为绿色表示成功,黄色表示警告,而红色表示错误,Fabric 支持带这些颜色的输出来提示相应类型的信息:
|
1
2
3
4
5
6
|
from fabric.colors import *
def hello():
print green("Successful")
print yellow("Warning")
print red("Error")
|
- 限制任务只能被执行一次
通过”execute()” 方法,可以在一个”fab” 命令中多次调用同一任务,如果想避免这个发生,就要在任务函数上加上”@runs_once” 装饰器。
|
1
2
3
4
5
6
7
8
9
|
from fabric.api import execute, runs_once
@runs_once
def hello():
print "Hello Fabric!"
def test():
execute(hello)
execute(hello)
|
现在不管我们”execute” 多少次 hello 任务,都只会输出一次”Hello Fabric!” 字样
更多内容请参阅 Fabric 的官方文档。本篇中的示例代码可以在这里下载。
转载请注明出处: 思诚之道
推荐 远程部署 fabric的更多相关文章
- Python 远程部署 Fabric
参考文章:http://zmrenwu.com/post/21/ Fabric是一个Python的库,它提供了丰富的同SSH交互的接口,可以用来在本地或远程机器上自动化.流水化地执行Shell命令.因 ...
- 图文详解远程部署ASP.NET MVC 5项目
话外篇: 由于感觉自己的机器比较慢,配置不好,所以最近想把之前的项目部署到实验室的服务器上,但是由于常不在实验室,所以在想能不能远程部署.因此今天专门研究了一下具体的过程,下面和大家分享一下.本人新手 ...
- 图文详解远程部署ASP.NET MVC 5项目 [转载]
话外篇: 由于感觉自己的机器比较慢,配置不好,所以最近想把之前的项目部署到实验室的服务器上,但是由于常不在实验室,所以在想能不能远程部署.因此今天专门研究了一下具体的过程,下面和大家分享一下.本人新手 ...
- 使用Qt Creator作为Linux IDE,代替Vim:实现两台Linux电脑远程部署和gdb调试(一台电脑有桌面系统,一台电脑无桌面系统)
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/libaineu2004/article/details/62423830 尊重作者,支持原创,如 ...
- WinServer远程部署系统(RDSystem)
系统简介 RemoteDeploySystem是一套BS结构的远程部署管理系统(简称RDSystem),可以通过浏览器上传web站点和windows服务的更新包到RDSystem服务器,然后对多个服务 ...
- WinServer远程部署系统打包批处理文件
前言 工作中一直在使用一个部署系统WinServer远程部署系统(RDSystem),部署.回滚都很方便.我们一直都是增量发布或者只更新需要更新的文件,每次发布完之后要整理出一个增量更新包,压缩成zi ...
- tomcat远程部署应用
Tomcat安装成功后,在ip地址:8080上就可以看见熟悉的首页,在这个首页中,上方有一个manage app按钮,点击就可以进行应用管理了.这样就不需要使用ftp把war包传上去了. 要想远程部署 ...
- 【2016-07-11】Qt远程部署失败,提示"没有那个文件或目录"的解决方法
首先明确一下,这里的部署失败与网络连接.ssh/scp/sftp等无关. 一般出现在删除了远端上的可执行文件,而本地程序未做明显改动时远程部署执行的时候. Qt应用程序输出中的提示信息如下: 究其原因 ...
- 用Maven打包成EAR远程部署JBoss(二)——部署到远程JBoss
用Maven打包成EAR远程部署JBoss(一)讲了如何使用Maven打包,可是在文章的最后也留下了一个问题,那就是如何将包部署到远程的JBoss中呢?近期在对之前的学习进行总结,发现少了这样一篇重要 ...
随机推荐
- Sitemesh 3使用及配置
1:Sitemesh简介 SiteMesh是一个网页布局和修饰的框架,利用它可以将网页的内容和页面结构分离,以达到页面结构共享的目的. SiteMesh是基于Servlet的filter的,即过滤流. ...
- Dubbo学习笔记3:Dubbo管理控制台与监控中心的搭建
Dubbo源码下载与编译 本文来讲下如何在Dubbo源码编译后,得到用于搭建管理控制台的war包和监控平台的jar包. 首先需要到Github上下载Dubbo的源码,解压后如下: 在dubbo-2.5 ...
- bzoj千题计划122:bzoj1034: [ZJOI2008]泡泡堂BNB
http://www.lydsy.com/JudgeOnline/problem.php?id=1034 从小到大排序后 最大得分: 1.自己最小的>对方最小的,赢一场 2.自己最大的>对 ...
- COGS 513 八
513. 八 http://www.cogs.pro/cogs/problem/problem.php?pid=513 ★☆ 输入文件:eight.in 输出文件:eight.out 简单 ...
- 高性能流媒体服务器EasyDarwin
标准RTSP拉模式直播(EasyRelayModule):适合内部监控 分布式部署(EasyCMSModule):负载均衡主要是用Reids作为负载
- linux netstat查看服务和端口状态
netstat可以查看linux系统中正在使用的服务和端口情况 常见参数 -a (all)显示所有选项,默认不显示LISTEN相关-t (tcp)仅显示tcp相关选项-u (udp)仅显示udp相关选 ...
- plsql developer导入数据库
需要指向导入命令
- VBscript.Encode 解码器
VBscript.Encode 解码器 此解码器算法来至互联网,我只是收集然后写了个简单的页面便于大家使用. 如有何不妥之处,请留言.
- sort函数(cmp)、map用法---------------Tju_Oj_2312Help Me with the Game
这道题里主要学习了sort函数.sort的cmp函数写法.C++的map用法(其实和数组一样) Your task is to read a picture of a chessboard posit ...
- POJ 1185 炮兵阵地 (状态压缩DP)
题目链接 Description 司令部的将军们打算在NM的网格地图上部署他们的炮兵部队.一个NM的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用& ...