fabric2.0 使用說明html
fabric框架,主要的目的就是用來遠程自動化部署。在最近,做者將fabric框架重寫了一遍,升級到了2.0版本。在我學習過程當中,遇到了很多的坑,最坑的一次就是python編譯器總是給我提示,fabric 導入 api失敗,沒有fabric.api。我不斷的懷疑本身是否是腦子瓦特了的時候,我pip list 查看了一下版本,再看了一下github版本。python
我謝謝做者嘔心瀝血的更新框架。mysql
本說明,結合官方文檔,使用效果更佳。git
安裝github
pip install fabric
複製代碼
查看一下pip安裝fabric的版本號:sql
fabric 2.1.3shell
一切OK,開始練習。ubuntu
初步的使用centos
準備兩臺機器。一個pc,一個虛機就行。個人是兩個虛機,ip地址以下:api
虛機1: 192.168.11.11 系統:ubuntu
虛機2: 192.168.11.111 系統:centos
確保兩個虛機都能使用SSH鏈接。
個人操做都是在(虛機1)上進行。。。
from fabric import Connection
In [3]: c = Connection('192.168.11.111', port=22, user='root', connect_kwargs={'password':'1'})
In [4]: result = c.run('uname -s')
Linux
複製代碼
代碼說明:
咱們一切的遠程shell命令的執行都是基於Connection來實現的。實現的原理,也就是SSH。
複製代碼
Connection中一些參數:
鏈接的一些其餘參數都放到connect_kwargs中。我這使用了密碼鏈接。(試了半天,查看api手冊才試對)
當咱們獲取到了Connection對象以後,咱們就可使用它來進行一些命令。
result是執行的結果,包含了許多屬性值,以下:
In [8]: result.
result.command result.connection result.encoding result.env result.exited result.failed result.hide result.ok result.pty result.return_code result.shell result.stderr result.stdout
複製代碼
關於c.run()命令:
Connection objects’ methods (like run) usually return instances of invoke.runners.Result (or subclasses thereof) exposing the sorts of details seen above: what was requested, what happened while the remote action occurred, and what the final result was.
-----引用 http://docs.fabfile.org/en/2.1/getting-started.html
複製代碼
也就是 Connection 對象的方法(例如run) 經常返回invoke.runners.Result的實例,這個實例暴露了一些細節:
咱們請求了什麼,咱們遠程操做發生了什麼,最終的結果又是什麼。
以上是fabric的初步使用。
自動回覆
當咱們須要sudo操做的權限的時候,遠程服務器會阻塞在那,直到咱們輸入密碼,這確定是不行的。若是這麼low,那咱們使用這個框架作啥子?
咱們開始試驗:(我centos是root權限,因此來個騷操做)
手動輸入版本:
In [13]: c.run('ssh tly@192.168.11.11', pty=True)
The authenticity of host '192.168.11.11 (192.168.11.11)' can't be established.
ECDSA key fingerprint is SHA256:vDOg8wbz0RSFDPGJGEmMc6lT32eR13xW9NxOPxRO2t0.
ECDSA key fingerprint is MD5:f7:77:c8:bf:e0:ba:bd:8b:4d:48:6a:86:f0:3a:dc:31.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.11.11' (ECDSA) to the list of known hosts.
tly@192.168.11.11's password:
Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-130-generic x86_64)
* Documentation: https://help.ubuntu.com/
350 packages can be updated.
0 updates are security updates.
Last login: Wed Jul 11 14:11:36 2018 from 192.200.41.46
tly@tly-dev:~$ exit
logout
Connection to 192.168.11.11 closed.
Out[13]: <Result cmd='ssh tly@192.168.11.11' exited=0>
複製代碼
pty=True,個人理解就是將遠程終端的stdout輸出到本地。若是不添加會報錯。
上面,咱們鏈接了192.168.11.111 ,而後又用ssh鏈接到了192.168.11.11(要不是測試,我想我腦子瓦特了),以後,命令返回了終端須要咱們輸入密碼的字眼。我手動的輸入密碼,操做成功。
自動輸入的版本:
In [14]: from invoke import Responder
In [15]: sudopass = Responder(
....: pattern=r"'s password:",
....: response='1\n',
....: )
In [16]: c.run('ssh tly@192.168.11.11', pty=True, watchers=[sudopass])
tly@192.168.11.11's password:
Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-130-generic x86_64)
* Documentation: https://help.ubuntu.com/
350 packages can be updated.
0 updates are security updates.
Last login: Wed Jul 11 15:11:53 2018 from 192.168.11.111
tly@tly-dev:~$ exit
logout
Connection to 192.168.11.11 closed.
Out[16]: <Result cmd='ssh tly@192.168.11.11' exited=0>
分析以下:
引入了invoke中的Responder庫。這個庫將用來匹配字符串,並自動回覆。
從終端發回來的數據來看,咱們阻塞的地方就是咱們須要填寫密碼的地方。即:
複製代碼
tly@192.168.11.11's password:
因此在建立Responder對象的時候,匹配的字符串就選擇「 's password:」 來匹配。
response參數也就是咱們須要自動回覆的文本。
複製代碼
sudo幫手
我遠程終端是centos 根用戶運行的。不須要root, 因此我切換到centos下使用fabric。
使用以下:
In [1]: import getpass
In [3]: sudo_pass = getpass.getpass("What's your sudo password?")
What's your sudo password?
In [5]: from fabric import Config
In [6]: from fabric import Connection
In [7]: sudo_pass = getpass.getpass("What's your sudo password?")
What's your sudo password?
In [8]: config = Config(overrides={'sudo': {'password': sudo_pass}})
In [11]: c = Connection('192.168.11.11', port=22, user='tly', config=config, connect_kwargs={'password':'1'})
In [12]: c.sudo('whoami', hide='stderr')
root
Out[12]: <Result cmd="sudo -S -p '[sudo] password: ' whoami" exited=0>
複製代碼
分析以下:
getpass 只是用來獲取密碼使用的。(私密處理了一下吧)
sudo_pass中就是你輸入的文本值。
複製代碼
傳輸文件
遠程部署的最經常使用的命令了吧。 (巨坑爹的來了)
命令以下:
In [20]: c
Out[20]: <Connection host=192.168.11.11 user=tly>
In [21]: result = c.put('mysql-rc.yaml', '/home/tly/mysql-rc.yaml')
只要使用put命令就能將文件推送過去了。
參數:
複製代碼
若是隻是在本地運行命令,可使用
In [27]: from invoke import run
In [28]: run('ls')
anaconda-ks.cfg
mysql-rc.yaml
test_dir
Out[28]: <Result cmd='ls' exited=0>
複製代碼