kikumotoのメモ帳

インフラ・ミドル周りを中心に、興味をもったことを適当な感じで。twitter : @takakiku

さくらのVPSにVyattaを入れて、Amazon VPCにVPN接続

第8回JAWS-UGに参加して、そこで富士ソフトの飯尾さんが話したVPCの話題、面白かったです。

ということで、年内にAWS東京リージョンに追加されるはずのVPCを試しおかなきゃ、、、、

といっても、ネットワーク装置なんて持ってないので、さくらのVPSにVyattaを入れて接続することを試みたのでそれをメモしておく。

さくらのVPSにVyattaをインストール

これは、

を参考にして実施。

Amazon VPCの構築

今回は、AWS Management Consoleを使ってVPCを構築する。

以下のような流れで画面を操作する。

  • VPC タブを選択
  • Region は "US East" を選択
  • "Get started creating a VPC" ボタンをクリック
  • "VPC with a Private Subnet Only and Hardware VPN Access" を選択して、"Continue"。
  • "Customer Gateway" にさくらのVPSのIPを入力して、"Continue"。
  • デフォルトをそのまま受け入れて、"Create VPC"。

以上で、VPCの構築がはじまるのでしばし待つ。

構築が終わると、Customer Gateway を設定するための設定データをダウンロードできる。

  • "Download Configutaion" をクリック。
  • "Vendor" を "Generic" に変更。
  • "Yes, Download" をクリック。

ダウンロードしたファイルは後で使うので保存しておく。

VPCのSecurity Groups

VPCの構築後、そのVPC内で立ち上げるEC2 インスタンスのためのSecurity Groupsを設定する。

これも AWS Management Console の VPC タブで以下のように操作をする。

  • 左ペインの"Security Groups"をクリック。
  • "default"にチェック。
  • 下ペインに表示される"Inbound"タブをクリック。
  • "Create a new rule"で"SSH"を選択。
  • "Source"を"172.22.0.0/24"に変更。
    • 今回、さくらのVPSにダミーで用意した内部ネットワークのアドレス帯が"172.22.0.0/24"。
  • "Add Rule"をクリック。
  • 引き続き、"Create a new rule"で"Custom ICMP rule"を選択。
    • このルールは、単にインスタンスへのPingによる疎通確認を行いたいので追加している。
  • "Type"を"Echo Request"に変更。
  • "Source"を"172.22.0.0/24"に変更。
  • "Add Rule"をクリック。
  • "Apply Rule Changes"をクリック。

これでSecurity Groupsの設定は完了。

VPC内にEC2インスタンスを起動

AWS Management ConsoleのEC2タブから、"US East" Regionにインスタンスを作成する。

今回の手順。

  • "Launch Instance"をクリック
  • "Basic 32-bit Amazon Linux AMI 2011.02.1 Beta"を選択。
  • "Launch Instances Into Your Virtual Private Cloud"を選択する。SubnetID はここまでの手順であれば1つしか作っていないので、そのままにして "Continue"。
  • "IP Adderess"はからのままで "Continue"。
  • Tag は必要であれば適宜入力して "Continue"。
  • Key Pairsは適宜設定して "Continue"。
  • "Choose one or more of your existing Security Groups"から、先に修正した default Security Groupsを選択して"Continue"。
  • 最後に内容を確認して "Launch"。

Vyattaを構成

VyattaでAmazon VPCに接続するために参考にさせてもらったのは以下のページ

まずさくらのVPS側の情報としては以下を使う。

 グルーバルIPv4アドレス: 49.212.xx.xx/23
 Gateway        : 49.212.22.1

なお、今回はさくらのVPSサーバ内に仮想的なプライベートアドレスとして 172.22.0.101/24 も用意している。

