Skip to content
This repository has been archived by the owner on Dec 7, 2022. It is now read-only.

Commit

Permalink
First stab at a libvirt agent
Browse files Browse the repository at this point in the history
  • Loading branch information
ripienaar committed Aug 21, 2011
1 parent 641f14b commit c6e21af
Show file tree
Hide file tree
Showing 3 changed files with 362 additions and 0 deletions.
87 changes: 87 additions & 0 deletions agent/libvirt/README.md
@@ -0,0 +1,87 @@
What?
=====

Basic management of Libvirt Hypervisors and domains

Usage?
======

There isn't a bundled application, it works fine through the normal RPC client:

Hypervisor Information:
-----------------------
<pre>
% mco rpc libvirt hvinfo

kvm1.xx.net
Inactive Domains: []
Type: QEMU
Sockets: 1
Max VCPUs: 16
Cores: 2
Model: x86_64
URI: qemu:///system
Version: 12001
Memory: 8063656
Numa Nodes: 1
Free Memory: 2292154368
CPUs: 2
Active Domains: ["dev2_devco", "dev4_devco", "dev5_devco", "dev3_devco"]
MHz: 1297
Threads: 1

Finished processing 1 / 1 hosts in 103.90 ms
</pre>

Domain Information:
-------------------

<pre>
% mco rpc libvirt domaininfo domain=dev2_devco

kvm1.xx.net
State: 1
State: Running
UUID: fd402bc2-9207-fb2a-d650-a3ba85214578
Autostart: true
Memory: 524288
VCPUs: 1
Max Memory: 524288
CPU Time: 29540000000

Finished processing 1 / 1 hosts in 92.90 ms
</pre>

Manage a Domain:
----------------

<pre>
% mco rpc libvirt destroy domain=dev4_devco

kvm1.xx.net
State: 5
State: Shut off

Finished processing 1 / 1 hosts in 320.48 ms
</pre>

Other available actions are:

* create / start
* destroy
* resume
* shutdown
* suspend

Todo?
====

* Make the hypervisor URL configurable, atm only QEMU and only unauthenticated
* Expose more hypervisor information like device lists, network lists, storage lists etc
* Allow for creation using provided XML
* More stats so that full feature auto provisioning can be built

Contact?
========

R.I.Pienaar / rip@devco.net / http://devco.net / @ripienaar
154 changes: 154 additions & 0 deletions agent/libvirt/agent/libvirt.ddl
@@ -0,0 +1,154 @@
metadata :name => "libvirt",
:description => "SimpleRPC Libvirt Agent",
:author => "R.I.Pienaar <rip@devco.net>",
:license => "ASL2.0",
:version => "0.1",
:url => "http://devco.net/",
:timeout => 10

action "hvinfo", :description => "Hypervisor Information" do
display :always

output :model,
:description => "Hypervisor Model",
:display_as => "Model"

output :memory,
:description => "Hypervisor Total Memory",
:display_as => "Memory"

output :cpus,
:description => "Number of CPUs",
:display_as => "CPUs"

output :mhz,
:description => "CPU Clock Frequency",
:display_as => "MHz"

output :nodes,
:description => "Number of NUMA Nodes",
:display_as => "Numa Nodes"

output :sockets,
:description => "CPU Sockets",
:display_as => "Sockets"

output :cores,
:description => "CPU Cores",
:display_as => "Cores"

output :threads,
:description => "CPU Threads",
:display_as => "Threads"

output :type,
:description => "Hypervisor Type",
:display_as => "Type"

output :version,
:description => "Hypervisor Version",
:display_as => "Version"

output :uri,
:description => "Hypervisor URI",
:display_as => "URI"

output :node_free_memory,
:description => "Total Free Memory",
:display_as => "Free Memory"

output :active_domains,
:description => "Active Domains",
:display_as => "Active Domains"

output :inactive_domains,
:description => "Inactive Domains",
:display_as => "Inactive Domains"

output :max_vcpus,
:description => "Maximum virtual CPUs",
:display_as => "Max VCPUs"
end

action "domaininfo", :description => "Domain Information" do
display :always

input :domain,
:prompt => "Domain Name",
:description => "Name of a defined domain",
:type => :string,
:validation => '^.+$',
:optional => false,
:maxlength => 50

