2016年1月13日 星期三

使用 flake8_docstrings python package 將 docstring 格式納入 flake8 檢查項目

長久以來一直都習慣在 Ubuntu 下使用 flake8 這個工具來檢查自己 python source code 有沒有符合 pep8 規範。

在 Ubuntu 下安裝 flake8

sudo apt-get install python-flake8

使用

flake8 <your source code>

這個工具同時也可以和 vim 共用,使得使用者在用 vim 的時候可以即時看到檢查結果。(但我今天沒打算聊這個 XD)

但今天被強者我同事糾正我的 docstring 沒有符合規範,建議我可以使用 flake8-docstrings 這個工具將檢查更完善一些。我才注意到 1. Ubuntu 下沒有這個 package 2. 以往我都漏掉這個檢查了。於是趕緊補上:

因為 Ubuntu 沒有納入管理 flake8-docstring 這個套件,所以我改用 pip 安裝工具來安裝:


sudo pip install flake8_docstrings

安裝之後再使用 flake8 就可以看到它會去掃出不符合規範的 docstring 了,例如:

$ flake8 <my source code>
......
D300 Use """triple double quotes"""
D400 First line should end with a period
D102 Missing docstring in public method
......


環境:Ubuntu Trusty

2016年1月11日 星期一

使用虛擬機器測試 secure boot (四) 使用 OVMF

前面提到我們已經用 OVMF (open source virtual machine firmware)建立一個虛擬機器了。現在我們想要讓 OVMF 這個 firmware 啟動 secure boot ,並且可以讓我們放入自己的 key 。這樣之後就可以模擬真實的 secure boot 的情形。

方法主要參考這篇文章,另外再根據自己環境的情況做調整。

使用 virsh 重新啟動稍早建立的虛擬機器

virsh list --all
virsh start <domain name>

開啟螢幕

virt-viewer <domain name>

啟動後,會 pop up 「Tianocore」,這是因為 OVMF 是移植並且開源 Intel 開發的 Tianocore 這個 firmware。因為還沒有安裝作業系統、虛擬機器的硬碟中也沒有 efi binary,所以會進入 OVMF 的 UEFI shell。輸入 exit 跳出後會進入到設定的畫面。如圖一路可以選到使用檔案匯入 key 的選項。當然,現在什麼檔案都沒有。所以問題變成是,我們要怎麼準備 key file 呢?










2016年1月6日 星期三

使用虛擬機器測試 secure boot (三) 使用 virtsh


呼叫使用提示
virsh help

顯示選項 list 的使用提示
virsh help list

連結本地端 qemu 這個 hypervisor (virsh 可以管理多種不同的 hypervisor,qemu 只是其中一種)
virsh connect qemu:///system
連進去後,
顯示 domains (但 inactive domain 不會顯示;一開始還以為沒有連成功,因為啥都沒顯示)
virsh list

顯示 domains (包括 inactive domain)
virsh list --all

立刻終止 active domain (相當於 virt-manager 下使用 force off )
virsh destroy <domain name>

刪除已經建立/定義好的 domain(要先 destroy 才可以 undefine)
virsh undefine <domain name>

virt-tools.org 這裡有簡單的教學。



virt-tools.org 的這個教學網頁裡也有提到如何透過 /proc/cpuinfo and demsg 檢查自身的機器是否支援虛擬化技術;如果有,又是哪一種虛擬化技術。簡單直白,值得一看(下面直接摘要):

/proc/cpuinfo flags #

/proc/cpuinfo will tell you if the processor supports virtualization and if it is enabled (but it could not show up in flags because it is disabled — more on this below).
The flags to look out for are:
  • vmx — Intel VT-x, basic virtualization
  • svm — AMD SVM, basic virtualization
  • ept — Extended Page Tables, an Intel feature to make emulation of guest page tables faster.
  • vpid — VPID, an Intel feature to make expensive TLB flushes unnecessary when context switching between guests.
  • npt — AMD Nested Page Tables, similar to EPT.
  • tpr_shadow and flexpriority — Intel feature that reduces calls into the hypervisor when accessing the Task Priority Register, which helps when running certain types of SMP guests.
  • vnmi — Intel Virtual NMI feature which helps with certain sorts of interrupt events in guests.

Kernel messages (dmesg) and the BIOS #

The next thing to look at are the kernel messages by running the command:
dmesg | less
The two messages to look out for are:
kvm: no hardware support
and
kvm: disabled by bios




詞彙:
hypervisor - 不精確地講,就是虛擬機器層。
domain - virtual machine instance

使用虛擬機器測試 secure boot (二) virt tool 的介紹

上文中使用到的 virt-install 是 virt-tools 中的其中一個,也是 virt-manager 專案下的一個功能。下面簡單說明幾個常被用但是稍微有點被混淆的名詞:

