遇到 python UnicodeDecodeError 其實有點頭大。

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import subprocess
import os
import sys
import locale

if __name__ == "__main__":
	locale.setlocale(locale.LC_ALL, 'en_US.UTF8')
	proc = subprocess.Popen(['date'], stdout=subprocess.PIPE,
									 stderr=subprocess.PIPE,
									 stdin=subprocess.PIPE,
									 env={'LANG': 'zh_TW.UTF8', 'LANGUAGE': 'zh_TW:zh'},
									 universal_newlines=True, shell=True)
	(out, err) = proc.communicate()
	import codecs
	sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())
	print(out)
	print(err)
$ ./date.py

再進一步查了一下,發現這跟環境變數有關。

$ env -i LANG='en_US.UTF8' /usr/bin/python3 -c 'import locale; print(locale.getpreferredencoding(False))'               
UTF-8
$ env -i  /usr/bin/python3 -c 'import locale; print(locale.getpreferredencoding(False))'
ANSI_X3.4-1968

看完這份 slides ,才比較知道 Unicode 在 Python 中較好的處理方法 Unicode In Python, Completely Demystified

Solution 1. Decode early 2. Unicode everywhere 3. Encode late

或是類似 Ubiquity 的直接強制使用 C.UTF http://bazaar.launchpad.net/~ubuntu-installer/ubiquity/trunk/view/head:/bin/ubiquity#L44

kindle 7 (2014)
2015-01-10

幾天前拿到了 Kindle 7 (2014),基本款kindle。今年即使在最基本款也已經有 touch 功能了。這幾天用下來,確實覺得滿特別的。有一些優缺點跟大家分享

優點: 1. 相較一般螢幕,透過電子紙閱讀,對眼睛確實舒服很多,也確實不容易受到其它網路資訊的干擾。 2. Kindle 提供 Chrome Extension 來將網路文章 Send to Kindle,如此一來以後較長的文章都可以送到 Kindle 上來閱讀。

缺點: 1. Send to Kindle 的同步功能做的不是很好。當文章被 Send to Kindle 後,實際上是存到 Amazon Cloud Drive,然後手上 Kindle 會自動下載一份在裝置上。但當閱讀完畢後,2邊的刪除不會同步,造成我想刪除文章必須去2個地方刪除。這點也很確實的寫在 Kindle 文件上,但這點應該是很重要需要改進的地方。 Kindle Personal Documents Service 2. PDF 也可以 Send to Kindle,但提供的方式不夠好。最好的話能提供 Web 界面讓使用者上傳 PDF。另外要注意的是,Send to Kindle 會將文件轉檔為 Amazona 使用的 azw 格式,所以文件有可能格式會跑掉,如果想在Kindle 上閱讀手上PDF,可能要有心理準備會有一些小問題。(補充一下,PDF是可以直接透過 USB 傳輸線不轉檔直接存到 Kindle 上,不過一來Kindle資料夾管理看起來很麻煩,二來 Kindle 6吋大小顯示 A4 內容閱讀起來會滿辛苦的。透過 Send to kindle 轉檔雖然格式會掉,但至少是易閱讀的電子書格式。)

Docker Insight
2014-12-11

這幾天弄懂了 cgroup, kernel capbability 的機制,再搭配這份投影片 Docker Insight,有種很多東西都串起來的感覺。

Docker 1.2 新增的 cap-add, cap-drop,再加上 Docker 本身附有的 Volume mount,讓 container 又有了更多方便的使用方式。

QEMU Advent Calendar 這個project 滿有趣的,到 Chrismas 前,每天介紹一個 qemu 的image 讓大家去玩。

今天 Canonical 發佈實驗性的作業系統 Ubuntu Core, Canonical 也跟他們合作,成為今天的 QEMU Advent Calendar image.

