某所でオウンゴールを決めてしまったみたいなので、Azure Driveに格納されたWebアプリケーションを、仮想アプリとして実行する方法についての考察です。仮想サイトとして構成してもよかったのですが、その場合は、InputEndpointを構成しておく必要がありそうなので、仮想アプリで実施しています。
基本的に技術屋なので、与えられた課題に対して実現できることが確認できるまでは燃え上がりますが、実現の見通しがつくと鎮火してしまう性質があります。
Driveの準備
WebRole
ポイントは以下。
- Runtime要素で管理者権限
- OnStartメソッドでドライブマウント。OnStopでUnmountすべきですが、手抜きしてます。
- マウントしたDriveのWebアプリを、仮想アプリとして構成。
ServiceDefinitison.csdefには、Runtime要素を追加して、管理者権限で実行させます。
WebRole.csのOnStartメソッドには、以下のコードを追加します。
今回は、以下を実施。
- Microsoft.Web.Administrationの参照追加。%windir%\system32\inetsrvあたりにあります。
- Driveをマウントする。
- ServerManagerクラスを利用して、Driveの直下のフォルダを仮想アプリとして構成する。アプリケーションプールは、Webロールのを利用。
Driveの中身をどう解釈するかは、アプリの設計依存なのでご自由に。
public override bool OnStart() { try { var conn = RoleEnvironment.GetConfigurationSettingValue("connection"); var account = CloudStorageAccount.Parse(conn); var blobClient = account.CreateCloudBlobClient(); var ls = RoleEnvironment.GetLocalResource("ls"); CloudDrive.InitializeCache(ls.RootPath + "cache", ls.MaximumSizeInMegabytes); var drive = account.CreateCloudDrive("disk/a.vhd"); string letter = drive.Mount(64, DriveMountOptions.None); using (ServerManager serverManager = new ServerManager()) { string siteName = RoleEnvironment.CurrentRoleInstance.Id + "_Web"; var site = serverManager.Sites[siteName]; var application = serverManager.Sites[siteName].Applications.First(); var applicationPoolName = application.ApplicationPoolName; //var applicationPool = serverManager.ApplicationPools[applicationPoolName]; foreach (var webapp in new DirectoryInfo(letter).GetDirectories()) { if(webapp.Name.ToLower().Contains("recycle")) continue; var path = "/" + webapp.Name; var physicalPath = letter + webapp.Name; var newapp = site.Applications.Add(path, physicalPath); newapp.ApplicationPoolName = applicationPoolName; } // コミット serverManager.CommitChanges(); } } catch (Exception e) { // 適宜例外処理を } }