OpenStack - 一個軟體專案。但這個軟體專案並不是典型開發或是維護一個軟體的那種專案,比較接近是「組合或是開發各種工具以提供某種 IaaS (infrastructure as a service) 服務的解決方案」。libvirt 是它支援的工具之一。

libvirt - 一套用 c 語言寫成的 API

virt tools - libvirt 與其週邊相關的工具、產品。包括 virt-manager 。

virt-manager - 這個詞有兩個意思,一個意思是有個指令叫做 virt-manager,可以提供 GUI 來管理基於 virt-manager 這個專案下支援的工具(例如 virt-install)所建立的虛擬機器。第二個意思就是這是一個專案的名稱,集成很多基於 libvirt 開發出的工具,例如 virt-install。

virsh - 可以想成是指令列版本的 virt-manager 工具。

下一篇:virsh 的使用!






使用虛擬機器測試 secure boot (一)

最近工作上開始需要自動化測試有開啟 secure boot 的機器,鴕鳥了好多年終於開始要好好面對這件事情了 XD

下面是跟著這篇 wiki 的資訊所作的測試。有些指令我有根據自己的狀況(host machine:Ubuntu Trusty)調整。覺得太繁瑣的話可以直接跳到幾乎是最後面的小結 XDD

因為我的系統中沒有 uvt 這個指令,找了一下沒有看到 uvt 這個指令從哪來,所以採用 wiki 中提供的另外一種作法:

virt-install --connect=qemu:///system --name=sb-saucy-amd64 --arch=x86_64 --ram=768 \
--disk=path=<path to>/sb-saucy-amd64.qcow2,size=8,format=qcow2,bus=ide,sparse=True \
--virt-type=kvm --accelerate --hvm --cdrom=<path to>/saucy-desktop-amd64.iso \
--os-type=linux --os-variant=generic26 --graphics=vnc --network=network=default,model=virtio \
--video=cirrus --noreboot --boot=loader=OVMF.fd

但會得到:

ERROR    Format cannot be specified for unmanaged storage.

這看起來似乎是要事先先建立好給虛擬機器使用的 storage file。因為急著想要看到結果,我使用 --nodisk 來取代 --disk [1]

virt-install --connect=qemu:///system --name=sb-trusty-amd64-02 --arch=x86_64 --ram=768 --nodisk --virt-type=kvm --accelerate --hvm --cdrom=./uuu/ubuntu-14.04.2-desktop-amd64.iso --os-type=linux --os-variant=generic26 --graphics=vnc --network=network=default,model=virtio --video=cirrus --noreboot --boot=loader=OVMF.fd
如果遇到這個訊息

Starting install...
Creating domain...                                                                                                                                                                    |    0 B     00:00  
WARNING  Unable to connect to graphical console: virt-viewer not installed. Please install the 'virt-viewer' package.
Domain installation still in progress. You can reconnect to
the console to complete the installation process.

表示要安裝 virt-veiwer package 來顯示開機過程的畫面:

sudo apt-get install virt-viewer

接下來就會看到開機畫面啦!

下一篇打算來解釋細節,敬請期待。









要印螢幕的時候按了 alt ,鍵盤的訊號同時被 host machine 和 guest machine 捕捉到的一瞬間 XD




















根據這封 virt-tool mailing list 中的 email,這是因為我們沒有事先告訴 virt-manager (or virtsh) 使用的 disk storage 存放位置(專有名詞叫做「pool」,一個 pool 下面可以有好幾個 storage file。),所以 virt-manager 認為這個地方它不敢亂動。

首先綁定資料夾 /tmp 成為 pool 之一,名字叫做 tmppool 的 pool

virsh pool-define-as --name tmppool --type dir --target /tmp

啟動 pool

virsh pool-start tmppool

接下來把上面一長串中 --disk 選項後面指定的位置改為 /tmp (新的 pool 位置)就可以用了:

$ virt-install --connect=qemu:///system --name=thho-trusty-amd64-01 --arch=x86_64 --ram=768 --disk=path=/tmp/thho-trusty-amd64.qcow2,size=8,format=qcow2,bus=ide,sparse=True --virt-type=kvm --accelerate --hvm --cdrom=./uuu/ubuntu-14.04.2-desktop-amd64.iso --os-type=linux --os-variant=generic26 --graphics=vnc --network=network=default,model=virtio --video=cirrus --noreboot --boot=loader=OVMF.fd
Starting install...
Allocating 'thho-trusty-amd64.qcow2'                                                                                                                                                  | 8.0 GB     00:00  
Creating domain...  

檢查 pool 相關的指令有哪些
virsh help pool

驗證一下是不是真的多了 tmppool 這個 pool

