You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltacloud.apache.org by mf...@redhat.com on 2011/03/14 18:06:16 UTC
[PATCH core] Initial Libvirt driver for Deltacloud API
From: Michal Fojtik <mf...@redhat.com>
---
server/config/drivers.yaml | 5 +
.../deltacloud/drivers/libvirt/libvirt_driver.rb | 240 ++++++++++++++++++++
2 files changed, 245 insertions(+), 0 deletions(-)
create mode 100644 server/lib/deltacloud/drivers/libvirt/libvirt_driver.rb
diff --git a/server/config/drivers.yaml b/server/config/drivers.yaml
index d028ca0..528469f 100644
--- a/server/config/drivers.yaml
+++ b/server/config/drivers.yaml
@@ -21,6 +21,11 @@
:name: Rackspace
:azure:
:name: Azure
+:libvirt:
+ :name: Libvirt
+ :entrypoints:
+ default:
+ default: qemu://system
:ec2:
:entrypoints:
s3:
diff --git a/server/lib/deltacloud/drivers/libvirt/libvirt_driver.rb b/server/lib/deltacloud/drivers/libvirt/libvirt_driver.rb
new file mode 100644
index 0000000..5ea5a22
--- /dev/null
+++ b/server/lib/deltacloud/drivers/libvirt/libvirt_driver.rb
@@ -0,0 +1,240 @@
+#
+# Copyright (C) 2009 Red Hat, Inc.
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+require 'deltacloud/base_driver'
+require 'libvirt'
+require 'nokogiri'
+
+module Deltacloud
+ module Drivers
+ module Libvirt
+
+ class LibvirtDriver < Deltacloud::BaseDriver
+
+ def supported_collections
+ [ :images, :hardware_profiles, :instances, :realms, :instance_states, :storage_volumes ]
+ end
+
+ define_instance_states do
+ start.to( :pending ) .automatically
+ pending.to( :running ) .automatically
+ stopped.to( :running ) .on( :start )
+ stopped.to( :finish ) .on( :destroy )
+ running.to( :running ) .on( :reboot )
+ running.to( :stopped ) .on( :stop)
+ running.to( :finish ) .on( :destroy )
+ end
+
+ def hardware_profiles(credentials, opts = nil)
+ profiles = []
+ new_client(credentials) do |lvirt|
+ result = Nokogiri::XML(lvirt.capabilities)
+ profiles << HardwareProfile.new((result/'/capabilities/host/cpu/model').text) do
+ architecture lvirt.node_get_info.model
+ cpu (1..lvirt.node_get_info.cpus.to_i)
+ memory (1..lvirt.node_get_info.memory.to_i)
+ storage 1000
+ end
+ end
+ profiles
+ end
+
+ def images(credentials, opts=nil)
+ [
+ Image.new({
+ :id => "default",
+ :name => "Default Image",
+ :description => "",
+ :owner_id => "root",
+ :architecture => "i686"
+ })
+ ]
+ end
+
+ def instances(credentials, opts={})
+ inst_arr = []
+ new_client(credentials) do |lvirt|
+ if opts and opts[:id]
+ domain = lvirt.lookup_domain_by_uuid(opts[:id])
+ domains = [domain.name]
+ else
+ domains = lvirt.list_defined_domains + lvirt.list_domains
+ end
+ inst_arr = domains.collect do |domain_name|
+ if domain_name.class.eql?(String)
+ domain = lvirt.lookup_domain_by_name(domain_name)
+ else
+ domain = lvirt.lookup_domain_by_id(domain_name)
+ end
+ convert_instance({
+ :id => domain.uuid,
+ :name => domain.name,
+ :state => state(domain.info.state),
+ :memory => domain.info.memory,
+ :cpu => domain.info.nr_virt_cpu,
+ :profile => hardware_profiles(credentials).first,
+ :xml => domain.xml_desc,
+ :actions => instance_actions_for( state(domain.info.state) ),
+ })
+ end
+ end
+ inst_arr = filter_on( inst_arr, :id, opts )
+ filter_on( inst_arr, :state, opts )
+ end
+
+ def create_image(credentials, opts={})
+ new_client(credentials) do |lv|
+ domain = lv.lookup_domain_by_uuid(opts[:id])
+ puts domain.xml_desc
+ end
+ end
+
+ def start_instance(credentials, id)
+ new_client(credentials) do |lv|
+ domain = lv.lookup_domain_by_uuid(id)
+ domain.restore("/var/lib/libvirt/images/#{domain.uuid}")
+ end
+ instances(credentials, :id => id)
+ end
+
+ def reboot_instance(credentials, id)
+ new_client(credentials) do |lv|
+ domain = lv.lookup_domain_by_uuid(id)
+ domain.destroy
+ domain.create
+ end
+ instances(credentials, :id => id)
+ end
+
+ def destroy_instance(credentials, id)
+ new_client(credentials) do |lv|
+ domain = lv.lookup_domain_by_uuid(id)
+ domain.destroy
+ domain.undefine
+ end
+ instances(credentials, :id => id)
+ end
+
+ def stop_instance(credentials, id)
+ new_client(credentials) do |lv|
+ domain = lv.lookup_domain_by_uuid(id)
+ domain.save("/var/lib/libvirt/images/#{domain.uuid}")
+ end
+ instances(credentials, :id => id)
+ end
+
+ def storage_volumes(credentials, opts=nil)
+ volumes = []
+ new_client(credentials) do |lvirt|
+ pool = lvirt.lookup_storage_pool_by_name('default')
+ volumes = pool.list_volumes.collect do |volume_name|
+ volume = pool.lookup_volume_by_name(volume_name)
+ StorageVolume.new({
+ :id => volume.name,
+ :created => '',
+ :state => 'attached',
+ :capacity => volume.info.capacity,
+ :device => volume.path
+ })
+ end
+ end
+ volumes
+ end
+
+ def realms(credentials, opts={})
+ realms_arr = []
+ new_client(credentials) do |lvirt|
+ realms_arr << Realm.new(
+ :id => '1',
+ :name => lvirt.hostname,
+ :limit => :unlimited,
+ :state => 'AVAILABLE'
+ )
+ end
+ realms_arr
+ end
+
+ private
+
+ def convert_instance(instance)
+ profile = instance[:profile]
+ puts instance[:state]
+ network_addresses = parse_network_addresses(Nokogiri::XML(instance[:xml]))
+ Instance.new({
+ :id => instance[:id],
+ :state => instance[:state],
+ :realm_id => 'default',
+ :name => instance[:name],
+ :actions => instance[:actions],
+ :image_id => 'default',
+ :owner_id => 'root',
+ :create_image => (instance[:state] == 'running') ? true : false,
+ :public_addresses => network_addresses,
+ :instance_profile => InstanceProfile.new(profile.name,{
+ :hwp_memory => instance[:memory],
+ :hwp_cpu => instance[:cpu]
+ })
+ })
+ end
+
+ def parse_network_addresses(doc)
+ (doc/'/domain/devices/interface/mac').map do |m|
+ { :mac => m[:address], :address => '' }
+ end
+ end
+
+ def new_client(credentials, &block)
+ safely do
+ hypervisor_url = Deltacloud::Drivers::driver_config[:libvirt][:entrypoints]['default']['default']
+ connection = ::Libvirt::open(hypervisor_url)
+ yield connection
+ connection.close unless connection.closed?
+ end
+ end
+
+ def state(id)
+ puts id
+ case id
+ when 1:
+ 'running'
+ when 2:
+ 'pending'
+ when 3:
+ 'stopped'
+ when 4:
+ 'shutting_down'
+ when 5:
+ 'stopped'
+ else
+ 'pending'
+ end
+ end
+
+
+ def catched_exceptions_list
+ {
+ :auth => [], # [ ::Aws::AuthFailure ],
+ :error => [ ::Libvirt::Error ],
+ :glob => [ /Libvirt::(\w+)/ ]
+ }
+ end
+
+ end
+ end
+ end
+end
--
1.7.4.1