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进阶教程之函数对象(函数也是对象)
Aug 30 Python
Python实现包含min函数的栈
Apr 29 Python
利用Python脚本生成sitemap.xml的实现方法
Jan 31 Python
Python实现字符串与数组相互转换功能示例
Sep 22 Python
Python自动发送邮件的方法实例总结
Dec 08 Python
解决python 文本过滤和清理问题
Aug 28 Python
Python 可变类型和不可变类型及引用过程解析
Sep 27 Python
Python爬虫如何应对Cloudflare邮箱加密
Jun 24 Python
基于selenium及python实现下拉选项定位select
Jul 22 Python
python 实现客户端与服务端的通信
Dec 23 Python
python基于openpyxl生成excel文件
Dec 23 Python
pytorch中的 .view()函数的用法介绍
Mar 17 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.ini 配置文件的深入解析
2013/06/17 PHP
PHP 5.5 创建和验证哈希最简单的方法详解
2013/11/07 PHP
PHP提交表单失败后如何保留已经填写的信息
2014/06/20 PHP
PHP连接access数据库
2015/03/27 PHP
JS+PHP实现用户输入数字后显示最大的值及所在位置
2017/06/19 PHP
Javascript new Date().valueOf()的作用与时间戳由来详解
2013/04/24 Javascript
使用js修改客户端注册表的方法
2013/08/09 Javascript
jquery实现全选、反选、获得所有选中的checkbox
2020/09/13 Javascript
JavaScript正则表达式替换字符串中图片地址(img src)的方法
2017/01/13 Javascript
JS实现购物车特效
2017/02/02 Javascript
详解JavaScript调用栈、尾递归和手动优化
2017/06/03 Javascript
nodeJS实现简单网页爬虫功能的实例(分享)
2017/06/08 NodeJs
Vue中建立全局引用或者全局命令的方法
2017/08/21 Javascript
Vue代码分割懒加载的实现方法
2017/11/23 Javascript
Vue数据双向绑定的深入探究
2018/11/27 Javascript
解决python写的windows服务不能启动的问题
2014/04/15 Python
编写Python脚本抓取网络小说来制作自己的阅读器
2015/08/20 Python
Python基于回溯法子集树模板解决0-1背包问题实例
2017/09/02 Python
numpy 计算两个数组重复程度的方法
2018/11/07 Python
基于numpy中数组元素的切片复制方法
2018/11/15 Python
基于python实现学生信息管理系统
2019/11/22 Python
如何将PySpark导入Python的放实现(2种)
2020/04/26 Python
python进行OpenCV实战之画图(直线、矩形、圆形)
2020/08/27 Python
Python二元算术运算常用方法解析
2020/09/15 Python
Python基于opencv的简单图像轮廓形状识别(全网最简单最少代码)
2021/01/28 Python
浅析CSS3中鲜为人知的属性:-webkit-tap-highlight-color
2017/01/12 HTML / CSS
借助HTML5 Canvas来绘制三角形和矩形等多边形的方法
2016/03/14 HTML / CSS
阿里旅行:飞猪
2017/01/05 全球购物
法国床上用品商店:La Compagnie du lit
2019/12/26 全球购物
旷课检讨书2000字
2014/01/14 职场文书
工伤事故赔偿协议书范文
2014/09/24 职场文书
机关副主任个人四风问题整改措施
2014/09/26 职场文书
书法社团活动总结
2015/05/07 职场文书
2016关于学习党章的心得体会
2016/01/15 职场文书
jquery插件实现代码雨特效
2021/04/24 jQuery
MySQL的prepare使用以及遇到的bug
2022/05/11 MySQL