また、先にVPCの構成時にダウロードしたファイルから使う値(ファイル毎に違うもの)は以下の通り。
ちなみに、今回使うのは IPSec Tunnel #1 の情報のみ。(Pre-Shared Key は本来秘密にしておくもの。以下のKeyはすでに破棄したVPCのKeyです)

 Pre-Shared Key           : vvFWtUb7xtBcKkYsTInb8g.6CveKDdS0

 Outside IP Addresses:
   - Customer Gateway:        : 49.212.xx.xx 
   - VPN Gateway              : 72.21.209.225
		
 Inside IP Addresses
   - Customer Gateway         : 169.254.255.2/30
   - VPN Gateway              : 169.254.255.1/30

 BGP Configuration Options:
   - Customer Gateway ASN     : 65000 
   - VPN Gateway ASN          : 7224
   - Neighbor IP Address      : 169.254.255.1

あと、VPCのネットワーク情報としては、

 10.0.0.0/16

を使う。

これらの情報をもとにすると、Vyattaに流し込む設定は以下のようになる。

interfaces {
    ethernet eth0 {
        address 49.212.xx.xx/23
        address 172.22.0.101/24
        address 169.254.255.2/32
    }
}
protocols {
    bgp 65000 {
        neighbor 169.254.255.1 {
            remote-as 7224
            update-source 169.254.255.2
        }
        network 0.0.0.0/0 {
        }
    }
    static {
        route 0.0.0.0/0 {
            next-hop 49.212.22.1 {
            }
        }
    }
}
vpn {
    ipsec {
        disable-uniqreqids
        esp-group ESP1 {
            compression disable
            lifetime 3600
            mode tunnel
            pfs enable
            proposal 1 {
                encryption aes128
                hash sha1
            }
        }
        ike-group IKE1 {
            lifetime 28800
            proposal 1 {
                dh-group 2
                encryption aes128
                hash sha1
            }
        }
        ipsec-interfaces {
            interface eth0
        }
        site-to-site {
            peer 72.21.209.225 {
                authentication {
                    mode pre-shared-secret
                    pre-shared-secret vvFWtUb7xtBcKkYsTInb8g.6CveKDdS0
                }
                ike-group IKE1
                local-ip 49.212.xx.xx
                tunnel 1 {
                    allow-nat-networks disable
                    allow-public-networks disable
                    esp-group ESP1
                    local-subnet 169.254.255.2/32
                    remote-subnet 169.254.255.1/30
                }
                tunnel 2 {
                    allow-nat-networks disable
                    allow-public-networks disable
                    esp-group ESP1
                    local-subnet 172.22.0.101/24
                    remote-subnet 10.0.0.0/16
                }
            }
        }
    }
}

これをファイルに記述して scp などで Vyatta のサーバにアップし

$ configure
# merge /path/to/vpc.config
# commit

すればよい。

さらにパケットの転送制御をするために、以下の内容のファイルをアップする。

#!/bin/sh

BGP_LOCAL_IP_SUBNET=169.254.255.0
BGP_LOCAL_IP_1=169.254.255.2
VPN_1_IP=72.21.209.225
MY_WAN_IP=49.212.xx.xx
MY_LOCAL_SUBNET_IP=172.22.0.101
VPC_CIDR=10.0.0.0/16


ip xfrm policy update dir fwd src $BGP_LOCAL_IP_SUBNET/30 dst $BGP_LOCAL_IP_1/32 tmpl src $VPN_1_IP dst $MY_WAN_IP proto esp level required mode tunnel
ip xfrm policy update dir in src $BGP_LOCAL_IP_SUBNET/30 dst $BGP_LOCAL_IP_1/32 tmpl src $VPN_1_IP dst $MY_WAN_IP proto esp level required mode tunnel
ip xfrm policy update dir fwd src $VPC_CIDR dst $MY_LOCAL_SUBNET_IP/24 tmpl src $VPN_1_IP dst $MY_WAN_IP proto esp level required mode tunnel
ip xfrm policy update dir in src $VPC_CIDR dst $MY_LOCAL_SUBNET_IP/24 tmpl src $VPN_1_IP dst $MY_WAN_IP proto esp level required mode tunnel 