$ apt-cache search hello | grep dbg
# apt-get install hello-dbg
gdb /usr/bin/hello
  1. Create Launchpad PPA at https://launchpad.net/people/+me/+activate-ppa
  2. Creating your OpenPGP keys with gpg command

    • Open a terminal and type: bash gpg --gen-key
    • GPG will now ask you a number of questions about the type of key you want to generate. follow the steps below to select the default option each time.
    • Check that your key has been generated by typing gpg –list-keys and, if successful. pub 1024D/12345678 -> this is the important number
    • Launchpad doesn’t store your key directly, so you need to export your public key to a key server, such as keyserver.ubuntu.com: bash gpg --keyserver keyserver.ubuntu.com --send-keys 12345678 Replace 12345678 with the pub id you noted in step 3. If successful, GPG will display a message similar to: bash gpg: sending key 12345678 to hkp server keyserver.ubuntu.com Importing your key into Launchpad with gpg
  3. Add OpenPGP key to Launchpad

    • Launchpad identifies your OpenPGP key by its fingerprint. In your terminal, you can ask GPG for your key’s fingerprint by typing: gpg --fingerprint GPG will display a message similar to: Key fingerprint = `0464 39CD 2486 190A 2C5A 0739 0E68 04DC 16E7 CB72` copy only the numeric fingerprint: 0464 39CD 2486 190A 2C5A 0739 0E68 04DC 16E7 CB72.
    • Visit your OpenPGP key page at https://launchpad.net/people/+me/+editpgpkeys
    • Paste the fingerprint that you copied in step 1 into the Fingerprint text-box, then click the Import Key button. Launchpad will use the fingerprint to check the Ubuntu key server for your key and, if successful, send you an encrypted email asking you to confirm the key import. (Note : this is a brief … from launchpad process….. both process take a while so just take your time…)
  4. set ~/.devscripts

    DEBUILD_DPKG_BUILDPACKAGE_OPTS="-us -I -i"
    DEBUILD_LINTIAN_OPTS="-i -I --show-overrides"
    
  5. get source

    apt-get build-dep lshw
    bzr lp:ubuntu/trusty/lshw
    dch -v X.XtestVersion -D trusty
    debuild -S
    
  6. upload changes to launchpad’s ppa and push code

    dput ppa:swem/ppa xxxxxxxxxxxxxxxxxx_source.changes
    bzr push lp:~swem/totem/trunk
    

Extra: Build debian package on your own machine

pbuilder-dist trusty amd64 create
pbuilder-dist trusty amd64 build xxxxxxxxxxxxxxxxxx_source.dsc

Check ~/pbuilder/trusty_result/, the xxxxxxxxxxxxxxxxxx.deb should be there.

Ref: - Ubuntu packaging guide - 6. Packaging New Software - 5. Tutorial: Fixing a bug in Ubuntu - Creating Ubuntu packages for Launchpad - 製作 deb package for Ubuntu Linux 並且上傳至 Launchpad PPA - 淺談 Launchpad 上面的 Bazaar 分支架構 - Chapter 6. Building the package

Brendan Gregg,是一位 Computer performance analyst,前幾個月很有名的那張 Linux Performance Observability Tools 就是他作的。(Linux Performance Tools at LinuxCon North America 2014)

今天在網路上看到他的書裡的一段話,滿受到激勵的。資訊技術發展到現在已是博大精深,每個系統深入下去了解都有很大的學問,學習的過程難免遇到挫折、犯錯,但這些累積,就是成為專家的過程。 >For a beginner, feeling lost when you’re studying a performance issue can be discouraging. This feeling, too, is normal: you will feel lost, you will make mistakes, and you will often be wrong. Quoting Niels Bohr, a Danish physicist: An expert is a person who has made all the mistakes that can be made in a very narrow field. By telling you stories like this one, I hope to reassure you that mistakes and wrong turns are normal (even for the best of us) and to show you some techniques and methodologies to help you find your way.” > >Brendan,Gregg. “Systems Performance: Enterprise and the Cloud.” Pearson Education, 2013-10-07。

最近才知道原來有 X virtual framebuffer 這種東西,可以在 Linux Server 端先把畫面 render 好,而 Client 端只要準備好 VNC Client,就可以連過去使用。啟動 X virtual framebuffer 與 x11vnc,並且開啟 window manager 與簡單的 gnome-panel 範例如下,初步試了一下滿順暢的(我跟server之間的 Round-trip time 約 38 ms):

(以下範例的 vnc port 為6000,登入密碼為 pass)

Xvfb :33 -screen 0 800x600x16 &
x11vnc -storepasswd pass ~/.vnc/passwd
x11vnc -display :33 -geometry 800x600 -rfbauth ~/.vnc/passwd -forever -rfbport 6000 -httpport 6001 &
export DISPLAY=:33
openbox-session &
gnome-panel &

