Python自动化运维和部署项目工具Fabric使用实例


Posted in Python onSeptember 18, 2016

Fabric 是使用 Python 开发的一个自动化运维和部署项目的一个好工具,可以通过 SSH 的方式与远程服务器进行自动化交互,例如将本地文件传到服务器,在服务器上执行shell 命令。

下面给出一个自动化部署 Django 项目的例子

# -*- coding: utf-8 -*-
# 文件名要保存为 fabfile.py

from __future__ import unicode_literals
from fabric.api import *

# 登录用户和主机名:
env.user = 'root'
# 如果没有设置,在需要登录的时候,fabric 会提示输入
env.password = 'youpassword'
# 如果有多个主机,fabric会自动依次部署
env.hosts = ['www.example.com']

TAR_FILE_NAME = 'deploy.tar.gz'

def pack():
  """
  定义一个pack任务, 打一个tar包
  :return:
  """
  tar_files = ['*.py', 'static/*', 'templates/*', 'vue_app/', '*/*.py', 'requirements.txt']
  exclude_files = ['fabfile.py', 'deploy/*', '*.tar.gz', '.DS_Store', '*/.DS_Store',
           '*/.*.py', '__pycache__/*']
  exclude_files = ['--exclude=\'%s\'' % t for t in exclude_files]
  local('rm -f %s' % TAR_FILE_NAME)
 
  local('tar -czvf %s %s %s' % (TAR_FILE_NAME, ' '.join(exclude_files), ' '.join(tar_files)))
  print('在当前目录创建一个打包文件: %s' % TAR_FILE_NAME)


def deploy():
  """
  定义一个部署任务
  :return:
  """
  # 先进行打包
  pack()

  # 远程服务器的临时文件
  remote_tmp_tar = '/tmp/%s' % TAR_FILE_NAME
  run('rm -f %s' % remote_tmp_tar)
  # 上传tar文件至远程服务器, local_path, remote_path
  put(TAR_FILE_NAME, remote_tmp_tar)
  # 解压
  remote_dist_base_dir = '/home/python/django_app'
  # 如果不存在, 则创建文件夹
  run('mkdir -p %s' % remote_dist_dir)

 # cd 命令将远程主机的工作目录切换到指定目录 
  with cd(remote_dist_dir):
    print('解压文件到到目录: %s' % remote_dist_dir)
    run('tar -xzvf %s' % remote_tmp_tar)
    print('安装 requirements.txt 中的依赖包')
    # 我使用的是 python3 来开发
    run('pip3 install -r requirements.txt')
    remote_settings_file = '%s/django_app/settings.py' % remote_dist_dir
    settings_file = 'deploy/settings.py' % name
    print('上传 settings.py 文件 %s' % settings_file)
    put(settings_file, remote_settings_file)

    nginx_file = 'deploy/django_app.conf'
    remote_nginx_file = '/etc/nginx/conf.d/django_app.conf'
    print('上传 nginx 配置文件 %s' % nginx_file)
    put(nginx_file, remote_nginx_file)
 
 # 在当前目录的子目录 deploy 中的 supervisor 配置文件上传至服务器
  supervisor_file = 'deploy/django_app.ini'
  remote_supervisor_file = '/etc/supervisord.d/django_app.ini'
  print('上传 supervisor 配置文件 %s' % supervisor_file)
  put(supervisor_file, remote_supervisor_file)
 
 # 重新加载 nginx 的配置文件
  run('nginx -s reload')
  run('nginx -t')
  # 删除本地的打包文件
  local('rm -f %s' % TAR_FILE_NAME)
  # 载入最新的配置文件,停止原有进程并按新的配置启动所有进程
  run('supervisorctl reload')
  # 执行 restart all,start 或者 stop fabric 都会提示错误,然后中止运行
  # 但是服务器上查看日志,supervisor 有重启
  # run('supervisorctl restart all')

执行 pack 任务

fab pack

执行 deploy 任务

fab deploy

再给大家分享一个使用Fabric进行代码的自动化部署

#coding=utf-8
from fabric.api import local, abort, settings, env, cd, run
from fabric.colors import *
from fabric.contrib.console import confirm

env.hosts = ["root@115.28.×××××"]
env.password = "×××××"


def get_git_status():
  git_status_result = local("git status", capture=True)
  if "无文件要提交,干净的工作区" not in git_status_result:
    print red("****当前分支还有文件没有提交")
    print git_status_result
    abort("****已经终止")


def local_unit_test():
  with settings(warn_only=True):
    test_result = local("python manage.py test")
    if test_result.failed:
      print test_result
      if not confirm(red("****单元测试失败,是否继续?")):
        abort("****已经终止")


def server_unit_test():
  with settings(warn_only=True):
    test_result = run("python manage.py test")
    if test_result.failed:
      print test_result
      if not confirm(red("****单元测试失败,是否继续?")):
        abort("****已经终止")


def upload_code():
  local("git push origin dev")
  print green("****代码上传成功")