これを Vyatta サーバ上で実行する。

以上で、うまくいっていれば

ping -I 169.254.255.2 169.254.255.1

で、VPN Gateway との疎通が確認できる。

さらに

ping -I 172.22.0.101 10.0.1.111

で(10.0.1.111 は EC2 インスタンスのIP)、インスタンスとの疎通が確認できる。

ここまでくれば、あとは EC2 インスタンスssh でログインできる。

sudo ssh -i /path/to/key.pem ec2-user@10.0.1.111

netstat で確認したら、172.22.0.101 からの接続があるので、IPSec VPN 接続が成功しているようだ。

長くなったけど、こんな感じでVPCを試すことができた。

最後に、、、

VPC、早く東京に来い!

はじめてのレシピ

Chef Server, Chef Client(Node), Knife Client と一通り環境が揃ったので、All about Chef ... — Chef Docsに従って、Recipeを書いて、Nodeに適応してみる。

Chefリポジトリの用意

cookbookを書いていくあたって、ローカルにChefリポジトリを用意する。これにはひな形が github に公開されているのでこれをもらってくる。今回は git はインストールしていないので tarball で取得し展開した。

$ wget --no-check-certificate https://github.com/opscode/chef-repo/tarball/master
$ tar xzf opscode-chef-repo-9769e69.tar.gz
$ mv opscode-chef-repo-9769e69 chef-repo

ちなみに作業しているのは knife が使える環境。

Chefの考え方としては、このリポジトリを git, bazaar, subversion などのソースコード管理に入れろということらしい。

Recipeの作成

Recipeを作成するにあたっては、knife コマンドでそのひな形を作成することができる。

$ cd chef-repo/cookbooks
$ knife cookbook create quick_start -o ./

これで、quick_start というディレクトリが作成されて、さらにその配下にいくつかディレクトリが作られる。

ChefのWikiに書かれているサンプルのRecipeでは、テキストファイルを作って、その中にAttributeで指定される値を流し込むという感じのもの。

そこで、Attributeを定義する。quick_start/attributes/default.rb を以下のように作成。

default["first_name"] = "Mickey"
normal["second_name"] = "Mouse"

後の説明ために、あえて default と normal Attribute で書いている。

このAttributeを利用して作成されるtemplate resourceをquick_start/recipes/default.rbに記述。

template "/tmp/name.txt" do
  source "name.txt.erb"
  action :create
end

そしてtemplate自体を、quick_start/templates/default/name.txt.erbとして以下のように作成。

My Name is <%= node["first_name"]%> <%= node["second_name"]%>.
This server address is <%= node[:ipaddress]%>.

これでRecipeができたので、Chef Serverに以下のコマンドでアップロードする。

$ cd chef-repo
$ knife cookbook upload quick_start -o cookbooks/

登録できていれば、以下のコマンドで登録状況を確認できる。

$ knife cookbook list
[
  "quick_start"
]

Nodeへの適用/反映

作ったRecipeをNodeに適用するためには、以下のようなコマンドを実行する。

$ knife node run_list add <NODENAME> 'recipe[quick_start]'
{
  "run_list": [
    "recipe[quick_start]"
  ]
}

これで対象となるNodeにログインして、chef-clientを実行する。

# chef-client

これで、/tmp/name.txt が作成されて以下の内容になっているはず(ここでは、このNodeのアドレスは192.168.100.11としている)。

My Name is Mickey Mouse.
This server address is 192.168.100.11.

chef-client は何度実行しても同じ状態になるというのが1つの特徴。この/tmp/name.txtを適当に修正してから、再度実行すれば元の内容に戻っていることが確認できる。

Attributeの変更(上書き)

attrributeを

default["first_name"] = "Mickey"
normal["second_name"] = "Mouse"

のように用意したけれど、これをNodeやRoleに応じて上書きしてみる。

Node Attributeでの変更