$ virsh pool-list
 Name                 State      Autostart
-------------------------------------------
 default              active     yes    
 tmppool              active     no      
 uvtool               active     yes  

使用 virt-install 建立新的 virtual machine instance (domain) 之後,我們只選 try ubuntu 但是不安裝,然後關機 or reboot。下一次只要直接使用 connect 和 start 就可以開啟虛擬機器了(這兩個動作請見下篇解釋)

virsh --connect qemu:///system start thho-trusty-amd64-01

啟動後因為不像 virt-install 一樣有自己啟動 virt-viewer ,所以要自己開:

virt-viewer thho-trusty-amd64-01

(thho-trusty-amd64-01 是 domain name)

開啟了之後就會進入 UEFI shell 如圖。





因為 storage (可以想成是虛擬硬碟)中我們還沒有安裝任何作業系統(上面只選 try ubuntu 但沒有安裝),所以開機後會進入 UEFI shell。這個 shell 是 ovmf 提供的。




比較:
所有指令和選項都一樣,但把  --boot=loader=OVMF.fd 拿掉。
也就是說我們預期不使用 OVMF.fd 這個 bootloader 開機,所以應該要直接進入使用 cdrom 開機。

virt-install --connect=qemu:///system --name=thho-trusty-amd64-02 --arch=x86_64 --ram=768 --disk=path=/tmp/thho-trusty-amd64-02.qcow2,size=8,format=qcow2,bus=ide,sparse=True --virt-type=kvm --accelerate --hvm --cdrom=./uuu/ubuntu-14.04.2-desktop-amd64.iso --os-type=linux --os-variant=generic26 --graphics=vnc --network=network=default,model=virtio --video=cirrus --noreboot

果然直接進入 cdrom iso






小結:

  • 使用 virt-install 建立虛擬機器。並且是建立一個擁有 ovmf 這個韌體的虛擬機器。
  • 使用 virsh 啟動 virt-install 建立的虛擬機器,開始操作 ovmf 提供的 UEFI shell。





因為我有打算在不久的將來自動化這些指令,所以刻意選擇使用 virsh 而不是 virt-manager。virt-manger 應該也是可以作到上面說的這些事情,只是在自動化上大概就會遇到問題。

2016年1月5日 星期二

初探 ipython parallel

最近為了開發 SOLVCON 平行運算的功能,開始評估可能的解決方案。這一塊自己的知識趨近於零 XD 有點亂槍打鳥地亂看,想看看別的專案怎麼設計的,看是要模仿、參考或是甚至直接拿來用的可能性如何。

下面簡單摘要這個頁面關於 ipython parallel 的介紹:

指令列輸入這個指令,建立四個 ipython kernel 給接下來的運算使用:
ipcluster start -n 4 

然後開始玩 hello world:

In [1]: from IPython.parallel import Client
In [2]: c = Client()
In [4]: c.ids
Out[4]: set([0, 1, 2, 3])
In [5]: c[:].apply_sync(lambda : "Hello, World")
Out[5]: [ 'Hello, World', 'Hello, World', 'Hello, World', 'Hello, World' ]
ipython parallel 中很多組態設定和通訊方式是採用 JSON (或是可以轉成 JSON 的 data object)的格式,例如這資料夾下面的東西:

~/.ipython/profile_default/security/




給 kvm 虛擬機器增加 USB 儲存裝置

最近為了開發給在 Snappy 架構下的 Ubuntu Core 用的、可以自動化 USB storage 讀寫測試的工具,採用了 kvm 虛擬機器作為開發環境。因為要測試標的是 USB ,所以花了一點時間了解了一下如何連結實體的 USB storage 裝置到使用 kvm 啟動的 image 。

在 Ubuntu desktop 下使用指令:

sudo kvm -m 512 -redir :8090::80 -redir :8022::22 the-image-you-want-to-test.img -usb -device usb-host,hostbus=2,hostaddr=11

要注意的是指定最後面兩個參數的值時比較麻煩,因為該值會根據 host machine 的狀態而改變。我自己是這樣找對應的值:

  1. 插入 USB storage
  2. 使用指令 lsusb 去看上面的 Bus and Device number ,把這兩個數字記下
  3. 退出 USB storage
  4. 啟動 kvm ,啟動時,根據上面的 Bus and Device number 分別填數 hostbus and hostaddr 。要注意的是這時候 hostaddr 要加 1 (因為重新插拔了一次。現在的 Linux kernel 會給裝置編號加一表示是新找到的裝置,用來和前一次區隔)
  5. 這時候再插入 USB storage ,原本在 host machine 會自動掛載的行為不會發生(推測 event signal 被 kvm 攔下來了);稍候也可以看到在 guest machine 中的 dmesg 指令指出有新的 USB storage 插入了。