def deploy_at_server():
  print green("****ssh到服务器进行下列操作")
  with cd("/var/www/××××××"):
    #print run("pwd")
    print green("****将在远程仓库下载代码")
    run("git checkout dev")
    get_git_status()
    run("git pull origin dev")
    print green("****将在服务器上运行单元测试")
    server_unit_test()
    run("service apache2 restart", pty=False)
    print green("****重启apache2成功")
    print green("********代码部署成功********")


def deploy():
  get_git_status()
  local("git checkout dev", capture=False)
  print green("****切换到dev分支")
  get_git_status()
  print green("****将开始运行单元测试")
  local_unit_test()
  print green("****单元测试完成,开始上传代码")
  upload_code()
  deploy_at_server()

fabric可以将自动化部署或者多机操作的命令固化到一个脚本里,从而减少手动的操作。上面是今天第一次接触这东西后写的,确实很实用。运行fab deploy就行了。

主要逻辑就是将本地的dev分支跑单元测试,然后提交到服务器,ssh登陆到服务器,然后pull下来,再跑单元测试,然后重启apache2。第一次写,可能比较简单,将持续改进。

Python 相关文章推荐
Python入门篇之面向对象
Oct 20 Python
使用Python实现一个简单的项目监控
Mar 31 Python
Python中的特殊语法:filter、map、reduce、lambda介绍
Apr 14 Python
Python中if __name__ == '__main__'作用解析
Jun 29 Python
深入理解NumPy简明教程---数组3(组合)
Dec 17 Python
Python 内置函数memoryview(obj)的具体用法
Nov 23 Python
详解tensorflow载入数据的三种方式
Apr 24 Python
在python中利用opencv简单做图片比对的方法
Jan 24 Python
python 将有序数组转换为二叉树的方法
Mar 26 Python
python使用paramiko模块通过ssh2协议对交换机进行配置的方法
Jul 25 Python
Python如何爬取51cto数据并存入MySQL
Aug 25 Python
pycharm 多行批量缩进和反向缩进快捷键介绍
Jan 15 Python
基于Python 的进程管理工具supervisor使用指南
Sep 18 #Python
打包发布Python模块的方法详解
Sep 18 #Python
在python的类中动态添加属性与生成对象
Sep 17 #Python
Python中字符串的处理技巧分享
Sep 17 #Python
Python中对象迭代与反迭代的技巧总结
Sep 17 #Python
发布你的Python模块详解
Sep 15 #Python
Python selenium 三种等待方式解读
Sep 15 #Python
You might like
PHP字符串函数系列之nl2br(),在字符串中的每个新行 (\n) 之前插入 HTML 换行符br
2011/11/10 PHP
让CodeIgniter数据库缓存自动过期的处理的方法
2014/06/12 PHP
Yii调试SQL的常用方法
2014/07/09 PHP
php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
2020/02/15 PHP
JS加ASP二级域名转向的代码
2007/05/17 Javascript
js event事件的传递与冒泡处理
2009/12/06 Javascript
一些常用且实用的原生JavaScript函数
2010/09/08 Javascript
js 获取radio按钮值的实例
2013/08/17 Javascript
多个jquery.datatable共存,checkbox全选异常的快速解决方法
2013/12/10 Javascript
轻量级网页遮罩层jQuery插件用法实例
2015/07/31 Javascript
JS之获取样式的简单实现方法(推荐)
2016/09/13 Javascript
easyui combobox开启搜索自动完成功能的实例代码
2016/11/08 Javascript
jquery mobile移动端幻灯片滑动切换效果
2020/04/15 Javascript
浅析vue数据绑定
2017/01/17 Javascript
javascript简单写的判断电话号码实例
2017/05/24 Javascript
vue实现一个移动端屏蔽滑动的遮罩层实例
2017/06/08 Javascript
使用 Node.js 开发资讯爬虫流程
2018/01/07 Javascript
探索Vue高阶组件的使用
2018/01/08 Javascript
使用webpack搭建vue项目实现脚手架功能
2019/03/15 Javascript
[05:46]2018完美盛典-《同梦共竞》
2018/12/17 DOTA
python中的hashlib和base64加密模块使用实例
2014/09/02 Python
python模块之re正则表达式详解
2017/02/03 Python
浅谈Python在pycharm中的调试(debug)
2018/11/29 Python
python实现kNN算法识别手写体数字的示例代码
2019/08/16 Python
英国最大的手表网站:The Watch Hut
2017/03/31 全球购物
澳大利亚窗帘商店:Curtain Wonderland
2019/12/01 全球购物
英语专业毕业生自我鉴定
2013/11/09 职场文书
大学生蛋糕店创业计划书
2014/01/13 职场文书
大专会计自我鉴定
2014/02/06 职场文书
1亿有多大教学反思
2014/05/01 职场文书
单位委托书怎么写
2014/08/02 职场文书
家庭暴力离婚起诉书
2015/05/18 职场文书
2016年“我们的节日·端午节”活动总结
2016/04/01 职场文书
导游词之河北白洋淀
2020/01/15 职场文书
Java Socket实现多人聊天系统
2021/07/15 Java/Android
聊聊SpringBoot自动装配的魔力
2021/11/17 Java/Android