Node Attributeではnormal attributeの定義しかできないみたいなので(All about Chef ... — Chef Docs)、上書きできるのはdefault attributeの方のみのようである。これは以下のようにして、Nodeの属性を直接編集する。

$ export EDITOR=/bin/vi
$ knife node edit <NODENAME>

これで、

  "normal": {
    "tags": [

    ],
    "second_name": "Mouse"
  },

という部分を

  "normal": {
    "tags": [

    ],
    "second_name": "Mouse",
    "first_name": "Minnie"
  },

に変える。

これで、対象のNodeで再度chef-clietを実行すると、/tmp/name.txtは

My Name is Minnie Mouse.
This server address is 192.168.100.11.

となる。

Role Attributeでの変更

normal Attribute は override できるので、これを Role Attribute に記述してみる。
Role を作成するためのコマンドを実行する。

$ knife role create roletest

すると、エディタが起動するので、以下のように記述して保存して閉じる。

{
  "name": "roletest",
  "description": "",
  "json_class": "Chef::Role",
  "default_attributes": {
  },
  "override_attributes": {
    "second_name": "Riperton"
  },
  "chef_type": "role",
  "run_list": [
    "recipe[quick_start]"
  ]
}

この段階では、Nodeにはquick_startレシピが直接反映されるので、このRoleが適用されるようにする。

knife node run_list remove <NODENAME> recipe[quick_start]
knife node run_list add <NODENAME> "role[roletest]"

以上で、再度対象Nodeにてchef-clientを実行すると、/tmp/name.txtは以下のようになる。

My Name is Minnie Riperton.
This server address is 192.168.100.11.

とりあえず、こんな感じでRecipeを書いていくというイメージはつかめた気がする。
で、気になったのはChfeリポジトリのcookbooks配下の構成方法。どういう感じがいいんだろう?
これについて後日少し考えてみようと思う。

ruby1.9.2でChef-severを動かす

先日書いたさくらのVPSにchef-serverをインストール - kikumotoのメモ帳では ruby は 1.8.6 が使われる。

個人的には 1.9.2 の環境の方が都合がよいので、ruby 1.9.2 で chef-server を動かすようにしたときの構築をメモ。

基本的にほぼ同様な手順だけど、一部異なることとなった。

ruby1.9.2のインストール

ruby1.9.2は自前でビルドするしかなさそうなので、2011-03-30 - akimatterを参考にビルド。

これで、gem もインストールされる。

chef-server

chef-server環境はEPELのモジュールを必要とするので、

# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm

は実行しておく。ELFFは不要。

で、

# gem install chef

を実行すると

