[Ovirt-devel] [PATCH] lvm storage volume HW pool admin tab.
Scott Seago
sseago at redhat.com
Thu Oct 30 23:53:15 UTC 2008
Includes 'view storage volume' facebox popup and new/delete LVM volume functionality. Although lvm tasks are created, taskomatic doesn't yet know what to do with them.
Signed-off-by: Scott Seago <sseago at redhat.com>
---
src/app/controllers/hardware_controller.rb | 5 +-
src/app/controllers/storage_controller.rb | 180 +++++++++++++++++++++++++-
src/app/controllers/task_controller.rb | 2 +
src/app/models/lvm_storage_pool.rb | 5 +
src/app/models/storage_volume_task.rb | 3 +-
src/app/views/storage/_lvm_volume_form.rhtml | 19 +++
src/app/views/storage/new_lvm_volume.rhtml | 42 ++++++
src/app/views/storage/show.rhtml | 63 +++++----
src/app/views/storage/show_volume.rhtml | 169 +++++++++++++++++-------
9 files changed, 404 insertions(+), 84 deletions(-)
create mode 100644 src/app/views/storage/_lvm_volume_form.rhtml
create mode 100644 src/app/views/storage/new_lvm_volume.rhtml
diff --git a/src/app/controllers/hardware_controller.rb b/src/app/controllers/hardware_controller.rb
index 4f24cb3..8c26184 100644
--- a/src/app/controllers/hardware_controller.rb
+++ b/src/app/controllers/hardware_controller.rb
@@ -117,7 +117,8 @@ class HardwareController < PoolController
def show_tasks
@task_types = [["VM Task", "VmTask"],
["Host Task", "HostTask"],
- ["Storage Task", "StorageTask", "break"],
+ ["Storage Task", "StorageTask"],
+ ["Storage Volume Task", "StorageVolumeTask", "break"],
["Show All", ""]]
super
end
@@ -162,7 +163,7 @@ class HardwareController < PoolController
if params[:id]
pre_show
storage_pools = @pool.storage_pools
- find_opts = {}
+ find_opts = {:conditions => "type != 'LvmStoragePool'"}
include_pool = false
else
# FIXME: no permissions or usage checks here yet
diff --git a/src/app/controllers/storage_controller.rb b/src/app/controllers/storage_controller.rb
index fe524f3..75058cd 100644
--- a/src/app/controllers/storage_controller.rb
+++ b/src/app/controllers/storage_controller.rb
@@ -25,6 +25,7 @@ class StorageController < ApplicationController
before_filter :pre_pool_admin, :only => [:refresh]
before_filter :pre_new2, :only => [:new2]
before_filter :pre_json, :only => [:storage_volumes_json]
+ before_filter :pre_create_volume, :only => [:create_volume]
def index
list
@@ -90,15 +91,25 @@ class StorageController < ApplicationController
flash[:notice] = 'You do not have permission to view this storage pool: redirecting to top level'
redirect_to :controller => 'dashboard'
end
- json_list(@storage_pool.storage_volumes,
- [:display_name, :size_in_gb, :get_type_label])
+ attr_list = []
+ attr_list << :id if (@storage_pool.user_subdividable and @can_modify)
+ attr_list += [:display_name, :size_in_gb, :get_type_label]
+ json_list(@storage_pool.storage_volumes, attr_list)
end
def show_volume
@storage_volume = StorageVolume.find(params[:id])
set_perms(@storage_volume.storage_pool.hardware_pool)
unless @can_view
flash[:notice] = 'You do not have permission to view this storage volume: redirecting to top level'
- redirect_to :controller => 'dashboard'
+ respond_to do |format|
+ format.html { redirect_to :controller => 'dashboard' }
+ format.xml { head :forbidden }
+ end
+ else
+ respond_to do |format|
+ format.html { render :layout => 'popup' }
+ format.xml { render :xml => @storage_volume.to_xml }
+ end
end
end
@@ -110,6 +121,70 @@ class StorageController < ApplicationController
render :layout => false
end
+ def new_volume
+ new_volume_internal(StoragePool.find(params[:storage_pool_id]),
+ { :storage_pool_id => params[:storage_pool_id]})
+ render :layout => 'popup'
+ end
+
+ def new_lvm_volume
+ @source_volume = StorageVolume.find(params[:source_volume_id])
+ @return_facebox = params[:return_facebox]
+ unless @source_volume.supports_lvm_subdivision
+ #fixme: proper error page for popups
+ redirect_to :controller => 'dashboard'
+ return
+ end
+ lvm_pool = @source_volume.lvm_storage_pool
+ unless lvm_pool
+ # FIXME: what should we do about VG/LV names?
+ # for now auto-create VG name as ovirt_vg_#{@source_volume.id}
+ lvm_pool = LvmStoragePool.new(:vg_name => "ovirt_vg_#{@source_volume.id}",
+ :hardware_pool_id => @source_volume.storage_pool.hardware_pool_id)
+ lvm_pool.source_volumes << @source_volume
+ lvm_pool.save!
+ end
+ new_volume_internal(lvm_pool, { :storage_pool_id => lvm_pool.id})
+ @storage_volume.lv_owner_perms='0744'
+ @storage_volume.lv_group_perms='0744'
+ @storage_volume.lv_mode_perms='0744'
+ render :layout => 'popup'
+ end
+
+ def create_volume
+ begin
+ StorageVolume.transaction do
+ @storage_volume.save!
+ @task = StorageVolumeTask.new({ :user => @user,
+ :task_target => @storage_volume,
+ :action => StorageVolumeTask::ACTION_CREATE_VOLUME,
+ :state => Task::STATE_QUEUED})
+ @task.save!
+ end
+ respond_to do |format|
+ format.json { render :json => { :object => "storage_volume",
+ :success => true,
+ :alert => "Storage Volume was successfully created." } }
+ format.xml { render :xml => @storage_volume,
+ :status => :created,
+ # FIXME: create storage_volume_url method if relevant
+ :location => storage_pool_url(@storage_volume)
+ }
+ end
+ rescue => ex
+ # FIXME: need to distinguish volume vs. task save errors
+ respond_to do |format|
+ format.json {
+ json_hash = { :object => "storage_volume", :success => false,
+ :errors => @storage_volume.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_volume.errors,
+ :status => :unprocessable_entity }
+ end
+ end
+ end
+
def insert_refresh_task
@task = StorageTask.new({ :user => @user,
:task_target => @storage_pool,
@@ -244,6 +319,67 @@ class StorageController < ApplicationController
end
end
+ def delete_volumes
+ storage_volume_ids_str = params[:storage_volume_ids]
+ storage_volume_ids = storage_volume_ids_str.split(",").collect {|x| x.to_i}
+ alerts = []
+ status = true
+ begin
+ StorageVolume.transaction do
+ storage = StorageVolume.find(:all, :conditions => "id in (#{storage_volume_ids.join(', ')})")
+ unless storage.empty?
+ set_perms(storage[0].storage_pool.hardware_pool)
+ unless @can_modify and storage[0].storage_pool.user_subdividable
+ respond_to do |format|
+ format.json { render :json => { :object => "storage_volume",
+ :success => false,
+ :alert => "You do not have permission to delete this storage volume." } }
+ format.xml { head :forbidden }
+ end
+ else
+ storage.each do |storage_volume|
+ alert, success = delete_volume_internal(storage_volume)
+ alerts << alert
+ status = false unless success
+ end
+ respond_to do |format|
+ format.json { render :json => { :object => "storage_volume",
+ :success => status, :alert => alerts.join("\n") } }
+ format.xml { head(status ? :ok : :method_not_allowed) }
+ end
+ end
+ else
+ respond_to do |format|
+ format.json { render :json => { :object => "storage_volume",
+ :success => false, :alert => "no volumes selected" } }
+ format.xml { head(status ? :ok : :method_not_allowed) }
+ end
+ end
+ end
+ end
+ end
+
+ def delete_volume
+ @storage_volume = StorageVolume.find(params[:id])
+ set_perms(@storage_volume.storage_pool.hardware_pool)
+ unless @can_modify and @storage_volume.storage_pool.user_subdividable
+ respond_to do |format|
+ format.json { render :json => { :object => "storage_volume",
+ :success => false,
+ :alert => "You do not have permission to delete this storage volume." } }
+ format.xml { head :forbidden }
+ end
+ else
+ alert, success = delete_volume_internal(@storage_volume)
+ respond_to do |format|
+ format.json { render :json => { :object => "storage_volume",
+ :success => success, :alert => alert } }
+ format.xml { head(success ? :ok : :method_not_allowed) }
+ end
+ end
+
+ end
+
def pre_new
@hardware_pool = HardwarePool.find(params[:hardware_pool_id])
@perm_obj = @hardware_pool
@@ -274,6 +410,16 @@ class StorageController < ApplicationController
@perm_obj = @storage_pool.hardware_pool
@redir_obj = @storage_pool
end
+ def pre_create_volume
+ volume = params[:storage_volume]
+ unless type = params[:storage_type]
+ type = volume.delete(:storage_type)
+ end
+ @storage_volume = StorageVolume.factory(type, volume)
+ @perm_obj = @storage_volume.storage_pool.hardware_pool
+ @redir_controller = @storage_volume.storage_pool.hardware_pool.get_controller
+ authorize_admin
+ end
def pre_json
pre_show
end
@@ -282,4 +428,32 @@ class StorageController < ApplicationController
authorize_admin
end
+ private
+ def new_volume_internal(storage_pool, new_params)
+ @storage_volume = StorageVolume.factory(storage_pool.get_type_label, new_params)
+ @perm_obj = @storage_volume.storage_pool.hardware_pool
+ authorize_admin
+ end
+
+ def delete_volume_internal(volume)
+ begin
+ name = volume.display_name
+ if !volume.vms.empty?
+ 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
+ @task = StorageVolumeTask.new({ :user => @user,
+ :task_target => volume,
+ :action => StorageVolumeTask::ACTION_DELETE_VOLUME,
+ :state => Task::STATE_QUEUED})
+ @task.save!
+ ["Storage Volume #{name} deletion was successfully queued.", true]
+ end
+ rescue => ex
+ ["Failed to delete storage volume #{name} (#{ex.message}.",false]
+ end
+ end
end
diff --git a/src/app/controllers/task_controller.rb b/src/app/controllers/task_controller.rb
index 73e5155..647d69c 100644
--- a/src/app/controllers/task_controller.rb
+++ b/src/app/controllers/task_controller.rb
@@ -24,6 +24,8 @@ class TaskController < ApplicationController
set_perms(@task.vm.vm_resource_pool)
elsif @task[:type] == StorageTask.name
set_perms(@task.storage_pool.hardware_pool)
+ elsif @task[:type] == StorageVolumeTask.name
+ set_perms(@task.storage_volume.storage_pool.hardware_pool)
elsif @task[:type] == HostTask.name
set_perms(@task.host.hardware_pool)
end
diff --git a/src/app/models/lvm_storage_pool.rb b/src/app/models/lvm_storage_pool.rb
index 08b8938..84fbb28 100644
--- a/src/app/models/lvm_storage_pool.rb
+++ b/src/app/models/lvm_storage_pool.rb
@@ -44,5 +44,10 @@ class LvmStoragePool < StoragePool
kb_to_gb(size)
end
+ # FIXME: needs to take free space into account here
+ def user_subdividable
+ true
+ end
+
end
diff --git a/src/app/models/storage_volume_task.rb b/src/app/models/storage_volume_task.rb
index 78f2895..136f1ba 100644
--- a/src/app/models/storage_volume_task.rb
+++ b/src/app/models/storage_volume_task.rb
@@ -20,7 +20,7 @@
class StorageVolumeTask < Task
ACTION_CREATE_VOLUME = "create_volume"
- ACTION_EDIT_VOLUME = "edit_volume"
+ ACTION_DELETE_VOLUME = "delete_volume"
def after_initialize
self.hardware_pool = task_target.storage_pool.hardware_pool if self.task_target_type=="StorageVolume"
@@ -29,7 +29,6 @@ class StorageVolumeTask < Task
def task_obj
"StorageVolume;;;#{self.storage_volume.id};;;#{self.storage_volume.display_name}"
end
- end
def host
nil
end
diff --git a/src/app/views/storage/_lvm_volume_form.rhtml b/src/app/views/storage/_lvm_volume_form.rhtml
new file mode 100644
index 0000000..823158e
--- /dev/null
+++ b/src/app/views/storage/_lvm_volume_form.rhtml
@@ -0,0 +1,19 @@
+<%= error_messages_for 'storage_volume' %>
+
+<!--[form:storage_pool]-->
+<%= hidden_field 'storage_volume', 'storage_pool_id' %>
+<%= hidden_field_tag 'storage_type', @storage_volume.get_type_label %>
+
+<%= text_field_with_label "Size (GB):", 'storage_volume', 'size_in_gb' %>
+
+<%= text_field_with_label "LV Name:", 'storage_volume', 'lv_name' %>
+
+<%= text_field_with_label "Owner permissions:", 'storage_volume', 'lv_owner_perms' %>
+
+<%= text_field_with_label "Group permissions:", 'storage_volume', 'lv_group_perms' %>
+
+<%= text_field_with_label "Mode permissions:", 'storage_volume', 'lv_mode_perms' %>
+
+
+<!--[eoform:storage_volume]-->
+
diff --git a/src/app/views/storage/new_lvm_volume.rhtml b/src/app/views/storage/new_lvm_volume.rhtml
new file mode 100644
index 0000000..ea51cc5
--- /dev/null
+++ b/src/app/views/storage/new_lvm_volume.rhtml
@@ -0,0 +1,42 @@
+<%- content_for :title do -%>
+ <%= _("Add New LVM Volume") %>
+<%- end -%>
+<%- content_for :description do -%>
+ Add a new LVM Storage Volume to <%= @source_volume.display_name %>.
+<%- end -%>
+<div class="panel_header"></div>
+<div class="dialog_form">
+<form method="POST" action="<%= url_for :action => 'create_volume' %>" id="lvm_volume_form" >
+ <div class="dialog_form">
+ <div id="new_storage_pool">
+ <%= render :partial => 'lvm_volume_form' %>
+ </div>
+ </div>
+ <!-- FIXME: need to pop up the details dialog again -->
+ <%= popup_footer("$('#lvm_volume_form').submit()", "New LVM Volume") %>
+</form>
+</div>
+<script type="text/javascript">
+function afterLvmVolume(response, status){
+ ajax_validation(response, status);
+ if (response.success) {
+ <% if @return_facebox %>
+ $('#window').fadeOut('fast');
+ $("#window").empty().load("<%= @return_facebox %>")
+ $('#window').fadeIn('fast');
+ <% else %>
+ $(document).trigger('close.facebox');
+ <% end %>
+ }
+}
+$(function() {
+ var lvmvolumeoptions = {
+ target: '<%= url_for :action => 'create_volume' %>', // target element to update
+ dataType: 'json',
+ success: afterLvmVolume // post-submit callback
+ };
+
+ // bind form using 'ajaxForm'
+ $('#lvm_volume_form').ajaxForm(lvmvolumeoptions);
+});
+</script>
diff --git a/src/app/views/storage/show.rhtml b/src/app/views/storage/show.rhtml
index 82c9dab..a84dc62 100644
--- a/src/app/views/storage/show.rhtml
+++ b/src/app/views/storage/show.rhtml
@@ -18,24 +18,24 @@
<div id="storage_selection_id" style="display:none"><%= @storage_pool.id %></div>
<div class="selection_key">
- IP address: </br>
+ IP address:<br/>
<% if @storage_pool[:type] == "IscsiStoragePool" %>
- Port: </br>
- Target: </br>
+ Port:<br/>
+ Target:<br/>
<% elsif @storage_pool[:type] == "NfsStoragePool" %>
- Export path:</br>
+ Export path:<br/>
<% end %>
- Type: </br>
+ Type:<br/>
</div>
<div class="selection_value">
- <%=h @storage_pool.ip_addr %></br>
+ <%=h @storage_pool.ip_addr %><br/>
<% if @storage_pool[:type] == "IscsiStoragePool" %>
- <%=h @storage_pool.port %></br>
- <%=h @storage_pool.target %></br>
+ <%=h @storage_pool.port %><br/>
+ <%=h @storage_pool.target %><br/>
<% elsif @storage_pool[:type] == "NfsStoragePool" %>
- <%=h @storage_pool.export_path %></br>
+ <%=h @storage_pool.export_path %><br/>
<% end %>
- <%=h @storage_pool.get_type_label %></br>
+ <%=h @storage_pool.get_type_label %><br/>
</div>
<%- content_for :right do -%>
<div class="selection_right_title">Volumes</div>
@@ -54,24 +54,33 @@
<%= confirmation_dialog("confirm_delete_storage", "Are you sure?", "delete_storage_pool()") %>
<script type="text/javascript">
- $("#storage_volumes_grid").flexigrid
- (
- {
- url: '<%= url_for :action => "storage_volumes_json", :id => @storage_pool.id %>',
- dataType: 'json',
- colModel : [
- {display: 'Alias', name : 'display_name', width : 180, sortable : false, align: 'left'},
- {display: 'Size (Gb)', name : 'size', width : 80, sortable : true, align: 'left'},
- {display: 'Type', name : 'type', width : 80, sortable : true, align: 'left'}
- ],
- sortname: "size",
- sortorder: "desc",
- usepager: false,
- useRp: true,
- rp: 40,
- showTableToggleBtn: true,
- }
+ $("#storage_volumes_grid").flexigrid
+ (
+ {
+ url: '<%= url_for :action => "storage_volumes_json", :id => @storage_pool.id %>',
+ dataType: 'json',
+ colModel : [
+ <%= "{display: '', width : 20, align: 'left', process: storage_volumes_gridcheckbox}," if (@storage_pool.user_subdividable and @can_modify) %>
+ {display: 'Alias', width : 180, sortable : false, align: 'left', process: storage_volume_details_link},
+ {display: 'Size (Gb)', name : 'size', width : 80, sortable : true, align: 'left'},
+ {display: 'Type', name : 'type', width : 80, sortable : true, align: 'left'}
+ ],
+ sortname: "size",
+ sortorder: "desc",
+ usepager: false,
+ useRp: true,
+ rp: 40,
+ showTableToggleBtn: true,
+ }
);
+ function storage_volumes_gridcheckbox(celDiv)
+ {
+ $(celDiv).html('<input class="grid_checkbox" type="checkbox" name="grid_checkbox'+$(celDiv).html()+'" value="'+$(celDiv).html()+'"/>');
+ }
+ function storage_volume_details_link(celDiv,pid)
+ {
+ $(celDiv).html('<a href="<%= url_for :controller => 'storage', :action => 'show_volume' %>/'+ pid +'" rel="facebox[.bolder]">' + $(celDiv).html() + '</a>');
+ }
</script>
<script type="text/javascript">
diff --git a/src/app/views/storage/show_volume.rhtml b/src/app/views/storage/show_volume.rhtml
index 9aeb808..e39c10e 100644
--- a/src/app/views/storage/show_volume.rhtml
+++ b/src/app/views/storage/show_volume.rhtml
@@ -1,54 +1,123 @@
- <div id="data">
- <div class="inside">
-
- <div id="dataTableWrapper">
-
- <div class="dataTable">
- <div class="inside">
-
- <div class="data-table-column">
+<%- content_for :title do -%>
+ <%=h @storage_volume.display_name %>
+<%- end -%>
+<%- content_for :description do -%>
+ Details for Storage Volume <%=h @storage_volume.display_name %>
+<%- end -%>
- <p><b>IP address:</b> <%=h @storage_volume.storage_pool.ip_addr %></p>
-<% if @storage_volume.storage_pool[:type] == "IscsiStoragePool" %>
- <p><b>Port:</b> <%=h @storage_volume.storage_pool.port %></p>
- <p><b>Target:</b> <%=h @storage_volume.storage_pool[:target] %></p>
-<% elsif @storage_volume.storage_pool[:type] == "NfsStoragePool" %>
- <p><b>Export path:</b> <%=h @storage_volume.storage_pool.export_path %></p>
-<% end %>
- <p><b>Type:</b> <%=h @storage_volume.storage_pool.get_type_label %></p>
- <p></p>
- <p><b>Path:</b> <%=h @storage_volume.path %></p>
-<% if @storage_volume[:type] == "IscsiStorageVolume" %>
- <p><b>LUN:</b> <%=h @storage_volume.lun %></p>
-<% elsif @storage_volume[:type] == "NfsStorageVolume" %>
- <p><b>Filename:</b> <%=h @storage_volume.filename %></p>
+<% if @storage_volume.supports_lvm_subdivision %>
+ <div id="dialog-content-area">
+ <div id="toolbar_nav">
+ <ul>
+ <li><a href="#" id="new_lvm_volume_button"><%=image_tag "icon_addstorage.png", :style=>"vertical-align:middle;" %>Add</a></li>
+ <% if (@storage_volume.lvm_storage_pool and
+ !@storage_volume.lvm_storage_pool.storage_volumes.empty?) %>
+ <li><a href="#" onClick="return remove_lvm_volumes();"><%=image_tag "icon_remove.png" %> Remove</a></li>
+ <% end %>
+ </ul>
+ </div>
+ </div>
<% end %>
- <p><b>Size:</b> <%=h @storage_volume.size_in_gb %> GB</p>
-
- </div>
-
- </div> <!-- end #data-table.inside -->
- </div> <!-- end #dataTable -->
-
- </div> <!-- end #dataTableWrapper -->
-
- </div> <!-- end #data.inside -->
- </div> <!-- end #data -->
-
- </td>
- <td id="right">
- <div class="heading"> </div>
- <div id="tools">
- <h3>Actions</h3>
- <%if @can_modify -%>
- <% end -%>
- <div class="actions">
- <%= link_to "Back to #{@storage_volume.storage_pool.ip_addr}: #{@storage_volume.storage_pool[:target]}", { :action => 'show', :id => @storage_volume.storage_pool.id }, { :class => "" } %>
- </div>
+<div class="panel_header"></div>
+ <div class="selection_key">
+ IP address:<br/>
+ <% if @storage_volume.storage_pool[:type] == "IscsiStoragePool" %>
+ Port:<br/>
+ Target:<br/>
+ <% elsif @storage_volume.storage_pool[:type] == "NfsStoragePool" %>
+ Export path:<br/>
+ <% end %>
+ Type:<br/>
+ Path:<br/>
+ <% if @storage_volume[:type] == "IscsiStorageVolume" %>
+ LUN:<br/>
+ <% elsif @storage_volume[:type] == "NfsStorageVolume" %>
+ Filename:<br/>
+ <% end %>
+ Size:<br/>
</div>
+ <div class="selection_value">
+ <%=h @storage_volume.storage_pool.ip_addr %><br/>
+ <% if @storage_volume.storage_pool[:type] == "IscsiStoragePool" %>
+ <%=h @storage_volume.storage_pool.port %><br/>
+ <%=h @storage_volume.storage_pool[:target] %><br/>
+ <% elsif @storage_volume.storage_pool[:type] == "NfsStoragePool" %>
+ <%=h @storage_volume.storage_pool.export_path %><br/>
+ <% end %>
+ <%=h @storage_volume.storage_pool.get_type_label %><br/>
+ <%=h @storage_volume.path %><br/>
+ <% if @storage_volume[:type] == "IscsiStorageVolume" %>
+ <%=h @storage_volume.lun %><br/>
+ <% elsif @storage_volume[:type] == "NfsStorageVolume" %>
+ <%=h @storage_volume.filename %><br/>
+ <% end %>
+ <%=h @storage_volume.size_in_gb %> GB<br/>
+ </div>
+<% if @storage_volume.supports_lvm_subdivision %>
+ <div class="dialog_form">
+ <div class="form_heading">LVM Volumes</div>
+ <% if @storage_volume.lvm_storage_pool %>
+ <form id="lvm_storage_volumes_grid_form">
+ <table id="lvm_storage_volumes_grid" style="display:none"></table>
+ </form>
+ <% end %>
+ </div>
+<% end %>
- </td>
-
-<%- content_for :title do -%>
-<%= _("Storage Volume") %>
-<%- end -%>
+<div class="facebox_timfooter">
+ <div class="button">
+ <div class="button_left_grey"></div>
+ <div class="button_middle_grey"><a href="#" onclick="jQuery(document).trigger('close.facebox')">Close</a></div>
+ <div class="button_right_grey"></div>
+ </div>
+</div>
+<script type="text/javascript">
+ $("#lvm_storage_volumes_grid").flexigrid
+ (
+ {
+ url: '<%= url_for :action => "storage_volumes_json", :id => @storage_volume.lvm_storage_pool.id %>',
+ dataType: 'json',
+ colModel : [
+ <%= "{display: '', width : 20, align: 'left', process: lvm_storage_volumes_gridcheckbox}," if @can_modify %>
+ {display: 'Alias', width : 180, sortable : false, align: 'left'},
+ {display: 'Size (Gb)', name : 'size', width : 80, sortable : true, align: 'left'},
+ {display: 'Type', name : 'type', width : 80, sortable : true, align: 'left'}
+ ],
+ sortname: "size",
+ sortorder: "desc",
+ usepager: false,
+ useRp: true,
+ rp: 40,
+ showTableToggleBtn: true,
+ }
+ );
+ function lvm_storage_volumes_gridcheckbox(celDiv)
+ {
+ $(celDiv).html('<input class="grid_checkbox" type="checkbox" name="grid_checkbox'+$(celDiv).html()+'" value="'+$(celDiv).html()+'"/>');
+ }
+ function get_selected_lvm_volumes()
+ {
+ return get_selected_checkboxes("lvm_storage_volumes_grid_form");
+ }
+ function remove_lvm_volumes()
+ {
+ var volumes = get_selected_lvm_volumes();
+ if (validate_selected(volumes, "storage volume")) {
+ $.post('<%= url_for :controller => "storage", :action => "delete_volumes" %>',
+ { storage_volume_ids: volumes.toString() },
+ function(data,status){
+ $("#lvm_storage_volumes_grid").flexReload();
+ if (data.alert) {
+ $.jGrowl(data.alert);
+ }
+ }, 'json');
+ }
+ }
+$('#new_lvm_volume_button').click(function(){
+ $('#window').fadeOut('fast');
+ $("#window").empty().load("<%= url_for :controller => 'storage', :action => 'new_lvm_volume' %>",
+ { source_volume_id: <%=@storage_volume.id%>,
+ return_facebox: '<%= url_for :controller => 'storage', :action => 'show_volume', :id => @storage_volume.id %>' });
+ $('#window').fadeIn('fast');
+});
+</script>
--
1.5.5.1
More information about the ovirt-devel
mailing list