TechReport

技術者情報

ソリューション

2011年11月30日(水)公開

第68回

Hyper-Vを使ったクラウドサービスの作り方 Vol.3

Hyper-V Provisioning 仮想マシン一覧の取得

GMOインターネット株式会社 事業本部 樋口 勝一が担当するGMO最新ネット業界レポート ソリューション編。『Hyper-Vを使ったクラウドサービスの作り方』として前回までにVol.1 Windows Server ライセンスの種類、使い方の紹介、Vol.2 Build to Orderな仮想マシンについてと紹介してきましたがVol.3となる今回は『Hyper-V Provisioning 仮想マシン一覧の取得』について紹介。

記事INDEX

Hyepr-Vへのプログラムからのアプローチ方法

今回からはHyper-V Provisioningの基本を踏まえて、Hyepr-Vへのプログラムからのアプローチ方法をご紹介していきたいと思います。まず、Hyper-Vをプログラムで制御するにはWindows Management Instrumentation(WMI)を利用してアプローチすることになります。 (参考:Hyper-V WMI Classes )

クラス一覧を見てみると、Memory Class や Networking Class など仮想マシンに必要な各パーツがクラス分けされているのが分かります。これら各クラスを利用することで、例えばメモリ量の情報取得や、メモリの割り当てなどを行なうことができます。おおよそ全てのクラスに対し決まったパターンの構文でアプローチ可能となっているので、パターンを覚えてしまえば、その応用で様々なプログラムを作ることができるようになります。


.NETのSystem.Management クラスを使ってWMIに接続

まずは、WMIの基本からです。.NETのSystem.Management クラスを使ってWMIに接続します。VisualStudioの参照設定で、System.Management を追加します。(参照:コード01)

[ コード01 ]
   1:  Function ConnectManagementScope(ByVal strServer As String, ByVal 
  strAccount As String, ByVal strPassword As String) As ManagementScope
   2:  Dim objConnectionOptions As New ConnectionOptions()
   3:  objConnectionOptions.Impersonation = ImpersonationLevel.Impersonate 
  'WMI への接続に使用される偽装レベルを設定
   4:  objConnectionOptions.EnablePrivileges = True 
  'WNI経由の操作のためにユーザー特権を有効にする
   5:  objConnectionOptions.Username = strAccount
   6:  objConnectionOptions.Password = strPassword
   7:  Dim objManagementScope As New ManagementScope("\\" + strServer +       
  "\root\virtualization", objConnectionOptions)
   8:  objManagementScope.Connect()
   9:  Return (objManagementScope)
  10:  End Function


WMIへの接続のため、接続先のサーバー情報、セキュリティー情報を設定します。



3行目の Impersonation と4行目の EnablePrivileges でリモートからWMIを操作するため権限設定を行なっています。



このサンプルではリモートのサーバーに対しての接続設定となりますが、ローカルサーバーの場合、ConnectionOptions の設定が必要ありませんのでこのようにシンプルになります。(参照:コード02)


接続先のサーバー名も「.」で代用することができます。

[ コード02 ]
   1:  Function ConnectManagementScope() As ManagementScope
   2:  Dim objManagementScope As New ManagementScope("\\.\root\virtualization")
   3:  objManagementScope.Connect()
   4:  Return (objManagementScope)
   5:  End Function


これでWMIに接続するための準備が完了しました。



Hyper-V上に搭載されている仮想マシンの一覧を取得するコード

次に、先ほど取得したManagementScope オブジェクトを使って実際にWMIを使って見ましょう。


簡単なところで、Hyper-V上に搭載されている仮想マシンの一覧を取得するコードをご紹介します。


(参照:コード03)