ERROR:  While generating documentation for chef-0.9.14
... MESSAGE:   Error while evaluating /usr/lib/ruby/1.9.1/rdoc/generator/template/darkfish/classpage.rhtml: undefined method `gsub' for nil:NilClass (at "\"method-source-code\"\n\t\t\t\t\t\tid=\"run-source\">\n<pre>\n")

というエラーがでた。解決策がわからいけれど、rdocとか不要にするととりあえず動作させるのに必要なものインストールできるようである。なので、以下を実行した。

# gem install chef --no-rdoc --no-ri

このあと、/etc/chef/solo.rb, chef.json などの記述は以前と同じで、chef-soloを実行すれば chef-server 環境がインストールされた。

ただし、ruby1.9.2 では ruby1.8.6 でしたときのような rack のバージョンダウンは不要。一方で、chef-server, chef-server-webuiの動作ユーザをrootに変更することは必要。

あとの作業は以前と同じ。

これで満足のいく環境ができた。。。と思う。

Chef ServerにClient/Nodeを登録

昨日書いたさくらのVPSにchef-serverをインストール - kikumotoのメモ帳で作成したChef Serverに、Chefのclietやnodeを登録した手順をメモする。インストール対象はここでもさくらのVPS CentOS5.5 i386環境。

client, nodeが何かについてはChefを最速で使いこなすためのいくつかのポイント - Masatomo Nakano Blogが非常にわかりやすかった。

knife client

Cookbookを作成してServerに反映(アップ)するためツールとしてknifeというものがあり、それをChef Serverのclientとして登録する必要がある。

rubyをインストールして、/etc/chef/solo.rbを記述するところまでは、serverと同じ手順。clientをインストールするためには ~/chef.jsonを以下のように記述。

{
  "chef": {
    "server_url": "http://[chef serverのホスト名orIP]:4000",
    "init_style": "init"
  },
  "run_list": [ "recipe[chef::bootstrap_client]" ]
}

これで、次のようにchef-soloコマンドを実行した。

chef-solo -c /etc/chef/solo.rb -j ~/chef.json -r http://s3.amazonaws.com/chef-solo/bootstrap-latest.tar.gz

なお、cookbookの作成やアップロードは一般ユーザで実行してよいものなので、適当なユーザを用意しておく。

で、knife clientのためにキーペア(公開鍵、秘密鍵)を作成する。私の理解では公開鍵はChef Serverに保持され、公開鍵を自身で管理することになる。これは、Chef Server上で作成したknifeの環境で以下のように実行する。

$ knife client create user1 -n -a -f ./user1.pem

この作成された秘密鍵(user1.pem)を、今回作業しているサーバにscpなどの手段で持ってくる。Chef Server側ではこのファイルは消してしまってよい。

$ cd ~
$ mkdir .chef
$ scp [chef-server]:/path/to/user1.pem ./chef/

この状態で以下のようにknife configureでknife環境を設定する。

$ knife configure
/usr/lib/ruby/gems/1.8/gems/rest-client-1.6.1/lib/restclient/abstract_response.rb:50: warning: parenthesize argument(s) for future version
No knife configuration file found
Where should I put the config file? [~/.chef/knife.rb] 
Please enter the chef server URL: [http://localhost:4000] http://[Chef Serverホスト名orIP]:4000
Please enter an existing username or clientname for the API: [root] user1
Please enter the validation clientname: [chef-validator] 
Please enter the location of the validation key: [/etc/chef/validation.pem] 
Please enter the path to a chef repository (or leave blank): 
WARN: *****
WARN: 
WARN: You must place your client key in:
WARN:   /home/user1/.chef/user1.pem
WARN: Before running commands with Knife!
WARN: 
WARN: *****
WARN: 
WARN: You must place your validation key in:
WARN:   /etc/chef/validation.pem
WARN: Before generating instance data with Knife!
WARN: 
WARN: *****
WARN: Configuration file written to /home/user1/.chef/knife.rb

これでknife client listとして、user1が含まれたリストが表示されればOK。

Nodeの登録

Chef Server上のrecipeを適用して、自分が望む状態にしたい対象のサーバがNodeという理解。そのサーバ上では別にknifeが動く必要性もない。

NodeはChef Serverに登録しないといけないので、その手順を書く。

chef-soloを実行するまでは上記のknife clientの場合と同じ。その後、Chef Serverから/etc/chef/validation.pemをNodeとして登録したサーバの同位置に持ってくる。そして

# chef-client

と実行すればOK。

これで、Chef Web UI とか、knife node list とかに登録したノードが表示される。また、clientとしても登録されている。

以上で、Cookbook を作成する環境と、構築したいNodeの環境が整った。

今後はCookbookのサンプルを試してみることにする。それはまた別途書くつもり。。。

さくらのVPSにchef-serverをインストール

久しぶりのブログ更新!!

サーバを増やすときに各種パケッケージのインストールだけでなく、必要な設定も含めて自動化していきたいと思い、最近はChefを勉強中。

chef-serverをさくらのVPSにインストールしたときの作業をメモしておく。さくらのVPSへのchef-serverインストールについては、id:masa_to さんが、さくらVPSにchef-serverをインストールする - happytanの足跡 で「Manual Chef Server Configuration」に従ってインストールしたものを記述されていますが、とりあえず試してみたい(よくわかってなくて、手を抜きたい)私は「Bootstrap Chef RubyGems Installation」に従ってインストールしてみた。

インストール先は、さくらのVPS 512 の CentOS 5.5 i386

Ubuntu の場合はドキュメントの通りだったけど、CentOS5.5 の場合は少しだけ違ったので、一応やったことをすべてメモしおく。

Ruby/RubyGemsのインストール

CentOSのデフォルトのrubyは若干古いので、他のYUMレポジトリからインストールする(それでもインストールされるのは 1.8.6*1 だけど、、、)。sudo 環境なんて整えてないから root で実行。

# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
# rpm -Uvh http://download.elff.bravenet.com/5/i386/elff-release-5-3.noarch.rpm
# yum install ruby ruby-shadow ruby-ri ruby-rdoc gcc gcc-c++ ruby-devel ruby-static

RubyGemsの方はソースからインストール。

# wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz
# tar  zxf rubygems-1.3.7.tgz
# cd rubygems-1.3.7
# ruby setup.rb --no-format-executable

Chef本体

Chef本体は、gem コマンド一発

# gem install chef

chef-soloの設定

chef-server自体は Chef 自身にインストールさせるため、chef-server を必要とせず単独で Chef の実行ができる chef-solo 使う。その chef-solo 向けの設定。

まず

# mkdir /etc/chdef

で、ディレクトリを作って、/etc/chef/solo.rb を以下のように記述。

file_cache_path "/tmp/chef-solo"
cookbook_path "/tmp/chef-solo/cookbooks"

で、chef-server と webui もインストールさせるために、インストールのための設定として ~/chef.json を以下のように記述した。

{
  "chef": {
    "server_url": "http://localhost:4000",
    "webui_enabled": true,
    "init_style": "init"
  },
  "run_list": [ "recipe[chef::bootstrap_server]" ]
}

CentOSなので、init_style を "init" にする必要があるので、これは忘れずに。

chef-serverインストール

インストールは chef-solo コマンドを実行する。

# chef-solo -c /etc/chef/solo.rb -j ~/chef.json -r http://s3.amazonaws.com/chef-solo/bootstrap-latest.tar.gz

実行に成功すれば、「Verify That All Components are Running」の通りにプロセスが動いていればいいのだけど、webui が起動していない。

rackのバージョンが新しすぎるようなので、以下のようにしてバージョンを下げた。

# gem uninstall rack
# gem install -v 1.1.0 rack

これで

# /etc/init.d/chef-server-webui restart

を実行して、無事に起動を確認。ブラウザからもアクセスできることを確認(http://[ホスト名]:4040/)。ちなみに、デフォルトのアカウント/パスワードは、admin/p@ssw0rd1。

しかし、CentOS環境では、chef-server, chef-server-webui とも chef ユーザで実行される。このためこのままでは、/etc/chef/valication.pem を読み込むことができず、このあとの Client 登録で失敗する。

Ubuntu 環境では root で実行されていたのでそれにならうことにした。そこで、/etc/sysconfig/chef-server, /etc/sysconfig/chef-server-webui ともに以下のように記述した。

SERVER_USER=root
SERVER_GROUP=root

これで、chef-server, chef-server-webui を再起動しておく。

Command Line Clientの登録

Chef では chef-server とやりとりするのに knife コマンドを多様する。これを chef-server に登録する。chef-server 上に適当にユーザを作って、登録した。

入力内容を含めて以下のような実行をした。

# useradd kikumoto
# mkdir ~kikumoto/.chef
# cp /etc/chef/validation.pem /etc/chef/webui.pem ~kikumoto/.chef
# chown -R kikumoto.kikumoto ~kikumoto/.chef
# su - kikumoto
$ knife configure -i
/usr/lib/ruby/gems/1.8/gems/rest-client-1.6.1/lib/restclient/abstract_response.rb:50: warning: parenthesize argument(s) for future version
Where should I put the config file? [~/.chef/knife.rb] 
Please enter the chef server URL: [http://localhost:4000] 
Please enter a clientname for the new client: [root] admin_kikumoto
Please enter the existing admin clientname: [chef-webui] 
Please enter the location of the existing admin client's private key: [/etc/chef/webui.pem] .chef/webui.pem
Please enter the validation clientname: [chef-validator] 
Please enter the location of the validation key: [/etc/chef/validation.pem] .chef/validation.pem
Please enter the path to a chef repository (or leave blank): 
WARN: Creating initial API user...
INFO: Created (or updated) client[admin_kikumoto]
WARN: Configuration file written to /home/kikumoto/.chef/knife.rb

登録に成功していれば knife client list を実行したときに、登録した clientname が表示される。

最後に

という感じで、とりあえず chef-server がインストールできて、cookbook にデータを登録する準備まではできた。

この後は、cookbook 作成/登録用のクライアントと、構築対象の Node を登録する。それはまた後日。

ちなみに、chef-cliet サービスが自動起動するようになっているので、このサーバを再起動すると chef-server にこのサーバが1つの Node として登録される。

*1:1.9.2での記事はこちら

CometDを試す

背景はともかく、CometDに興味を持ったのでまずは使ってみることに。

Primerのページによると、Maven で scaffold 見たいなものを作れるようになっているが、この日記を書いた時点でのバージョンでは少し出力が異なっていたので、Primer をなぞる形で自分が実行した内容をメモしておく。

まずは、以下の通りにmvnコマンドを実行する。

$ mvn archetype:generate -DarchetypeCatalog=http://cometd.org
...
Choose archetype:
1: http://cometd.org -> cometd-archetype-dojo-jetty6 (1.1.2 - CometD archetype for creating a server-side event-driven web application)
2: http://cometd.org -> cometd-archetype-jquery-jetty6 (1.1.2 - CometD archetype for creating a server-side event-driven web application)
3: http://cometd.org -> cometd-archetype-dojo-jetty7 (1.1.2 - CometD archetype for creating a server-side event-driven web application)
4: http://cometd.org -> cometd-archetype-jquery-jetty7 (1.1.2 - CometD archetype for creating a server-side event-driven web application)
Choose a number: :

ここで、jetty のバージョンと、JavaScript ライブラリとして dojo/jQuery の組み合わせの選択をする。なお、括弧内の1.1.2という数字はCometDのバージョンのようだけど、この直後に2.0.0の選択もできるようになっているのであまり意味はないかも。

で、今回は4番を選択することにする。jQueryを普段使っているのと、なるべく最新を選択したいから。
そすると、CometDのバージョンの選択をせまられるので、こちらも最新の2.0.0を選択する。

Choose a number: : 4
Choose version: 
1: 1.1.2
2: 2.0.0
Choose a number: : 2

あとは、groupId とかを聞かれるので適当に入力し、確認して、'BUILD SUCCESSFUL'が出ればOK。

Define value for property 'groupId': : org.cometd.primers
Define value for property 'artifactId': : jquery-jetty7-primer
Define value for property 'version': 1.0-SNAPSHOT: 
Define value for property 'package': org.cometd.primers: 
Confirm properties configuration:
groupId: org.cometd.primers
artifactId: jquery-jetty7-primer
version: 1.0-SNAPSHOT
package: org.cometd.primers
cometdVersion: 2.0.0
jettyVersion: 7.1.5.v20100705
Y: 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------

Primerにあるのと同じようにディレクトリの状況を確認すると以下のような感じ。

$ cd jquery-jetty7-primer
$ tree
.
|-- pom.xml
`-- src
    `-- main
        |-- java
        |   `-- org
        |       `-- cometd
        |           `-- primers
        |               |-- BayeuxInitializer.java
        |               `-- HelloService.java
        `-- webapp
            |-- WEB-INF
            |   `-- web.xml
            |-- application.js
            `-- index.jsp

