« 2010年2月 | メイン | 2010年5月 »

2010年4月

2010年4月30日 (金)

KVM にシリアルコンソールで Ubuntu をインストールする

最近はインフラ屋な山本です。

KVMにシリアルコンソールで Ubuntu をインストールする、と題しているわけですが、
やりたいことはこんな感じです。

  • インターネットにつながらない環境で
  • X Window System とか VNC とかを使わずに
  • Ubuntu Server をゲスト VM にインストール

実は、インターネットにつながる環境だとこれはとても簡単です。こんな感じ。

$ sudo virt-install --connect=qemu:///system -n test \
  -r 2048 --serial pty -v --disk=... --nographics \
  -l http://us.archives.ubuntu.com/ubuntu/dists/lucid/main/installer-amd64/ \
  --extra-args=console=ttyS0,9600

"-l http://..." を "-c ISO_FILE" に置き換えたいところなわけですが、うまくいきません。ブートローダーがシリアルコンソールを認識しないんですかね。

そこで少し考えると、上のコマンドがうまくいく理由はおそらく、kernel をダウンロードしてきて "console=ttyS0" というカーネルブートパラメーターを与えて QEMU だか KVM だかがブートローダーがわりにブートしているんでしょう。推測ですが。

そこまで推測したらやることはひとつ、ISO をループバックマウントです。こんな感じ。

$ sudo mount -t iso9660 -o loop,ro \
  ubuntu-10.04-server-amd64.iso /home/cybozu/cdrom

そして "-l http://..." を "-l /home/cybozu/cdrom/install" にしてみます。が、動きません。そこでおもむろに virt-install のコード(Python)を眺めると、以下のことがわかります。

  • OSDistro.py がディストリビューションの自動判別をしている
  • Ubuntu の自動判別に用いているファイルやディレクトリが ISO にはない
  • でも、ISOにブートに必要なカーネルや initrd は存在する

ここまでわかればやることはひとつ。OSDistro.py にパッチをあてちゃいましょう。パッチは Ubuntu 10.04 専用ですけど、やってることは単純なんで他の distro に対応させたければ同じようにやってみてください。

あとひとつ。OSDitro.py は元々ネットワークインストール用にできてるのですが、このパッチをあてることで、DVDブート用のカーネルを立ち上げるようになります。が、当然 DVD が見える必要があるので、"--disk=ISO_FILE,device=cdrom,perms=ro" も追加します。

パッチをあてた virt-install で以下のように実行すると、見事シリアルコンソールで Ubuntu Server のインストールが開始できます。VNCやXやネットワークが使えないことはそうそうないでしょうけど、インフラ屋的にはとっても嬉しい?かなと。

$ sudo virt-install --connect=qemu:///system -n test -r 2048 \
  --serial pty -v --disk=... --nographics \
  --disk=ubuntu-10.04-server-amd64.iso,device=cdrom,perms=ro \
  -l /home/cybozu/cdrom/install --extra-args=console=ttyS0,9600

インストールが終わったら、そのままシリアル端末でログインできます。
ログインしたら、grub やゲストのVMカーネルがシリアル端末を使うように設定します。
c.f. Ubuntu Wiki

$ sudo vi /etc/default/grub
  GRUB_CMDLINE_LINUX="console=ttyS0,9600"
  GRUB_TERMINAL=serial
$ sudo update-grub $ sudo poweroff

最後にゲストVMの定義ファイルから、ISOファイルを削除しておきましょう。

$ virsh edit test
$ virsh start test

ゲストVMのシリアル端末には以下のコマンドでアクセスできます。

$ sudo virsh console test

以上です。

--
http://twitter.com/tnnrg

2010年4月15日 (木)

本気で作るWindows Mobileアプリケーション(1) - サイボウズモバイル KUNAIのアーキテクチャ

Kunai_3

こんにちは。サイボウズ開発部モバイル・リモートチームの米川です。
本日「サイボウズモバイル KUNAI for Windows(R) phone」(以下 KUNAI)がリリースされました。
それを記念して、KUNAIのアーキテクチャや技術的なトピックについて、
ご紹介させていただこうと思います。

KUNAIとは
KUNAIはWindows Mobile用のクライアントアプリケーションです。
グループウェアのスケジュール、メール、アドレス帳に加え、社内メールやワークフローのデータを
端末上にシンクし、いつでもどこでも利用することができます。

KUNAIは.NET Compact Framework 2.0を採用し、C#で書かれていますが、
後述するToday Pluginや、インストーラーなどの一部はC++で実装されています。
ローカルへのデータの保存にはSQLiteを採用しています。

アーキテクチャ
KUNAIは大きくわけて以下の2つの要素で構成されています。

- Today Plugin
- C# アプリケーション

