1.fabric3的安装
1.1 安装fabric
pip3 install fabric3
1.2 确认安装
python -c "import fabric"
2.fab命令行参数
-l 查看fabric的任务列表
-f 指定入口文件名,默认fabfile.py
-g 指定网关设备,比如堡垒机环境下堡垒机的ip。guarantee
-H 指定目标服务器,通过";"分隔多个服务器
-P 并行的方式运行任务,默认是串行
-R 以角色区分不同的服务
-t 超时时间(s)
-w 命令执行失败的警告,默认是终止任务
-- Fabric提供的便捷方式,不需要编写代码,直接在命令中执行远程操作输入,如:-- \'ifconfig\'
3.env字典
# 常见配置
env.hosts 定义目标服务器列表
env.exclude_hosts 排除特定服务器
env.user SSH远程服务器的用户名
env.port 远程服务器端口
env.key_filename 私钥文件的地址
env.password SSH远程服务器的密码
env.reject_unknown_hosts控制未知host行为,默认会True(相当于:ssh -o StrictHostKeyChecking=no)
4.fabric提供的API
run 执行远程服务器的命令
返回终端输出
result.failed 是一个布尔值,表示命令执-行失败
sudo 以sudo的方式执行远程服务器命令
伪终端:执行命令后常驻的服务进程,比如启动redis后,需要设置pty=False
local 执行本地命令
get 从远程服务器获取文件
get(remote_path="远程文件路径", local_path=\'本地文件路径\')
put 向远程服务器上传文件
put("本地文件所在路径", "远程文件所在路径", mode=0755) # mode执行远程文件的权限
reboot 重启服务器, reboot(wait=30) 延迟关机
prompt 交互式获取输入信息
5.Fabric提供的上下文管理器
# 通过with来调用
cd 切换远程目录
lcd 切换本地目录
path 配置远程服务器PTAH环境变量,只对当前的会话有用
append 将给定路径添加至PATH后面
prepend 将给定的路径添加至PATH前面
replace 替换当前环境的PATH环境变量
prefix 在指定命令后执行多个命令
示例:
with cd(\'/path/to/app\'):
with prefix("workon myvenv")
run("./manage.py syncdb")
run("./manage.py loaddata myfixture")
相当于:
cd /path/to/app && workon myvenv && ./manage.py syncdb
cd /path/to/app && workon myvenv && ./manage.py loaddata myfixture
shell_env 设置shell脚本的环境变量
settings 通用设置,临时覆盖env设置
remote_tunnel 通过ssh端口转发通道
示例:
with remote_tunnel(3306):
run(\'mysql -u root -p password\')
hide 隐藏指定类型的输出
示例:
with hide("running", "stdout", "stderr"):
run("ls /var/www")
选项:
status 状态信息,比如服务器断开连接,ctrl+c等
aborts 终止信息
warnings 警告信息
runnings 运行过程中的输出
stdout 执行shell的标准输出
stderr 执行shell的错误输出
user 用户输出,类似print
封装:
output
stdout/stderr
everything
stdout/stderr/warnings/running/user
commands
stdout/running
示例:
# fabric执行命令失败时默认会中止后续命令,warn_only=True设置可以打印警告信息,但是不中止。
settings(hide("everything"), warn_only=True)
6.fabric提供的装饰器
# 控制如何执行具体操作
1.@task 显式定义任务,没有该装饰器则不能通过fab调用
2.@hosts("host1", "host2")
指定远程服务器的方式:
a.env
b.fab -H
c.@hosts
3.@role 定义服务器角色
# role的定义保存在env.roledef中
from fabric import env
env.roledefs["webservers"] = [
"www1",
"www2",
"www3",
]
或者:
env.roledefs = {
"web": [\'www1\', \'www2\', \'www3\'],
"db": [\'db1\', \'db2\', \'db3\']
}
@roles(\'db\')
def migrate():
pass
@roles(\'web\')
def update():
pass
4.@parallel装饰器 设置并行任务
5.@runs_once 防止task多次调用,比如:上传本地打包文件至多个服务器,而本地打包的操作只需要执行一次。
6.@serial 强制task串行执行
即便做了其他并行设置,都不生效。
7.并行执行任务
# fabric默认是串行的
1.fab -P(--parallel)
2.env.parallel设置是否并行
3.@parallel装饰器
8.其他功能函数
1.execute()函数,传入任务名称from fabric.api import run, role, execute env.roledefs = { "db": ["db1", "db2"], "web": ["web1", "web2", "web3"] } @roles("db") def migrate(): pass @roles("web") def update(): pass def deploy(): execute(migrate) execute(update)2.util函数
from fabric.utils import abort, warn, puts
abort # 中止函数执行,打印错误信息到stderr,并且以退出码为1退出;
warn # 输出警告信息,但是不会中止函数执行;
puts # 打印输出,类似print();
3.带颜色终端输出
from fabric.colors import blue, cyan, green, magenta, red, white, yellow
print(green("绿色的输出!"))
9.简单示例
# fabric_demo.pyfrom fabric.api import * from fabric.contrib.console import confirm from fabric.context_managers import * # 1.服务器信息 env.user = \'root\' env.hosts = [\'192.168.44.131\'] env.password = \'password\' # 2.打包本地文件 @runs_once def tar_task(): with lcd(\'/home/mkl/Desktop/tesu_pros/base_drm/\'): local("sudo tar -zcf base_drm.tar.gz *") # 3.上传文件 @task def put_task(): run("mkdir -p /root/base_drm") with cd("/root/base_drm"): with settings(warn_only=True): result = put("/home/mkl/Desktop/tesu_pros/base_drm/base_drm.tar.gz", "/root/base_drm/base_drm.tar.gz") if result.failed and not confirm("put file failed.Continue[Y/N]?"): abort("Aborting file put task!") # 出现异常,确认用户是否继续 # 4.检测文件 def check_task(): with settings(warn_only=True): lmd5 = local(\'md5sum /home/mkl/Desktop/tesu_pros/base_drm/base_drm.tar.gz\', capture=True).split(\' \')[0] rmd5 = run(\'md5sum /root/base_drm/base_drm.tar.gz\').split(\' \')[0] if lmd5 == rmd5: prompt("OK") else: prompt("ERROR") # 5.执行任务 @task def go(): tar_task() put_task() check_task()# 终端执行命令
fab -f fabric_demo.py go
10.本地执行fab命令,并且获取终端输出
import os ret = os.popen("fab -f Linux.py run_cmd") print(ret.read())