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生成随机验证码的两种方法
Dec 22 Python
关于Python如何避免循环导入问题详解
Sep 14 Python
Python字符串格式化的方法(两种)
Sep 19 Python
Django基于ORM操作数据库的方法详解
Mar 27 Python
详解Python中的正则表达式
Jul 08 Python
Python实用技巧之列表、字典、集合中根据条件筛选数据详解
Jul 11 Python
python实现抖音点赞功能
Apr 07 Python
Flask之pipenv虚拟环境的实现
Nov 26 Python
在win64上使用bypy进行百度网盘文件上传功能
Jan 02 Python
Java多线程实现四种方式原理详解
Jun 02 Python
Django日志及中间件模块应用案例
Sep 10 Python
pytorch 两个GPU同时训练的解决方案
Jun 01 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
discuz authcode 经典php加密解密函数解析
2020/07/12 PHP
php处理json时中文问题的解决方法
2011/04/12 PHP
php适配器模式介绍
2012/08/14 PHP
解决PhpMyAdmin中导入2M以上大文件限制的方法分享
2014/06/06 PHP
CI(CodeIgniter)框架介绍
2014/06/09 PHP
PHP SPL标准库之文件操作(SplFileInfo和SplFileObject)实例
2015/05/11 PHP
PHP中有关长整数的一些操作教程
2019/09/11 PHP
JavaScript高级程序设计 DOM学习笔记
2011/09/10 Javascript
使用js实现按钮控制文本框加1减1应用于小时+分钟
2013/12/09 Javascript
前台js对象在后台转化java对象的问题探讨
2013/12/20 Javascript
js实现改进的仿蓝色论坛导航菜单效果代码
2015/09/06 Javascript
JavaScript实现点击按钮直接打印
2016/01/06 Javascript
ionic在开发ios系统微信时键盘挡住输入框的解决方法(键盘弹出问题)
2016/09/06 Javascript
详解vue-router 2.0 常用基础知识点之router-link
2017/05/10 Javascript
vue.js实现的绑定class操作示例
2018/07/06 Javascript
解决Vue axios post请求,后台获取不到数据的问题方法
2018/08/11 Javascript
vue实现多个元素或多个组件之间动画效果
2018/09/25 Javascript
JavaScript基础之静态方法和实例方法分析
2018/12/26 Javascript
ES6 Map结构的应用实例分析
2019/06/26 Javascript
原生JS实现萤火虫效果
2020/03/07 Javascript
Nuxt的路由配置和参数传递方式
2020/11/06 Javascript
Python读写Redis数据库操作示例
2014/03/18 Python
python中for循环输出列表索引与对应的值方法
2018/11/07 Python
详解配置Django的Celery异步之路踩坑
2018/11/25 Python
Python3 Tkinter选择路径功能的实现方法
2019/06/14 Python
kali中python版本的切换方法
2019/07/11 Python
nginx黑名单和django限速,最简单的防恶意请求方法分享
2019/08/09 Python
python [:3] 实现提取数组中的数
2019/11/27 Python
Python如何基于rsa模块实现非对称加密与解密
2020/01/03 Python
Python接口测试get请求过程详解
2020/02/28 Python
关于python中的xpath解析定位
2020/03/06 Python
Django 解决上传文件时,request.FILES为空的问题
2020/05/20 Python
企业精细化管理实施方案
2014/03/23 职场文书
《假如》教学反思
2014/04/17 职场文书
医院保洁服务方案
2014/06/11 职场文书
基层组织建设年活动总结
2015/05/09 职场文书