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得到一個單個數據。