2014年4月11日金曜日

Python3 から XML-RPC 経由で Python2.7 の libvirt を使って KVM 操作

Python3 で libvirt を使って KVM ゲスト操作をしたいのですが、Ubuntu 12.04 では Python2.7 用の python-libvirt パッケージはありますが、Python3 用のものは用意されていません。

そこで、libvirt を使って KVM ゲストを操作するための XML-RPC サーバーを Python2.7 で用意し、Python3 からこの XML-RPC サーバーにアクセスすることで KVM ゲストを操作してみました。

概要

イメージはこんな感じです。

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYoU_iQ_JtFnyvtFbb2E1KSsaYyvEAl1vIxTvHFYPNL3e02wjtdvuMZpEJKNqVWkOnZjTnk_Y69QsfcUfVpoSEbVlQz4TgL4VZTzpFXOSTa4AqSiNHb14a4TE5o7sfnYX-BTsIqb8D/s1600/outline.png

環境

Ubuntu 12.04.4 LTS Server

Python2.7 で KVM ゲスト操作のための XML-RPC サーバー用意

パッケージインストール

$ sudo apt-get install python-libvirt
SimpleXMLRPCServer.register_instance() に登録するインスタンスを生成するためのクラスを記述したモジュールファイルを用意

以下の内容の mLibVirtConn.py を設置

#!/usr/bin/env python2.7
# coding: utf-8

import  libvirt

# Class for XML-RPC instance.
class LibVirtConn:
    def __init__(self):
        self.__oConn = libvirt.open('qemu:///system')

    def __get_oDomain(self, xNameOrID):
        if isinstance(xNameOrID, str):
            return self.__oConn.lookupByName(xNameOrID)
        else:
            return self.__oConn.lookupByID(xNameOrID)

    def listDomainsID(self):
        return self.__oConn.listDomainsID()

    def listDefinedDomains(self):
        return self.__oConn.listDefinedDomains()

    def domain_name(self, xNameOrID):
        return self.__get_oDomain(xNameOrID).name()

    def domain_create(self, sName):
        return self.__oConn.lookupByName(sName).create()

    def domain_destroy(self, xNameOrID):
        return self.__get_oDomain(xNameOrID).destroy()

複雑なことは XML-RPC でメソッドを呼び出す Python3 側でやるので、薄いラッパー程度の内容に留めてます。

LibVirtConn インスタンスのメソッドを XML-RPC で公開

以下の xmlRpcServer.py を mLibVirtConn.py と同じディレクトリに設置

#!/usr/bin/env python2.7
# coding: utf-8

from __future__ import print_function
from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler

from mLibVirtConn import LibVirtConn

class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RPC2',)

def main():
    oServer = SimpleXMLRPCServer(("localhost", 8000), requestHandler=RequestHandler)
    oServer.register_introspection_functions()
    oServer.register_instance(LibVirtConn())
    oServer.serve_forever()

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print()
xmlRpcServer.py を実行
$ ./xmlRpcServer.py

プログラムは終了せず、実行されたままとなります。

XML-RPC サーバーを終了する場合は Ctrl-C です。

Python3 で XML-RPC メソッドを呼び、KVM ゲストを操作

まず、ゲスト OS の状態はこんな感じになっていたとします。

$ sudo virsh list --all
 Id Name                 State
----------------------------------
 10 KvmGuest1            running
 11 KvmGuest2            running
  - KvmGuest3            shut off
xmlRpcServer.py を実行したサーバーで ipython3 シェルを起動
$ ipython3

以下は ipython3 シェル内での python3 コードの実行内容です。

XML-RPC クライアントインスタンス生成
In [XXX]: import xmlrpc.client
In [XXX]: oProxy = xmlrpc.client.ServerProxy('http://localhost:8000')
起動しているゲスト OS の ID リストを取得
In [XXX]: oProxy.listDomainsID()
Out[XXX]: [11, 10]
停止しているゲスト OS の名前リストを取得
In [XXX]: oProxy.listDefinedDomains()
Out[XXX]: ['KvmGuest3']
ゲスト OS の名前を取得
In [XXX]: oProxy.domain_name(10)
Out[XXX]: 'KvmGuest1'

ID 10 のゲスト OS の名前は KvmGuest1 でした。

ゲスト OS を起動
In [XXX]: oProxy.domain_create('KvmGuest3')
Out[XXX]: 0

KvmGuest3 を起動しました。

ゲスト OS を強制停止

ID でゲスト OS を指定

In [XXX]: oProxy.domain_destroy(11)
Out[XXX]: 0

名前でゲスト OS を指定

In [XXX]: oProxy.domain_destroy('KvmGuest2')
Out[XXX]: 0

0 件のコメント:

コメントを投稿