Raspberry Pi (ラズベリーパイ) でFirefoxOSを動かしてみました
Amazonで Raspberry Pi を入手しました。
写真の上部の黒い線はHDMIです。右上の白い小さいUSBが電源で、左上の白がLANケーブルです。あと、左側の黒いのはマウス・キーボードにつながるUSBです。
HDDやSSDに当たるモノは存在せず、SDカードがその役割を果たしています。
使い方は拍子抜けするほど簡単でした。
普通のSDカードをFAT32でフォーマットして、http://www.raspberrypi.org/downloadsにあるNOOBSのZIPファイルを展開し、SDカードの中にぶちまけるだけで準備が出来上がります。
Win32DiskImagerとか必要ありません。
NOOBSは「初心者」の意味かと思ったら「New Out of Box Software」だそうです。
Raspberry Pi にSDを刺して、マウス・キーボード・LAN・HDMIをつなげば配線は完了、給電用のUSBケーブルをつなぐと起動します。起動後は
https://github.com/raspberrypi/noobs/blob/master/README.md の説明にある通りインストールするOSを選択する画面が出てきます。推奨となっているRaspbianを選ぶとダウンロードが始まり、インストールされます。ちなみにインストール画面では言語設定を日本語へ変更することができるようになっています。が、これを日本語へ変えたところその後のコンソール画面で文字化けしていました。
後からでもいいので日本語フォントを入れた方が良いのかもしれません。
$ sudo apt-get install ttf-kochi-gothic xfonts-intl-japanese
こんな感じで普通にインストールできました。
普通にDebian系なのでubuntuによく似た操作感です。SSHを有効にしておけば他のマシンからターミナルでログインできますし、最初からlightdmが入ってますのでWindowsPC上のXmingでXDMCPすることもできます。
XDMCPの設定は、/etc/lightdm/lightdm.conf に下記のように設定するだけでOKでした。
[LightDM]
start-default-seat=false
xserver-allow-tcp=True
[SeatDefaults]
xserver-allow-tcp=false
greeter-session=lightdm-greeter
greeter-hide-users=true
session-wrapper=/etc/X11/Xsession
autologin-user=pi
[XDMCPServer]
enabled=true
Firefox OS を動かしてみました
先人達の足跡をたどるべく、http://www.slideshare.net/EnsekiTT/firefox-os-raspberry-pi-15769470 のとおり実行、なんなく起動まで行けました。画面が小さい場合は--screenを付けて調整できるようです。
$ ./b2g -profile profile --screen 1600x900
マウスポインタがすごく小さい赤い点なので一瞬操作方法を見失います。
OSというよりコマンドとして動いているのでこれをFirefoxOSと呼んでいいものやら悩みますが、エミュレータと違ってARMのHWで動作しているところに価値がありそうです。
起動されるプロセスはb2gの他はplugin-contaionが一個だけという潔さです。mediaserverもrildもありません。UIDは「pi」ユーザで動作します。ZTE-Openあたりの実装とはかなり違っていて強引に組み込んだ感が透けて見えました。これはこれでおもしろいです。
あとXmingの画面には表示されません。。DISPLAY環境変数には関係なくHDMIに出力される模様です。Xサーバに出すことができればHDMIもキーボードもマウスも取っ払ってしまってすっきりできるのですが・・・。
Jenkinsによる自動ビルド
Androidでアプリなんかを開発するとき、gitリポジトリへコミットするだけで勝手にビルドしてくれるとありがたいものです。継続的インテグレーション(CI)というやつです。
習慣的にこれをやっておくと思う以上に効率が上がります。プログラミングに向かう集中力が途切れないためかもしれませんね。 割り込みで思考が中断された後の割り込み復帰後は「さて、なにをやってたっけかな?」から始まるわけです。アタマが別なスコープに切り替わってしまったら、元の状態へ復帰するにはそれなりの時間が掛かってしまうのだと思います。
その環境を構築したときの手順を書いておきます。
Jenkinsのインストールと初期設定
次のようにしてインストールしました。環境はubuntu12.04(64bit)を使用しています。
(https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins+on+Ubuntu)
$ wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
$ sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list'
$ sudo apt-get update
$ sudo apt-get install jenkins
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが自動でインストールされましたが、もう必要とされていません:
gir1.2-ubuntuoneui-3.0 lib32ncurses5 lib32tinfo5 libtinfo-dev
libubuntuoneui-3.0-1 lib32tinfo-dev thunderbird-globalmenu
これらを削除するには 'apt-get autoremove' を利用してください。
以下の特別パッケージがインストールされます:
daemon
以下のパッケージが新たにインストールされます:
daemon jenkins
アップグレード: 0 個、新規インストール: 2 個、削除: 0 個、保留: 0 個。
60.2 MB のアーカイブを取得する必要があります。
この操作後に追加で 66.5 MB のディスク容量が消費されます。
続行しますか [Y/n]? y
取得:1 http://jp.archive.ubuntu.com/ubuntu/ precise/universe daemon amd64 0.6.4-1 [98.2 kB]
取得:2 http://pkg.jenkins-ci.org/debian/ binary/ jenkins 1.544 [60.1 MB]
60.2 MB を 1分 7秒 で取得しました (890 kB/s)
以前に未選択のパッケージ daemon を選択しています。
(データベースを読み込んでいます ... 現在 215812 個のファイルとディレクトリがインストールされています。)
(.../daemon_0.6.4-1_amd64.deb から) daemon を展開しています...
以前に未選択のパッケージ jenkins を選択しています。
(.../archives/jenkins_1.544_all.deb から) jenkins を展開しています...
man-db のトリガを処理しています ...
ureadahead のトリガを処理しています ...
daemon (0.6.4-1) を設定しています ...
jenkins (1.544) を設定しています ...
システムユーザ `jenkins' (UID 116) を追加しています...
新しいユーザー `jenkins' (UID 116) をグループ `nogroup' に追加しています...
ホームディレクトリ `/var/lib/jenkins' を作成しません。
* Starting Jenkins Continuous Integration Server jenkins [ OK ]
これでデフォルトではブラウザからポート8080でJenkinsのダッシュボードへ行けると思います。ubuntuのIPが192.168.0.1だとしたら http://192.168.0.1:8080/ です。
ダッシュボードから git plugin をインストールしておきます。
Jenkinsの管理 > プラグインの管理 > 利用可能タブ と辿って「git plugin」にチェックを入れ、「再起動せずにインストール」ボタンを押します。
次にAndoridSDKへのパスを設定しておきます。
Jenkinsの管理 > システムの設定 > グローバル プロパティと辿って「環境変数」にチェックを入れるとキーと値のリストという入力フィールドが出てきますので設定してやります。
ベアリポジトリ作成
Jenkinsをインストールしたのと同じマシン上にベアリポジトリを作ります。Jenkinsはこれを自らのワーク領域へgit clone
してビルドします。
$ mkdir myapp.git
$ cd myapp.git
$ git init --bare --share
ベアリポジトリにフックを書く
ベアリポジトリに対してgit push
があったらビルドします。それを自動化するためベアリポジトリ内にフックを書きましょう。
先ほど作ったベアリポジトリ内のhooksへ移動します。
$ cd hooks
この中へpost-update
というファイルを作成します。中身は下記のように書けばよいでしょう。testの箇所は後述するJenkinsのジョブ作成で作ったジョブの名前を入れてください。
#!/bin/sh
wget -q "http://localhost:8080/job/test/build?delay=0"
作成したら実行権を与えます。
$ chmod +x post-update
Jenkinsのジョブ作成
どうやってビルドするかをJenkinsへ設定します。
新規ジョブを作成し、フリースタイルのジョブを選びます。
次の画面がジョブ設定のメインです。まずソースコード管理にgitを選択し、ベアリポジトリのパスを記載します。
次にビルド手順の追加のところで「Antの呼び出し」を選びます。
「Antの呼び出し」を選ぶと入力フォームが現れるのでその中に clean
debug
とでも記載しましょう。
作業リポジトリから git push
ベアリポジトリからcloneして作業用リポジトリを作り、コミット、pushします。
$ git clone /path/to/myapp.git
$ cd myapp
・・・ソースコードを編集・・・
$ git add .
$ git commit -m "first commit"
$ git push origin
pushするとJenkinsが自動的にビルドまで行ってくれるはずです。
FirefoxOS のネットワーク層
Firefox OS Advent Calendar 2013 用の記事です。といっても最近勉強しはじめたばかりなのであまり深く突っ込んだ内容は書けそうもなく、たまたま興味を持って見始めていた箇所で簡単に書いてみたいと思います。
勉強中の身ですので文中に間違いがあるかもしれません。こっそり教えて頂ければ幸いです。
Neckoの話です
FxOSだけでなくブラウザとしてのFirefoxでも共通だと思います。ネットワーク層はNeckoと呼ばれるソフトブロックで構成されていて、URIに対する通信チャネルを作成できるようになっています。
位置的にはGecko内部に存在していて、/B2G/gecko/netwerk 配下に展開されています。netwerkというディレクトリ名がnetworkのtypoなのかな?と思えるのですが、調べたところオランダ語でnetwerkと表現するそうですね。これが語源なのかどうかは知りませんが。
レイヤはOSI参照モデルで言うところのレイヤ4~7までを包含しています。つまりTCP層のレイヤ4から始まってセッション管理やMIME処理などを行い、アプリケーション層のHTTP/HTTPS/FTPあたりまでを実現できることになります。IPより下はsocketを使用します。(SSL/TLSも含んでいて、ここはレイヤ3.5あたりだと思うので少々不正確な言い方をしたかもしれません。)
IP層以下の層での接続に関しては、Necko内にWifi接続があるようです。他の接続は外に(rildとか)追い出されているようなので、このあたりの設計ポリシーはちょっとまだよく分かっていません。
汎用のプロトコルスタックみたいに使えるようですが、キャッシュ・cookieを保持する仕組みを包含しているところがさすがブラウザ用のプロトコルスタックです。キャッシュ・cookieはRFC的にもHTTPと一体的なので切っても切れない関係にあるのだと思います。
FxOSの日本語対応はまだ途上だと思うのですが、Firefoxブラウザと共通品と見えて Accept-Language ヘッダは ja の指定も可能になっています。結構枯れた技術と思いきやSPDY1.3の対応が取り込まれていたりしますし、翌年にはHTTP/2.0にも対応されることになるのでしょう。
使い方としては、nsIIOServiceのnewURIにURIを渡して、newChannelFromURIでチャネル(nsIChannel)を作り、asyncOpenでコネクション確立に向かうのがHTTPの基本的フローのようです。この辺をとっかかりに徐々にコードリーディングしていきたいと思います。読み始めて間もないので薄い内容ですみません、もうちょっと詳しくなったらまた更新するかもです。
repo のコマンド
AndoroidやFirefoxOSをやっていると避けて通れないのがgit/repoです。 gitは文献豊富だし多くのサイトで解説が為されているので情報収集に苦労しないのですが、repoはあまり情報がなくて困ることがあります。 コマンド一覧を書いておきます。
サブコマンド一覧
まずサブコマンドの一覧はこんな感じです。
$ repo help --all
usage: repo COMMAND [ARGS]
The complete list of recognized repo commands are:
abandon Permanently abandon a development branch
branch View current topic branches
branches View current topic branches
checkout Checkout a branch for development
cherry-pick Cherry-pick a change.
diff Show changes between commit and working tree
download Download and checkout a change
forall Run a shell command in each project
grep Print lines matching a pattern
help Display detailed help on a command
info Get info on the manifest branch, current branch or unmerged branc
init Initialize repo in the current directory
list List projects and their associated directories
manifest Manifest inspection utility
overview Display overview of unmerged project branches
prune Prune (delete) already merged topics
rebase Rebase local branches on upstream branch
selfupdate Update repo to the latest version
smartsync Update working tree to the latest known good revision
stage Stage file(s) for commit
start Start a new branch for development
status Show the working tree status
sync Update working tree to the latest revision
upload Upload changes for code review
version Display the version of repo
repo abandon <branchname> [<project>...]
指定したprojectにgit branch -D <branchname>
をやってまわるのと同じ。ローカルリポジトリからブランチを削除します。
repo branch [<project>...]
repo branches [<project>...]
この二つは同じ動きをするようです。指定したprojectのローカルブランチ一覧を表示します。
repo checkout <branchname> [<project>...]
指定したprojectにgit checkout <branchname>
をやってまわるのと同じ。指定したブランチ名でチェックアウトします。
repo cherry-pick <sha1>
ローカルリポジトリ中に存在する<sha1>
のコミットを現在のブランチへマージします。
repo diff [<project>...]
ワークツリーと、コミット済みの内容とを比べます。
repo download {project change[/patchset]}...
gerritのようなレビューシステムから変更点をダウンロードします。
repo upload
と逆の動きをするコマンドです。
repo forall [<project>...] -c <command> [<arg>...]
指定したcommandを、指定したproject達に対して順々に全部対応します。かなり便利なコマンドです。
repo grep {pattern | -e pattern} [<project>...]
指定した指定したproject内からpatternにマッチするものを検索します。
repo help
コマンド一覧の出力
repo info [-dl] [-o [-b]] [<project>...]
指定したprojectごとの、パスやリビジョン、ローカルブランチ数が見れます。
repo init [options]
よく使う初期化するコマンド。カレントディレクトリに".repo"ディレクトリができてその中に環境が構築されます。-uオプションでマニフェストファイルへのURLを、-bオプションでリビジョンを指定する使い方が多いです。
repo list [-f] [<project>...]
プロジェクトのリストを表示します。
repo manifest [-o {-|NAME.xml} [-r]]
-oを使ってマニフェストファイルをエクスポートできます。local_manifest.xmlも使っている場合は合体して1ファイルのマニフェストにしたものが出力されます。
repo overview [--current-branch] [<project>...]
指定したprojectごとの、未マージの情報が出力されます。
repo prune [<project>...]
マージされ済みのトピックブランチを削除します。
repo rebase {[<project>...] | -i <project>...}
リモートのブランチで、現在のローカルブランチをrebaseします。
repo selfupdate
repoコマンド自身を最新版にアップグレードします。 デフォルトでは https://gerrit.googlesource.com/git-repo から引っ張ってきます。
repo smartsync [<project>...]
repo sync -s と同じです。 最終のブランチでワークツリーを更新します。
repo start <newbranchname> [--all | <project>...]
指定したproject全部に対してローカルブランチを作成します。
repo status [<project>...]
指定したproject全部に対して git status を実行するような感じです。
repo sync [<project>...]
最後に指定したリビジョンで、リモートリポジトリからアップデートを行います。
repo upload [--re --cc] [<project>]...
レビューサーバへアップします。修正が終わってレビュー依頼するときに使います。 送信先はマニフェストファイルの review に書かれたURLです。
repo version
repoコマンド自身のバージョンを表示します。
Xサーバでubuntuを使う(XDMCP版)
前回はMultiWindowで設定しましたがデスクトップ画面が見たくなったのでXDMCPにしてみました。
ubuntu側の設定
ubuntuはLightDMというディスプレイマネージャが入っています。このLightDMに対してXDMCPを有効とする設定をしてやればOKです。
$sudo vi /etc/lightdm/lightdm.conf
下記の内容を追記するだけです。
[XDMCPServer]
enabled=true
あとはLightDMを再起動してやれば設定が有効になります。
$sudo restart lightdm
Xming側の設定
XLaunchで設定を作成します。
まず Display settings では "One winodw" を選びました。別に Fullscreen でも良いと思います。
Display settings で Multiple windows 以外を選ぶとこちらの Session type 画面で"Open session via XDMCP"を選ぶことができるようになります。
"Open session via XDMCP"を選んで次へ行くと XDMCP settings という画面になり、ここでは接続先のIPアドレスを入れます。
次の画面では Additional parameters を入れます。 "-screen 0" と入れました。
で、ここで Save configuration で設定を保存します。完了ボタンを押せば起動するはずです。
苦戦したことの覚え書き
最初うまく接続できず苦労しました。
$ sudo vi /var/log/lightdm/lightdm.log
ここにLightDMのログがあるので見てみたところ、Windows→ubuntu への要求時に渡されるIPアドレスがうそっぱちな値になっていました。そのせいで接続タイムアウトしていたようです。
なんでこんなIPが・・と調べたところ私のWindowsにはVMware用の「VMware Network Adapter VMnet1」「VMware Network Adapter VMnet8」のようなネットワークアダプタが設定されており、こいつのIPが使われようとしていたためでした。これらのアダプタを無効化して無事接続完了。
ログイン画面が出てログインできるとこまでは行ったのですが、その後は壁紙しか見えない・・・。ちゃんと起動できていない模様です。
どうも「ubuntu2D」を選ばないと動かない模様。ログイン画面のところで切り替えて、無事に立ち上がりました。
XDMCPの方はこれで完了なのですが、この後 Multi Windows の設定の方が起動できなくなってしまいました。
$ sudo vi /etc/ssh/sshd_config
sshの設定ファイルに
AddressFamily inet
と書き込むことで対応できました。
$ sudo service ssh restart
ssh を再起動して完了です。
Xサーバでubuntuを使う
ubuntu12.04にWindowsPCからTeraTermでログインして作業しています。 滅多な事でGUIを使わないのでTeraTermが大好きなのですが、極々まれにGUIが必要な場面もあったりしますのでWindowsPCにXサーバを入れました。
なぜubuntuの前に行ってデスクトップを使わないのかというと、ubuntuのマシンにはキーボードもマウスもモニタすらも繋げていないためです。すみません。。
インストール
下記サイトで公開されているフリーのXサーバであるXmingを使いました。
Xming X Server for Windows プロジェクト日本語トップページ - SourceForge.JP
Xming-6-9-0-31-setup.exe をダウンロードして実行、簡単にインストールが終わります。私はWindows8.1(64bit)に入れましたが問題なく動作しています。
設定
インストール後、XLaunchを起動します。これはランチャにもなる設定ファイルを作ってくれるWizardのようなものです。
「Multiplewindows」を選びました。複数の画面が個別のウィンドウとして表示されますので見た目的にはWindowsと最も親和性があると思います。
こちらはXサーバ起動時、最初になにを開くかです。とりあえずターミナル画面でも開きたいので「Start a program」を選びました。
デフォルトではxtermと書かれていましたが個人的趣向により"gnome-terminal"としました。あと、PuTTYを使用するにチェックを入れ、接続先のIPアドレスとユーザ名を入れます。画像の例は私のubuntuマシンのIPとユーザ名なので環境に合わせてください。
次は起動時の追加パラメータですが特に必要ないのでそのままで「次へ」。
これで設定が完了です。Save configuration のボタンを押してファイルを適当な所へ保存してください。次からはそれをダブルクリックするだけで起動できるようになります。
ubuntu12.04にsun-java6をインストールする方法
AndroidにしてもFirefoxOSにしても推奨ビルド環境にubuntuを指定している割に、必要なJDKはsun-java6だったりします。ですがubuntuで普通に apt-get install java なんてやってもOpenJDKが入っちゃうのでうまくいきません。
やむなく個別にインストールすることになりますのでその手順をご紹介します。というか自分用のリマインダーです。
githubに公開されている OAB-Java というのを使います。古いバージョンだと動きません。現時点で最新は0.3.0です。
$ wget https://github.com/flexiondotorg/oab-java6/raw/0.3.0/oab-java.sh -O oab-java.sh
$ chmod +x oab-java.sh
$ sudo ./oab-java.sh
0.3.0が最新なら上記の手順でOKですが、新しくなっていないか念のためチェックをお薦めします。 こちらのサイトです。→ https://github.com/flexiondotorg/oab-java6
で、スクリプトの実行が終わったらあとは普通にインストールできます。
$ sudo apt-get install sun-java6-jdk
これで完了です。