zoukankan      html  css  js  c++  java
  • <zz>PYTHON FABRIC实现远程操作和部署

    from http://www.cnblogs.com/liujianzuo888/articles/6230691.html

    • fabric

      title是开发,但是同时要干开发测试还有运维的活 (o(╯□╰)o)

      近期接手越来越多的东西,发布和运维的工作相当机械,加上频率还蛮高,导致时间浪费还是优点多。

      修复bug什么的,测试,提交版本库(2分钟),ssh到测试环境pull部署(2分钟),rsync到线上机器A,B,C,D,E(1分钟),分别ssh到ABCDE五台机器,逐一重启(8-10分钟) = 13-15分钟

      其中郁闷的是,每次操作都是相同的,命令一样,要命的是在多个机器上,很难在本机一个脚本搞定,主要时间都浪费在ssh,敲命令上了,写成脚本,完全可以一键执行,花两分钟看下执行结果

      直到,发现了fabric这货

      官方文档 入口

      作用

      很强大的工具

      可以将自动化部署或者多机操作的命令固化到一个脚本里

      和某些运维工具很像,用它主要是因为,python…..

      简单好用易上手

      当然,shell各种命令组合起来也可以,上古神器和现代兵器的区别

      环境配置

      在本机和目标机器安装对应包(注意,都要有)

      sudo easy_install fabric
      

      目前是1.8版本

      安装完后,可以查看是否安装成功

      [ken@~$] which fab
      /usr/local/bin/fab
      

      装完之后,可以浏览下官方文档

      然后,可以动手了

      hello world

      先进行本机简单操作,有一个初步认识,例子来源与官网

      新建一个py脚本: fabfile.py

      def hello():
          print("Hello world!")
      

      命令行执行:

      [ken@~/tmp/fab$] fab hello
      Hello world!
      
      Done.
      

      注意,这里可以不用fabfile作为文件名,但是在执行时需指定文件

      [ken@~/tmp/fab$] mv fabfile.py test.py
      fabfile.py -> test.py
      [ken@~/tmp/fab$] fab hello
      
      Fatal error: Couldn't find any fabfiles!
      
      Remember that -f can be used to specify fabfile path, and use -h for help.
      
      Aborting.
      [ken@~/tmp/fab$] fab -f test.py hello
      Hello world!
      
      Done.
      

      带参数:

      修改fabfile.py脚本:

      def hello(name, value):
          print("%s = %s!" % (name, value))
      

      执行

      [ken@~/tmp/fab$] fab hello:name=age,value=20
      age = 20!
      
      Done.
      [ken@~/tmp/fab$] fab hello:age,20
      age = 20!
      
      Done.
      

      执行本机操作

      简单的本地操作:

      from fabric.api import local, lcd
      
      def lsfab():
          with lcd('~/tmp/fab'):
              local('ls')
      

      结果:

      [ken@~/tmp/fab$] pwd;ls
      /Users/ken/tmp/fab
      fabfile.py   fabfile.pyc  test.py      test.pyc
      [ken@~/tmp/fab$] fab -f test.py lsfab
      [localhost] local: cd ~/tmp/fab
      [localhost] local: ls
      fabfile.py  fabfile.pyc test.py     test.pyc
      
      Done.
      

      实战开始:

      假设,你每天要提交一份配置文件settings.py到版本库(这里没有考虑冲突的情况)

      如果是手工操作:

      cd /home/project/test/conf/
      git add settings.py
      git commit -m 'daily update settings.py'
      git pull origin
      git push origin
      

      也就是说,这几个命令你每天都要手动敲一次,所谓daily job,就是每天都要重复的,机械化的工作,让我们看看用fabric怎么实现一键搞定:(其实用shell脚本可以直接搞定,但是fab的优势不是在这里,这里主要位后面本地+远端操作做准备,毕竟两个地方的操作写一种脚本便于维护)

      from fabric.api import local, lcd
      
      def setting_ci():
          with lcd('/home/project/test/conf/'):
              local("git add settings.py")
              #后面你懂的,懒得敲了…..
      

      混搭整合远端操作

      这时候,假设,你要到机器A的/home/ken/project对应项目目录把配置文件更新下来

      #!/usr/bin/env python
      # encoding: utf-8
      
      from fabric.api import local,cd,run, env
      
      env.hosts=['user@ip:port',] #ssh要用到的参数
      env.password = 'pwd'
      
      
      def setting_ci():
          local('echo "add and commit settings in local"')
          #刚才的操作换到这里,你懂的
      
      def update_setting_remote():
          print "remote update"
          with cd('~/temp'):   #cd用于进入某个目录
              run('ls -l | wc -l')  #远程操作用run
      
      def update():
          setting_ci()
          update_setting_remote()
      

      然后,执行之:

      [ken@~/tmp/fab$] fab -f deploy.py update
      [user@ip:port] Executing task 'update'
      [localhost] local: echo "add and commit settings in local"
      add and commit settings in local
      remote update
      [user@ip:port] run: ls -l | wc -l
      [user@ip:port] out: 12
      [user@ip:port] out:
      
      
      Done.
      

      注意,如果不声明env.password,执行到对应机器时会跳出要求输入密码的交互

      多服务器混搭

      操作多个服务器,需要配置多个host

      #!/usr/bin/env python
      # encoding: utf-8
      
      from fabric.api import *
      
      #操作一致的服务器可以放在一组,同一组的执行同一套操作
      env.roledefs = {
                  'testserver': ['user1@host1:port1',],
                  'realserver': ['user2@host2:port2', ]
                  }
      
      #env.password = '这里不要用这种配置了,不可能要求密码都一致的,明文编写也不合适。打通所有ssh就行了'
      
      @roles('testserver')
      def task1():
          run('ls -l | wc -l')
      
      @roles('realserver')
      def task2():
          run('ls ~/temp/ | wc -l')
      
      def dotask():
          execute(task1)
          execute(task2)
      

      结果:

      [ken@~/tmp/fab$] fab -f mult.py dotask
      [user1@host1:port1] Executing task 'task1'
      [user1@host1:port1] run: ls -l | wc -l
      [user1@host1:port1] out: 9
      [user1@host1:port1] out:
      
      [user2@host2:port2] Executing task 'task2'
      [user2@host2:port2] run: ls ~/temp/ | wc -l
      [user2@host2:port2] out: 11
      [user2@host2:port2] out:
      
      
      Done.
      

      扩展

      1.颜色

      可以打印颜色,在查看操作结果信息的时候更为醒目和方便

      from fabric.colors import *
      
      def show():
          print green('success')
          print red('fail')
          print yellow('yellow')
      #fab -f color.py show
      

      2.错误和异常

      关于错误处理

      默认,一组命令,上一个命令执行失败后,不会接着往下执行

      失败后也可以进行不一样的处理, 文档

      目前没用到,后续用到再看了

      3.密码管理

      文档

      更好的密码管理方式,哥比较土,没打通,主要是服务器列表变化频繁,我的处理方式是:

      3.1 host,user,port,password配置列表,所有的都写在一个文件

      或者直接搞到脚本里,当然这个更........

      env.hosts = [
              'host1',
              'host2'
      ]
      # 注意: 要使env.passwords生效, host格式必须是  user@ip:port 端口号一定要显式写出来,即使是使用的默认22端口
      env.passwords = {
          'host1': "pwdofhost1",
          'host2': "pwdofhost2",
      }
      
      或者
      env.roledefs = {
      'testserver': ['host1:22', 'host2:22'],
      'realserver': ['host3:22', ]
      }
      # 注意: 要使env.passwords生效, host格式必须是  user@ip:port 端口号一定要显式写出来,即使是使用的默认22端口
      env.passwords = {
          'host1:22': "pwdofhost1",
          'host2:22': "pwdofhost2",
          'host3:22': "pwdofhost3",
      }
      

      3.2 根据key解析成map嵌套,放到deploy中

      另外命令其实也可以固化成一个cmds列表的…..

      粗略就用到这些,后续有更多需求的时候再去捞文档了,话说文档里好东西真多,就是太多了,看了晕。。。

      TODO:

      装饰器作用?
      @task
      @parallel
      
      命令行常用: fab --help
      fab -l             -- 显示可用的task(命令)
      fab -H             -- 指定host,支持多host逗号分开
      fab -R             -- 指定role,支持多个
      fab -P             -- 并发数,默认是串行
      fab -w             -- warn_only,默认是碰到异常直接abort退出
      fab -f             -- 指定入口文件,fab默认入口文件是:fabfile/fabfile.py
      
      状态确认及错误处理
      
      更复杂的操作
      

      update log

      2014-10-26 fix error of local/lcd
      

      The end!

  • 相关阅读:
    java 继承(下)
    java继承
    java代码封装与编译
    使用Access-Control-Allow-Origin解决跨域
    java (基本语法)
    ZendStudio如何汉化
    如何让数据库在每天的某一个时刻自动执行某一个存储过程或者某一个sql语句
    百度地图不用密匙也可以使用
    .net在当前日期的基础上加一天
    当你的IIS需要运行ASP网站时,需要这样配置下你的IIS
  • 原文地址:https://www.cnblogs.com/zhangqiang1981/p/6238342.html
Copyright © 2011-2022 走看看