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常用随机数与随机字符串方法实例
Apr 09 Python
Python 专题二 条件语句和循环语句的基础知识
Mar 19 Python
Pycharm学习教程(6) Pycharm作为Vim编辑器使用
May 03 Python
Python数据分析之双色球统计两个红和蓝球哪组合比例高的方法
Feb 03 Python
wxPython实现窗口用图片做背景
Apr 25 Python
numpy 计算两个数组重复程度的方法
Nov 07 Python
Python实现合并两个有序链表的方法示例
Jan 31 Python
python Manager 之dict KeyError问题的解决
Dec 21 Python
tensorflow如何继续训练之前保存的模型实例
Jan 21 Python
利用Python实现斐波那契数列的方法实例
Jul 26 Python
pytorch损失反向传播后梯度为none的问题
May 12 Python
Python 数据可视化神器Pyecharts绘制图像练习
Feb 28 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中time(),date(),mktime()区别介绍
2013/09/28 PHP
php获取QQ头像并显示的方法
2014/12/23 PHP
PHP实现冒泡排序的简单实例
2016/05/26 PHP
PHP面向对象程序设计之命名空间与自动加载类详解
2016/12/02 PHP
PHP实现的AES加密、解密封装类与用法示例
2018/08/02 PHP
常见效果实现之返回顶部(结合淡入、淡出、减速滚动)
2012/01/04 Javascript
A标签中通过href和onclick传递的this对象实现思路
2013/04/19 Javascript
详解JavaScript函数绑定
2013/08/18 Javascript
JS的Document属性和方法小结
2013/09/17 Javascript
教你如何使用node.js制作代理服务器
2014/11/26 Javascript
深入理解JavaScript系列(50):Function模式(下篇)
2015/03/04 Javascript
比较常见的javascript中定义函数的区别
2015/11/09 Javascript
JavaScript File API文件上传预览
2016/02/02 Javascript
jquery 中toggle的2种用法详解(推荐)
2016/09/02 Javascript
JavaScript使用readAsDataURL读取图像文件
2017/05/10 Javascript
Angular 5.0 来了! 有这些大变化
2017/11/15 Javascript
使用vue-router设置每个页面的title方法
2018/02/11 Javascript
JavaScript面向对象继承原理与实现方法分析
2018/08/09 Javascript
Nodejs使用Mongodb存储与提供后端CRD服务详解
2018/09/04 NodeJs
关于JavaScript中高阶函数的魅力详解
2018/09/07 Javascript
JavaScript判断对象和数组的两种方法
2019/05/31 Javascript
微信小程序 拍照或从相册选取图片上传代码实例
2019/08/28 Javascript
Python如何快速实现分布式任务
2017/07/06 Python
详解Python if-elif-else知识点
2018/06/11 Python
numpy返回array中元素的index方法
2018/06/27 Python
python3安装speech语音模块的方法
2018/12/24 Python
Python中的self用法详解
2019/08/06 Python
Python StringIO如何在内存中读写str
2020/01/07 Python
六十岁生日答谢词
2014/01/10 职场文书
小学六一儿童节活动总结
2015/05/05 职场文书
2015年九一八事变纪念活动实施方案
2015/05/06 职场文书
毕业设计致谢词
2015/05/14 职场文书
新店开业策划方案怎么书写?
2019/07/05 职场文书
python实现图片九宫格分割的示例
2021/04/25 Python
DIY胆机必读:各国电子管评价
2022/04/06 无线电
Docker下安装Oracle19c
2022/04/13 Servers