2017年4月29日 星期六

淺談 Testflinger 的工作模型


原本的解決方案不符現在需求、也不適合大規模重構


隨著時間推移,業務型態也跟著逐漸改變。從只需要單純大量測試原生 Ubuntu 逐漸轉變到現在發展中、需要測試各種 Ubuntu 在各種平台上的表現。原本負責大量原生 Ubuntu 批次安裝與測試的 checkbox-satellite project ,其最初的設計似乎並沒有考慮到這些使用情境。與其大規模的重構來符合一個當初設想外的使用情境,或許是發展另外一套解決方案的時候了。

想克服的問題:分開安裝與系統調整兩個動作


我在最初構思新的解決方案的時候,最想解決的問題是 checkbox-satellite 因為奠基於 d-i 的成熟技術所帶來的限制。因為採用 d-i,所以 checkbox-satellite 可以說是不得不將安裝(provisioning)與調整系統(使系統能夠自我自動測試)兩個動作,透過 preseed、early command file 和 late command file 等等好用與成熟的機制高度地綁在一起。好處是這個 preseed 機制在 Debian 和 Ubuntu 社群長久的發展下,功能已經非常穩定、成熟與強大,完全能夠勝任快速開發安裝與調整原生 Ubuntu 的重責大任,缺點則是 checkbox-satellite 當用於非原生 Ubuntu 或是非支援 d-i 機制的 images 時,就要另外發展安裝(provisioning)與調整系統(使系統能夠自我自動測試)兩個動作的需求。

於是我設計了一套基本上是 master-client 式的 client-server model,將 provisioning 和 system configuration 分開,master 只需要分別在不同的階段去觸發這兩個動作、client 只需要針對觸發做回應即可,藉此來 decouple。我很快就意識到這是一個很直覺、所以應該會被大量實做的概念,例如 Puppet[1]、OpenLMI[2]和接下來要聊聊的 Testflinger[3]。

Testflinger 的工作模式:server、agent、cli


Testflinger 很自然地也是採用 master-client 的設計,不過可以再細分為 server、agent 與 cli。定位如下:


  • Testflinger server:負責接收來自 cli 的任務請求、指派任務給 agent 與回收 agent 執行結果。
  • Testflinger agent:負責去認領在 server 上面還沒有被處理的任務。實際與測試目標溝通、執行測試任務、回收測試結果並回報給 server。
  • Testflinger cli:負責觸發任務請求。


所以很自然地,deployment 會像這樣:


  • Testflinger server:裝在某台可以收、送 Restful 通訊機制的 server 即可。該 server 必須要有 Redis server 服務,因為 Testflinger server 透過 Redis 來管理任務佇列。
  • Testflinger agent:裝在某台可以收、送 Restful 通訊機制的機器上即可。通常會設定固定排程讓 agent 定期去 server 上查看有沒有還沒被認領的工作。
  • Testflinger cli:裝在某台可以收、送 Restful 通訊機制的機器上即可。通常是自己的筆電。


因此,所有的測試目標只要是能夠運作 ssh server(或任何其他能夠收到來自 agent 訊息的管道)以及 shell(或是任何其他能夠執行來自 agent 指令的方式)即可。至此 system configuration 的問題已經解決;只要是能夠透過 command line 完成的 configuration,使用這種工作模型,應該都可以滿足。

所以我們只剩下 provisioning 這個問題:那測試目標要怎麼預先準備好 ssh server 和 shell  呢?

使用 MAAS 安裝測試目標


MAAS 提供 bare metal provisioning 的一系列解決方案。因此直接使用 MAAS 將「安裝」這個動作本身,成為一個 Testflinger agent 指派的任務即可。只是 Testflinger agent 驅動的「測試目標」其實變成 MAAS controller,「測試內容」變成「觸發 MAAS controller 去安裝目標機器」。

將 Jenkins 做為 Testflinger cli 觸發來源


從以上討論,其實就暗示了 Testflinger 本質上是「安裝與觸發系統工作」的機制,這套機制如果配合其他的排程機制,基本上就是一套完整的自動化測試解決方案。例如我們可以考慮使用 Jenkins 定期透過 Testflinger cli 發出測試請求、並且回收統整 Testflinger server 的執行結果。




[1] https://docs.puppet.com/puppetserver/latest/services_master_puppetserver.html
[2] http://www.openlmi.org/
[3] 當然還有其他可能的解決方案,例如 Ansible、Chef、Salt 等等。我認為其中最重要的概念是區分自己要做的是「system configuration」還是「application configuration」,而去選擇最適合自己使用情境的。

2017年4月13日 星期四

bluez 與藍牙測試 - 簡介(一)

