Archive : 2013

このエントリは、CloudStack Advent Calendarの12月17日分のエントリです。

さて、12/4のエントリでは、CloudStackをIntelliJ IDEAでビルドする方法を説明しました12/6のエントリでは、JenkinsでCloudStackのdebパッケージをビルドする方法を説明しました。今日はそのdebパッケージを使ってCloudStackを実際に構築したとして、その環境をIntelliJ IDEAからリモートデバッグをする方法を解説します。

Debuggee(CloudStack)の設定

CloudStackはJavaのプログラムですが、Javaは起動時のオプションで、リモートデバッグの受付を設定出来ます。Management Serverの場合はTomcatの設定ファイル(/etc/cloudstack/management/tomcat6.conf)、KVM Host Agentの場合は起動スクリプト(/etc/init.d/cloudstack-agent)内で起動オプションを設定変更できるので、例えば以下のように変更を加えると、8787番ポートでデバッガのアタッチを待ち受けるようになります。

sed -i 's/JAVA_OPTS="/JAVA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n /g' /etc/cloudstack/management/tomcat6.conf
sed -i 's/$JSVC -cp/$JSVC -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -cp/g' /etc/init.d/cloudstack-agent

なお、上記の例ではsuspendオプションにnを渡していますが、yを渡すと、デバッガがアタッチされるまで実行が抑止されます。このオプションは、起動してすぐ、デバッガをアタッチする間もなく実行されてしまう箇所のデバッグをするときに有効です。yを渡しておくと、デバッガがアタッチされるまで実行が抑止されることでその箇所のデバッグが可能になります。

Debugger(IntelliJ IDEA)の設定

“Run”メニューの”Edit configuration”メニューから、“Run/Debug Configuration”ウィンドウを開きます。

すると、デバッグ対象を左上の"+"ボタンから追加できるので、"Remote"を選択して追加し、NameとHost、Portを対象のサーバーにあわせて適宜編集してください。

image

これを対象のサーバー分だけ繰り返すと、Debugボタンを押したときにデバッグ対象を選択してリモートデバッグを行えるようになります。

image

当然、ソースコード中にブレークポイントを置いてコードの実行を一時停止させたり、

image

Intelli J IDEAの"Expression Evaluation"ウィンドウという、Visual Studioで言うところの"Immidiate Window"的な、入力した式を現在のスコープで評価するツールを使ったりすることも出来ます。

image

ちょっと短めですが、以上、CloudStackをIntelliJ IDEAでリモートデバッグするまでの手順の紹介でした。CloudStackは、比較的OSSとしてはドキュメントが充実している方ですが、それでも開発が非常にアクティブなこともあり、ドキュメント化されていない仕様や、周知が十分でない仕様変更が多くあります。CloudStackの開発にこれから取り組もうという方は勿論、CloudStackを導入するにあたって、仕様を深く理解しようとコードを追う人にとっても、この記事が一つの参考になれば幸いです。

このエントリは、CloudStack Advent Calendar 12月6日分のエントリです。

前回のエントリに引き続きCloudStackの開発方法について書いていきます。前回のエントリではIntelliJ IDEAを使って、CloudStackのコードを手元でビルド出来るところまでセットアップする方法を紹介しました。ただビルドするだけではなく、パッケージとして纏めるところまで出来たら、自分でコードの変更を加えたCloudStackをインストールしてテストするときに便利だよね、ということで、今日はamd64版向けのdebパッケージを自分でビルドしてみましょう。そして、debパッケージをビルドするだけではなく、今回はJenkinsでビルドサーバーを立てて、Jenkinsでdebパッケージをビルドしてみることを目指します。

Jenkinサーバーのセットアップ

debパッケージをビルドするため、前回のエントリで使っていたWindows+IntelliJ IDEA環境から離れて、今日はUbuntu ServerにJenkinsをインストールしてみましょう。今回は12.04 LTSを使用しました。

Javaの開発環境のインストール

まずはJavaの開発環境のセットアップから。Oracle JDKをインストールしていきます。標準ではOracle JDKは入らないので、ppaを使用して、以下のようにインストールします。

sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java7-installer
sudo bash -c "echo \"JAVA_HOME=/usr/lib/jvm/java-7-oracle/\" >> /etc/profile" 
sudo bash -c "echo \"export JAVA_HOME" >> /etc/profile"
sudo bash -c "echo \"JAVA_HOME=/usr/lib/jvm/java-7-oracle/\" >> /etc/default/tomcat6" 

add-apt-repositoryが見つからないと起こられる場合は、以下のコマンドでインストールできます。あるいは自分でレポジトリを追加してもよいでしょう。

sudo apt-get install python-software-properties

つづいてMavenのインストール

sudo apt-get install maven

状況確認。ちゃんとインストールされてますね。

mvn -v                                                                                                       
Apache Maven 3.0.4
Maven home: /usr/share/maven
Java version: 1.7.0_45, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-7-oracle/jre
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "3.8.0-34-generic", arch: "amd64", family: "unix"

パッケージビルド用のツールのインストール

パッケージビルド時に必要となるツールを、以下のコマンドでインストールしましょう。

sudo apt-get install debhelper tomcat6 genisoimage python-mysqldb

Jenkinsのインストール

そしてJenkinsを以下のコマンドでインストールしましょう。今回はパッケージからインストールを行います。

sudo apt-get install jenkins-tomcat

では、JenkinsのWeb UIにアクセスしてみましょう。デフォルトで、ポート8080番で立ち上がっています。

image

本当はここでちゃんとユーザーや認証の設定などをするべきなのですが、今回はCloudStackをビルドすることに絞って説明を行います。

まずは、「Jenkinsの管理」->「システムの設定」からMavenを追加します。3.0.4をパッケージからインストールしてあるので、そのパスをMAVEN_HOME欄に設定します。

image

続いて、プラグインの追加画面から、Git Pluginの追加を行います。プラグインの追加が終わったら、有効化するために、Jenkinsを再起動する必要があります。

image

debパッケージのビルド

image

さて、いよいよパッケージのビルドをするために、Jenkinsのジョブのセットアップを行いましょう。Jenkinsのトップから、「新規ジョブ作成」を選択し、適宜名前をつけてジョブを作成してください。

image

ジョブの設定画面では、ソースコード管理システムはGitを選択し、Repository URLには使用しているレポジトリのURLを入力してください。
ビルドの項は、「ビルド手順の追加」から「シェルの実行」を選択し、以下の内容を貼り付けてください。

cd $WORKSPACE
VERSION=`(mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version) | grep '^[0-9]\.'`
rm -rf dists
mkdir -p $WORKSPACE/dists/debian
tar --transform s,^\./,cloudstack-${VERSION}/, -c -z -f dists/debian/cloudstack-${VERSION}.tgz --exclude .git --exclude dists .
cd $WORKSPACE/dists/debian
tar -xzf cloudstack-${VERSION}.tgz
cd $WORKSPACE/dists/debian/cloudstack-${VERSION}
dpkg-buildpackage -uc -us
cd $WORKSPACE/dists/debian
mkdir -p $WORKSPACE/dists/debian/main/binary-amd64
mv *.deb *.changes *.dsc main/binary-amd64
cd $WORKSPACE
dpkg-scanpackages dists/debian/main/binary-amd64 /dev/null | tee $WORKSPACE/dists/debian/main/binary-amd64/Packages | gzip -9 > $WORKSPACE/dists/debian/main/binary-amd64/Packages.gz

以上で、Jenkinsのジョブのセットアップは完了しました。これでジョブを実行すれば、以下のようにビルドに成功する筈です。

image

そして、ワークスペースのdists/debian/main/binary-amd64/ディレクトリ配下には、debパッケージとPackagesファイルが生成されている筈です。

image

このdebパッケージを使えば、ビルドされたCloudStackをDebian/Ubuntu環境にインストールすることが出来ます。また、同時に生成されたPackagesファイルは、そのディレクトリ配下にあるパッケージの情報を含んだメタデータファイルであり、aptコマンドがそのディレクトリをレポジトリとして扱うことを可能にします。Jenkinsはワークスペースの内容をデフォルトでインターネットに対して公開してくれるので、そのURLを対象のサーバーにレポジトリとして登録すれば、Jenkinsサーバーをレポジトリとして使用することが出来ます。

