deltacloud-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfoj...@redhat.com
Subject [PATCH core] Initial Libvirt driver for Deltacloud API
Date Mon, 14 Mar 2011 17:06:16 GMT
From: Michal Fojtik <mfojtik@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


Mime
View raw message