最近為了大量測試藍牙,稍微評估了一下常見的幾種工具來計畫自動測試的方法。摘要如下。

bluez(protocol stack): Linux kernel 所採納的最新 bluetooth (bt) stack
bluez(debian package): 基於 bluez(protocol stack) 所實做的 daemon 和 tools。

因此透過 dpkg -L bluez 可以知道很多對應的 daemon configuration file 和常用工具有哪些,包括:

顯然是透過 dbus 溝通[1]

/etc/dbus-1/system.d/bluetooth.conf

其中 main.conf 可以調整  discoverable time

/etc/init/bluetooth.conf
/etc/bluetooth/network.conf
/etc/bluetooth/proximity.conf
/etc/bluetooth/input.conf
/etc/bluetooth/main.conf

這裡看起來可以設定自動開啟

/lib/udev/rules.d/50-bluetooth-hci-auto-poweron.rules

常見個一堆工具;我自己比較常用 hciconfig(啟動、調整設備)[2]、hcitool(啟動、調整連線)、bluetoothctl(類似 hcitool, 但是是交互式操作)、obexctl(交互式操作 obex)[3]


/bin/hciconfig
......
/usr/bin/hciattach
/usr/bin/hcitool
/usr/bin/gatttool
/usr/bin/btmon
/usr/bin/l2test
/usr/bin/bluemoon
/usr/bin/ciptool
/usr/bin/bluetoothctl
/usr/bin/l2ping
/usr/bin/rctest
/usr/bin/btmgmt
/usr/bin/hex2hcd
/usr/bin/btattach
/usr/bin/obexctl
/usr/bin/bccmd
/usr/bin/sdptool
/usr/bin/rfcomm

daemon; 如果是使用桌機版,應該一開始開機完進入桌面環境之後就可以查閱這個 daemon 有沒有啟動了(例如 ps aux | grep bluetoothd)

/usr/sbin/bluetoothd


接下來幾篇來寫測試方式和自動化實做。


[1] 有幾次玩到 obexctl 退出的時候,系統抱怨 dbus connection error;應該可以從這裡開始著手除錯。
[2] 別忘了 hci 是 host control interface:用來統一操作 device 的介面;所以 hciconfig 就是「透過 hci 設置、調整藍牙裝置」(hci --> driver --> kernel --> bt device)
[3] object exchange. OBEX is "a communications protocol that facilitates the exchange of binary objects between devices." (wikipedia) 藍牙通訊協議也採納此協議為支援 protocol 的一部分。


distribution: Ubuntu 16.04

2017年3月30日 星期四

使用 QEMU KVM 初探 MAAS - [3] 安裝 MAAS controller


如果上一篇建立虛擬機順利的話,應該可以從你自己的 host machine 連到剛才建立的虛擬機器了。立刻連進去操作(我們可以把 virt-manager 的螢幕關掉沒關係 XD 系統還在背景跑就好,伺服器嘛)(也就是說接下來的頁面都沒圖了 XDD[1]):


└──╼ ssh ubuntu@192.168.101.10
The authenticity of host '192.168.101.10 (192.168.101.10)' can't be established.
ECDSA key fingerprint is SHA256:n1YlztUI2/5EgeVrSNbnmbD1KPEHk1Ud8uOvy0mrkOQ.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.101.10' (ECDSA) to the list of known hosts.
ubuntu@192.168.101.10's password:
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic x86_64)
 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
42 packages can be updated.
31 updates are security updates.


The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
ubuntu@maas-ctl-01:~$

安裝需要的套件:

sudo apt-get install maas maas-dns maas-dhcp

maas: 主程式
maas-dns: 我們要 maas controller 替我們負責底下 node 的 dns 管理
maas-dhcp: 同 maas-dns,但管理 dhcp

應該就會一口氣裝到可以用[2][3][4]。如果有裝好,這時候你打開你 host machine 的瀏覽器,輸入位置 http://192.168.101.10/MAAS [5],應該要看到下面的畫面:還沒初始化、初次使用的 MAAS cluster 等著你建立第一個使用者。




這介面真是比 1.5 版的時代好看太多了 XDDDDDDDD

[1] 好啦其實還是有一張圖,建議可以先 clone 一份剛裝好的起來,這樣以後要拿去別地方用,或是稍後亂搞搞爛了可以馬上回來,不用重新建立虛擬機,比較省事。




[2] 啊我記得 2015 年剛開始玩 1.5.x 的時候花超多時間去調校的,包括 PostgreSQL語系問題、import boot image etc.,現在這個 2.1.3.x 大概打包和組態設定上已經改善很多了。一口氣到底好過癮喔。