sudo add-apt-repocitory 'http://<domain>:8080/jenkins/job/<jobname>/ws/dists/debian main'

CloudStackの実際のインストール手順については、CloudStack Installation Guideを参照されると良いかと思います。

以上、CloudStackのdebパッケージをビルドするためのJenkinsジョブセットアップ手順でした。明日のAdvent Calenderの担当は・・・誰なんだろう。。

image

このエントリは、CloudStack Advent Calender 12/4のエントリです。

 

みなさん、CloudStack開発してますか?
まだ始めていない方には、きっとこの記事は良い導入になるかと思います。
既に始めている方は、お使いのIDEは何ですか?Eclipse?それともVim/Emacs?
Java開発で敢えてVim/Emacsをお使いの方々は、それぞれ譲れない宗教をお持ちでしょうからいいですが、 Eclipseで開発している方は、CloudStackだとm2eのエラーが出て、なんとかならないかな、とか感じていませんか?
残念ながら、Eclipseを使い続ける限り、今のところ回避策はないようです。
エラーが出続ける状態で開発を行うのは心の健康にも、また実際の開発上も他のエラーを見落とす可能性があることから良くありません。 幸い、JavaのIDEには、軽量でモダンなUIを持ちながら、十分な機能を予め備えたIntelliJ IDEAというIDEが存在します。
今回はIntelliJ IDEAでCloudStack開発を行うためのセットアップ方法を紹介します。なお、今回はWindows上での手順を解説しますが、IntelliJ IDEAはマルチプラットフォーム対応なので、適宜読み替えることでMacやLinuxでも動くかと思います。

IntelliJ IDEAとは?

IntelliJ IDEAとは、JetBrains社が開発しているIDEで、Javaを中心にRubyやPython、PHPの開発にも対応した高機能IDEです。
JetBrains社は、他に、RubyMineやPyCharmというIDEをリリースしていますが、これらは、IntelliJ IDEAからRuby開発やPython開発に関わる部分を切り出して単体IDEとしてまとめたものになります。
そして、Java開発に機能を絞ったものとしてIntelliJ IDEA Community Editionというバージョンがあり、これはOSSとして配布されています。
今回はこのCommunity Editionを使っていきます。

Javaのセットアップ

IntelliJは、Javaで記述されたIDEであり、Javaの実行環境を必要とします。また、CloudStackのコンパイルを行うときにも必要になるので、まだインストールしていない場合は、JDKをインストールしましょう。

Oracle JDKは以下のサイトからダウンロードできます。

http://www.oracle.com/technetwork/java/javase/downloads/index.html

image

gitのセットアップ

CloudStackのソースコードは、gitで管理されています。git for windowsでgitをインストールしてしまいましょう。

http://www.git-scm.com/

image

Mavenのセットアップ

CloudStackは、ビルドシステムとしてMavenを使用しています。IntelliJはMaven連携機能がありますが、Mavenのバイナリは別に用意する必要があるので、以下のサイトからダウンロードの上、適宜展開しておきましょう。

http://maven.apache.org/

IntelliJのセットアップ

先述のとおり、IntelliJには、OSSであるCommunity Editionと、Ruby開発やPython開発、その他多くの機能強化がされたUltimate Editionがあります。とりあえずはCommunity Editionで十分かと思いますが、Ultimate Editionにはオープンソース開発者向けのライセンスもあるので、Apache CloudStackのコミッタになって、ライセンスを狙うのもありかもしれません。

image

IntelliJは以下のサイトからダウンロード出来ます。

http://www.jetbrains.com/idea/download/

image

IntelliJでCloudStackのプロジェクトの作成

image

IntelliJの初回起動時は上のようなダイアログが開きます。この中から、”Checkout from Version Control”を使用して、CloudStackをレポジトリからcloneしましょう。

Apache CloudStackのCommunityのレポジトリのURLは

https://git-wip-us.apache.org/repos/asf/cloudstack.git

になります。結構レポジトリのサイズが大きいので、多少時間が掛かっても驚かないようにしましょう。

image

