2012年3月6日火曜日

連載「libvirt を利用して日々の作業を効率化」第3回

こんにちは、OSSテクノロジーセンターの原です。

この連載も 3回目になりました。

前回は Web 上に list_domains と list_defined_domains で取得したゲストの一覧を表示するところまででした。

現在 webvirt ファルダ以下はこのような状態です。

# tree
.
|-- views
|   `-- index.erb
`-- webvirt.rb

1 directory, 2 files

今回はこの取得したゲストのパワーオン/オフを実装していきたいと思います。

まずはパワーオンの実装です。

views/index.erb:
<b>My KVM VMs</b>
<hr>
Active VMs<br>
<% for act_vm in @act_vm_list %>
  <%= act_vm %><br>
<% end %>

<hr>
Standby VMs<br>
<form method="POST" action="/vm_start">
  <% for sby_vm in @sby_vm_list %>
    <input type="radio" name="vm_name" value="<%= sby_vm %>"/> <%= sby_vm %><br>
  <% end %>
  <input type="submit" name="Submit" value="start">
</form>

form で Standby VM のお名前を /vm_start に POST するだけの簡単な実装です。

次はこの POST を受け取る処理を実装しましょう。

webvirt.rb:
#!/usr/bin/ruby

require 'rubygems'
require 'sinatra'
require 'libvirt'

get '/' do
    conn = Libvirt::open("qemu+ssh://root@kvmhost/system")
    @act_vm_list = conn.list_domains
    @sby_vm_list = conn.list_defined_domains
    erb :index
end

post '/vm_start' do
  conn = Libvirt::open("qemu+ssh://root@kvmhost/system")
  vm = conn.lookup_domain_by_name(params[:vm_name])
  vm.create
  redirect '/'
end

sinatra の良いところは、こういった GET や POST に対応する処理を書くのが非常に手軽な所ですね。Rails で書く場合は更に routes を記述しなければならないですから、この手軽さは大変気に入っています :)

post '/vm_start' do で受け取った Standby VM のお名前( params[:vm_name] )を lookup_domain_by_name メソッドに入れて、該当ゲストマシン のオブジェクト取得、それを create すれば電源を入れることが可能です。

最後に / にリダイレクトして処理は完了です。

非常に簡単ですね。

シャットダウンも同じ要領で記述することが可能ですが、その前にアクティブマシンのリストは現在 ID 表示になっているので、こちらもお名前が出るようにしておきましょう。

webvirt.rb:
#!/usr/bin/ruby

require 'rubygems'
require 'sinatra'
require 'libvirt'

get '/' do
  conn = Libvirt::open("qemu+ssh://root@kvmhost/system")
  @act_vm_list = conn.list_domains
  @act_vm_list_name = []
  act_vms = @act_vm_list
  act_vms.each do |act_vm|
    act_vm = act_vm.to_i
    vm = conn.lookup_domain_by_id(act_vm)
    @act_vm_list_name << vm.name
  end
  @sby_vm_list = conn.list_defined_domains
  erb :index
end

post '/vm_start' do
  conn = Libvirt::open("qemu+ssh://root@kvmhost/system")
  vm = conn.lookup_domain_by_name(params[:vm_name])
  vm.create
  redirect '/'
end
views/index.erb:
<b>My KVM VMs</b>
<hr>
Active VMs<br>
<% for act_vm in @act_vm_list_name %>
  <%= act_vm %><br>
<% end %>

<hr>
Standby VMs<br>
<form method="POST" action="/vm_start">
  <% for sby_vm in @sby_vm_list %>
    <input type="radio" name="vm_name" value="<%= sby_vm %>"/> <%= sby_vm %><br>
  <% end %>
  <input type="submit" name="Submit" value="start">
</form>

webvirt.rb 側で、一旦 @act_vm_list を展開して、名前を引いてから、 @act_vm_list_name に入れ直す処理を加えました。

さて、これでようやくシャットダウンも実装できます。

やり方はパワーオンと基本的に同じです。

webvirt.rb:
#!/usr/bin/ruby

require 'rubygems'
require 'sinatra'
require 'libvirt'

