Fabric
Fabric是一个python的远程执行shell的库,同时它也是一个命令行工具。它提供了丰富的同 SSH 交互的接口,可以用来在本地或远程机器上自动化、流水化地执行 Shell 命令。
安装Fabric
Fabric的官网是 www.fabfile.org,源码托管在Github上。你可以clone源码到本地,然后通过下面的命令来安装。但是在源码安装前,你必须先将Fabric的依赖包Paramiko装上。
python setup.py develop
同时也可以使用pip安装,因为fabric是python的一个第三方库,只需一条命令即可:
pip install fabric
python3 安装时使用的是fabric3 :( 安装fabric3之前,需要先卸载fabric.)
# fabric3 支持 python3
pip uninstall fabric
pip3 install fabric3
fabric 不只是一个Python 模块,fabric 还是一个命令行工具,可以使用fab -h查看帮助信息
E:\my_data\hk-project>fab -V
Fabric3 1.14.post1
Paramiko 2.4.2
E:\my_data\hk-project>fab -h
入门使用
fabric的使用方式是通过编写一个python文件,该文件中包含多个函数,然后使用fab命令调用这些函数,做相应的任务。这些函数在fabric中称为task。
# filename:abc.py
from fabric.api import *
def task1():
print("hello")
def hello():
print("hello world")
写好这个python文件后,在当前目录的路径下使用fab工具执行文件中的函数
[root@localhost python文件所在的目录]# fab -f abc.py hello
hello world
# -f 指定fabfile文件,默认为fabfile.py,若文件名是当前目录下的fabfile.py则无需指定
任务参数
此时你可能会想,如果这个函数有参数怎么办呢?应该如何传递参数给函数呢?Fabric 支持 Shell 兼容的参数用法: <任务名>:<参数>, <关键字参数名>=<参数值>,...
用起来就是这样。
def hello(name="world"):
print("hello {}".format(name))
我们可以这样去指定参数
$ fab hello:name=Jeff # 或者 fab hello:Jeff
hello Jeff
Done.
小试牛刀
现在我们假设需要写一个fabfile.py,能够在每次web项目代码更新后使用git提交并远程服务器拉去最新代码并运行,需求描述清楚了,开干吧!
# fabfile.py
# 这里建议将该文件放入项目文件的根目录中,方便git提交
from fabric.api import local
def test():
local('python manage.py test myapp')
# 测试是否能正常运行
def commit():
local('git add -p && git commit -m "for test"')
def push():
local('git push')
def prepare_deploy():
test()
commit()
push()
这个 prepare_deploy
任务可以单独调用,也可以调用更细粒度的子任务。
故障
Fabric 会检查被调用程序的返回值,如果这些程序没有干净地退出,Fabric 会终止操作。我们什么都不用做,Fabric 检测到了错误并终止,不会继续执行 commit 任务。
我们也可以对故障进行一定的处理和判断
from fabric.api import local, settings, abort
from fabric.contrib.console import confirm
def test():
with settings(warn_only=True):
result = local('./manage.py test my_app', capture=True)
# result.return_code返回码(0/1)和result.failed
if result.failed and not confirm("Tests failed. Continue anyway?"): # confirm判断用户输入
abort("Aborting at user request.") # 指定错误退出信息
# 一个名为 warn_only 的设置(或着说 环境变量 ,通常缩写为 env var )可以把退出换为警告,以提供更灵活的错误处理。如果设置为False,则一条命令运行失败会就会退出,不再执行后面的命令。
建立连接
终于到了连接了,这个工具主要作用就是在远程执行命令呀,学会了这个,我们就可以在本地执行远程服务器的命令了。
from fabric.api import *
env.hosts = ['root@192.168.10.11:22']
def deploy():
run('ls') # run()用于执行远程命令,local()执行本地命令
# 执行后会提示你输入密码,输入密码即可
使用fabric安装lamp
# 采用ThreadingGroupd对象并发执行
from fabric import ThreadingGroup as Group
hosts = (
"root@192.168.10.50", "root@192.168.10.51"
)
group = Group(*hosts, connect_kwargs={"password": "abc123"})
print("自动安装LAMP ......")
# 安装Apache服务器
group.run("yum install httpd -y")
# 安装并启动MariaDB服务器
group.run("yum install mariadb mariadb-server -y")
group.run("systemctl start mariadb")
group.run("systemctl enable mariadb")
# 以非交互方式运行MariaDB数据库安全配置向导
group.run("echo -e '\ny\nabc123\nabc123\ny\ny\ny\ny\n' | /usr/bin/mysql_secure_installation")
# 安装PHP
group.run(
"yum install pcre gcc-c++ zlib* php php-mysqlnd php-gd libjpeg* php-ldap php-odbc php-pear php-xml* php-json php-mbstring php-bcmath php-mhash -y")
# 生成PHP测试文件
group.run("echo '<?php phpinfo(); ?>' | tee /var/www/html/test.php")
# 启动Apache服务器
group.run("systemctl start httpd")
group.run("systemctl enable httpd")
# 防火墙开启HTTP和HTTPS服务
group.run("systemctl start firewalld", warn=True)
group.run("firewall-cmd --permanent --zone=public --add-service=http --add-service=https", warn=True)
group.run("firewall-cmd --reload")
# 安装phpMyAdmin
group.run("curl -o phpMyAdmin.zip https://files.phpmyadmin.net/phpMyAdmin/4.9.10/phpMyAdmin-4.9.10-all-languages.zip")
group.run("mv phpMyAdmin.zip /var/www/html")
group.run("unzip -d /var/www/html /var/www/html/phpMyAdmin.zip")
group.run("rm /var/www/html/phpMyAdmin.zip")
group.run("mv /var/www/html/phpMyAdmin-4.9.10-all-languages /var/www/html/phpmyadmin")
group.run("mv /var/www/html/phpmyadmin/config.sample.inc.php /var/www/html/phpmyadmin/config.inc.php")
group.close()
参考链接:
fabric官方中文文档:https://fabric-chs.readthedocs.io/zh_CN/chs/tutorial.html