perl Sys::Virt でlibvirt APIを叩いてKVM 仮想マシンを操作する
Sys::Virt - libvirt のperl バインディング。virt-manager で出来るようなストレージの設定や仮想マシンの起動、停止、削除、設定変更などが可能。(自分で確認したのは仮想マシンを操作するSys::Virt::Domain のみ)
久しぶりに触ろうとしたら忘れすぎて悲惨だったのでおさらいしておく。
install
OSのlibvirt に依存しているので、cpanm Sys::Virt などとして最新版を入れようとしても失敗するのでOSパッケージのものを使う。(もしくはlibvirtをsourceから取って最新のものをinstallしてからcpanm Sys::Virt するか)
使い方
- perldoc Sys::Virt
- perldoc Sys::Virt::Domain
- その他のperldoc Sys::Virt::*
接続
remote hostにログインする時はsshを使って qemu+ssh://hostname/system などで接続する。認証情報をSys::Virtに渡すことも出来るけど、sshの場合は公開鍵を作って ~/.ssh/config に設定しておいたほうが色々と楽になる。Sys::Virt->new で接続に失敗すると例外で落ちるのでeval しておくなど。
my $user = "user"; my $host = "kvm.example.com"; my $uri = "qemu+ssh://$user\@$host/system"; my $vmm; eval { #$vmm = Sys::Virt->new(uri => $uri, readonly => 1); $vmm = Sys::Virt->new(uri => $uri); }; if ($@) { die "$@"; }
情報取得
$vmm->list_domains, $vmm->list_defined_domains などで仮想マシンのオブジェクト(Sys::Virt::Domain)の配列を取得する。list_domainsは稼働中な仮想マシン、list_defined_domainsは停止中の仮想マシンのSys::Virt::Domain オブジェクトを返す。
my @doms = $vmm->list_domains() Return a list of all domains currently known to the VMM. The elements in the returned list are instances of the Sys::Virt::Domain class. my @doms = $vmm->list_defined_domains() Return a list of all domains defined, but not currently running, on the VMM. The elements in the returned list are instances of the Sys::Virt::Domain class.
全仮想マシンの名前,uuid, cpu/memory/state を取得。この辺は/etc/libvirt/qemu/仮想マシン.xml の情報と同じ。$dom->get_info はハッシュリファレンスで返ってくるので手抜きしてdumpしてる例。
use Data::Dump qw(dump); for my $dom ($vmm->list_domains, $vmm->list_defined_domains) { ## see perldoc Sys::Virt::Domain print "name: ", $dom->get_name, "\n"; print "uuid: ", $dom->get_uuid_string(), "\n"; ## $dom->get_info returns a hash reference dump $dom->get_info; print "\n"; }
この辺までを実行するとこうなる。
# foo 起動中、bar 停止中、baz 一時停止中(suspend) の仮想マシン
$ perl sysvirt.pl name: foo uuid: f33fa104-dbc3-5328-49c2-474bf3733664a { cpuTime => "66750000000", maxMem => 2097152, memory => 2097152, nrVirtCpu => 2, state => 1, } name: bar uuid: 19b95335-806f-53f1-0149-fae39fbd9872 { cpuTime => 0, maxMem => 2097152, memory => 2097152, nrVirtCpu => 2, state => 5, } name: baz uuid: 19b95335-806f-53f1-0149-f2ae39fbd981 { cpuTime => "81660000000", maxMem => 1048576, memory => 1048576, nrVirtCpu => 1, state => 3, }
stateはperldoc Sys::Virt::Domain 参照。
my $info = $dom->get_info() (snip) state The execution state of the machine, which will be one of the constants &Sys::Virt::Domain::STATE_*.
とあるように判別するときは直接数字を指定するではなくて、この関数を実行して値とってくる。関数を叩くと並んでいる順に0~6までの数値が返ってくる。
DOMAIN STATE The domain state constants are useful in interpreting the "state" key in the hash returned by the "get_info" method. Sys::Virt::Domain::STATE_NOSTATE The domain is active, but is not running / blocked (eg idle) Sys::Virt::Domain::STATE_RUNNING The domain is active and running Sys::Virt::Domain::STATE_BLOCKED The domain is active, but execution is blocked Sys::Virt::Domain::STATE_PAUSED The domain is active, but execution has been paused Sys::Virt::Domain::STATE_SHUTDOWN The domain is active, but in the shutdown phase Sys::Virt::Domain::STATE_SHUTOFF The domain is inactive, and shut down. Sys::Virt::Domain::STATE_CRASHED The domain is inactive, and crashed.
停止/起動
- $dom->create();
- $dom->shutdown();
- $dom->destroy();
- $dom->suspend();
- $dom->resume();
あたり。shutdownは電源ボタンを押すのと同じなので、仮想マシン側でapicdを動かしておかないと意味がない。 destroyは強制停止。
ex: 停止中の(正常に停止状態にある)仮想マシンを起動する
for my $dom ($vmm->list_domains, $vmm->list_defined_domains) { if ($dom->get_info->{state} == &Sys::Virt::Domain::STATE_SHUTOFF) { $dom->create(); print $dom->get_name, " created\n"; } }
code
また忘れたら嫌だからgist に置いておいた。