Scott Seago
2008-Oct-15 14:21 UTC
[Ovirt-devel] [PATCH] initial model work for lvm storage (revised)
This includes the model classes w/ migrations for the lvm storage pools and volumes, and some changes required to support Storage Volume tasks. This patch does not include all of the necessary model API methods to support lvm, but it's a starting point -- some changes to clalance's taskomatic bits will be required to support this, and we will need additional model enhancements when the UI work is done, and when the taskomatic back end is finalized. revised to fix a couple controller bugs and to increment the migration version # Signed-off-by: Scott Seago <sseago at redhat.com> --- src/app/controllers/host_controller.rb | 8 +- src/app/controllers/storage_controller.rb | 35 ++----- src/app/controllers/vm_controller.rb | 34 +++--- src/app/models/host.rb | 2 +- src/app/models/host_task.rb | 11 ++- src/app/models/iscsi_storage_pool.rb | 2 +- .../models/{host_task.rb => lvm_storage_pool.rb} | 30 ++++-- .../{nfs_storage_pool.rb => lvm_storage_volume.rb} | 12 +-- src/app/models/nfs_storage_pool.rb | 2 +- src/app/models/storage_pool.rb | 12 ++- src/app/models/storage_task.rb | 11 ++- src/app/models/storage_volume.rb | 15 +++- .../{host_task.rb => storage_volume_task.rb} | 22 +++- src/app/models/task.rb | 15 ++- src/app/models/vm.rb | 2 +- src/app/models/vm_task.rb | 15 ++- src/db/migrate/025_add_lvm_storage.rb | 106 ++++++++++++++++++++ src/dutils/active_record_env.rb | 2 + 18 files changed, 251 insertions(+), 85 deletions(-) copy src/app/models/{host_task.rb => lvm_storage_pool.rb} (62%) copy src/app/models/{nfs_storage_pool.rb => lvm_storage_volume.rb} (82%) copy src/app/models/{host_task.rb => storage_volume_task.rb} (69%) create mode 100644 src/db/migrate/025_add_lvm_storage.rb diff --git a/src/app/controllers/host_controller.rb b/src/app/controllers/host_controller.rb index 417d11f..a40d297 100644 --- a/src/app/controllers/host_controller.rb +++ b/src/app/controllers/host_controller.rb @@ -139,10 +139,10 @@ class HostController < ApplicationController def clear_vms begin Host.transaction do - task = HostTask.new({ :user => get_login_user, - :host_id => @host.id, - :action => HostTask::ACTION_CLEAR_VMS, - :state => Task::STATE_QUEUED}) + task = HostTask.new({ :user => get_login_user, + :task_target => @host, + :action => HostTask::ACTION_CLEAR_VMS, + :state => Task::STATE_QUEUED}) task.save! @host.is_disabled = true @host.save! diff --git a/src/app/controllers/storage_controller.rb b/src/app/controllers/storage_controller.rb index bbd7840..fe524f3 100644 --- a/src/app/controllers/storage_controller.rb +++ b/src/app/controllers/storage_controller.rb @@ -111,10 +111,10 @@ class StorageController < ApplicationController end def insert_refresh_task - @task = StorageTask.new({ :user => @user, - :storage_pool_id => @storage_pool.id, - :action => StorageTask::ACTION_REFRESH_POOL, - :state => Task::STATE_QUEUED}) + @task = StorageTask.new({ :user => @user, + :task_target => @storage_pool, + :action => StorageTask::ACTION_REFRESH_POOL, + :state => Task::STATE_QUEUED}) @task.save! end @@ -144,12 +144,14 @@ class StorageController < ApplicationController :location => storage_pool_url(@storage_pool) } end - rescue + rescue => ex # FIXME: need to distinguish pool vs. task save errors (but should mostly be pool) respond_to do |format| format.json { - render :json => { :object => "storage_pool", :success => false, - :errors => @storage_pool.errors.localize_error_messages.to_a } } + json_hash = { :object => "storage_pool", :success => false, + :errors => @storage_pool.errors.localize_error_messages.to_a } + json_hash[:message] = ex.message if json_hash[:errors].empty? + render :json => json_hash } format.xml { render :xml => @storage_pool.errors, :status => :unprocessable_entity } end @@ -181,7 +183,7 @@ class StorageController < ApplicationController @redir_controller = @perm_obj.get_controller authorize_admin @storage_pools = @hardware_pool.storage_volumes - @storage_types = StoragePool::STORAGE_TYPES.keys + @storage_types = StoragePool::STORAGE_TYPE_PICKLIST end def addstorage @@ -226,23 +228,6 @@ class StorageController < ApplicationController end end - def vm_action - if @vm.get_action_list.include?(params[:vm_action]) - @task = VmTask.new({ :user => get_login_user, - :vm_id => params[:id], - :action => params[:vm_action], - :state => Task::STATE_QUEUED}) - if @task.save - flash[:notice] = "#{params[:vm_action]} was successfully queued." - else - flash[:notice] = "Error in inserting task for #{params[:vm_action]}." - end - else - flash[:notice] = "#{params[:vm_action]} is an invalid action." - end - redirect_to :controller => 'vm', :action => 'show', :id => params[:id] - end - def destroy pool = @storage_pool.hardware_pool if @storage_pool.destroy diff --git a/src/app/controllers/vm_controller.rb b/src/app/controllers/vm_controller.rb index a9ac9a5..585e524 100644 --- a/src/app/controllers/vm_controller.rb +++ b/src/app/controllers/vm_controller.rb @@ -49,19 +49,19 @@ class VmController < ApplicationController Vm.transaction do @vm.save! _setup_vm_provision(params) - @task = VmTask.new({ :user => @user, - :vm_id => @vm.id, - :action => VmTask::ACTION_CREATE_VM, - :state => Task::STATE_QUEUED}) + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_CREATE_VM, + :state => Task::STATE_QUEUED}) @task.save! end start_now = params[:start_now] if (start_now) if @vm.get_action_list.include?(VmTask::ACTION_START_VM) - @task = VmTask.new({ :user => @user, - :vm_id => @vm.id, - :action => VmTask::ACTION_START_VM, - :state => Task::STATE_QUEUED}) + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_START_VM, + :state => Task::STATE_QUEUED}) @task.save! alert = "VM was successfully created. VM Start action queued." else @@ -105,19 +105,19 @@ class VmController < ApplicationController _setup_vm_provision(params) if (params[:start_now] and @vm.get_action_list.include?(VmTask::ACTION_START_VM) ) - @task = VmTask.new({ :user => @user, - :vm_id => @vm.id, - :action => VmTask::ACTION_START_VM, - :state => Task::STATE_QUEUED}) + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_START_VM, + :state => Task::STATE_QUEUED}) @task.save! elsif ( params[:restart_now] and @vm.get_action_list.include?(VmTask::ACTION_SHUTDOWN_VM) ) - @task = VmTask.new({ :user => @user, - :vm_id => @vm.id, - :action => VmTask::ACTION_SHUTDOWN_VM, - :state => Task::STATE_QUEUED}) + @task = VmTask.new({ :user => @user, + :task_target => @vm, + :action => VmTask::ACTION_SHUTDOWN_VM, + :state => Task::STATE_QUEUED}) @task.save! @task = VmTask.new({ :user => @user, - :vm_id => @vm.id, + :task_target => @vm, :action => VmTask::ACTION_START_VM, :state => Task::STATE_QUEUED}) @task.save! diff --git a/src/app/models/host.rb b/src/app/models/host.rb index de5c5ee..546da19 100644 --- a/src/app/models/host.rb +++ b/src/app/models/host.rb @@ -31,7 +31,7 @@ class Host < ActiveRecord::Base def consuming_resources find(:all, :conditions=>{:state=>Vm::RUNNING_STATES}) end - has_many :tasks, :class_name => "HostTask", :dependent => :destroy, :order => "id DESC" do + has_many :tasks, :as => :task_target, :dependent => :destroy, :order => "id ASC" do def queued find(:all, :conditions=>{:state=>Task::STATE_QUEUED}) end diff --git a/src/app/models/host_task.rb b/src/app/models/host_task.rb index 0aea41b..82298db 100644 --- a/src/app/models/host_task.rb +++ b/src/app/models/host_task.rb @@ -22,11 +22,20 @@ class HostTask < Task ACTION_CLEAR_VMS = "clear_vms" def after_initialize - self.hardware_pool = host.hardware_pool if self.host + self.hardware_pool = task_target.hardware_pool if self.task_target_type=="Host" end def task_obj "Host;;;#{self.host.id};;;#{self.host.hostname}" end + def vm + nil + end + def storage_volume + nil + end + def storage_pool + nil + end end diff --git a/src/app/models/iscsi_storage_pool.rb b/src/app/models/iscsi_storage_pool.rb index 1280834..7802a90 100644 --- a/src/app/models/iscsi_storage_pool.rb +++ b/src/app/models/iscsi_storage_pool.rb @@ -19,7 +19,7 @@ class IscsiStoragePool < StoragePool - validates_presence_of :port, :target + validates_presence_of :ip_addr, :port, :target validates_uniqueness_of :ip_addr, :scope => [:port, :target] def label_components diff --git a/src/app/models/host_task.rb b/src/app/models/lvm_storage_pool.rb similarity index 62% copy from src/app/models/host_task.rb copy to src/app/models/lvm_storage_pool.rb index 0aea41b..08b8938 100644 --- a/src/app/models/host_task.rb +++ b/src/app/models/lvm_storage_pool.rb @@ -1,4 +1,4 @@ -# +# # Copyright (C) 2008 Red Hat, Inc. # Written by Scott Seago <sseago at redhat.com> # @@ -17,16 +17,32 @@ # MA 02110-1301, USA. A copy of the GNU General Public License is # also available at http://www.gnu.org/copyleft/gpl.html. -class HostTask < Task +require 'util/ovirt' + +class LvmStoragePool < StoragePool + + has_many :source_volumes, :class_name => "StorageVolume", + :foreign_key => "lvm_pool_id", + :dependent => :nullify do + def total_size + find(:all).inject(0){ |sum, sv| sum + sv.size } + end + end - ACTION_CLEAR_VMS = "clear_vms" + validates_presence_of :vg_name + validates_uniqueness_of :vg_name - def after_initialize - self.hardware_pool = host.hardware_pool if self.host + def display_name + "#{get_type_label}: #{vg_name}" end - def task_obj - "Host;;;#{self.host.id};;;#{self.host.hostname}" + def size + source_volums.total_size end + def size_in_gb + kb_to_gb(size) + end + + end diff --git a/src/app/models/nfs_storage_pool.rb b/src/app/models/lvm_storage_volume.rb similarity index 82% copy from src/app/models/nfs_storage_pool.rb copy to src/app/models/lvm_storage_volume.rb index 2d05305..7dde2d1 100644 --- a/src/app/models/nfs_storage_pool.rb +++ b/src/app/models/lvm_storage_volume.rb @@ -1,4 +1,4 @@ -# +# # Copyright (C) 2008 Red Hat, Inc. # Written by Scott Seago <sseago at redhat.com> # @@ -17,12 +17,8 @@ # MA 02110-1301, USA. A copy of the GNU General Public License is # also available at http://www.gnu.org/copyleft/gpl.html. -class NfsStoragePool < StoragePool - - validates_presence_of :export_path - validates_uniqueness_of :ip_addr, :scope => :export_path - - def label_components - "#{export_path}" +class LvmStorageVolume < StorageVolume + def display_name + "#{get_type_label}: #{storage_pool.vg_name}:#{lv_name}" end end diff --git a/src/app/models/nfs_storage_pool.rb b/src/app/models/nfs_storage_pool.rb index 2d05305..a27944b 100644 --- a/src/app/models/nfs_storage_pool.rb +++ b/src/app/models/nfs_storage_pool.rb @@ -19,7 +19,7 @@ class NfsStoragePool < StoragePool - validates_presence_of :export_path + validates_presence_of :ip_addr, :export_path validates_uniqueness_of :ip_addr, :scope => :export_path def label_components diff --git a/src/app/models/storage_pool.rb b/src/app/models/storage_pool.rb index bc98f8e..7a6f8f0 100644 --- a/src/app/models/storage_pool.rb +++ b/src/app/models/storage_pool.rb @@ -19,7 +19,7 @@ class StoragePool < ActiveRecord::Base belongs_to :hardware_pool - has_many :tasks, :class_name => "StorageTask", :dependent => :destroy, :order => "id DESC" do + has_many :tasks, :as => :task_target, :dependent => :destroy, :order => "id ASC" do def queued find(:all, :conditions=>{:state=>Task::STATE_QUEUED}) end @@ -33,14 +33,18 @@ class StoragePool < ActiveRecord::Base has_many :smart_pool_tags, :as => :tagged, :dependent => :destroy has_many :smart_pools, :through => :smart_pool_tags - validates_presence_of :ip_addr, :hardware_pool_id + + validates_presence_of :hardware_pool_id acts_as_xapian :texts => [ :ip_addr, :target, :export_path, :type ], :terms => [ [ :search_users, 'U', "search_users" ] ] ISCSI = "iSCSI" NFS = "NFS" + LVM = "LVM" STORAGE_TYPES = { ISCSI => "Iscsi", - NFS => "Nfs" } + NFS => "Nfs", + LVM => "Lvm" } + STORAGE_TYPE_PICKLIST = STORAGE_TYPES.keys - [LVM] def self.factory(type, params = nil) case type @@ -48,6 +52,8 @@ class StoragePool < ActiveRecord::Base return IscsiStoragePool.new(params) when NFS return NfsStoragePool.new(params) + when LVM + return LvmStoragePool.new(params) else return nil end diff --git a/src/app/models/storage_task.rb b/src/app/models/storage_task.rb index db604d5..785f0ea 100644 --- a/src/app/models/storage_task.rb +++ b/src/app/models/storage_task.rb @@ -22,10 +22,19 @@ class StorageTask < Task ACTION_REFRESH_POOL = "refresh_pool" def after_initialize - self.hardware_pool = storage_pool.hardware_pool if self.storage_pool + self.hardware_pool = task_target.hardware_pool if self.task_target_type=="StoragePool" end def task_obj "StoragePool;;;#{self.storage_pool.id};;;#{self.storage_pool.display_name}" end + def host + nil + end + def vm + nil + end + def storage_volume + nil + end end diff --git a/src/app/models/storage_volume.rb b/src/app/models/storage_volume.rb index ef9cd6e..378b58f 100644 --- a/src/app/models/storage_volume.rb +++ b/src/app/models/storage_volume.rb @@ -23,12 +23,23 @@ class StorageVolume < ActiveRecord::Base belongs_to :storage_pool has_and_belongs_to_many :vms + belongs_to :lvm_storage_pool, :class_name => "LvmStoragePool", + :foreign_key => "lvm_pool_id" + + has_many :tasks, :as => :task_target, :dependent => :destroy, :order => "id ASC" do + def queued + find(:all, :conditions=>{:state=>Task::STATE_QUEUED}) + end + end + def self.factory(type, params = nil) case type - when "iSCSI" + when StoragePool::ISCSI return IscsiStorageVolume.new(params) - when "NFS" + when StoragePool::NFS return NfsStorageVolume.new(params) + when StoragePool::LVM + return LvmStorageVolume.new(params) else return nil end diff --git a/src/app/models/host_task.rb b/src/app/models/storage_volume_task.rb similarity index 69% copy from src/app/models/host_task.rb copy to src/app/models/storage_volume_task.rb index 0aea41b..78f2895 100644 --- a/src/app/models/host_task.rb +++ b/src/app/models/storage_volume_task.rb @@ -1,4 +1,4 @@ -# +# # Copyright (C) 2008 Red Hat, Inc. # Written by Scott Seago <sseago at redhat.com> # @@ -17,16 +17,26 @@ # MA 02110-1301, USA. A copy of the GNU General Public License is # also available at http://www.gnu.org/copyleft/gpl.html. -class HostTask < Task +class StorageVolumeTask < Task - ACTION_CLEAR_VMS = "clear_vms" + ACTION_CREATE_VOLUME = "create_volume" + ACTION_EDIT_VOLUME = "edit_volume" def after_initialize - self.hardware_pool = host.hardware_pool if self.host + self.hardware_pool = task_target.storage_pool.hardware_pool if self.task_target_type=="StorageVolume" end def task_obj - "Host;;;#{self.host.id};;;#{self.host.hostname}" + "StorageVolume;;;#{self.storage_volume.id};;;#{self.storage_volume.display_name}" + end + end + def host + nil + end + def vm + nil + end + def storage_pool + nil end - end diff --git a/src/app/models/task.rb b/src/app/models/task.rb index efbed64..f231c18 100644 --- a/src/app/models/task.rb +++ b/src/app/models/task.rb @@ -1,4 +1,4 @@ -# +# # Copyright (C) 2008 Red Hat, Inc. # Written by Scott Seago <sseago at redhat.com> # @@ -20,13 +20,20 @@ class Task < ActiveRecord::Base belongs_to :hardware_pool belongs_to :vm_resource_pool + belongs_to :task_target, :polymorphic => true # moved associations here so that nested set :include directives work # StorageTask association - belongs_to :storage_pool + belongs_to :storage_pool, :class_name => "StoragePool", + :foreign_key => "task_target_id" + # StorageVolumeTask association + belongs_to :storage_volume, :class_name => "StorageVolume", + :foreign_key => "task_target_id" # HostTask association - belongs_to :host + belongs_to :host, :class_name => "Host", + :foreign_key => "task_target_id" # VmTask association - belongs_to :vm + belongs_to :vm, :class_name => "Vm", + :foreign_key => "task_target_id" STATE_QUEUED = "queued" STATE_RUNNING = "running" diff --git a/src/app/models/vm.rb b/src/app/models/vm.rb index 6853157..4885b5c 100644 --- a/src/app/models/vm.rb +++ b/src/app/models/vm.rb @@ -22,7 +22,7 @@ require 'util/ovirt' class Vm < ActiveRecord::Base belongs_to :vm_resource_pool belongs_to :host - has_many :tasks, :class_name => "VmTask", :dependent => :destroy, :order => "id ASC" do + has_many :tasks, :as => :task_target, :dependent => :destroy, :order => "id ASC" do def queued find(:all, :conditions=>{:state=>Task::STATE_QUEUED}) end diff --git a/src/app/models/vm_task.rb b/src/app/models/vm_task.rb index 6251919..d1966dc 100644 --- a/src/app/models/vm_task.rb +++ b/src/app/models/vm_task.rb @@ -107,9 +107,9 @@ class VmTask < Task :popup_action => 'migrate'} } def after_initialize - if self.vm - self.vm_resource_pool = vm.vm_resource_pool - self.hardware_pool = vm.get_hardware_pool + if self.task_target_type=="Vm" + self.vm_resource_pool = task_target.vm_resource_pool + self.hardware_pool = task_target.get_hardware_pool end end @@ -141,4 +141,13 @@ class VmTask < Task def self.label_and_action(action) return [action_label(action), action, action_icon(action)] end + def host + nil + end + def storage_volume + nil + end + def storage_pool + nil + end end diff --git a/src/db/migrate/025_add_lvm_storage.rb b/src/db/migrate/025_add_lvm_storage.rb new file mode 100644 index 0000000..697df4d --- /dev/null +++ b/src/db/migrate/025_add_lvm_storage.rb @@ -0,0 +1,106 @@ +# +# Copyright (C) 2008 Red Hat, Inc. +# Written by Scott Seago <sseago at redhat.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. A copy of the GNU General Public License is +# also available at http://www.gnu.org/copyleft/gpl.html. + +class AddLvmStorage < ActiveRecord::Migration + def self.up + #LVM pool does not use ip_addr + + # VG Name + add_column :storage_pools, :vg_name, :string + + # LV name + add_column :storage_volumes, :lv_name, :string + # LV capacity==existing size attr + + # LV <target><permissions> + # FIXME: do we want to make these user-determined, or should + # these be defined by the model itself? + add_column :storage_volumes, :lv_owner_perms, :string + add_column :storage_volumes, :lv_group_perms, :string + add_column :storage_volumes, :lv_mode_perms, :string + + # VG pool ID + add_column :storage_volumes, :lvm_pool_id, :integer + execute "alter table storage_volumes add constraint fk_storage_volumes_lvm_pools + foreign key (lvm_pool_id) references storage_pools(id)" + + # use polymorphic tasks association + add_column :tasks, :task_target_id, :integer + add_column :tasks, :task_target_type, :string + begin + Task.transaction do + HostTask.find(:all).each do |task| + task.task_target_type = 'Host' + task.task_target_id = task.host_id + task.save! + end + StorageTask.find(:all).each do |task| + task.task_target_type = 'StoragePool' + task.task_target_id = task.storage_pool_id + task.save! + end + VmTask.find(:all).each do |task| + task.task_target_type = 'Vm' + task.task_target_id = task.vm_id + task.save! + end + end + remove_column :tasks, :vm_id + remove_column :tasks, :storage_pool_id + remove_column :tasks, :host_id + rescue + puts "could not update tasks..." + end + + end + + def self.down + remove_column :storage_pools, :vg_name + + remove_column :storage_volumes, :lv_name + remove_column :storage_volumes, :lv_owner_perms + remove_column :storage_volumes, :lv_group_perms + remove_column :storage_volumes, :lv_mode_perms + remove_column :storage_volumes, :lvm_pool_id + + add_column :tasks, :vm_id, :integer + add_column :tasks, :storage_pool_id, :integer + add_column :tasks, :host_id, :integer + begin + Task.transaction do + HostTask.find(:all).each do |task| + task.host_id = task.task_target_id + task.save! + end + StorageTask.find(:all).each do |task| + task.storage_pool_id = task.task_target_id + task.save! + end + VmTask.find(:all).each do |task| + task.vm_id = task.task_target_id + task.save! + end + end + remove_column :tasks, :task_target_id + remove_column :tasks, :task_target_type + rescue + puts "could not update tasks..." + end + end +end diff --git a/src/dutils/active_record_env.rb b/src/dutils/active_record_env.rb index 3903c87..26caac2 100644 --- a/src/dutils/active_record_env.rb +++ b/src/dutils/active_record_env.rb @@ -80,10 +80,12 @@ require 'models/vm_task.rb' require 'models/storage_pool.rb' require 'models/iscsi_storage_pool.rb' require 'models/nfs_storage_pool.rb' +require 'models/lvm_storage_pool.rb' require 'models/storage_volume.rb' require 'models/iscsi_storage_volume.rb' require 'models/nfs_storage_volume.rb' +require 'models/lvm_storage_volume.rb' require 'models/smart_pool.rb' require 'models/smart_pool_tag.rb' -- 1.5.5.1
Chris Lalancette
2008-Oct-16 08:11 UTC
[Ovirt-devel] [PATCH] initial model work for lvm storage (revised)
Scott Seago wrote:> This includes the model classes w/ migrations for the lvm storage pools and > volumes, and some changes required to support Storage Volume tasks. This > patch does not include all of the necessary model API methods to support lvm, > but it's a starting point -- some changes to clalance's taskomatic bits will > be required to support this, and we will need additional model enhancements > when the UI work is done, and when the taskomatic back end is finalized. > > revised to fix a couple controller bugs and to increment the migration > version #Well, this version is better, but still not working. I downloaded this patch, applied it with git-am (thanks Jim), then rebuilt an RPM with it. Then I did "rpm -Uvh ovirt-server", followed by "cd /usr/share/ovirt-server ; rake db:migrate". Then I shut down all of the services (including mongrel-rails), and restarted them. Now, I was able to successfully add the iSCSI storage pool, but taskomatic barfed when trying to do the scanning. In particular, the error I got in the database was: Couldn't find StoragePool without an ID And a more complete stack trace from /var/log/ovirt-server/taskomatic.log is: refresh_pool Task action processing failed: ActiveRecord::RecordNotFound: Couldn't find StoragePool without an ID /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:1364:in `find_from_ids' /usr/lib/ruby/gems/1.8/gems/activerecord-2.1.1/lib/active_record/base.rb:541:in `find' /usr/share/ovirt-server/task-omatic/./task_storage.rb:26:in `refresh_pool' /usr/share/ovirt-server/task-omatic/taskomatic.rb:106 /usr/share/ovirt-server/task-omatic/taskomatic.rb:88:in `each' /usr/share/ovirt-server/task-omatic/taskomatic.rb:88 /usr/share/ovirt-server/task-omatic/taskomatic.rb:68:in `loop' /usr/share/ovirt-server/task-omatic/taskomatic.rb:68 Any ideas? -- Chris Lalancette