[3] 14.04 搭配的 MAAS 會一口氣弄進很多 boot image ,空間至少要 10GB(後來的 MAAS 版本就可以選要拉哪些 boot image 了);這篇文章是 xenial server。

[4] 14.04 搭配的 MAAS 在拉 boot image 的時候不會顯示下載進度、甚至按下去有沒有反應都不知道(這後來有改掉),可以在 console 輸入  ps aux | grep import 來觀察下載有沒有正常啟動。

[5] 192.168.101.10 是前面文章在建立虛擬機器時指定的 IP,請換成你自己的值。

[6] trouble shooting: 如果 dhcpd 沒有啟動,可能是因為沒有去 subnet 裡面把 maas-dhcp 打開。

使用 QEMU KVM 初探 MAAS - [2] 建立 MAAS server 用的虛擬機


概念上是新增虛擬網路後,在建立虛擬機器的「硬體」組態時可以指定使用該虛擬網路。再基於該組態安裝 MAAS server。



新增虛擬網路


重點兩個:


  • DHCP 要關掉(因為我們要讓 MAAS server 去負責 DHCP,如果這邊也有 DHCP 就會打架)
  • NAT 要透過 host machine 上的實體裝置連外(因為我想要之後碰到網路來更新或是裝其他的東西;如果沒這打算可以不用連外)











這裡我的 gatewat 是 192.168.101.1,這個數字稍後會用到。

安裝 MAAS server

建立虛擬機


virt-manager 的圖形介面很直覺,廢話不多說,截圖幾個關鍵。


用 image 裝


選自己要用的 image [1]


這一步要注意,要選稍早我們建立的 NAT


[1]
安裝的時候要注意 iso 檔案存放位置的存取權限;常見的問題是把 iso 存在另外一個硬碟或是磁區,這會造成  virt-manager 存取的問題。



啟動虛擬機開始安裝 


雖然安裝一開始有提供很多選項,但我自己是偏好裝最基本的,然後再自己去手動裝與調整需要的套件。


我打算做這樣的配置:

MAAS controller: 192.168.101.10
MAAS node 01: 192.168.101.11
MAAS node 02: 192.168.101.12
......
name server and gateway: 192.168.101.1 (兩個都是同一個,往外找 name;注意這個值來自稍早虛擬網路的設定值)


所以這裡給 MAAS controller IP



netmask (因為我要 IP of nodes 像是 192.168.101.xx),所以是 255.255.255.0

稍早提到的 name server and gateway IP


The hostname of this controller

不填 domain name


如果虛擬網路有對外 bridge 成功的話,就會自動偵測到你的時區


中間有些過程就是一般安裝系統會看到的設定,應該滿直覺的,我就略過太細節的部份。

因為是測試機,所以就不更新了;還沒玩過 landscape,有機會再來玩玩。


稍早有提到我喜歡從基本開始裝,所以只選標準套件;因為之後也想要透過 ssh 連進來使用指令操作 MAAS 和 Juju,所以也順手裝一下 ssh server 的功能。


接著就會一路跑到完、安裝好,等著我們做進一步調校囉!請看下一篇:安裝 MAAS controller。

使用 QEMU KVM 初探 MAAS - [1] 安裝 virt-manager

kvm 是個很早就有的概念(1970??),然而在 20?? 左右,有顯著的突破,並且被 Linux 核心所採用。[1]

MAAS 自建雲,然而大多數人都不太有機會輕易蒐集兩台甚至以上的機器,所以虛擬機器自然是一個很直觀的選擇。如果覺得 Virualbox 太吃資源、也用不到太多的硬體模擬的話,可以考慮使用 qemu on kvm,並且透過 virt-manager 來管理。


首先,安裝虛擬機器管理員

sudo apt-get install virt-manager

讀者在安裝完 virt-manager 之後,透過 dash 打開;
第一次打開的時候可能會遇到 virt-manager 抱怨沒有安裝 qemu-system ,
這是正常的[2]

sudo apt-get install qemu-system




安裝完後打開,會被抱怨無法連接到 libvirt




ls -alh /var/run/libvirt/libvirt-sock
srwxrwx--- 1 root libvirtd 0  2月 18 20:37 /var/run/libvirt/libvirt-sock

可以看到 libvirt-sock 是一種 socket 以及錯誤訊息

libvirtError: Failed to connect socket to '/var/run/libvirt/libvirt-sock': Permission denied

不用擔心,這時候使用 sudo 給予權限打開就好

sudo virt-manager

如果左上方的 QEMU/KVM 沒有顯示未連結的話,就表示 virt-manager 已經準備好可以使用了。請到下一篇:安裝 MAAS server