output :autostart,
:description => "Will the domain auto start",
:display_as => "Autostart"

output :vcpus,
:description => "Number of Virtual CPUs",
:display_as => "VCPUs"

output :memory,
:description => "Current Memory",
:display_as => "Memory"

output :max_memory,
:description => "Maximum Memory",
:display_as => "Max Memory"

output :cputime,
:description => "CPU Time",
:display_as => "CPU Time"

output :state,
:description => "Domain State",
:display_as => "State"

output :state_description,
:description => "Domain State",
:display_as => "State"

output :uuid,
:description => "Domain UUID",
:display_as => "UUID"
end

action "domainxml", :description => "Retrieve the full libvirt XML description for a domain" do
display :always

input :domain,
:prompt => "Domain Name",
:description => "Name of a defined domain",
:type => :string,
:validation => '^.+$',
:optional => false,
:maxlength => 50

output :xml,
:description => "Domain XML",
:display_as => "XML"
end

[:destroy, :shutdown, :suspend, :resume, :create, :start].each do |act|
action act.to_s, :description => "#{act.to_s.capitalize} a domain" do
display :always

input :domain,
:prompt => "Domain Name",
:description => "Name of a defined domain",
:type => :string,
:validation => '^.+$',
:optional => false,
:maxlength => 50

output :state,
:description => "Domain State",
:display_as => "State"

output :state_description,
:description => "Domain State",
:display_as => "State"

end
end
121 changes: 121 additions & 0 deletions agent/libvirt/agent/libvirt.rb
@@ -0,0 +1,121 @@
module MCollective
module Agent
class Libvirt<RPC::Agent
require 'libvirt'

metadata :name => "libvirt",
:description => "SimpleRPC Libvirt Agent",
:author => "R.I.Pienaar <rip@devco.net>",
:license => "ASL2.0",
:version => "0.1",
:url => "http://devco.net/",
:timeout => 10

action "hvinfo" do
conn = connect

nodeinfo = conn.node_get_info

[:model, :memory, :cpus, :mhz, :nodes, :sockets, :cores, :threads].each do |i|
reply[i] = nodeinfo.send(i)
end

[:type, :version, :uri, :node_free_memory, :max_vcpus].each do |i|
reply[i] = conn.send(i)
end

reply[:active_domains] = []
conn.list_domains.each do |domain|
reply[:active_domains] << conn.lookup_domain_by_id(domain).name
end
reply[:active_domains].sort!

reply[:inactive_domains] = conn.list_defined_domains.sort

conn.close
end

action "domaininfo" do
validate :domain, String

conn = connect

begin
domain = conn.lookup_domain_by_name(request[:domain])
info = domain.info

reply[:autostart] = domain.autostart?
reply[:vcpus] = info.nr_virt_cpu
reply[:memory] = info.memory
reply[:max_memory] = info.max_mem
reply[:cputime] = info.cpu_time
reply[:state] = info.state
reply[:state_description] = virtstates[info.state]
reply[:uuid] = domain.uuid
rescue Exception => e
reply.fail! "Could not load domain %s: %s" % [request[:domain], e]
end

conn.close
end

action "domainxml" do
validate :domain, String

conn = connect

begin
domain = conn.lookup_domain_by_name(request[:domain])
reply[:xml] = domain.xml_desc
rescue Exception => e
reply.fail! "Could not load domain %s: %s" % [request[:domain], e]
end

conn.close
end

[:destroy, :shutdown, :suspend, :resume, :create].each do |act|
action act do
validate :domain, String

reply[:state] = domain_action(request[:domain], act)
reply[:state_description] = virtstates[reply[:state]]
end
end

alias :start_action :create_action

private
def connect
conn = ::Libvirt::open('qemu:///system')

raise "Could not connect to hypervisor" if conn.closed?

conn
end

def virtstates
{0 => "No state",
1 => "Running",
2 => "Blocked on resource",
3 => "Paused",
4 => "Shutting down",
5 => "Shut off",
6 => "Crashed"}
end

def domain_action(name, action)
conn = connect

begin
domain = conn.lookup_domain_by_name(name)
domain.send(action.to_sym)

return domain.info.state
rescue Exception => e
reply.fail! "Could not #{action} domain %s : %s" % [request[:domain], e]
end
end
end
end
end

0 comments on commit c6e21af

Please sign in to comment.