なお、gitコマンドを直接使用してcloneしてきたディレクトリが既にある場合は、Import Projectオプションを使用して、プロジェクトを作成することも出来ます。

IntelliJの設定変更

Appearance

IntelliJは設定画面の”Appearance”->”Theme”の項から、IDEとしての外観を変更することが出来ます。趣味の問題ですが、個人的には”Darcula”がお勧めです。

image

Allow placement of caret after the end of line

IntelliJでは、デフォルトで、”Editor”->”Allow placement of caret after the end of line”というオプションがオンになっており、これはキャレットを行のどこにでも置いてそこから編集を始められるという機能なのですが、あまり使いどころがなく、むしろ邪魔になることが多い機能なのでオフにするのをお勧めします。なお、次のVersionではデフォルトでオフになると聞いています。

image

IntelliJへのMavenの設定

Mavenのセットアップの項でダウンロードして展開したMavenのパスをIntelliJに設定します。

IntelliJの設定で、”Maven”->”Maven home directory”か、環境変数”M2_HOME”のどちらかで設定することが出来ます。

image

プロジェクトで使用するJDKの設定

続いて、プロジェクトで使用するJDKの設定を行いましょう。”File”->”Project Structure”のメニューから、Project Structure画面を呼び出し、その中の”Project”->”Project SDK”を使用して、使用するJDKのパスをセットしてください。

image

IntelliJのMaven連携を使用したCloudStackのビルド

以上の設定によって、IntelliJでCloudStackをコンパイルする用意が出来ました。では実際に、CloudStackをMavenでビルドしてみましょう。

InteliJには右側にMavenというペインがあり、それを開くと、Mavenのプロジェクト一覧が表示されます。その中で一番上にある、CloudStackプロジェクトを選択し、”Run Maven Build”を実行すると、Mavenによるビルドが始まります。初回は、Mavenによる必要な依存パッケージのインターネットからの取得などで結構時間が掛かるかと思いますが、最終的に以下のようなメッセージが出れば、ビルド成功です。

image

 

 

…と、ここまでエントリ書いたところで、IntelliJ IDEA 13がちょうど今日リリースされました!なんというタイミングの良さ!(悪さ?)IntelliJ IDEA 12で以上説明してきましたが、多分IntelliJ IDEA 13でも同じ手順でセットアップできるかと思います。CloudStack開発を始めるうえで、参考になれば幸いです。

image

CloudStackをご存知でしょうか。CloudStackは、オープンソースで開発が進んでいるIaaS基盤のソフトウェアです。もとはCloud.comというベンチャーが開発を進めていたのですが、CitrixがCloud.comを買収し、Apacheライセンスに変更の上Apache Foundationにソースコードを寄贈したことで、今はApache CloudStackとしてコミュニティを中心にCitrixが支援する形で開発が進んでいます。

現在、会社の業務の一環として、Apache CloudStackへのコードでの貢献に一部の時間を割いており、これまでいくつかのBugfixと、KVM上に構築されたCloudStackのゲストネットワークをVXLAN対応させるコードの投稿を行ってきました。

VXLAN対応の開発は、前任の@haeenaさんが行った開発の引継ぎなのですが、このVXLANという技術、VLANのVLAN ID枯渇問題(VLANはVLAN IDのフィールド長が12bitしかないため、複数ゲストネットワークをマルチテナントでIaaSとして提供しようとするような環境ではVLAN IDが足りなくなる)に対応するために、IETFで策定中のプロトコルです。L2のオーバーレイネットワークをIPネットワーク上に実現するため、L2フレームをUDPデータグラムでカプセル化し、ユニキャストフレームはIPユニキャスト、ブロードキャストフレームはIPマルチキャストで転送するというシンプルな仕様であり、そこが魅力ですね。Linuxでは、Kernel 3.7以降でVXLANを扱うための実装が入っており、CloudStackのVXLAN対応は、VLANの仮想インターフェイスを作成する代わりにVXLANの仮想インターフェイスを作成するように変更することで実現されています。

 