Ref. 1. fcwu/docker-ubuntu-vnc-desktop 2. Xvfb - Wikipedia

有很多工具可以用來建立 Virtual Machine ,例如 VirtualBox, VMware, LXC, Qemu, Qemu with KVM, Xen 等等。

QEMU - Debian Wiki 簡單的介紹了如何使用 Qemu 來運行虛擬環境

使用現有 Image

Debian developer Aurelien Jarno 提供了數個預先建立的 Image https://people.debian.org/~aurel32/qemu/,這邊我使用 amd64 的架構做示範幾種啟動虛擬環境的方式:

  • 開啟 QEMU,預設使用 SDL 顯示 guest OS 的畫面

    qemu-system-x86_64 -hda debian_wheezy_amd64_standard.qcow2 -m 256
    
  • 開啟 QEMU,使用 terminal 操作虛擬環境 (一般PC上開機約180秒)

    qemu-system-x86_64 -hda debian_wheezy_amd64_standard.qcow2 -m 256 -curses
    
  • 開啟QEMU,並將 host OS port 5555 的封包轉送給 Guest OS 的 port 80

    qemu-system-x86_64 -hda debian_wheezy_amd64_standard.qcow2 -m 256 -curses -redir tcp:5555::80
    
  • 開啟QEMU,並且開啟 kvm full virtualization support。如果 kernel,processor 有支援,將大大提昇虛擬環境運行速度。這項操作需 root 權限。 (一般PC上開機約30秒,可大大看出 -enable-kvm 的差異)

    qemu-system-x86_64 -hda debian_wheezy_amd64_standard.qcow2 -m 256 -curses -enable-kvm
    

特別注意的是我這邊沒有特別對網路做設定,根據 Documentation ,TCP, UDP可以運作,但ICMP 不會。我實際測試的結果確實是如此。(Note - if you are using the (default) SLiRP user networking, then ping (ICMP) will not work, though TCP and UDP will. Don’t try to use ping to test your QEMU network configuration!)

自已建立 qemu image

  1. 建立虛擬硬碟 bash dd if=/dev/zero of=rootfs.img bs=1G count=2
  2. 格式化虛擬硬碟為 ext4 bash mkfs.ext4 rootfs.img
  3. mount 虛擬硬碟 (需要 root 權限) bash mount -o loop rootfs.img /mnt
  4. 執行 debootstrap (需要 root 權限) bash debootstrap --no-check-gpg --arch=amd64 wheezy /mnt/ http://debian.nctu.edu.tw/debian/
  5. 查詢虛擬硬碟的 UUID,我這邊是”4cc6834a-df20-4cb3-ad55-79433346e000” bash blkid rootfs.img

rootfs.img: UUID=“4cc6834a-df20-4cb3-ad55-79433346e000” TYPE=“ext4”

  1. 填寫 /etc/fstab,讓虛擬機開機時就會 mount 虛擬硬碟 bash echo "UUID=4cc6834a-df20-4cb3-ad55-79433346e000 / ext4 0 1" >> /mnt/etc/fstab
  2. chroot 進 /mnt,安裝 linux kernel,安裝並設定 grub bootloader。結束後退出 chroot 環境。(需root權限) chroot /mnt apt-get update apt-get install -y linux-image-amd64 apt-get install -y grub-pc grub-install /dev/hda update-grub exit
  3. umount 虛擬硬碟 (需 root 權限) bash umount /mnt

至此,rootfs.img裡面就是一個完整的 debian OS 了。可以用前面所說的方法,以 qemu 開啟。也可以將這個虛擬硬碟轉換為 qcow2 格式,可以佔用較小空間(但虛擬作業系統跑起來的時候則需多花一些計算效能)。

qemu-img convert -f raw -O qcow2 rootfs.img mydebian.qcow2

Ref: - QEMU - Debian Wiki - QEMU - ArchWiki - debian.org - Installing Debian GNU/Linux from a Unix/Linux System - QEMU/Networking - Creating a Debian Based QEMU Image

Update: Linaro 有提供 Debian Jessie 8.0 的 image: http://images.validation.linaro.org/kvm/jessie.img.gz