引き続いて

$ mvn install

で、コンパイルして環境を整える。

実行してできたディレクトリ構成は以下の通り。必要なものをとりあえずすべて集めきてくれるようである。

$ cd target/jquery-jetty7-primer-1.0-SNAPSHOT
$ tree
.
|-- META-INF
|-- WEB-INF
|   |-- classes
|   |   `-- org
|   |       `-- cometd
|   |           `-- primers
|   |               |-- BayeuxInitializer.class
|   |               `-- HelloService.class
|   |-- lib
|   |   |-- bayeux-api-2.0.0.jar
|   |   |-- cometd-java-common-2.0.0.jar
|   |   |-- cometd-java-server-2.0.0.jar
|   |   |-- jetty-continuation-7.1.5.v20100705.jar
|   |   |-- jetty-servlets-7.1.5.v20100705.jar
|   |   `-- jetty-util-7.1.5.v20100705.jar
|   `-- web.xml
|-- application.js
|-- index.jsp
|-- jquery
|   |-- jquery-1.4.2.js
|   |-- jquery.cometd-ack.js
|   |-- jquery.cometd-reload.js
|   |-- jquery.cometd-timestamp.js
|   |-- jquery.cometd-timesync.js
|   |-- jquery.cometd.js
|   `-- jquery.json-2.2.js
`-- org
    |-- cometd
    |   |-- AckExtension.js
    |   |-- ReloadExtension.js
    |   |-- TimeStampExtension.js
    |   `-- TimeSyncExtension.js
    `-- cometd.js

