Movable Type の Windows Azure 対応のお話

ようやく秋めいてきた今日この頃、いかがお過ごしでしょうか。Movable Type開発担当の高山です。

先週 Movable Type 5.2 をリリースしました(パチパチパチ)が、我々開発チームは休む間もなく、次のリリースである Movable Type Advanced 5.2 や、次回以降を見据えた機能の開発などを行っています。詳細はまだお伝えすることが出来ませんが・・・。

さて、Movable Type Advanced 5.2 では、だいぶ前にお伝えしたとおり Microsoft のクラウド環境である Windows Azure の対応を行っています。Windows Azure へのデプロイは、バッチファイルからPowerShell のスクリプトを起動して実行していますが、何カ所かハマる場面があったので苦労話をお届けしたいと思います。

Perl は Azure SDK ではインストール手順が用意されていません

Windows Azure 環境では、PHPは簡単に導入する仕組みが用意されていますが、Perl に関しては用意がされていないので、何らかの方法でインストールを行う必要があります。幸いにも、ActivePerl には msi パッケージが用意されているので、こちらを Azure へのデプロイ時に自動的にインストールする事で問題をクリアできました。今のご時世、Strawberry Perl じゃないの?という声もありますが、実際に試してみたときに様々な問題が有ったため、今回は PerlIS.DLL が利用可能な ActivePerl の 32bit 版を選択しています。

具体的には、ActivePerl の msi パッケージをダウンロードして、インストールを行うと言うことを PowerShell のスクリプトファイルで行っています。このスクリプトファイルは、Azure へのデプロイ時に Startup Tasks として実行されています。

# .NET Framework の WebClient オブジェクトを利用してファイルをダウンロードする
$pack = 'http://downloads.activestate.com/ActivePerl/releases/5.14.2.1402/ActivePerl-5.14.2.1402-MSWin32-x86-295342.msi'
$webClient = new-object System.Net.WebClient
$webClient.DownloadFile($pack, "perl.msi")
# msiexec を起動してインストールを行う
# /qn オプションを渡すことで、インストール時にUIを表示しない
$install_base = "C:\"
$params = "/qn /i perl.msi TARGETDIR=$install_base"
$proc = [System.Diagnostics.Process]::Start( "msiexec", $params )
$proc.WaitForExit()

ActivePerl 32bit を動かす

デプロイ時に導入される Windows Server は 2008 R2 64bit 版を選択しています。しかし、先ほどインストールした Active Perl は 32bit 版になるために、導入直後の IIS では動作しません。そこで、32bit アプリケーションを動作するようにコマンド ( appcmd ) が実行されます。

%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.enable32BitAppOnWin64:true

Perl の実行権限がない

CGI プロセスは、"NETWORK SERVICES" ユーザ権限で動作しますが、Perl のディレクトリには同ユーザに対する実行権限がないために、このまま CGI を起動しようとすると、エラーとなってしまいます。そこで、権限を与える為のコマンド ( icacls ) が実行されます。

icacls c:\perl /inheritance:e /grant:r "NT AUTHORITY\NETWORK SERVICE":(OI)(CI)(M)

Startup Tasks の実行時点では、IIS にサイトは生成されていない

Windows Azure 対応の Movable Type Advanced では、データの永続化を行うために更新されるコンテンツは特定のディレクトリ配下に作成するように設定されます。この際に、IIS に設定されているディレクトリの情報を変更するのですが、Azure へデプロイを行うときに実行される Startup Tasks の時点では、IIS に対してサイトの登録がまだ行われていません。

では、どうすれば良いのか?

Startup Tasks で実行されるスクリプトをバックグラウンドで実行するようにして、IIS への設定が終わるのを待つしか無いです。

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")
while( 1 ) {
$SiteInfo = new-object Microsoft.Web.Administration.ServerManager
$iLoop = 1
foreach ( $s in $SiteInfo.Sites ) {
if ( $s.Name -like "MovableTypeOnAzure*" ) {
$iLoop = 0;
break;
}
}
if ( $iLoop ) {
[System.Threading.Thread]::Sleep(1000)
} else {
break
}
}

今回ご紹介した以外にも色々と起きたのですが、それはまた別のお話と言うことで。Movable Type Advanced は今冬にリリース予定となっております。今しばらくお待ちください。

Six Apart をフォローしませんか?

次の記事へ

「仕事で使うのは英語とPerlと第六感?」〜シックス・アパート・エンジニア対談

前の記事へ

シックス・アパートのスタッフに訊いた、5分で理解する"楽チン"情報収集術