メモ

調べたり思いついたりしたことをメモします

Raspberry Pi (ラズベリーパイ) でFirefoxOSを動かしてみました

Amazonで Raspberry Pi を入手しました。

f:id:uenoshin:20140101225339j:plain

写真の上部の黒い線は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上のXmingXDMCPすることもできます。
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」にチェックを入れ、「再起動せずにインストール」ボタンを押します。

f:id:uenoshin:20131229222012p:plain

次にAndoridSDKへのパスを設定しておきます。
Jenkinsの管理 > システムの設定 > グローバル プロパティと辿って「環境変数」にチェックを入れるとキーと値のリストという入力フィールドが出てきますので設定してやります。

  • キー:PATH
  • 値:${PATH}:/path/to/sdk/tools:/path/to/sdk/platform-tools

ベアリポジトリ作成

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へ設定します。

新規ジョブを作成し、フリースタイルのジョブを選びます。

f:id:uenoshin:20131229223256p:plain

次の画面がジョブ設定のメインです。まずソースコード管理にgitを選択し、ベアリポジトリのパスを記載します。

f:id:uenoshin:20131229223935p:plain

次にビルド手順の追加のところで「Antの呼び出し」を選びます。

f:id:uenoshin:20131229224013p:plain

「Antの呼び出し」を選ぶと入力フォームが現れるのでその中に clean debugとでも記載しましょう。

f:id:uenoshin:20131229224120p:plain

作業リポジトリから 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を保持する仕組みを包含しているところがさすがブラウザ用のプロトコルスタックです。キャッシュ・cookieRFC的にも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で設定を作成します。

f:id:uenoshin:20131216142201p:plain

まず Display settings では "One winodw" を選びました。別に Fullscreen でも良いと思います。

f:id:uenoshin:20131216142337p:plain

Display settings で Multiple windows 以外を選ぶとこちらの Session type 画面で"Open session via XDMCP"を選ぶことができるようになります。

f:id:uenoshin:20131216142505p:plain

"Open session via XDMCP"を選んで次へ行くと XDMCP settings という画面になり、ここでは接続先のIPアドレスを入れます。

f:id:uenoshin:20131216142626p:plain

次の画面では Additional parameters を入れます。 "-screen 0" と入れました。

f:id:uenoshin:20131216142730p:plain

で、ここで 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のようなものです。

f:id:uenoshin:20131216133744p:plain

「Multiplewindows」を選びました。複数の画面が個別のウィンドウとして表示されますので見た目的にはWindowsと最も親和性があると思います。

f:id:uenoshin:20131216134053p:plain

こちらはXサーバ起動時、最初になにを開くかです。とりあえずターミナル画面でも開きたいので「Start a program」を選びました。

f:id:uenoshin:20131216134517p:plain

デフォルトではxtermと書かれていましたが個人的趣向により"gnome-terminal"としました。あと、PuTTYを使用するにチェックを入れ、接続先のIPアドレスとユーザ名を入れます。画像の例は私のubuntuマシンのIPとユーザ名なので環境に合わせてください。

f:id:uenoshin:20131216134822p:plain

次は起動時の追加パラメータですが特に必要ないのでそのままで「次へ」。

f:id:uenoshin:20131216135009p:plain

これで設定が完了です。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

これで完了です。