get '/' do
  conn = Libvirt::open("qemu+ssh://root@kvmhost/system")
  @act_vm_list = conn.list_domains
  @act_vm_list_name = []
  act_vms = @act_vm_list
  act_vms.each do |act_vm|
    act_vm = act_vm.to_i
    vm = conn.lookup_domain_by_id(act_vm)
    @act_vm_list_name << vm.name
  end
  @sby_vm_list = conn.list_defined_domains
  erb :index
end

post '/vm_start' do
  conn = Libvirt::open("qemu+ssh://root@kvmhost/system")
  vm = conn.lookup_domain_by_name(params[:vm_name])
  vm.create
  redirect '/'
end

post '/vm_shutdown' do
  conn = Libvirt::open("qemu+ssh://root@kvmhost/system")
  vm = conn.lookup_domain_by_name(params[:vm_name])
  vm.shutdown
  redirect '/'
end
views/index.erb:
<b>My KVM VMs</b>
<hr>
Active VMs<br>
<form method="POST" action="/vm_shutdown">
<% for act_vm in @act_vm_list_name %>
  <input type="radio" name="vm_name" value="<%= act_vm %>"/> <%= act_vm %><br>
<% end %>
<input type="submit" name="Submit" value="shutdown">
</form>

<hr>
Standby VMs<br>
<form method="POST" action="/vm_start">
  <% for sby_vm in @sby_vm_list %>
    <input type="radio" name="vm_name" value="<%= sby_vm %>"/> <%= sby_vm %><br>
  <% end %>
  <input type="submit" name="Submit" value="start">
</form>

パワーオンが create なら、シャットダウンは shutdown です。非常に単純ですね。

ついでなので、destroy も実装しましょう。

ちなみに shutdown と destroy の違いですが、shutdown はいわゆる PC の電源ボタンを押した状態、destroy は電源をブチ切りした状態となります。

従って、shutdown はゲストマシン上で acpid が有効でないと、何度 shutdown を発行してもシャットダウンしてくれません。これはゲストマシンを作成するときのチェックポイントですね。

余談ですが、RHEL6(ないしそのクローン)をインストールする際 minimal を選択すると、acpid は入りません。見落としがちなので、minimal をよく利用する方は見落としの無いよう注意してください。

webvirt.rb:
#!/usr/bin/ruby

require 'rubygems'
require 'sinatra'
require 'libvirt'

get '/' do
  conn = Libvirt::open("qemu+ssh://root@kvmhost/system")
  @act_vm_list = conn.list_domains
  @act_vm_list_name = []
  act_vms = @act_vm_list
  act_vms.each do |act_vm|
    act_vm = act_vm.to_i
    vm = conn.lookup_domain_by_id(act_vm)
    @act_vm_list_name << vm.name
  end
  @sby_vm_list = conn.list_defined_domains
  erb :index
end

post '/vm_start' do
  conn = Libvirt::open("qemu+ssh://root@kvmhost/system")
  vm = conn.lookup_domain_by_name(params[:vm_name])
  vm.create
  redirect '/'
end

post '/vm_shutdown' do
  conn = Libvirt::open("qemu+ssh://root@kvmhost/system")
  vm = conn.lookup_domain_by_name(params[:vm_name])
  if params[:Submit] == "shutdown"
    vm.shutdown
  elsif params[:Submit] == "destroy"
    vm.destroy
  end
  redirect '/'
end
views/index.erb:
<b>My KVM VMs</b>
<hr>
Active VMs<br>
<form method="POST" action="/vm_shutdown">
  <% for act_vm in @act_vm_list_name %>
    <input type="radio" name="vm_name" value="<%= act_vm %>"/> <%= act_vm %><br>
  <% end %>
  <input type="submit" name="Submit" value="shutdown">
  <input type="submit" name="Submit" value="destroy">
</form>

<hr>
Standby VMs<br>
<form method="POST" action="/vm_start">
  <% for sby_vm in @sby_vm_list %>
    <input type="radio" name="vm_name" value="<%= sby_vm %>"/> <%= sby_vm %><br>
  <% end %>
  <input type="submit" name="Submit" value="start">
</form>

できましたね。実際にクリックして挙動を確かめることをお忘れなく。

いかがでしたでしょうか。

段々とそれっぽい機能が使えるようになって来ましたが、連載はもう少し続きます。

次回もお楽しみに。ではでは。

0 件のコメント:

コメントを投稿