zoukankan      html  css  js  c++  java
  • python fabric的用法

    1. Fabric的任务运行规则
    根据Fabric Execution model的说明,fabric默认以串行方式运行tasks,具体而言:
    1)在fabfile及其import文件中定义的task对象依次被创建(只是创建对象,并未真正执行),任务之间保持其定义的先后顺序。
    2)对于每个task,生成将要运行该task的目标机器列表。
    3)fab执行tasks时,按任务被指定的顺序依次执行这些任务;针对每个任务,依次在其指定的目标机器运行且只运行一次。
    4)未指定目标机器的task被当作本地任务运行,且只会被运行一次。

    假设在fabfile.py中定义了如下tasks:

    from fabric.api import run, env

    env.hosts = ['host1', 'host2']

    def taskA():
    run('ls')

    def taskB():
    run('whoami')
    1
    2
    3
    4
    5
    6
    7
    8
    9
    在终端运行fab –list时,我们会看到taskA和taskB两个任务,运行之:

    $ fab taskA taskB
    1
    结果示例如下:

    taskA executed on host1
    taskA executed on host2
    taskB executed on host1
    taskB executed on host2
    1
    2
    3
    4
    通过上面的实例,大家应该可以明白fabric默认的串行执行策略是怎么回事。

    Fabric还允许我们指定以并行方式(借助multiprocessing模块实现多个进程并行执行)在多台机器上并行地运行任务,甚至还可在同一个fabfile文件中指定某些task以并行方式运行,而某些task以默认的串行方式运行。具体地,可以借助@parallel或@serial指定任务的运行模式,还可以在命令行中通过-P参数指定任务是否要并性执行。示例如下:

    from fabric.api import *

    @parallel
    def runs_in_parallel():
    pass

    def runs_serially():
    pass
    1
    2
    3
    4
    5
    6
    7
    8
    当运行如下命令时:

    $ fab -H host1,host2,host3 runs_in_parallel runs_serially
    1
    执行结果示例如下:

    runs_in_parallel on host1, host2, and host3
    runs_serially on host1
    runs_serially on host2
    runs_serially on host3
    1
    2
    3
    4
    此外,还可以通过对@parallel传入pool_size参数来控制并行进程数以防并行进程太多把机器拖垮。

    2. 为task指定目标机器
    有多种方式可以指定任务的将要运行的目标机器,下面分别进行说明。
    1)通过env.hosts或env.roles进行全局指定
    Fabric的env模块中定义了一系列全局变量,可以将其理解为可以控制fabric行为的环境变量。其中env.hosts和env.roles可以用来全局指定task的目标机器列表,这两个“环境变量”的默认值都是空列表[]。

    env.hosts的元素是fabric约定的”host strings”,每个host strings由username@hostname:port三部分构成,其中username和port部分可以缺省。本篇笔记前面的第1个代码实例其实已经说明了如何用env.hosts全局地指定task的目标机器列表,这里不再赘述。

    env.roles则是在配置了env.roledefs的情况下才有用武之地。在很多时候,不同的机器有着不同的角色,如有些是接入层,有些是业务层,有些是数据存储层。env.roledefs可以用来组织这些机器列表以体现其角色,示例如下:

    from fabric.api import env

    env.roledefs = {
    'web': {
    'hosts': ['www1', 'www2', 'www3'],
    },
    'db': {
    'hosts': ['db1', 'db2'],
    }
    }

    @roles('web')
    def mytask():
    run('ls /var/www')
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    上例通过env.roledefs配置了两个角色web和db,分别包含3台、2台机器,并借助@roles为mytask指定了目标机器列表。

    2)通过命令行进行全局指定

    $ fab -H host1,host2 mytask
    1
    需要注意的是,命令行通过-H参数指定的机器列表在fabfile脚本load前被解释,故如果fabfile中重新配置了env.hosts或env.roles,则命令行指定的机器列表会被覆盖。为了避免fabfile覆盖命令行参数,在fabfile中应该借助list.extend()指定env.hosts或env.roles,示例如下:

    from fabric.api import env, run

    env.hosts.extend(['host3', 'host4'])

    def mytask():
    run('ls /var/www')
    1
    2
    3
    4
    5
    6
    此时,当我们运行”fab -H host1,host2 mytask”时,env.hosts包含来自命令行和fabfile的4台机器。

    3)通过命令行为每个任务指定机器列表

    $ fab mytask:hosts="host1;host2"
    1
    上述方式会覆盖全局指定的机器列表,确保mytask只会在host1, host2上执行。

    4)借助装饰器@hosts为每个任务指定目标机器

    from fabric.api import hosts, run

    @hosts('host1', 'host2')
    def mytask():
    run('ls /var/www')
    1
    2
    3
    4
    5
    或者:

    my_hosts = ('host1', 'host2')
    @hosts(my_hosts)
    def mytask():
    # ...
    1
    2
    3
    4
    每个任务的@hosts装饰器指定的机器列表会覆盖全局目标机器列表,但不会覆盖通过命令行为该任务单独指定的目标机器列表。

    上述4种为task指定目标机器列表的方式之间的优先级规则总结如下:
    1) Per-task, command-line host lists (fab mytask:host=host1) override absolutely everything else.
    2) Per-task, decorator-specified host lists (@hosts(‘host1’)) override the env variables.
    3) Globally specified host lists set in the fabfile (env.hosts = [‘host1’]) can override such lists set on the command-line, but only if you’re not careful (or want them to.)
    4) Globally specified host lists set on the command-line (–hosts=host1) will initialize the env variables, but that’s it.

    截止目前,我们可以看到,fabric允许我们混合使用上面列出的几种目标机器指定方式,但是我们要明白混合的结果是否符合预期。

    此外,fabric默认会对通过不同来源出现多次的同一个目标机器做去重,当然,可以通过设置env.dedupe_hosts为False来关闭默认的去重策略。甚至还可以指定任务需要跳过的机器列表。具体细节可以参考Fabric Execution model的说明,这里不赘述。

    3. 任务执行时,目标机器的密码管理
    如果你亲自运行上面的示例代码,就会发现,每次在目标机器远程执行task时,fabric均会要求输入目标机器的登录名及密码。如果要在多台机器上执行task,那这些密码输入的过程可以自动化吗?

    答案是肯定的。实现方式有两种,下面分别进行说明。

    1)通过env.password或env.passwords配置目标机器的登录信息
    下面的示例说明了如何通过env.passwords配置多台机器的登录信息:

    #!/bin/env python
    #-*- encoding: utf-8 -*-

    from fabric.api import run, env, hosts

    ## 需要注意的是,这里的host strings必须由username@host:port三部分构成,缺一不可,否则运行时还是会要求输入密码
    env.passwords = {
    'slvher@10.123.11.209:22': 'xxx',
    'work@10.123.11.210:23': 'yyy',
    }

    @hosts('10.123.11.209', '10.123.11.210')
    def host_os_type():
    run('uname -a')
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    由于通过env.passwords配置了目标机器的登录用户名/密码,所以,当我们在终端运行fab host_os_type时,会发现不用手动输入密码了,大大方便了脚本远程自动执行。

    但是,这种明文指定登录名/密码的方式存在安全性问题,所以,fabric还支持以ssh key认证的方式免密在远程机器执行任务。

    在具体实现上,需要事先在目标机器上生成ssh public key并配置在~/.ssh/config文件中,然后在定义任务的fabfile中将env.use_ssh_config设置为True来启用基于ssh public key方式的身份认证,以便实现免密码远程执行任务。
    ---------------------
    作者:slvher
    来源:CSDN
    原文:https://blog.csdn.net/slvher/article/details/50414675
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    The Python Standard Library
    Python 中的round函数
    Python文件类型
    Python中import的用法
    Python Symbols 各种符号
    python 一行写多个语句
    免费SSL证书(https网站)申请,便宜SSL https证书申请
    元宇宙游戏Axie龙头axs分析
    OLE DB provider "SQLNCLI10" for linked server "x.x.x.x" returned message "No transaction is active.".
    The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "xxx.xxx.xxx.xxx" was unable to begin a distributed transaction.
  • 原文地址:https://www.cnblogs.com/linwenbin/p/10617236.html
Copyright © 2011-2022 走看看