[ コード03 ]
   1:  SubGetVMList(ByVal objManagementScope As ManagementScope)
   2:  Dim objObjectQuery AsNew ObjectQuery("SELECT * FROM Msvm_ComputerSystem
  WHERE Caption LIKE '仮想マシン'")
   3:  Dim objManagementObjectSearcher As New
  ManagementObjectSearcher(objManagementScope, objObjectQuery)
   4:  Dim objManagementObjectCollection As 
  ManagementObjectCollection = objManagementObjectSearcher.Get
   5:  For Each objManagementObjectAs ManagementObject In
  objManagementObjectCollection
   6:   Console.WriteLine(objManagementObject("ElementName"))
   7:  Next
   8:  End Sub

先ほど、取得したManagementScope オブジェクトを引数として渡します。



2行目:


WMIはSQLクエリ文のように目的のアイテムを抽出することができます。



4行目:


SELECT文で作成したたクエリオブジェクトを使用してManagementObjectCollectionを取得します。



5~7行目:


コレクションは複数のオブジェクトを返すので、For~Next文でそれぞれ単体のManagementObject として取得します。取得したManagementObjectは1つの仮想マシンに対応しているので、プロパティーのElementNameで仮想マシンの名前を知ることができます。コードを実行してみると、Hyper-V上に作成されている仮想マシンの名前の一覧が表示されます。



このように、ManagementScope オブジェクトを取得してクエリで抽出、ManagementObjectCollection をFor~Nextで回して目的のManagementObject を取得する、といった一連の流れがWMIを利用するお決まりのパターンとなります。



これを踏まえて、いよいよ実際に仮想マシンを作っていきましょう。 はじめは仮想マシンの骨組みとなる部分を作り、後からメモリやハードディスクなどを追加していきます。(参照:コード04)

[ コード04 ]
   1:  Function DefineVM(ByVal objManagementScope As ManagementScope, ByVal
  strVMName As String, ByVal strFolderPath As String) As Boolean
   2:  Dim objVirtualSystemGlobalsettingData As New
  ManagementClass(objManagementScope, New ManagementPath
  ("Msvm_VirtualSystemGlobalsettingData"), Nothing)
   3:  Dim objVirtualSystemGlobalsettingDataInstance As ManagementObject =
  objVirtualSystemGlobalsettingData.CreateInstance
   4:  objVirtualSystemGlobalsettingDataInstance("ElementName") = strVMName
   5:  objVirtualSystemGlobalsettingDataInstance("ExternalDataRoot") =
  strFolderPath
   6:  Dim strSystemsettingData As String =
  objVirtualSystemGlobalsettingDataInstance.GetText(TextFormat.CimDtd20)
   7:   
   8:  For Each objVirtualSystemManagementService As ManagementObject In New
  ManagementObjectSearcher(objManagementScope, NewObjectQuery
  ("SELECT * FROM Msvm_VirtualSystemManagementService")).Get
   9:  Dim objParams As ManagementBaseObject =
  objVirtualSystemManagementService.GetMethodParameters
  ("DefineVirtualSystem")
  10:  objParams("ResourceSettingData") = Nothing
  11:  objParams("Sourcesetting") = Nothing
  12:  objParams("SystemsettingData") = strSystemsettingData
  13:  Dim objManagementBaseObject As ManagementBaseObject =
  objVirtualSystemManagementService.InvokeMethod
   ("DefineVirtualSystem", objParams, Nothing)
  14:  Return JobComplete(objManagementBaseObject, objManagementScope)
  15:  Next
  16:  End Function
  17:   
  18:  Function JobComplete(ByVal objManagementBaseObject As
  ManagementBaseObject, ByVal objManagementScope As ManagementScope) 
  As Boolean
  19:  'JobState New = 2  Starting = 3  Running = 4  Suspended = 5
  ShuttingDown = 6  Completed = 7  Terminated = 8  Killed = 9
  Exception = 10  Service = 11
  20:  If objManagementBaseObject("ReturnValue") <> 0 Then
  21:  Dim strJobPath As String = objManagementBaseObject("Job")
  22:  Dim objJob As New ManagementObject(objManagementScope, New
  ManagementPath(strJobPath), Nothing)
  23:  objJob.Get()
  24:  Do While objJob("JobState") = 3 Or objJob("JobState") = 4
  25:  System.Threading.Thread.Sleep(1000)
  26:  objJob.Get()
  27:  Loop
  28:  If objJob("JobState") <> 7 Then
  29:  Console.WriteLine("ErrorCode=" & objJob("ErrorCode") & " JobState=" &
  objJob("JobState"))
  30:  Return False
  31:  Else
  32:  Return True
  33:  End If
  34:  Else
  35:  Return True
  36:  End If
  37:  End Function


引数として渡すのは、ManagementScopeオブジェクト、仮想マシン名、仮想マシンの格納フォルダ となります。



2~3行目:


Msvm_VirtualSystemGlobalsettingDataクラスから仮想マシンを作成するための設定情報の新しいインスタンスを作成します。objVirtualSystemGlobalsettingData.CreateInstance は仮想マシンを作成しているわけではなく、仮想マシンの設定情報を新たに作成しているので、間違わないようにしてください。

4~5行目:


最低限の設定項目として、仮想マシン名と、仮想マシンを格納するフォルダパスを指定します。


6行目:設定情報としてXML形式で保存します。

8行目:


ここからちょっと難しくなりますが、これもパターンとして毎回出てくるので覚えておいてください。仮想マシンはMsvm_VirtualSystemManagementService クラスから作成したり、修正したり、削除することができます。Msvm_VirtualSystemManagementServiceクラスのオブジェクトを一つをFor~Next文で取り出します。

9行目:


仮想マシンを作成(定義)するためにはDefineVirtualSystemメソッドを使用することになります。事前にDefineVirtualSystemメソッドで必要となるパラメーターオブジェクトをGetMethodParametersで取得して、各項目に設定値を入力しておきます。

12行目:


先ほど仮想マシン名と仮想マシンの格納フォルダをXML化していた設定情報を、SystemsettingDataパラメーターに入力します。仮想マシンの骨組みを作成するのであれば、この設定内容だけで十分です。

13行目:


DefineVirtualSystemメソッドを、入力したパラメーターの内容で実行します。

14行目:


DefineVirtualSystemメソッドによって、仮想マシンが作成されることになるのですが、メソッドが実行される過程において、Hyper-V上では、刻々とステータスが変化してゆきます。最終的にはCompleted = 7 になれば成功となります。その過程でのエラーを正確に取得するため、Hyper-Vでメソッド実行時には毎回 JobCompleteを使うことにします。



以上で、エラー無くコードが走れば、Hyper-V上にはVM01という名前の仮想マシンが作成されているはずです。ですが、VM01の設定内容をみてみると、ハードディスクなどは接続されておらず、512MBのメモリと1個の仮想プロセッサが割り当てられているだけとなっています。

ここから、いろいろなオプションを付け足して本来必要な仮想マシンを作り上げていくことになります。


次回以降は、ハードディスクを初めとしたオプションの追加方法をご紹介する予定です。







*本文中に記載されている会社名および商品名・サービス名は、各社の商標 または登録商標です。

樋口 勝一

GMOインターネット株式会社

1999年6月GMOインターネットに入社。Windowsを用いたホスティング事業の立ち上げの際、サービス開発からその後の保守・運用まで1人で担当。2010年には「お名前.comWindowsデスクトップ」をリリースし、マイクロソフト社と強い信頼関係を構築。2007年から連続で「マイクロソフトMVPアワード」を受賞し、Windowsのスペシャリストとして活躍。

執筆者一覧

 執筆協力した本が出版されました

 当レポートを担当しているGMOインターネット株式会社 事業本部 樋口 勝一が執筆協力をした書籍が出版されました。

Dynamic Memory
  最新!Android徹底活用読本

出版社:宝島社
価格:880円(税込) ※価格は店舗によって異なります。

次々に発売されるAndroidケータイを「コミュニケーションしたい」「情報をブラウジングしたい」「ビジネス手帳の代わりにしたい」「音楽や動画を120%楽しみたい」など、やりたいこと別に章立てした活用書。

Dynamic Memory
  GALAXY Sユーザーのためのアプリ245

出版社:三才ブックス
価格:1,260円(税込) ※価格は店舗によって異なります。

25万本以上あるといわれるAndroidアプリの中から、目的別・状況別に本当に使えるアプリだけを厳選。

Dynamic Memory
  ソニー・エリクソン公式 Xperia arc ガイドブック

出版社:日経BP社
価格:1,260円(税込) ※価格は店舗によって異なります。

こだわりのデザインと薄さを追求しながら、Androidスマートフォンのフラッグシップモデルとして世界に先駆けて日本で発売されるXperia arcの公式ガイドブックです。