[Ovirt-devel] [PATCH] add 'state' field to storage pools and volumes
Scott Seago
sseago at redhat.com
Thu Nov 6 20:24:42 UTC 2008
I've added a state field to StoragePool and StorageVolume. When initially created, pools and volumes are in the pending_setup state -- once taskomatic is done they're 'available'. Upon deletion, they go into pending_deletion until taskomatic is done.
Taskomatic changes to take this into account have not yet been included, since clalance's LVM patch hasn't been pushed.
Signed-off-by: Scott Seago <sseago at redhat.com>
---
src/app/controllers/storage_controller.rb | 4 +-
src/app/controllers/vm_controller.rb | 2 +-
src/app/models/hardware_pool.rb | 17 +++++++++--
src/app/models/storage_pool.rb | 33 ++++++++++++++++++-----
src/app/models/storage_volume.rb | 33 ++++++++++++++++++-----
src/app/views/storage/show.rhtml | 2 +
src/app/views/storage/show_volume.rhtml | 2 +
src/db/migrate/029_storage_state_field.rb | 42 +++++++++++++++++++++++++++++
src/test/fixtures/storage_pools.yml | 10 +++++++
src/test/fixtures/storage_volumes.yml | 6 ++++
10 files changed, 131 insertions(+), 20 deletions(-)
create mode 100644 src/db/migrate/029_storage_state_field.rb
diff --git a/src/app/controllers/storage_controller.rb b/src/app/controllers/storage_controller.rb
index 75058cd..e3e5522 100644
--- a/src/app/controllers/storage_controller.rb
+++ b/src/app/controllers/storage_controller.rb
@@ -442,9 +442,9 @@ class StorageController < ApplicationController
vm_list = volume.vms.collect {|vm| vm.description}.join(", ")
["Storage Volume #{name} must be unattached from VMs (#{vm_list}) before deleting it.",
false]
- #FIXME: create delete volume task. include metadata in task
else
- #FIXME: need to set volume to 'unavailable' state once we have states
+ volume.state=StorageVolume::STATE_PENDING_DELETION
+ volume.save!
@task = StorageVolumeTask.new({ :user => @user,
:task_target => volume,
:action => StorageVolumeTask::ACTION_DELETE_VOLUME,
diff --git a/src/app/controllers/vm_controller.rb b/src/app/controllers/vm_controller.rb
index ee956da..ff74a37 100644
--- a/src/app/controllers/vm_controller.rb
+++ b/src/app/controllers/vm_controller.rb
@@ -81,7 +81,7 @@ class VmController < ApplicationController
end
def edit
- @storage_tree = @vm.vm_resource_pool.get_hardware_pool.storage_tree(@vm).to_json
+ @storage_tree = @vm.vm_resource_pool.get_hardware_pool.storage_tree(:vm_to_include => @vm).to_json
render :layout => 'popup'
end
diff --git a/src/app/models/hardware_pool.rb b/src/app/models/hardware_pool.rb
index 6780329..d39d8e7 100644
--- a/src/app/models/hardware_pool.rb
+++ b/src/app/models/hardware_pool.rb
@@ -101,10 +101,21 @@ class HardwarePool < Pool
return {:total => total, :labels => labels}
end
- def storage_tree(vm_to_include=nil)
+ # params accepted:
+ # :vm_to_include - if specified, storage used by this VM is included in the tree
+ # :filter_unavailable - if true, don't include Storage not currently available
+ # :include_used - include all storage pools/volumes, even those in use
+ def storage_tree(params = {})
+ vm_to_include=params.fetch(:vm_to_include, nil)
+ filter_unavailable = params.fetch(:filter_unavailable, true)
+ include_used = params.fetch(:include_used, false)
+ conditions = "type != 'LvmStoragePool'"
+ if filter_unavailable
+ conditions = "(#{conditions}) and (storage_pools.state = '#{StoragePool::STATE_AVAILABLE}')"
+ end
storage_pools.find(:all,
- :conditions => "type != 'LvmStoragePool'").collect do |pool|
- pool.storage_tree_element(vm_to_include)
+ :conditions => conditions).collect do |pool|
+ pool.storage_tree_element(params)
end
end
end
diff --git a/src/app/models/storage_pool.rb b/src/app/models/storage_pool.rb
index 9c550b8..9c80f54 100644
--- a/src/app/models/storage_pool.rb
+++ b/src/app/models/storage_pool.rb
@@ -50,7 +50,12 @@ class StoragePool < ActiveRecord::Base
LVM => "Lvm" }
STORAGE_TYPE_PICKLIST = STORAGE_TYPES.keys - [LVM]
- def self.factory(type, params = nil)
+ STATE_PENDING_SETUP = "pending_setup"
+ STATE_PENDING_DELETION = "pending_deletion"
+ STATE_AVAILABLE = "available"
+
+ def self.factory(type, params = {})
+ params[:state] = STATE_PENDING_SETUP unless params[:state]
case type
when ISCSI
return IscsiStoragePool.new(params)
@@ -82,7 +87,10 @@ class StoragePool < ActiveRecord::Base
false
end
- def storage_tree_element(vm_to_include=nil)
+ def storage_tree_element(params = {})
+ vm_to_include=params.fetch(:vm_to_include, nil)
+ filter_unavailable = params.fetch(:filter_unavailable, true)
+ include_used = params.fetch(:include_used, false)
return_hash = { :id => id,
:type => self[:type],
:text => display_name,
@@ -90,14 +98,25 @@ class StoragePool < ActiveRecord::Base
:available => false,
:create_volume => user_subdividable,
:selected => false}
- condition = "vms.id is null"
- if (vm_to_include and vm_to_include.id)
- condition +=" or vms.id=#{vm_to_include.id}"
+ conditions = nil
+ unless include_used
+ conditions = "vms.id is null"
+ if (vm_to_include and vm_to_include.id)
+ conditions +=" or vms.id=#{vm_to_include.id}"
+ end
+ end
+ if filter_unavailable
+ availability_conditions = "storage_volumes.state = '#{StoragePool::STATE_AVAILABLE}'"
+ if conditions.nil?
+ conditions = availability_conditions
+ else
+ conditions ="(#{conditions}) and (#{availability_conditions})"
+ end
end
return_hash[:children] = storage_volumes.find(:all,
:include => :vms,
- :conditions => condition).collect do |volume|
- volume.storage_tree_element(vm_to_include)
+ :conditions => conditions).collect do |volume|
+ volume.storage_tree_element(params)
end
return_hash
end
diff --git a/src/app/models/storage_volume.rb b/src/app/models/storage_volume.rb
index 6f14c4d..56cdcef 100644
--- a/src/app/models/storage_volume.rb
+++ b/src/app/models/storage_volume.rb
@@ -32,7 +32,12 @@ class StorageVolume < ActiveRecord::Base
end
end
- def self.factory(type, params = nil)
+ STATE_PENDING_SETUP = "pending_setup"
+ STATE_PENDING_DELETION = "pending_deletion"
+ STATE_AVAILABLE = "available"
+
+ def self.factory(type, params = {})
+ params[:state] = STATE_PENDING_SETUP unless params[:state]
case type
when StoragePool::ISCSI
return IscsiStorageVolume.new(params)
@@ -75,7 +80,10 @@ class StorageVolume < ActiveRecord::Base
return false
end
- def storage_tree_element(vm_to_include=nil)
+ def storage_tree_element(params = {})
+ vm_to_include=params.fetch(:vm_to_include, nil)
+ filter_unavailable = params.fetch(:filter_unavailable, true)
+ include_used = params.fetch(:include_used, false)
vm_ids = vms.collect {|vm| vm.id}
return_hash = { :id => id,
:type => self[:type],
@@ -92,14 +100,25 @@ class StorageVolume < ActiveRecord::Base
if return_hash[:available]
return_hash[:available] = lvm_storage_pool.storage_volumes.full_vm_list.empty?
end
- condition = "vms.id is null"
- if (vm_to_include and vm_to_include.id)
- condition +=" or vms.id=#{vm_to_include.id}"
+ conditions = nil
+ unless include_used
+ conditions = "vms.id is null"
+ if (vm_to_include and vm_to_include.id)
+ conditions +=" or vms.id=#{vm_to_include.id}"
+ end
+ end
+ if filter_unavailable
+ availability_conditions = "storage_volumes.state = '#{StoragePool::STATE_AVAILABLE}'"
+ if conditions.nil?
+ conditions = availability_conditions
+ else
+ conditions ="(#{conditions}) and (#{availability_conditions})"
+ end
end
return_hash[:children] = lvm_storage_pool.storage_volumes.find(:all,
:include => :vms,
- :conditions => condition).collect do |volume|
- volume.storage_tree_element(vm_to_include)
+ :conditions => conditions).collect do |volume|
+ volume.storage_tree_element(params)
end
else
return_hash[:children] = []
diff --git a/src/app/views/storage/show.rhtml b/src/app/views/storage/show.rhtml
index a84dc62..123cf20 100644
--- a/src/app/views/storage/show.rhtml
+++ b/src/app/views/storage/show.rhtml
@@ -26,6 +26,7 @@
Export path:<br/>
<% end %>
Type:<br/>
+ State:<br/>
</div>
<div class="selection_value">
<%=h @storage_pool.ip_addr %><br/>
@@ -36,6 +37,7 @@
<%=h @storage_pool.export_path %><br/>
<% end %>
<%=h @storage_pool.get_type_label %><br/>
+ <%=h @storage_pool.state %><br/>
</div>
<%- content_for :right do -%>
<div class="selection_right_title">Volumes</div>
diff --git a/src/app/views/storage/show_volume.rhtml b/src/app/views/storage/show_volume.rhtml
index e39c10e..c1cb66a 100644
--- a/src/app/views/storage/show_volume.rhtml
+++ b/src/app/views/storage/show_volume.rhtml
@@ -28,6 +28,7 @@
Export path:<br/>
<% end %>
Type:<br/>
+ State:<br/>
Path:<br/>
<% if @storage_volume[:type] == "IscsiStorageVolume" %>
LUN:<br/>
@@ -45,6 +46,7 @@
<%=h @storage_volume.storage_pool.export_path %><br/>
<% end %>
<%=h @storage_volume.storage_pool.get_type_label %><br/>
+ <%=h @storage_volume.state %><br/>
<%=h @storage_volume.path %><br/>
<% if @storage_volume[:type] == "IscsiStorageVolume" %>
<%=h @storage_volume.lun %><br/>
diff --git a/src/db/migrate/029_storage_state_field.rb b/src/db/migrate/029_storage_state_field.rb
new file mode 100644
index 0000000..d8f3ab1
--- /dev/null
+++ b/src/db/migrate/029_storage_state_field.rb
@@ -0,0 +1,42 @@
+#
+# 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 StorageStateField < ActiveRecord::Migration
+ def self.up
+ add_column :storage_pools, :state, :string
+ add_column :storage_volumes, :state, :string
+ begin
+ StoragePool.transaction do
+ StoragePool.find(:all).each do |pool|
+ pool.state = 'available'
+ pool.save!
+ end
+ StorageVolume.find(:all).each do |volume|
+ volume.state = 'available'
+ volume.save!
+ end
+ end
+ end
+ end
+
+ def self.down
+ remove_column :storage_pools, :state
+ remove_column :storage_volumes, :state
+ end
+end
diff --git a/src/test/fixtures/storage_pools.yml b/src/test/fixtures/storage_pools.yml
index ac042a0..d52bf51 100644
--- a/src/test/fixtures/storage_pools.yml
+++ b/src/test/fixtures/storage_pools.yml
@@ -5,18 +5,21 @@ one:
type: 'IscsiStoragePool'
port: 53
target: 'footarget'
+ state: 'available'
two:
id: 2
hardware_pool_id: 4
type: 'NfsStoragePool'
ip_addr: '127.0.0.1'
export_path: '/tmp/foopath'
+ state: 'available'
three:
id: 3
hardware_pool_id: 4
type: 'NfsStoragePool'
ip_addr: '192.168.50.1'
export_path: '/tmp/barpath'
+ state: 'available'
four:
id: 4
hardware_pool_id: 9
@@ -25,24 +28,28 @@ four:
ip_addr: '192.168.50.1'
target: 'rubarb'
hardware_pool_id: 1
+ state: 'available'
five:
id: 5
hardware_pool_id: 9
type: 'NfsStoragePool'
ip_addr: '192.168.50.2'
export_path: '/tmp/thepath'
+ state: 'available'
six:
id: 6
hardware_pool_id: 9
type: 'NfsStoragePool'
ip_addr: '192.168.50.3'
export_path: '/tmp/anotherpath'
+ state: 'available'
seven:
id: 7
hardware_pool_id: 9
type: 'NfsStoragePool'
ip_addr: '192.168.50.4'
export_path: '/tmp/apath'
+ state: 'available'
eight:
id: 8
hardware_pool_id: 9
@@ -50,12 +57,14 @@ eight:
type: 'IscsiStoragePool'
port: 531
target: 'bartarget'
+ state: 'available'
nine:
id: 9
hardware_pool_id: 9
type: 'NfsStoragePool'
ip_addr: '1.2.3.4'
export_path: '/tmp/somepath'
+ state: 'available'
ten:
id: 10
hardware_pool_id: 9
@@ -63,3 +72,4 @@ ten:
ip_addr: '192.168.50.3'
port: 539
target: 'stayontarget'
+ state: 'available'
diff --git a/src/test/fixtures/storage_volumes.yml b/src/test/fixtures/storage_volumes.yml
index 1c49ace..4761d95 100644
--- a/src/test/fixtures/storage_volumes.yml
+++ b/src/test/fixtures/storage_volumes.yml
@@ -6,6 +6,7 @@ one:
path: '/tmp/foobar'
storage_pool_id: 1
type: 'IscsiStorageVolume'
+ state: 'available'
two:
id: 2
size: '20485760'
@@ -13,6 +14,7 @@ two:
storage_pool_id: 2
type: 'NfsStorageVolume'
filename: 'secretstuff'
+ state: 'available'
three:
id: 3
lun: 'abcd'
@@ -20,21 +22,25 @@ three:
path:
storage_pool_id: 1
type: 'IscsiStorageVolume'
+ state: 'available'
four:
id: 4
lun: '49723e4d-32e6-469e-8019-913a3dc1bb5d'
size: '01223542'
storage_pool_id: 4
type: 'IscsiStorageVolume'
+ state: 'available'
five:
id: 5
size: '42424242'
storage_pool_id: 2
type: 'NfsStorageVolume'
filename: 'foobar'
+ state: 'available'
six:
id: 6
size: '007007'
storage_pool_id: 6
type: 'NfsStorageVolume'
filename: 'barfoo'
+ state: 'available'
--
1.5.5.1
More information about the ovirt-devel
mailing list