* 是說這一系列的文章我在 2015 年初就寫了草稿,那時候還只是 MAAS 1.5.x,現在兩年過去了 2.1.x 都出來了 XDDD ,剛好又回頭要裝一次當除錯環境。因為原本裝好的 trusty 筆電最近炸掉,換成現在在用的 xenial;當時的操作截圖還留在原本的筆電中,一方面懶得救資料、一方面也覺得版本升級了藉機更新一次訊息。這次一口氣發出來這篇 XDD 從草稿上看到很多當時的痕跡,覺得很有意思。

2017年2月5日 星期日

paraview python macro

paraview 是一套強大的、可用於呈現 VTK 系列檔案[1]的工具,同時也是由 Kitware 公司維護的 open source software。

通常操作 paraview 的流程是:啟動 GUI、讀入檔案[2]、選擇要呈現的屬性[3]、操作 camera 來檢視圖形、播放隨時間流逝的動畫(需要讀入數個檔案,見[2])。

在 CFD 開發與實驗的過程中,如果每次產生的資料與數據,都要手動調整 GUI (例如上述的步驟)來檢查每次的結果,是非常沒有效率的事情。paraview 有提供接口,讓使用者可以透過 python 來操作 paraview 引擎;因此使用者可以撰寫 python macro 來簡化每次的操作。

安裝


Ubuntu 可以透過安裝 paraview-python 套件來取得 python 支援。

使用


參考 paraview wiki,或是 paraview 本身的 document 都很不錯。

tips - 好用的 trace


paraview 本身有提供「記錄使用者操作的流程,然後直接輸出成 python macro 」的超級好用功能。這樣使用者可以很直觀地操作之後(例如轉動物體到自己看得順眼的角度),直接取得 python script (欸欸欸這樣認真 K 上面 document 或是 wiki 的人情何以堪 XD)。

使用上就從 GUI 選擇 Tools 列表中的 Start Trace 選項,然後開始操作 paraview GUI[4]。操作完畢後選擇 Stop Trace ,並且存檔取得 python script。這樣就大功告成了。非常方便的功能!

理解 paraview python script


paraview 的運作邏輯大致上如下:


  • 資料 IO 、讀入檔案(注意支援一次讀多個檔案),用 reader 物件代表讀入結果。
  • Show:產生即將要呈現的資料的圖形屬性管理者 display
  • Render:渲染、呈現 display。包括動畫的部份。
  • Camera:決定使用者的視角(所以旋轉圖形什麼的由這裡操作)

由 paraview.simple module 提供操作層。(注意不是 module paraview;module paraview 應該是引擎本身)


資料讀入


  • OpenDataFile (泛用的方法,會自己判定是哪種 grid 幾何)
  • XMLUnstructuredGridReader、xxxxReader (直接指定 reader,注意可以透過 Filename keyword 來傳入檔案 list)



[1] 一種檔案格式,有多種延伸格式(例如 vtu)。常用於呈現 3D 幾何圖形,廣泛在地球科學與計算流體力學中被採用。特色之一是支援平行化運算。
[2] paraview 支援一次讀入檔名連續的不同檔案,常用於顯示不同時間的圖形幾何。
[3] 通常是用來呈現物理意義上的屬性。由檔案寫入者決定任何的 attribute 名稱。例如可以是壓力或者溫度。
[4] 你可能會遇到需要 python-pygments 套件的問題;Ubuntu 上透過 apt 安裝該套件可以解決這個問題。

2017年1月18日 星期三

diff 工具中的 unified format

稍早在討論 cram 這個測試工具的文章中[1],有提到 unified format。這邊文章稍微補充一些更多的香關知識。動機很單純,因為 diff 這個實用的工具用很久了,順便整理一下對於新接觸這種格式的人可能會有的障礙。wikipedia 上面其實已經整理得很清楚了[2],這邊算是中文摘要。

[1] http://zh-tw-tai271828.blogspot.tw/2017/01/cram.html
[2] https://en.wikipedia.org/wiki/Diff_utility#Unified_format

unified format

最主要是要知道要怎麼解讀這個格式

@@ -l,s +l,s @@ optional section heading


  • 格式開頭由兩個 @包夾
  • - 原本的檔案
  • + 更動後的檔案
  • l 開始的行數
  • s 由開始起算的相關行數(刪減、更動或是增加)

簡史


Wayne Davison 在 1990 八月提出,隨後由 Richard Stallman 加入 GNU diff 中 (GNU diff 1.15)

字彙



  • hunk - 在這裡指「一整個更動過的文字區塊」。了解這個字義有助於使用 patch 時,可以更清楚地解讀上 patch 後 patch 工具所反饋的訊息。