Today Pluginは待ち受け画面を拡張するためにWindows Mobileに用意された仕組みです。
KUNAIは、Today Pluginの仕組みを使って待ち受け画面をカスタマイズしています。
C#アプリケーションは.NET Compact Framework 2.0上で実装されており、
各アプリケーションの機能やシンク処理などを担当します。

Today PluginとC#アプリケーションは、ウインドウメッセージでやり取りをし、
C#アプリケーションの起動やシンクの開始、データの取得を行います。
逆にC#側からToday Pluginに対して指示を出すことも可能で、
画面の更新などをデータが更新されたタイミングで行うことが可能です。

基本的には、SQLやXMLなどが絡む複雑な処理はC#で実装し、
必要に応じてToday Pluginに受け渡す、というアーキテクチャになっています。

リストコントロール
Windows Mobile 6.5では、標準のWindowsコントロールがタッチインタフェースに対応しました。
これは確かに何も考えなくてもアプリケーションのタッチ対応ができるので便利です。
しかしKUNAIはサイボウズならではのUIを実現するために、より柔軟で高度なインタフェースを実現する仕組みが必要でした。

そのためKUNAIのリストコントロールは、UIをプログラムで描画すること前提として設計されています。
もちろん簡単なプロパティの変更などはデザイナ上で行えるようになっていますが、
リストアイテムの細かい描画処理はすべてプログラマが記載します。
その代わりにスクロールやタッチ処理などは全てListControlクラスがやってくれるため、
開発時にはリストアイテムの描画処理だけを書けばよいことになります。

例えば以下のようなコードを書きます。

TitleListItem itemTitleItem = new TitleListItem();
itemTitleItem.Text = "タイトル";
this.accountNameListControl.Items.Add(itemTitleItem);
MultiLineListItem textItem = new MultiLineListItem(); textItem.Text = "サイボウズモバイル KUNAI"; textItem.TextAlignment = DrawUtility.HorizontalAlignment.Center; this.accountNameListControl.Items.Add(textItem);
TitleListItem itemTitleItem2 = new TitleListItem(); itemTitleItem2.Text = "チェック"; this.accountNameListControl.Items.Add(itemTitleItem2);
BoolBindingListItem useItem = new BoolBindingListItem(); useItem.ShowCheckBox = true; useItem.Text = "利用する"; useItem.Margin = 4; this.accountNameListControl.Items.Add(useItem);

MultilineListItemやTitleListItemなどはフレームワークとして用意しているので、
複数行文字列を表示するだけ、などの時であれば自分で描画処理を書かなくていいようになっています。
当然自作のリストアイテムも再利用できるため、同じような画面で重複してリストアイテムを作る必要はありません。
このコードを実行すると以下のような画面が表示されます。

Listcontrol_2

リストコントロールはKUNAIの中でも中核となる機構なので、
その中には様々なノウハウとテクニックが存在しています。
この詳しい実装についてはまた別の記事でご紹介します。

FormBase
KUNAIの画面は通常のFormクラスではなく、それを継承した自作のFormBaseというクラスの子クラスです。
FormBaseは以下の機能を提供します。
- 画面の表示順を考慮したダイアログの表示
- Formの親子関係の管理
- ソフトウエアキーボードボタン(SIPボタン)の表示/非表示
- 画面をリフレッシュする必要のあるイベントの登録

KUNAIでは、メールを読んで返信するためにスケジュールを確認する、のようなことをできるように
アプリケーションごとに、さっきまで操作していた画面を覚えておくようになっています。
つまりメールの詳細画面を開いた状態でTodayに戻り、スケジュールアプリを立ち上げ、
再度メールのアプリを表示した時に、先程の詳細画面がそのまま表示されます。

しかし、Windows Mobileではダイアログの表示順が複雑で、通常のFormクラスで
ShowとShowDialogを使って画面を表示していては、どうしてもこの挙動を実現できませんでした。
そのために自作のFormBaseを作成し、Form同士の親子関係を管理することで
適切な画面を表示できるようにしました。

また、入力が必要無いところではSIPボタンが邪魔になるので、
画面ごとにこれを非表示にできる機能を実装しています。

listView.ShowSip = false;

内部的にはP/Invokeを使ってSIPボタンのウインドウハンドルを取得したりと
意外と面倒なことをしています。
しかしこの処理を行うと、そのままだとすべての画面でSIPボタンが消えてしまうため、
画面がDeactivateする時には必ずSIPボタンを表示するようにしています。

まとめ
いかがでしょうか。
ご紹介したのはほんの一部で、KUNAIにはまだまだたくさんのノウハウやテクニックが詰め込まれています。
これから何回かに分けて、それらをご紹介させていただきたいと思います。

それではサイボウズモバイル KUNAIをよろしくお願いいたします。

サイボウズモバイル KUNAI