fabric2.0 使用說明

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中一些參數:

  1. host 主機地址
  2. port 端口號
  3. user 用戶名

鏈接的一些其餘參數都放到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命令就能將文件推送過去了。 

參數:
複製代碼
  1. 爲本機路徑
  2. 爲遠程路徑 如今這個版本必定要指定遠程文件名!!!否則會報錯 本機默認目錄就是你執行腳本的目錄。若是要切換怎麼辦? 暫時尚未找到比較方便的方式。因此先建議使用絕對路徑。

若是隻是在本地運行命令,可使用

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>
複製代碼
相關文章
相關標籤/搜索