Tools仮想マシン環境と言えば色々ありますが、個人的にはVirtualBoxがPC環境でも使いやすいと思っています。安定性や品質、機能面では他の仮想化ソフトに道を譲りますが、開発用途では十分な印象があります。何台か運用しているうち、CLIやスクリプトからも扱いたいと思い、PythonでのAPI連携を試してみました。VirtualBoxが標準で提供しているAPI、vboxapiはあまり積極的にはエンハンスされていないようで、Pythonから使うのはひと工夫必要なようです。歴史上の経緯で若干制限もあるため、最初からサードパーティ製のものを使うという選択肢もありますが、せっかくなので標準のものもちょっと調べてみました。今回のサンプルは最後のほうで掲載します。(一応6.0でも確認済)です。(XPCOM)で実装されており、様々な言語から制御できるようになっているようです。SDKとしてPython向けのバインディングが用意されているので、マニュアルでCOMインタフェースの使い方を調べればPythonでもおおよそ同じ操作を実装することができます。VirtualBoxではSOAP経由で同じインタフェースを公開しているRPCが提供されているので、VirtualBox(ハイパバイザ)がインストールされていないリモートのマシンからもAPIの呼び出しが可能です。ローカルとリモートの関係を図示するとこんな感じです。Python用クライアント環境のインストールPython2.x系のみサポートなので、システムを汚したくなければvirtualenv,pyenvなどの仮想環境を使ったほうが良いと思います。(Miniconda)が導入されていましたので、condaコマンドで仮想環境を作ることにしました。name}は何か適当に読み替えて下さい。name}VirtualBoxがローカルにインストールされている環境ではSDKのインストーラもデフォルトで同梱されています。バージョンを気にしたくない場合は素直に同梱されているものを使うと良いと思います。Windowsの場合、デフォルトでは下記のような感じです。vboxapisetup.pyあるいは、VirtualBoxがインストールされていない環境なら(もちろん、されている環境でも)pip経由で入手できます。Python2(pip2)系でないとエラーになります。vbox-sdkWindows環境の場合はその他(COM操作関連)に依存パッケージpywin32(またはpypiwin32)が必要です。pywin32ローカルで利用するのみ(つまりVirtualBoxホストで使う場合)であればここでインストール作業は終了です。リモートで利用する場合はさらに必要な依存関係があります。リモート管理用クライアント環境のインストールリモートでAPIを扱うには、SOAPクライアントが必要になります。SDK(のサンプル)ではちょっと古いモジュールを使っているので、そのままでは使えません。SOAPを扱うためのZSIモジュールがそもそも古いですが、ZSIが依存しているPyXMLも既にサポートが停止されているようです。そのまま頑張るなら、どこぞから拾ってきたPyXMLをオフラインインストールし、さらにZSIをpip経由で導入します。サードパーティ製のものを使うのも手です。インタフェース定義(WSDL)もSDKに同梱されているので自前でSOAPの手続きを実装することも一応可能なようです。SOAPを使う必要性も感じなければ、リモート呼び出し部分のインタフェースは自作する、というやり方でもいいかもしれません。ここではとりあえずSDKのサンプルに準拠してみます。PyXMLをWindowsにインストールするには、VC++コンパイラ(vcpython27)が必要です。Microsoftのサイトから入手してインストールします。https://www.microsoft.com/en-us/download/details.aspx?id=44266PyXMLは既にPyPIから削除されているので、Tarアーカイブをネットから入手します。現時点ではSourceForgeで配布していました。https://sourceforge.net/projects/pyxml/files/仮想環境でインストールします。vbox-sdk一部のリモート呼び出し用のバインディングは上記のvbox-sdkパッケージに含まれていないようなので別途設置が必要です。公式サイトからSDK(ZIPアーカイブ)を入手し、個別にパスを通します。condaのような仮想環境を使っている場合はvboxapiが入っている場所にコピーしてしまうのが簡単です。具体的には、vboxapi.__file__が指しているパスと同じ階層ですね。vboxapi,os;print(os.path.dirname(vboxapi.__file__))"公式サイトから入手したzipアーカイブを解凍し、sdk/bindings/webservice/python/libのパスにあるスクリプト(VirtualBox_client.py、VirtualBox_types.py、VirtualBox_wrappers.py)を上記のvboxapiと同じ場所にコピーします。リモートアクセス用Webサーバのセットアップローカルで実行する際には不要ですが、リモートから操作する場合にはVirtualBoxに同梱のWebサーバVBoxWebSrvを使います。Windows編Windowsの場合は、VirtualBoxがインストールされたディレクトリにあるVBoxWebSrv.exeで、リモートからの通信を受け付けるために起動しておきます。実行には管理者権限が必要ですので、管理者として起動したコマンドプロンプトまたはPowershellから実行するなどします。name}を指定します。name}使用している場合はファイヤウォールを設定します。終了する際にはタスクキルではなくCtrl+Cを使ったほうが良いです。リモートから設定変更中にキルすると、VMがabort状態になったりします。Linux編Linuxの場合、例えばUbuntuでは普通にaptを使って(例によって古いバージョンですが)VirtualBoxをインストールすることができ、Webサーバもサービスとしてセットアップされます。-)aptインストールしたほうが無難です。サービスとしてセットアップされたものをちょっと修正して使うことにしました。起動オプションの指定は上記のWindowsの場合と同じで、ExecStartのところに追加します。vboxweb.serviceファイヤウォールを使っている場合は設定しておきます。上記のようにWebサーバは管理者アカウントで起動されるので、GUIを使いたい際にもsudoする必要があります。VirtualBoxManager実際のクライアント用スクリプトでは、ローカルでもリモートでも、基本的にはVirtualBoxManagerオブジェクトを使って操作していきます。このVirtualBoxManagerによって隠蔽されるので、後で呼び出すメソッドはローカル、リモートに関わらず同じです。getpass()})リモートで操作する場合には第一引数に"WEBSERVICE"をセットします。URLは普通にhttp/httpsの、VBoxWebSrvの起動オプションに使用したホスト名とポートの組合せになります。認証はデフォルトではVBoxWebSrvを起動しているのと同じものです。Windowsならログイン中のアカウント、Linuxならプロセスを起動している(PAM)アカウントです。https/SSL通信や外部認証の利用など、標準で他のカスタマイズもサポートされています。ローカル/リモートともに、VirtualBoxへの操作は個別にセッション的なものを張る仕様になっていますが、複数生成されても暗黙的には同期されません。Pythonから呼び出したセッションと、例えば普通のGUIとはそのままでは見かけのVMの状態が一致しないこともあります。設定系の操作のためにロック機構が用意されているので実質的に不整合になることが無いように設計されていますが、明示的に同期させるか、単一のセッションのみ使用するようにしたほうが良いです。VMを対象とする操作に関してはVirtualBoxインスタンスを取得する必要があります。VMの操作ここでは基本的と思われる操作について記載していきます。VM一覧の取得VirtualBoxManager.getArray()メソッドに'machines'を指定すると、VMのリストに相当するものを取得することができます。リストの各要素はIMachineインタフェースになっており、VMの属性や設定値を表すプロパティを参照できます。'machines'):print("{}".format(vm_.name))...サンプルでは特定のプロパティを文字列にキャストして表示させる処理を実装しており、実行するとこんな感じの結果になると思います。VM(ゲスト)の起動うまく起動に成功した場合、状態(state)が停止(PoweredOff)から実行中(FirstOnline)になります。今回はホストにログインしてGUI操作するのが面倒という動機なので、ヘッドレスで起動させることにします。サンプルの使用例はこんな感じ。VMの名前を指定して起動します。_client.start_vm("vm1")まず、所望のVMへの参照を取得し、セッションを作成します。self.manager.getSessionObject(self.vbox)ゲストの起動はIMachine.launchVMProcess()で実行でき、下記のようにヘッドレス(コンソールを表示しない)を指定することができます。起動状態への遷移にはある程度時間がかかるので、当該タスクの完了を待つ処理を入れます。sessionprog_.waitForCompletion(self.__timeout_msec)self.manager.closeMachineSession(session_)完了後にはセッション終了(closeMachineSession())を呼んだほうが無難です。VMのシャットダウンVMを終了する際には他のハイパバイザと同様に、いわゆる強制停止と、ゲストOSのシャットダウンとの2種類があります。ディストリビューションで問題なく動くので、もちろんACPIシャットダウンを使ったほうが良いでしょう。サンプルの使用例はこんな感じ。VMの名前を指定してシャットダウンします。force=False)内部的には、明示的にロックを取得した上で、停止IConsole.powerDown()、またはACPIシャットダウンIConsole.powerButton()を実行します。サンプル上記の操作の実装はこんな感じです。shutdownsession_.console.powerButton()別記事に続く。usta関連記事pycryptoでAES暗号化を試す認証機能はWebサービスを作るときに重要ですが、パスワードの保管って厄介ですよね。Cookieやらスクリプトに平文を直書きするのは抵抗があり...記事を読むPythonでなんちゃってディスク空き容量取得サイズの大きいファイルを書き出すスクリプトなど、実行中の環境でディスクの空き容量を取得したいときがあります。ServerのセットアップUbuntuを最小限のサーバとしてセットアップする場合のメモ。~二代目の帰朝~別記事の続きです。データの登録と検索について記載します。UpdateでHyper-Vの仮想スイッチが使えなくなった話タイトルの通りです。やってみて何とか解決?したので書いておきます。10)を使っていると、画面の...記事を読むSourcegraphサーバーのインストールGitで管理しているソースを検索したい、そんな時に便利なSourcegraph。Github向けなどのブラウザ拡張もあるようですが、サー...記事を読むPythonでMongoDBにアクセスするMongoDBはスキーマ定義が柔軟なドキュメント指向のデータベース。JSONっぽいデータ形式で何でも突っ込んでおけますし、最低限ならそこまで...記事を読むpysmbを使ってPythonでWindowsファイルサーバにアクセスするWindowsファイルサーバ(SMB)をスクリプトから操作するとき、ネイティブにはPowerShellですが、Pythonで実装するとLin...記事を読むPython3でJPEG画像のExifを取得し、回転方向を修正するちょっと古いPCや安物のデバイスでJPEGを表示させようとすると、上下が反転していたりします。コメントをキャンセルメールアドレスが公開されることはありません。コメントデータの処理方法の詳細はこちらをご覧ください。