`
san_yun
  • 浏览: 2653724 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

使用Fabric自动化你的任务

 
阅读更多

fabric是什么?

Fabric 是一个Python库,可以通过SSH在多个host上批量执行任务。你可以编写任务脚本,然后通过Fabric在本地就可以使用SSH在大量远程服务器上自动运行。这些功能非常适合应用的自动化部署,或者执行系统管理任务。
让我们首先看一个例子。我们知道在*NIX下面,uname命令是查看系统的发行版。可以写这样一个Fabric脚本:

from fabric.api import run
def host_type():
    run('uname -s')

将上面的脚本保存为fabfile.py,就可以通过fab命令在多个主机上执行host_type脚本了:
$ fab -H localhost,linuxbox host_type
[localhost] run: uname -s
[localhost] out: Darwin
[linuxbox] run: uname -s
[linuxbox] out: Linux

 

任务函数

Fabric中的任务就是一个python函数,姑且让我们称之为“任务函数”。既然是python函数,那么对函数的一些用法也适用于任务函数。比如传递参数、互相调用、返回值等等。首先看一个传递参数的例子:

 

def
 hello(name="
world
"
):
    print
("
Hello %s!
"
 % name)

 

在执行任务的时候,可以通过fab的命令行参数为任务函数传递参数:
$ fab hello:name=Holbrook
Hello Holbrook!

 

组合任务的例子如下:

from fabric.api import run
def host_type():
    run('uname -s')

def hello(name="world"):
    print("Hello %s!" % name)

def composite(name="world"):
    hello(name)
    host_type()

 

Fabric提供的命令

前面我们见过了fabric.api模块中的run函数,其功能是在远端主机上执行命令。fabric.api中还提供了local函数,用于执行本地(Fabric所在的主机)命令。如下:

 

from
 fabric.api import
 local
def
 lslocal():
    local('
ls
'
)

类似远端命令和本地命令,Fabric也区分远端目录和本地目录。Fabric提供的对远端和本地目录的操作分别是cd和lcd。如果你用过命令行的ftp,这很容易理解。让我们看一个例子:

def filepath():
    remote_dir = '/opt/xxx'
    with cd(remote_dir):
        run("touch README")

 

管理服务器连接

前面的例子中,都需要在fab命令行参数中指定server。当要管理大量服务器时很麻烦。Fabric提供了环境变量的字典env,其中就包含了hosts字典项,可以定义需要连接的server。如下:

 

from
 fabric.api import
 env, run

env.hosts = ['
host1
'
, '
host2
'
]
def
 mytask():
    run('
ls /var/www
'
)

也可以为每个任务单独指定要执行该任务的host列表:

 
from fabric.api import env, run

def set_hosts():
    env.hosts = ['host1', 'host2']

def mytask():
    run('ls /var/www') 

一个比较完整的例子

import re
import json
import os
import sys
import time
from fabric.api import local, roles, run, execute, parallel, cd, put
from fabric.api import env
from fabric.state import output
from stat import *

log_file ="/duitang/logs/sys/fab.log"
class Logger(object):
    def __init__(self, filename="Default.log"):
        self.terminal = sys.stdout
        self.log = open(filename, "a")

    def write(self, message):
        self.terminal.write(message)
        self.log.write(message)

    def flush(self):
        self.terminal.flush()
        self.log.flush()

    def close(self):
        self.terminal.close()
        self.log.close()

    def isatty(self):
        return False

sys.stdout = Logger(log_file)
sys.stderr = sys.stdout

def load_config():
    """加载配置"""
    result = {}
    file = open("env.conf", "rb")
    configs = [config.strip() for config in file.readlines() \
               if config and config.strip() and not config.strip().startswith("#")]
    for config in configs:
        name, val = config.split("=")
        name, val = name.strip().lower(), val.strip()
        try:
            val =json.loads(val)
        except:
            pass
        result[name] = val
    for name, val in result.items():
        if isinstance(val, str):
            pattern = re.compile(r"\$\{\s*(?P<name>\w+)\s*\}")
            cnames = re.findall(pattern, val)
            for cname in cnames:
                pattern = re.compile(r"\$\{\s*%s\s*\}" % cname)
                val, count = re.subn(pattern, result.get(cname.lower()), val)
                if count:
                    result[name] = val

    return result

@roles("gunicorn")
def where(image):
    run("ls %s; echo ok" % image)

config = load_config()
static_dir, duitang_dir = config.get("static_dir"), config.get("duitang_dir")
local_template_dir, online_template_dir = os.path.join(duitang_dir, "templates"), os.path.join(static_dir, "templates")
local_templatesopen_dir, online_templatesopen_dir = os.path.join(duitang_dir, "templatesopen"), os.path.join(static_dir, "templatesopen")
local_templatesmobile_dir, online_templatesmobile_dir = os.path.join(duitang_dir, "templatesmobile"), os.path.join(static_dir, "templatesmobile")

env.roledefs = {
    'nginx': config.get("nginx").split(","),
    'gunicorn': env.hosts or config.get("gunicorn").split(","),
}

def deploy_static(restart=True):
    execute(compress_style)
    local("python gerenate_version.py %s %s" % (static_dir, static_dir))
    execute(push_static_version, restart=False)
    if restart:
        execute(restart_all_servers)

@parallel
@roles("gunicorn")
def push_static_version(restart=True):
    fversion_path = os.path.join(static_dir, "fversion.json")
    put(fversion_path, duitang_dir)
    if restart:
        run("kill -HUP `more %s`" % "/duitang/data/work/gunicorn.pid")

@parallel
@roles("nginx")
def compress_style():
    with cd("/duitang/dist/app/bin/"):
        run("sh single_style.sh")

# gfw is not to deploy in this way!!!!!!!!!!
@roles("gunicorn")
def deploy_gfw(restart=True):
    svnup('/duitang/dist/app/trunk/duitang/gfw/')
    if restart:
        run("touch %s" % "/duitang/data/work/gunicorn.reload")

# gfw is not to deploy in this way!!!!!!!!!!
@roles("gunicorn")
def deploy_api(restart=True):
    svnup('/duitang/dist/app/trunk/duitang/api/')
    if restart:
        run("touch %s" % "/duitang/data/work/gunicorn.reload")

@roles("gunicorn")
def deploy_beansdb(restart=True):
    svnup("/duitang/dist/app/trunk/duitang/dynamicloader/middleware.py")
    #run("python /duitang/dist/app/trunk/duitang/beansdb/import_to_db.py %s" % date)

@roles("gunicorn")
def deploy_template(restart=True):
    svnup(local_template_dir)
    svnup(local_templatesopen_dir)
    svnup(local_templatesmobile_dir)
#    run("python /duitang/dist/app/bin/compress_template.py")
#    if restart:
#        run("touch %s" % "/duitang/data/work/gunicorn.reload")

@roles("gunicorn")
def deploy_python(restart=True):
    svnup(duitang_dir)
    if restart:
        run("kill -HUP `more %s`" % ("/duitang/data/work/gunicorn.pid"))
        time.sleep(2)

@roles("gunicorn")
def restart_all_servers():
    run("kill -HUP `more %s`" % ("/duitang/data/work/gunicorn.pid"))
    time.sleep(2)

@roles("nginx")
def restart_all_nginx():
    time.sleep(5)
    run("sudo nginx -c /duitang/dist/conf/nginx/nginx.conf -s reload")

@roles("gunicorn")
def check_gu_timeout(last=8):
    run("/duitang/dist/app/bin/check_timeout.py %d"%(last))

@roles("gunicorn")
def start_all_gu():
    #safe even if gunicorn is already started
    run("gunicorn_django  -c /duitang/dist/conf/gunicorn/gunicorn.conf", pty=False)

def xrun(command, hidden='', *args, **kwargs):
    old_state = output.running
    output.running = False
    print '[%s] run: %s' % (env.host_string, command)
    run(command + hidden, *args, **kwargs)
    output.running = command

def svnup(path):
   run("svn update %s %s" % (path, '--username app --password "x6QN)TnX"'))

def deploy():
    execute(deploy_static, restart=False)
    execute(deploy_template, restart=False)
    execute(deploy_python, restart=False)
    execute(restart_all_servers)
 参考:http://smilejay.com/2013/03/fabric-introduction/
http://www.libaoyin.com/2013/07/21/使用python-fabric批量执行远端命令/
 
 
分享到:
评论

相关推荐

    如何利用Fabric自动化你的任务.pdf

    一旦安装完成,你就可以开始编写和执行自动化任务。 在 Fabric 中,任务本质上就是 Python 函数,可以接收参数、返回值,并支持函数间的调用。例如,你可以创建一个 `hello` 任务,接受一个名字参数并打印欢迎消息...

    如何利用Fabric自动化你的任务

    Fabric是一个强大的Python库,专为自动化任务和部署而设计,尤其适合通过SSH在多台远程服务器上批量执行命令。它允许开发者编写简单的Python脚本来实现复杂的远程操作,从而极大地提高了工作效率。 首先,让我们...

    Python自动化部署工具Fabric的简单上手指南.pdf

    Python自动化部署工具Fabric是一个强大的用于远程服务器自动化执行任务的库,它基于SSH协议,使得开发者可以用Python语言编写脚本来管理和部署应用程序。Fabric简化了传统SSH命令行工具的操作,提高了效率和可读性。...

    使用Fabric自动化部署Django项目的实现

    【使用Fabric自动化部署Django项目的实现】 Fabric是一个Python库,用于编写可执行于远程服务器的命令,主要用于自动化运维任务,包括但不限于部署Web应用程序。在这个场景中,Fabric将帮助我们简化Django项目的...

    python自动化运维

    3. **自动化任务**:通过Python可以实现自动备份、日志分析、性能监控、系统状态检查、定时任务(如cron jobs)等。例如,使用schedule库可以创建定时任务,使用loguru进行日志记录,使用requests库进行HTTP请求,对...

    运维自动化之ANSIBLE.pdf

    Ansible Playbook 是定义自动化任务的剧本,它使用 YAML 编写,包含了各种任务、变量、条件判断、标签和处理器(handlers)。通过 Playbook 变量,我们可以灵活地管理和使用动态数据。Tags 可以用来选择性地执行 ...

    fabric安装

    Fabric是一个基于Python的库,用于自动化远程服务器的任务执行和部署。它提供了一种简单而强大的命令行工具,允许用户在多台主机上执行命令,类似于SSH客户端,但更加强大和灵活。Fabric的核心功能包括远程命令执行...

    Python自动化运维::技术与最佳实践

    自动化运维是指通过使用自动化工具和技术来简化和加速日常运维任务的过程。它可以帮助企业更高效地管理服务器、应用程序和服务,同时降低出错率和运维成本。 ##### 2.2 Python在自动化运维中的优势 - **简洁性**:...

    Python Linux系统管理与自动化运维_opt1

    首先,它介绍了Python在Linux环境中的基础应用,包括安装Python环境、常用Linux系统管理模块的使用,如paramiko用于远程控制,fabric用于自动化部署等。其次,书中深入探讨了Python在监控、日志分析、性能调优等系统...

    Python Linux系统管理与自动化运维

    2. 自动化部署:通过`Fabric`或`Ansible`实现远程服务器的自动化部署和配置。 3. 脚本化故障排查:Python脚本可以自动化执行诊断任务,如检查服务状态、网络连通性等。 4. 邮件通知:Python可以结合SMTP发送邮件,...

    自动化部署教程.docx

    自动化部署是指使用自动化工具和技术来实现软件的部署和管理,旨在提高部署效率和可靠性。下面将从 pexpect 和 Fabric 两个方面对自动化部署进行讲解。 1. pexpect 模块 pexpect 是一个 Python 模块,实现了 ...

    第012章 鲤鱼跳龙门第一招式-自动化工具.rarpython面试

    特别是在Python领域,由于其语法简洁且库丰富,Python成为了自动化任务的首选语言。本章“鲤鱼跳龙门第一招式——自动化工具”主要探讨了如何利用Python在面试中展示自己的自动化能力,以及在实际工作中如何运用这些...

    Fabric-1.8.2.zip

    Fabric是Python中一个强大的自动化部署和系统管理工具,它基于Paramiko库,提供了一种简单易用的SSH接口,使得用户可以通过Python脚本执行远程命令。在这个“Fabric-1.8.2.zip”压缩包中,您将找到Fabric库的1.8.2...

    python2.6安装fabric

    由于 Fabric 是一个用于执行远程命令的任务自动化工具,主要用于简化通过 SSH 连接的服务器管理任务,因此它依赖于 Python 和其他一些必要的软件包。 ##### 第一步:安装 EPEL 源 EPEL (Extra Packages for ...

    Python项目自动化多服务器部署的工具

    2. 配置管理:了解如何编写配置文件,如Ansible的playbooks或Fabric的任务函数,是实现自动化部署的关键。 3. 版本控制:Git等版本控制系统用于跟踪代码更改,确保每次部署的都是最新的、经过测试的代码。 4. 环境...

    devops持续集成自动化部署常用功能

    1. **Shell脚本**:在Linux或Unix环境中,Shell脚本是自动化任务的首选工具。在持续集成流程中,Shell脚本常用于执行构建、测试、清理等工作。例如,可以编写一个脚本来拉取代码仓库的最新代码、执行编译命令、运行...

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

    Fabric是一个用Python编写的开源库,主要用于简化系统管理员的任务——实现远程服务器上的自动化部署、管理等操作。它通过SSH协议来与远程服务器交互,允许开发者编写简洁且易于理解的Python脚本来完成一系列复杂的...

    Ganymed实现自动化部署接口

    - **Fabric**是一个Python库,用于简化和自动化Linux/Unix服务器的运维任务。Ganymed虽然在Java环境中提供类似功能,但它们的使用场景和语言环境不同。 - **相似性**:两者都支持远程执行命令、文件传输等功能,...

Global site tag (gtag.js) - Google Analytics