最近 Canonical 公司在 IoT 的浪潮下,也開始力推自己的系統,稱為 Snappy ;例如這個 Canonical 的創辦人在 youtube 的介紹影片。喜歡湊熱鬧的我,也跳進來攪和了一下,瞧瞧 Snappy 究竟是什麼。
這次湊熱鬧所選用的硬體為 Raspberry Pi 2 (RP2)。下面的 demo 主要是參考 Snappy 官方文件,加上一些個人心得。
事前準備
Snappy 在 RP2 上面目前(2015五月)還沒有官方釋出,不過已經有開發者準備好了移植到 RP2 的映像檔案,可以從這裡下載,取得映像檔 pi2.img.gz 。解壓縮後取得檔案 pi2.img ,將 pi2.img 透過指令 dd 寫入 micro SD 裝置 /dev/sdX (根據你的系統狀況,請自行用適當字串代換 sdX ) [1][2]
sudo dd if=pi2.img of=/dev/sdX
映像檔接近 4G ,讀寫要花上一點時間。如果想知道 dd 的進度,可以用這個技巧偷看一下寫入進度。讀寫完畢後,將 micro SD 插到 RP2 上面、開啟電源。預設帳號、密碼都是 ubuntu ,登入後就可以開始玩了。
因為設計上是給物連網 client 端產品使用,基於效能考量,當然不會有圖形介面。操作上可以選擇使用 RP2 的 HDMI 輸出,或是像我所採取的作法:第一次使用 HDMI 登入,登入後使用 ifconfig 取得 RP2 Snappy 的 IP ,之後都透過自己慣用的作業系統,透過 ssh 登入 RP2 Snappy 。RP2 Snappy image 已經將 ssh server 服務事先準備好,因此直接從慣用的作業連過去就好。[3] 例如使用這個指令(IP 位置視您的環境而定):
ssh ubuntu@<您的 RP2 Snappy IP> ex. ssh ubuntu@192.168.1.23
Let's party!!
接下來就是今天的重頭戲了。下達指令 snappy info
(RaspberryPi2)ubuntu@localhost:~$ snappy info release: ubuntu-core/devel architecture: armhf frameworks: apps:
release 和 architecture 分別就是 image release 版本和適用的平台類型,RP2 使用 ARM ,所以是 armhf 版本。frameworks 和 apps 分別是什麼意思呢? 望文生義, apps 很明顯就是 applications ,那 frameworks 呢?
簡而言之,根據官方文件,framework 在這邊指的是一個獨立的、因目的導向而事先配置好所需軟硬體資源存取管道的「環境」。
「獨立的」,意指各個 framework (與該 framework 下的 apps) 彼此之間不互相影響,所以可以顧及安全問題(檔案權限不會被亂改、存放密碼的檔案別人讀不到等)。
一般 IoT client side device,通常為了滿足某種目的,都會依照該目的,去設計、製造、配置所需的對應資源。例如,假設有個瓦斯洩漏偵測器,可以在偵測到一氧化碳時,將警告與一氧化碳濃度值送到我們的手機裡面。所以這個裝置,起碼必須要有一氧化碳偵測器、網路連線(此處假設我們選用乙太網路)。而一個這樣的瓦斯洩漏偵測器 framework ,就會保證所有在這個偵測器下的 applications ,可以取用到一氧化碳偵測器的讀數、和取用系統乙太網路資料。
說得落落長又很抽象,直接舉例,docker 就可以是一個提供 framework 服務的工具。
接著我們看一下這個 snappy 系統中,裝了什麼 snappy 套件
(RaspberryPi2)ubuntu@localhost:~$ snappy list Name Date Version Developer ubuntu-core 2015-04-10 4 pi2 2015-04-15 0.11 lool
系統還很乾淨,就只有 ubuntu-core (官方文件稱這是一種 system-layer)和 pi2 (官方文件稱這個叫做 OEM snappy package or device) 而已。[4]
好吧!我們來裝 framework 和 app 吧!
framework 我們選擇使用 docker ;可以看出來裝了 docker 之後, snappy list 就多了這個 snappy package 。
(RaspberryPi2)ubuntu@localhost:~$ sudo snappy install docker Installing docker Starting download of docker.canonical 8.36 MB / 8.36 MB [====================================] 100.00 % 41.93 KB/s Done Name Date Version Developer ubuntu-core 2015-04-10 4 docker 2015-05-31 1.6.1.002 pi2 2015-04-15 0.11 lool
(RaspberryPi2)ubuntu@localhost:~$ snappy list Name Date Version Developer ubuntu-core 2015-04-10 4 docker 2015-05-31 1.6.1.002 pi2 2015-04-15 0.11 lool
請注意這時候已經有 framework docker 了[5]
(RaspberryPi2)ubuntu@localhost:~$ snappy info release: ubuntu-core/devel architecture: armhf frameworks: docker apps:
app 我們選用 go-example-webserver
(RaspberryPi2)ubuntu@localhost:~$ sudo snappy install go-example-webserver Installing go-example-webserver Starting download of go-example-webserver.canonical 3.06 MB / 3.06 MB [================================] 100.00 % 44.75 KB/s Done Name Date Version Developer ubuntu-core 2015-04-10 4 docker 2015-05-31 1.6.1.002 go-example-webserver 2015-05-31 1.0.7 pi2 2015-04-15 0.11 lool
(RaspberryPi2)ubuntu@localhost:~$ snappy list Name Date Version Developer ubuntu-core 2015-04-10 4 docker 2015-05-31 1.6.1.002 go-example-webserver 2015-05-31 1.0.7 pi2 2015-04-15 0.11 lool
這時候 apps 果然也補上了 go-example-webserver
(RaspberryPi2)ubuntu@localhost:~$ snappy info release: ubuntu-core/devel architecture: armhf frameworks: docker apps: go-example-webserver
go-example-webserver 是一個用 go 寫成、用來做 snappy 打包教學的 snappy 套件,原始碼可以在 Launchpad 上面找到。
當初以為裝了 go-example-webserver 以後,web server 的服務會自己啟動,搞了半天發現根本沒有自己啟動,不曉得這是 by-design 還是一個 bug 。最後我直接參考原始碼(裡面有 README),手動尋找執行 web 服務的指令、並且啟用服務:
尋找可能可以用的指令
root@localhost:/# find ./ -name go-example-webserver ./var/lib/apps/go-example-webserver ./writable/system-data/var/lib/apps/go-example-webserver ./writable/system-data/apps/go-example-webserver ./writable/system-data/apps/go-example-webserver/1.0.7/magic-bin/go-example-webserver ./writable/system-data/apps/go-example-webserver/1.0.7/magic-bin/arm-linux-gnueabihf/go-example-webserver ./writable/system-data/apps/go-example-webserver/1.0.7/magic-bin/x86_64-linux-gnu/go-example-webserver ./apps/go-example-webserver ./apps/go-example-webserver/1.0.7/magic-bin/go-example-webserver ./apps/go-example-webserver/1.0.7/magic-bin/arm-linux-gnueabihf/go-example-webserver ./apps/go-example-webserver/1.0.7/magic-bin/x86_64-linux-gnu/go-example-webserver
這裡有兩點滿有意思,第一是 /var/lib/apps/go-example-webserver 是空的,不曉得在其他 Snappy package 中,實際上會放入什麼樣類型的檔案。第二是整個 app 程式似乎就是集中在 /apps 這個資料夾裡。
找到疑似可以用的可執行檔後,直接給他執行下去啦!
(RaspberryPi2)ubuntu@localhost:/apps/go-example-webserver/1.0.7$ ./magic-bin/go-example-webserver snapp_name: go-example-webserver snapp_bin: go-example-webserver snapp_dir: /apps/go-example-webserver/1.0.7 snapp_org_bin: go-example-webserver plat_abi: arm-linux-gnueabihf 2015/05/31 10:06:53 Starting webserver on :8081
最後開啟本地端(不是 RP2 ,而是,例如說,你慣用的作業系統)的瀏覽器,瀏覽器 url 填入 RP2 的 IP ,port 8081 (這是上面執行時,程式告訴我的)。一切順利的話,應該就可以看到下面的畫面。另外,在 RP2 中可以使用 ctrl+c 以中斷程式伺服器服務的運行。
[1] 注意!!這個指令在使用之前務必確定知道自己在做什麼。這個指令操作錯誤的話有可能抹除您系統裡面的資料。
[2] 如果使用上有問題,例如 Snappy 操作起來怪怪的,像我遇到的問題就是明明已經把 docker 裝上去了,但是 snappy list 卻看不到這個訊息。遇到這種情況的話,可以試試 dd 前先把 micro SD 上面的 partition 全部清掉之後,再用 dd 寫入。寫入完畢後,下達兩三次 sync 指令,確認所有必要的訊息都寫進 micro SD ,再將 micro SD 退出、插到 RP2 上面。
[3] 在這之前,當然要先確定慣用的作業系統和 RP2 在同一個、彼此可以看見彼此、允許 ssh 通訊 port 的網域。
[4] 根據官方文件,在未來 system-layer 和 device package 會整合成一個 snappy package 。
[5] Snappy for RP2 似乎不太穩定;有時候我明明已經裝了 docker ,但是把系統放在那邊一陣子,大約二十分鐘, snappy info 卻看不到 docker 了。reboot 之後再安裝一次 docker 還會報錯。不太確定是不是自己有哪裡不清楚,或是真的是一個 bug ;需要更多測試與資訊。