さて、そのVXLAN対応の開発について、先日11/20-22の日程でAmsterdamで開催された、CloudStack Collaboration Conference November 2013喋ってきました。Hackathonやセッション後の機会に、Hugo TrippaersやAlex HuangといったCloudStackのトップ開発者と話す機会がありましたが、いずれも建設的なコメントを貰えたのはありがたい限りです。また、聴講したパネルセッションなどを通じて、CloudStackの開発者が抱いているCloudStackの開発プロセスに対しての課題認識(masterへのマージ前にテストやコンパイルを行うようなゲートチェックが行われていないためにmasterがビルドすら通らなくなるなど品質が悪い等)が共有されていることを知ることが出来たのも収穫でした。来年はCloudStack Dayというイベントを日本でやるそうですが、こういったオフラインのイベントも、大切にしていきたいですね。

※アニメーションやビデオを使用しているので、PowerPointで開きなおすとわかりやすいかと思います。

一年前に引っかかった話がドラフトとして眠っていたのでポスト。

 

attr_accessorで定義したsetterメソッドを同一クラス内から呼び出す時、期待するように値が更新されず困っていたのですが(以下参照)、

#!/usr/bin/env ruby

class InstanceVariableEval

  attr_accessor :val

  def initialize
    @val = "initial data"
  end

  def set_from_instance_method_through_accessor
    val = "set_from_instance_method_through_accessor"
  end

end


a = InstanceVariableEval.new

puts a.val
a.set_from_instance_method_through_accessor
puts a.val
a.val = "set_through_accessor"
puts a.val

## Following is the output. I can't understand why val is not updated by the method "set_from_instance_method_through_accessor".
# initial data
# initial data
# set_through_accessor

shigeyas先生に教えて頂き解決することが出来ました。

Rubyは、setter系のメソッドを同一クラス内から呼び出す場合(代入っぽい呼び出しを行う場合)、レシーバとしてselfを必要とするようです。selfを付けない場合、ローカル変数と区別がつかないために、ローカル変数の宣言兼代入として扱われてしまうのです。C#のプロパティだと、この問題に直面しにくいのは、C#では変数を使用するにあたって、宣言が必要なため、setter系のメソッドの呼び出しをローカル変数の宣言兼代入と誤認することがないためです。既に同名のローカル変数がその呼び出し元メソッド内で宣言されている場合は、thisをレシーバとして明示して呼び出しをする必要がある点は一緒ですね。

OCT
12

近況報告

Published:2013-10-12 15:48:45 UTC

また更新が空いてしまいましたが。。生きてます。
もう社会人二年目になってしまいました。時がたつのがはやいですね。。

さて、突然の報告ですが、今仕事でアメリカはユタ州に来ています。期間はこの8月から一年の予定。うちの会社の若手育成プログラムの一環で海外現地法人に武者修行の旅。会社に感謝です。英語には苦労させられていますが、今回は他に出向者の日本人上司もいるので、メンタル的には大分気楽にやれています。

生活も、会社の近くに一人暮らしをしていることもあり、大分楽が出来ています。異動前は片道70分かけて通勤していたのが、今は車で20分程に短縮されたので、時間的にも体力的にも余裕が出来てきました。そして、自炊を始めたのですが、2ヶ月たってもちゃんと続いています。ほら、アメリカの食事って美味しくないですし。。豚の薄切り肉が手に入らないとかは不便もありますが、とりあえずメインの米についてはこちらでもカリフォルニア産のコシヒカリが手に入るので、まぁ何とかやっています。

仕事。こちらに来て、取り組み内容を外に話しやすい仕事が増えたので、このブログでもそこから学んだことを取り上げられたらなと思います。異動前の仕事も、技術的なことに対して理解のある上司だったので、多分書こうとしたら許可は下りたと思うのですが、そのプロジェクトで使っている技術はRuby等慣れないものが多く、中々自分の中で試行錯誤している部分ばかりで、アウトプットに繋げられませんでした。今年こそは、しっかり技術的なことをBlogに書いていく習慣を身につけたいと思います。(なんか毎年同じことを書いている気もしますが。。)

そういうわけで、頑張っています。たまに日記的なことを書きつつ、技術的なことも書く感じで、このBlogも徐々に書いていきたいと思いますので、よろしくお願いします。