Scott Seago
2008-Oct-03 05:45 UTC
[Ovirt-devel] [PATCH] initial model work for lvm storage
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. Signed-off-by: Scott Seago <sseago at redhat.com> --- 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 | 11 ++- 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/023_add_lvm_storage.rb | 106 ++++++++++++++++++++ src/dutils/active_record_env.rb | 2 + 15 files changed, 219 insertions(+), 39 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/023_add_lvm_storage.rb 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..c49e090 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,17 @@ 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" } def self.factory(type, params = nil) case type @@ -48,6 +51,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 ace6fb1..73e78f8 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 31c4ac8..2d93af2 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 @@ -144,4 +144,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/023_add_lvm_storage.rb b/src/db/migrate/023_add_lvm_storage.rb new file mode 100644 index 0000000..697df4d --- /dev/null +++ b/src/db/migrate/023_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 c6f37eb..bcec565 100644 --- a/src/dutils/active_record_env.rb +++ b/src/dutils/active_record_env.rb @@ -78,10 +78,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