元のディレクトリに戻って

$ mvn jetty:run

とすることで、サーバを実行できる。

これで、http://localhost:8080/jquery-jetty7-primer をブラウザで開くと

Server Says: Hello, World
CometD Connection Established

のように表示される。Primerにある結果とは、出力順が違うようであるけれど、多分それはタイミングの問題とかかもしれない。

まずは、このscaffoldのソースを参考にしつつ、CometDを理解することにする。

Android エミュレータの system.img を書き換える。

すっかり間があいていましまったけど、最近 Android をいじり始めたのでそれについてメモを再開。

Android エミュレータの /system は adb remount で、書き換えはできるけれども、結局エミュレータを終了すればまた元に戻ってしまう。

毎回 adb remount して、adb push してなんかはしてらんないので、エミュレータの /system の実体である ANDROID_SDK_HOME/platforms/android-1.6/images/system.img を書き換える方法を調べてみた。

そすると、http://discuz-android.blogspot.com/2008/01/customize-google-android-systemimg-for.html にやり方があって、必要なバイナリは http://www.dotphone.org/viewthread.php?tid=32&extra=page%3D1 から取得できるようになっていた。

手順としては以下のような感じになる。

エミュレータの system.img を書き換えたいので、ここでは mkfs.yaffs2.arm.tar.gz をダウンロードして解凍しておく。以降では、mkfs.yaffs2.arm を解凍したディレクトリで作業しているものとする。また、エミュレータの名前は MyAVD としている。

準備として AVD 作成時に SD カードの容量を 128M として作成しておく。

エミュレータを起動し、/system を read/write でリマウントしておく。

$ adb remount

system/bin に mkfs.yaffs2.arm を mkfs.yaffs2 としてアップ。

$ adb push mkfs.yaffs2.arm /system/bin/mkfs.yaffs2

他にも /system に対して書き換えたいことがあればここでしておく。

/system 配下を望む状態にしたら、以下のコマンドでエミュレータの SD カード上に system.img を構築する。

$ adb shell mkfs.yaffs2 /system /sdcard/system.img

system.img が作成できたらこれをローカルディスクに持ってくる。

$ adb pull /sdcard/system.img system.img

エミュレータを終了し、今度は今作成した system.img を指定してエミュレータを起動すればよい。

$ emulator -avd MyAVD -system system.img

これで、/system 配下が先ほど修正した状態になっていれば成功している。