FABRIC
什么是Fabric
fabric是一个python(2.7,3.4+)的库,用来通过SSH远程执行shell命令,并返回有用的python对象。
它建立在“invoke”和“paramiko”库之上,同时扩展了他们的API以提供更多的功能。
Fabric使用方法
Connection
fabric的Connection方法继承自INVOKE,实现对单个主机的SSh连接,返回一个该主机的连接对象。通过该对象,对主机进行操作和管理。
下面来看一下connectin方法参数。
def __init__(
self,
host,
user=None,
port=None,
config=None,
gateway=None,
forward_agent=None,
connect_timeout=None,
connect_kwargs=None,
inline_ssh_env=None,
):
- host:(str)主机名或IP地址,另外可以采用以下几种速写的格式:
user@host
,host:port
,user@host:port
- user:登录用户名
- port:(int)登录端口
- config:登录配置文件
- gateway:连接的网关或代理
- forword_agent:(bool)是否开启agent_forwording
- connect_timeout:(int)连接超时时间
- connect_kwargs:(dict)提交连接参数的字典,多用于密码,密钥等。
- inline_ssh_env:(bool)略
下面是一个简单例子:
from fabric import Connection
con = Connection(host='xxx.xxx.xxx.xxx', user='root', connect_kwargs={'password': '***'})
print(con)
>> <Connection host=xxx.xxx.xxx.xxx user=root>
Group
goup是一个部分抽象类,需要通过具象的子类(SerialGroup或者ThreadingGroup)来使用,否则python会抛出一个NotImplimentError。
很多情况下,我们需要同时操作多台服务器。最直接的办法自然是通过迭代的方法遍历整个主机列表。
>>> from fabric import Connection
>>> for host in ('web1', 'web2', 'mac1'):
>>> result = Connection(host).run('uname -s')
... print("{}: {}".format(host, result.stdout.strip()))
...
web1: Linux
web2: Linux
mac1: Darwin
但有些时候会想将所有的主机连接合并在一个对象当中,这就需要SerialGroup这样的子类。
>>> from fabric import SerialGroup as Group
>>> results = Group('web1', 'web2', 'mac1').run('uname -s')
>>> print(results)
<GroupResult: {
<Connection 'web1'>: <CommandResult 'uname -s'>,
<Connection 'web2'>: <CommandResult 'uname -s'>,
<Connection 'mac1'>: <CommandResult 'uname -s'>,
}>
group方法和Connection在参数上有很多不同。
class fabric.group.Group(*hosts, **kwargs)
- *hosts:可以传入多个主机名或IP,同时和Connection的host参数一样,支持
user@host
,host:port
,user@host:port
速写方式。 - **kwargs:fabric2.3版本新增的参数,使得group可以接收同Connection一样的参数。
group = SerialGroup(
"host1", "host2", "host3", user="admin", forward_agent=True,
)
Run
执行shell命令,通过invoke.runners.Runner.run来实现。
run(command, **kwargs)
- command:需要执行的shell命令
- **kwargs:接受多种参数,详见invoke文档
run的结果返回一个resul的实例。
这个实例在group和Connection之间不尽相同。
>>> from fabric import SerialGroup as Group
>>> results = Group('web1', 'web2', 'mac1').run('uname -s')
>>> print(results)
<GroupResult: {
<Connection 'web1'>: <CommandResult 'uname -s'>,
<Connection 'web2'>: <CommandResult 'uname -s'>,
<Connection 'mac1'>: <CommandResult 'uname -s'>,
}>
>>> for connection, result in results.items():
... print("{0.host}: {1.stdout}".format(connection, result))
...
...
web1: Linux
web2: Linux
mac1: Darwin
group得到一个字典;connection得到一个单个数据。