Scott Seago
2008-Sep-18 21:06 UTC
[Ovirt-devel] [PATCH] finished smart pools implementation. (revised)
Nav now works for smart pools (but Jay's going to do some tweaking). All of the smart pool tabs work properly with add/remove functions, although summary is stubbed out. search results are not yet integrated with smart pools. Signed-off-by: Scott Seago <sseago at redhat.com> --- src/app/controllers/application.rb | 13 +- src/app/controllers/hardware_controller.rb | 122 +++-------- src/app/controllers/host_controller.rb | 5 + src/app/controllers/pool_controller.rb | 31 +++- src/app/controllers/resources_controller.rb | 4 +- src/app/controllers/smart_pool_controller.rb | 22 -- src/app/controllers/smart_pools_controller.rb | 239 ++++++++++++++++++++ src/app/controllers/storage_controller.rb | 5 + src/app/controllers/tree_controller.rb | 14 +- src/app/controllers/vm_controller.rb | 5 + src/app/models/directory_pool.rb | 1 + src/app/models/pool.rb | 42 +++- src/app/models/smart_pool.rb | 23 ++ src/app/views/hardware/_move_menu.rhtml | 17 -- src/app/views/hardware/show_hosts.rhtml | 20 +- src/app/views/hardware/show_storage.rhtml | 14 +- src/app/views/hardware/show_vms.rhtml | 2 +- src/app/views/host/_grid.rhtml | 14 +- src/app/views/host/add_to_smart_pool.rhtml | 28 +++ src/app/views/host/addhost.html.erb | 2 +- src/app/views/layouts/_navigation_tabs.rhtml | 17 ++ src/app/views/layouts/_side_toolbar.rhtml | 45 +++-- src/app/views/layouts/_tree.rhtml | 6 +- src/app/views/layouts/redux.rhtml | 26 -- src/app/views/resources/show_vms.rhtml | 8 +- src/app/views/smart_pools/_form.rhtml | 6 + src/app/views/smart_pools/_pools_grid.rhtml | 39 ++++ src/app/views/smart_pools/add_pool_dialog.rhtml | 52 +++++ src/app/views/smart_pools/new.rhtml | 26 ++ src/app/views/smart_pools/show.rhtml | 17 ++ .../{hardware => smart_pools}/show_hosts.rhtml | 64 ++--- src/app/views/smart_pools/show_pools.rhtml | 74 ++++++ src/app/views/smart_pools/show_storage.rhtml | 72 ++++++ src/app/views/smart_pools/show_users.rhtml | 2 + src/app/views/smart_pools/show_vms.rhtml | 77 +++++++ src/app/views/storage/_grid.rhtml | 19 ++- src/app/views/storage/add_to_smart_pool.rhtml | 22 ++ src/app/views/user/_show.rhtml | 4 +- src/app/views/vm/_grid.rhtml | 70 ++++--- src/app/views/vm/add_to_smart_pool.rhtml | 27 +++ src/db/migrate/017_add_smart_pools.rb | 2 +- .../jquery-treeview/jquery.treeview.async.js | 2 +- src/public/javascripts/jquery.ovirt.treeview.js | 12 +- src/public/javascripts/ovirt.js | 98 ++++++++- 44 files changed, 1112 insertions(+), 298 deletions(-) delete mode 100644 src/app/controllers/smart_pool_controller.rb create mode 100644 src/app/controllers/smart_pools_controller.rb delete mode 100644 src/app/views/hardware/_move_menu.rhtml create mode 100644 src/app/views/host/add_to_smart_pool.rhtml create mode 100644 src/app/views/smart_pools/_form.rhtml create mode 100644 src/app/views/smart_pools/_pools_grid.rhtml create mode 100644 src/app/views/smart_pools/add_pool_dialog.rhtml create mode 100644 src/app/views/smart_pools/new.rhtml create mode 100644 src/app/views/smart_pools/show.rhtml copy src/app/views/{hardware => smart_pools}/show_hosts.rhtml (50%) create mode 100644 src/app/views/smart_pools/show_pools.rhtml create mode 100644 src/app/views/smart_pools/show_storage.rhtml create mode 100644 src/app/views/smart_pools/show_users.rhtml create mode 100644 src/app/views/smart_pools/show_vms.rhtml create mode 100644 src/app/views/storage/add_to_smart_pool.rhtml create mode 100644 src/app/views/vm/add_to_smart_pool.rhtml diff --git a/src/app/controllers/application.rb b/src/app/controllers/application.rb index 3126748..6dcf6f8 100644 --- a/src/app/controllers/application.rb +++ b/src/app/controllers/application.rb @@ -89,7 +89,7 @@ class ApplicationController < ActionController::Base end # don't define find_opts for array inputs - def json_hash(full_items, attributes, arg_list=[], find_opts={}) + def json_hash(full_items, attributes, arg_list=[], find_opts={}, id_method=:id) page = params[:page].to_i paginate_opts = {:page => page, :order => "#{params[:sortname]} #{params[:sortorder]}", @@ -101,7 +101,7 @@ class ApplicationController < ActionController::Base json_hash[:total] = item_list.total_entries json_hash[:rows] = item_list.collect do |item| item_hash = {} - item_hash[:id] = item.id + item_hash[:id] = item.send(id_method) item_hash[:cell] = attributes.collect do |attr| if attr.is_a? Array value = item @@ -115,9 +115,12 @@ class ApplicationController < ActionController::Base end json_hash end - # don't define find_opts for array inputs - def json_list(full_items, attributes, arg_list=[], find_opts={}) - render :json => json_hash(full_items, attributes, arg_list, find_opts).to_json + + # json_list is a helper method used to format data for paginated flexigrid tables + # + # FIXME: what is the intent of this comment? don't define find_opts for array inputs + def json_list(full_items, attributes, arg_list=[], find_opts={}, id_method=:id) + render :json => json_hash(full_items, attributes, arg_list, find_opts, id_method).to_json end diff --git a/src/app/controllers/hardware_controller.rb b/src/app/controllers/hardware_controller.rb index a366e4c..42ff9cb 100644 --- a/src/app/controllers/hardware_controller.rb +++ b/src/app/controllers/hardware_controller.rb @@ -1,4 +1,4 @@ -# +# # Copyright (C) 2008 Red Hat, Inc. # Written by Scott Seago <sseago at redhat.com> # @@ -20,10 +20,6 @@ class HardwareController < PoolController - XML_OPTS = { - :include => [ :storage_pools, :hosts, :quota ] - } - EQ_ATTRIBUTES = [ :name, :parent_id ] verify :method => [:post, :put], :only => [ :create, :update ], @@ -59,12 +55,12 @@ class HardwareController < PoolController end def json_view_tree - json_tree_internal(Permission::PRIV_VIEW, false) + json_tree_internal(Permission::PRIV_VIEW, :select_hardware_and_vm_pools) end def json_move_tree - json_tree_internal(Permission::PRIV_MODIFY, true) + json_tree_internal(Permission::PRIV_MODIFY, :select_hardware_pools) end - def json_tree_internal(privilege, filter_vm_pools) + def json_tree_internal(privilege, filter_method) id = params[:id] if id @pool = Pool.find(id) @@ -77,11 +73,9 @@ class HardwareController < PoolController end if @pool pools = @pool.children - pools = Pool.select_hardware_pools(pools) if filter_vm_pools open_list = [] else pools = Pool.list_for_user(get_login_user,Permission::PRIV_VIEW) - pools = Pool.select_hardware_pools(pools) if filter_vm_pools current_id = params[:current_id] if current_id current_pool = Pool.find(current_id) @@ -90,26 +84,26 @@ class HardwareController < PoolController open_list = [] end end + pools = Pool.send(filter_method, pools) - render :json => Pool.nav_json(pools, open_list, filter_vm_pools) + render :json => Pool.nav_json(pools, open_list, + (filter_method==:select_hardware_pools)) end def show_vms show end - def show_hosts - @hardware_pools = HardwarePool.find :all + def show_hosts show end - + def show_graphs show end def show_storage show - @hardware_pools = HardwarePool.find :all end def show_tasks @@ -142,21 +136,16 @@ class HardwareController < PoolController # filtering on which pool to exclude id = params[:exclude_pool] hosts = Host - find_opts = {:include => :hardware_pool, + find_opts = {:include => :hardware_pool, :conditions => ["pools.id != ?", id]} include_pool = true end - attr_list = [] - attr_list << :id if params[:checkboxes] - attr_list << :hostname - attr_list << [:hardware_pool, :name] if include_pool - attr_list += [:uuid, :hypervisor_type, :num_cpus, :cpu_speed, :arch, :memory_in_mb, :status_str, :load_average] - json_list(hosts, attr_list, [:all], find_opts) + super(:full_items => hosts,:include_pool => include_pool,:find_opts => find_opts) end def vm_pools_json - json_list(Pool, - [:id, :name, :id], + json_list(Pool, + [:id, :name, :id], [@pool, :children], {:finder => 'call_finder', :conditions => ["type = 'VmResourcePool'"]}) end @@ -172,24 +161,22 @@ class HardwareController < PoolController # filtering on which pool to exclude id = params[:exclude_pool] storage_pools = StoragePool - find_opts = {:include => :hardware_pool, + find_opts = {:include => :hardware_pool, :conditions => ["pools.id != ?", id]} include_pool = true end - attr_list = [:id, :display_name, :ip_addr, :get_type_label] - attr_list.insert(2, [:hardware_pool, :name]) if include_pool - json_list(storage_pools, attr_list, [:all], find_opts) + super(:full_items => storage_pools,:include_pool => include_pool,:find_opts => find_opts) end def storage_volumes_json - json_list(@pool.all_storage_volumes, + json_list(@pool.all_storage_volumes, [:display_name, :size_in_gb, :get_type_label]) end def move pre_modify @resource_type = params[:resource_type] - render :layout => 'popup' + render :layout => 'popup' end def new @@ -279,87 +266,44 @@ class HardwareController < PoolController end end - #FIXME: we need permissions checks. user must have permission on src pool - # in addition to the current pool (which is checked). We also need to fail - # for hosts that aren't currently empty def add_hosts - host_ids_str = params[:resource_ids] - host_ids = host_ids_str.split(",").collect {|x| x.to_i} - - begin - @pool.transaction do - @pool.move_hosts(host_ids, @pool.id) - end - render :json => { :object => "host", :success => true, - :alert => "Hosts were successfully added to this Hardware pool." } - rescue - render :json => { :object => "host", :success => false, - :alert => "Error adding Hosts to this Hardware pool." } - end + edit_items(Host, :move_hosts, @pool.id, :add) end - #FIXME: we need permissions checks. user must have permission on src pool - # in addition to the current pool (which is checked). We also need to fail - # for hosts that aren't currently empty def move_hosts - target_pool_id = params[:target_pool_id] - host_ids_str = params[:resource_ids] - host_ids = host_ids_str.split(",").collect {|x| x.to_i} - - begin - @pool.transaction do - @pool.move_hosts(host_ids, target_pool_id) - end - render :json => { :object => "host", :success => true, - :alert => "Hosts were successfully moved." } - rescue - render :json => { :object => "host", :success => false, - :alert => "Error moving hosts." } - end + edit_items(Host, :move_hosts, params[:target_pool_id], :move) end - #FIXME: we need permissions checks. user must have permission on src pool - # in addition to the current pool (which is checked). We also need to fail - # for storage that aren't currently empty def add_storage - storage_pool_ids_str = params[:resource_ids] - storage_pool_ids = storage_pool_ids_str.split(",").collect {|x| x.to_i} - - begin - @pool.transaction do - @pool.move_storage(storage_pool_ids, @pool.id) - end - render :json => { :object => "storage_pool", :success => true, - :alert => "Storage Pools were successfully added to this Hardware pool." } - rescue - render :json => { :object => "storage_pool", :success => false, - :alert => "Error adding storage pools to this Hardware pool." } - end + edit_items(StoragePool, :move_storage, @pool.id, :add) + end + + def move_storage + edit_items(StoragePool, :move_storage, params[:target_pool_id], :move) end #FIXME: we need permissions checks. user must have permission on src pool # in addition to the current pool (which is checked). We also need to fail # for storage that aren't currently empty - def move_storage - target_pool_id = params[:target_pool_id] - storage_pool_ids_str = params[:resource_ids] - storage_pool_ids = storage_pool_ids_str.split(",").collect {|x| x.to_i} + def edit_items(item_class, item_method, target_pool_id, item_action) + resource_ids_str = params[:resource_ids] + resource_ids = resource_ids_str.split(",").collect {|x| x.to_i} begin @pool.transaction do - @pool.move_storage(storage_pool_ids, target_pool_id) + @pool.send(item_method, resource_ids, target_pool_id) end - render :json => { :object => "storage_pool", :success => true, - :alert => "Storage Pools were successfully moved." } + render :json => { :success => true, + :alert => "#{item_action.to_s} #{item_class.table_name.humanize} successful." } rescue - render :json => { :object => "storage_pool", :success => false, - :alert => "Error moving storage pools." } + render :json => { :success => false, + :alert => "#{item_action.to_s} #{item_class.table_name.humanize} failed." } end end def removestorage pre_modify - render :layout => 'popup' + render :layout => 'popup' end def destroy diff --git a/src/app/controllers/host_controller.rb b/src/app/controllers/host_controller.rb index 5174c88..417d11f 100644 --- a/src/app/controllers/host_controller.rb +++ b/src/app/controllers/host_controller.rb @@ -84,6 +84,11 @@ class HostController < ApplicationController render :layout => 'popup' end + def add_to_smart_pool + @pool = SmartPool.find(params[:smart_pool_id]) + render :layout => 'popup' + end + def new end diff --git a/src/app/controllers/pool_controller.rb b/src/app/controllers/pool_controller.rb index ce41701..02ef290 100644 --- a/src/app/controllers/pool_controller.rb +++ b/src/app/controllers/pool_controller.rb @@ -23,9 +23,14 @@ class PoolController < ApplicationController before_filter :pre_show_pool, :only => [:show_vms, :show_users, :show_hosts, :show_storage, :users_json, :show_tasks, :tasks, - :vms_json, :vm_pools_json, + :vm_pools_json, + :pools_json, :show_pools, :storage_volumes_json, :quick_summary] + XML_OPTS = { + :include => [ :storage_pools, :hosts, :quota ] + } + def show respond_to do |format| format.html { @@ -86,6 +91,28 @@ class PoolController < ApplicationController json_hash(@pool.tasks, attr_list, [:all], find_opts) end + def hosts_json(args) + attr_list = [] + attr_list << :id if params[:checkboxes] + attr_list << :hostname + attr_list << [:hardware_pool, :name] if args[:include_pool] + attr_list += [:uuid, :hypervisor_type, :num_cpus, :cpu_speed, :arch, :memory_in_mb, :status_str, :load_average] + json_list(args[:full_items], attr_list, [:all], args[:find_opts]) + end + + def storage_pools_json(args) + attr_list = [:id, :display_name, :ip_addr, :get_type_label] + attr_list.insert(2, [:hardware_pool, :name]) if args[:include_pool] + json_list(args[:full_items], attr_list, [:all], args[:find_opts]) + end + + def vms_json(args) + attr_list = [:id, :description, :uuid, + :num_vcpus_allocated, :memory_allocated_in_mb, + :vnic_mac_addr, :state, :id] + json_list(args[:full_items], attr_list, [:all], args[:find_opts]) + end + def new render :layout => 'popup' end @@ -120,7 +147,7 @@ class PoolController < ApplicationController @current_pool_id=@pool.id set_perms(@perm_obj) unless @can_view - flash[:notice] = 'You do not have permission to view this pool pool: redirecting to top level' + flash[:notice] = 'You do not have permission to view this pool: redirecting to top level' respond_to do |format| format.html { redirect_to :controller => "dashboard" } format.xml { head :forbidden } diff --git a/src/app/controllers/resources_controller.rb b/src/app/controllers/resources_controller.rb index a0a65a6..2c54ccc 100644 --- a/src/app/controllers/resources_controller.rb +++ b/src/app/controllers/resources_controller.rb @@ -68,8 +68,8 @@ class ResourcesController < PoolController end def vms_json - json_list(@pool.vms, - [:id, :description, :uuid, :num_vcpus_allocated, :memory_allocated_in_mb, :vnic_mac_addr, :state, :id]) + pre_show + super(:full_items => @pool.vms, :find_opts => {}, :include_pool => :true) end def create diff --git a/src/app/controllers/smart_pool_controller.rb b/src/app/controllers/smart_pool_controller.rb deleted file mode 100644 index eb087a6..0000000 --- a/src/app/controllers/smart_pool_controller.rb +++ /dev/null @@ -1,22 +0,0 @@ -# -# 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 SmartPoolController < ApplicationController -end diff --git a/src/app/controllers/smart_pools_controller.rb b/src/app/controllers/smart_pools_controller.rb new file mode 100644 index 0000000..99ae8b8 --- /dev/null +++ b/src/app/controllers/smart_pools_controller.rb @@ -0,0 +1,239 @@ +# +# 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 SmartPoolsController < PoolController + + before_filter :pre_modify, :only => [:add_hosts, :remove_hosts, + :add_storage, :remove_storage, + :add_vms, :remove_vms, + :add_pools, :remove_pools] + def show_vms + show + end + + def show_hosts + show + end + + def show_pools + show + end + + def show_storage + show + end + + def create + begin + @pool.create_with_parent(@parent) + render :json => { :object => "smart_pool", :success => true, + :alert => "Smart Pool was successfully created." } + rescue + render :json => { :object => "smart_pool", :success => false, + :errors => @pool.errors.localize_error_messages.to_a} + end + end + + def update + begin + @pool.update_attributes!(params[:smart_pool]) + render :json => { :object => "smart_pool", :success => true, + :alert => "Smart Pool was successfully modified." } + rescue + render :json => { :object => "smart_pool", :success => false, + :errors => @pool.errors.localize_error_messages.to_a} + end + end + + def add_pool_dialog + pre_modify + @selected_pools = @pool.tagged_pools.collect {|pool| pool.id} + render :layout => 'popup' + end + + def hosts_json + super(items_json_internal(Host, :tagged_hosts)) + end + + def storage_pools_json + super(items_json_internal(StoragePool, :tagged_storage_pools)) + end + + def vms_json + super(items_json_internal(Vm, :tagged_vms)) + end + + def pools_json + args = items_json_internal(Pool, :tagged_pools) + attr_list = [:id, :name, :get_type_label] + json_list(args[:full_items], attr_list, [:all], args[:find_opts], :class_and_id) + + end + + def items_json_internal(item_class, item_assoc) + if params[:id] + pre_show + full_items = @pool.send(item_assoc) + find_opts = {} + else + # FIXME: no permissions or usage checks here yet + # filtering on which pool to exclude + id = params[:exclude_pool] + full_items = item_class + pool_items = SmartPool.find(id, + :include => item_assoc).send(item_assoc).collect {|x| x.id} + if pool_items.empty? + conditions = [] + else + conditions = ["#{item_class.table_name}.id not in (?)", pool_items] + end + find_opts = {:conditions => conditions} + end + { :full_items => full_items, :find_opts => find_opts, :include_pool => :true} + end + + def add_hosts + edit_items(Host, :add_items, :add) + end + + def remove_hosts + edit_items(Host, :remove_items, :remove) + end + + def add_storage + edit_items(StoragePool, :add_items, :add) + end + + def remove_storage + edit_items(StoragePool, :remove_items, :remove) + end + + def add_vms + edit_items(Vm, :add_items, :add) + end + + def remove_vms + edit_items(Vm, :remove_items, :remove) + end + + def add_pools + edit_items(Pool, :add_items, :add) + end + + def remove_pools + edit_items(Pool, :remove_items, :remove) + end + + def edit_items(item_class, item_method, item_action) + resource_ids_str = params[:resource_ids] + resource_ids = resource_ids_str.split(",").collect {|x| x.to_i} + begin + @pool.send(item_method,item_class, resource_ids) + render :json => { :success => true, + :alert => "#{item_action.to_s} #{item_class.table_name.humanize} successful." } + rescue + render :json => { :success => false, + :alert => "#{item_action.to_s} #{item_class.table_name.humanize} failed." } + end + end + + def destroy + if @pool.destroy + alert="Smart Pool was successfully deleted." + success=true + else + alert="Failed to delete Smart pool." + success=false + end + render :json => { :object => "smart_pool", :success => success, :alert => alert } + end + + # handled + # show_hosts + # show_graphs + # show_storage + # show + # show_vms + # show_tasks + # new xxx + # create xxx + # hosts_json + # storage_pools_json + # add_hosts + # move_hosts + # add_storage + # move_storage + # removestorage + + #HW only + # json_view_tree + # json_move_tree + # vm_pools_json + # move + #VM only + # vms_json + # delete + # vm_actions + #both + # move + # update + # destroy + + #inherited + # used + # new + # edit + # show_users + # users_json + # unneeded + # tasks + # show_tasks + # quick_summary + + protected + #filter methods + def pre_new + @pool = SmartPool.new + @parent = DirectoryPool.get_or_create_user_root(get_login_user) + @perm_obj = @parent + @current_pool_id=@parent.id + end + def pre_create + @pool = SmartPool.new(params[:smart_pool]) + @parent = DirectoryPool.get_or_create_user_root(get_login_user) + @perm_obj = @parent + @current_pool_id=@parent.id + end + def pre_edit + @pool = SmartPool.find(params[:id]) + @parent = @pool.parent + @perm_obj = @pool + @current_pool_id=@pool.id + end + def pre_show + @pool = SmartPool.find(params[:id]) + super + end + def pre_modify + pre_edit + authorize_admin + end + +end diff --git a/src/app/controllers/storage_controller.rb b/src/app/controllers/storage_controller.rb index 7e97764..7eec618 100644 --- a/src/app/controllers/storage_controller.rb +++ b/src/app/controllers/storage_controller.rb @@ -199,6 +199,11 @@ class StorageController < ApplicationController render :layout => false end + def add_to_smart_pool + @pool = SmartPool.find(params[:smart_pool_id]) + render :layout => 'popup' + end + #FIXME: we need permissions checks. user must have permission on src pool # in addition to the current pool (which is checked). We also need to fail # for storage that aren't currently empty diff --git a/src/app/controllers/tree_controller.rb b/src/app/controllers/tree_controller.rb index 5ad8426..1aed544 100644 --- a/src/app/controllers/tree_controller.rb +++ b/src/app/controllers/tree_controller.rb @@ -1,10 +1,18 @@ class TreeController < ApplicationController - + + def get_pools + # TODO: split these into separate hash elements for HW and smart pools + pools = HardwarePool.get_default_pool.full_set_nested(:method => :json_hash_element, + :privilege => Permission::PRIV_VIEW, :user => get_login_user) + pools += DirectoryPool.get_smart_root.full_set_nested(:method => :json_hash_element, + :privilege => Permission::PRIV_VIEW, :user => get_login_user, + :smart_pool_set => true) + end def fetch_nav - @pools = HardwarePool.get_default_pool.full_set_nested(:method => :json_hash_element) + @pools = get_pools end def fetch_json - render :json => HardwarePool.get_default_pool.full_set_nested(:method => :json_hash_element).to_json + render :json => get_pools.to_json end end diff --git a/src/app/controllers/vm_controller.rb b/src/app/controllers/vm_controller.rb index d3f16b6..6d06b48 100644 --- a/src/app/controllers/vm_controller.rb +++ b/src/app/controllers/vm_controller.rb @@ -35,6 +35,11 @@ class VmController < ApplicationController render :layout => 'selection' end + def add_to_smart_pool + @pool = SmartPool.find(params[:smart_pool_id]) + render :layout => 'popup' + end + def new render :layout => 'popup' end diff --git a/src/app/models/directory_pool.rb b/src/app/models/directory_pool.rb index f62d980..82486af 100644 --- a/src/app/models/directory_pool.rb +++ b/src/app/models/directory_pool.rb @@ -55,6 +55,7 @@ class DirectoryPool < Pool permission.save! end end + user_root end end diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb index 9d71fa5..eb71be8 100644 --- a/src/app/models/pool.rb +++ b/src/app/models/pool.rb @@ -111,6 +111,9 @@ class Pool < ActiveRecord::Base def self.select_vm_pools(pools) pools.select {|pool| pool[:type] == "VmResourcePool"} end + def self.select_hardware_and_vm_pools(pools) + pools.select {|pool| ["HardwarePool", "VmResourcePool"].include?(pool[:type])} + end def sub_hardware_pools children({:conditions => "type='HardwarePool'"}) @@ -225,22 +228,44 @@ class Pool < ActiveRecord::Base # or :current_id to specify which pool gets ":selected => true" set def full_set_nested(opts={}) method = opts.delete(:method) {:hash_element} + privilege = opts.delete(:privilege) + user = opts.delete(:user) + smart_pool_set = opts.delete(:smart_pool_set) + if privilege and user + opts[:include] = "permissions" + opts[:conditions] = "permissions.uid='#{user}' and + permissions.user_role in + ('#{Permission.roles_for_privilege(privilege).join("', '")}')" + end current_id = opts.delete(:current_id) opts.delete(:order) subtree_list = full_set(opts) - return_tree = send(method) - ref_hash = { id => return_tree} + subtree_list -= [self] if smart_pool_set + return_tree_list = [] + ref_hash = {} subtree_list.each do |pool| - unless pool.id==return_tree[:id] - new_element = pool.send(method) - ref_hash[pool.id] = new_element - parent = ref_hash[pool.parent_id] + new_element = pool.send(method) + ref_hash[pool.id] = new_element + parent = ref_hash[pool.parent_id] + if parent parent[:children] ||= [] parent[:children] << new_element + else + # for smart pools include the parent DirectoryPool + if smart_pool_set and pool[:type]=="SmartPool" + pool_parent = pool.parent + parent_element = pool_parent.send(method) + ref_hash[pool_parent.id] = parent_element + return_tree_list << parent_element + parent_element[:children] ||= [] + parent_element[:children] << new_element + else + return_tree_list << new_element + end end end ref_hash[current_id][:selected] = true if current_id - return_tree + return_tree_list end def self.call_finder(*args) @@ -273,6 +298,9 @@ class Pool < ActiveRecord::Base end end + def class_and_id + self.class.name + "_" + self.id.to_s + end protected def traverse_parents if id diff --git a/src/app/models/smart_pool.rb b/src/app/models/smart_pool.rb index e672c5b..9104ee5 100644 --- a/src/app/models/smart_pool.rb +++ b/src/app/models/smart_pool.rb @@ -30,6 +30,10 @@ class SmartPool < Pool :conditions => "smart_pool_tags.tagged_type = 'Vm'" + def get_type_label + "Smart Pool" + end + def create_for_user(user) create_with_parent(DirectoryPool.get_or_create_user_root(user)) end @@ -44,4 +48,23 @@ class SmartPool < Pool :tagged_id=>item.id}).destroy end + def add_items(item_class, item_ids) + items = item_class.find(:all, :conditions => "id in (#{item_ids.join(', ')})") + transaction do + items.each { |item| add_item(item)} + end + end + + def remove_items(item_class, item_ids) + tags = smart_pool_tags.find(:all, + :conditions => "tagged_id in + (#{item_ids.join(', ')}) + and tagged_type='#{item_class.name}'") + transaction do + tags.each do |tag| + tag.destroy + end + end + end + end diff --git a/src/app/views/hardware/_move_menu.rhtml b/src/app/views/hardware/_move_menu.rhtml deleted file mode 100644 index cc7ed73..0000000 --- a/src/app/views/hardware/_move_menu.rhtml +++ /dev/null @@ -1,17 +0,0 @@ -<%= image_tag "icon_move.png", :style => "vertical-align:middle;" %> Move <%= image_tag "icon_toolbar_arrow.gif", :style => "vertical-align:middle;" %> -<ul> - <% @hardware_pools.each { |hw_pool| %> - <% if @pool.parent_id != hw_pool.id and @pool.id != hw_pool.id %> - <li onclick="window.location='<%= url_for :controller => :hardware, :action => 'foobar' %>'"> <!-- FIXME point me at the right place --> - <% else %> - <li style="color: #CCCCCC; cursor: default;"> - <% end %> - <%= image_tag "icon_hdwarepool.png" %> - <%= hw_pool.name %></a> - </li> - <% } %> - - <li style="border-top: 1px solid black; border-bottom: 1px solid black;"> - Move to New Resource Group... - </li> -</ul> diff --git a/src/app/views/hardware/show_hosts.rhtml b/src/app/views/hardware/show_hosts.rhtml index 31c575d..d33c920 100644 --- a/src/app/views/hardware/show_hosts.rhtml +++ b/src/app/views/hardware/show_hosts.rhtml @@ -14,17 +14,17 @@ <script type="text/javascript"> function get_selected_hosts() { - return get_selected_checkboxes("hosts_grid_form") + return get_selected_checkboxes("hosts_grid_form"); } function validate_for_move() { if (validate_selected(get_selected_hosts(), 'host')) { - $('#move_link_hidden').click() + $('#move_link_hidden').click(); } } function remove_hosts() { - hosts = get_selected_hosts() + var hosts = get_selected_hosts(); if (validate_selected(hosts, "host")) { $.post('<%= url_for :controller => "hardware", :action => "move_hosts", :id => @pool %>', { resource_ids: hosts.toString(), target_pool_id: <%= HardwarePool.get_default_pool.id %> }, @@ -34,22 +34,22 @@ $.jGrowl(data.alert); } if (hosts.indexOf($('#hosts_selection_id').html()) != -1){ - empty_summary('hosts_selection', 'Host') - } + empty_summary('hosts_selection', 'Host'); + } }, 'json'); } } function hosts_select(selected_rows) { - var selected_ids = new Array() - for(i=0; i<selected_rows.length; i++) { + var selected_ids = new Array(); + for(i=0; i<selected_rows.length; i++) { load_widget_select(selected_rows[i]); selected_ids[i] = selected_rows[i].id; } if (selected_ids.length == 1) { - $('#hosts_selection').load('<%= url_for :controller => "host", :action => "show", :id => nil %>/' + parseInt(selected_ids[0].substring(3))) + $('#hosts_selection').load('<%= url_for :controller => "host", :action => "show", :id => nil %>/' + parseInt(selected_ids[0].substring(3))); } } </script> @@ -63,7 +63,7 @@ :exclude_host => nil, :show_pool => false, :checkboxes => true, - :on_select => "hosts_select", + :on_select => "hosts_select", :on_deselect => "load_widget_deselect", :on_hover => "load_widget_hover", :on_unhover => "load_widget_unhover", @@ -79,7 +79,7 @@ <div class="data_section"> <div class="no-grid-items"> <%= image_tag 'no-grid-items.png', :style => 'float: left;' %> - + <div class="no-grid-items-text"> No hosts found in this pool. <br/><br/> <%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> diff --git a/src/app/views/hardware/show_storage.rhtml b/src/app/views/hardware/show_storage.rhtml index 564b9ed..6466f9b 100644 --- a/src/app/views/hardware/show_storage.rhtml +++ b/src/app/views/hardware/show_storage.rhtml @@ -15,7 +15,7 @@ <script type="text/javascript"> function remove_storage() { - storage = get_selected_storage() + var storage = get_selected_storage(); if (validate_selected(storage, "storage pool")) { $.post('<%= url_for :controller => "hardware", :action => "move_storage", :id => @pool %>', { resource_ids: storage.toString(), target_pool_id: <%= HardwarePool.get_default_pool.id %> }, @@ -25,14 +25,14 @@ $.jGrowl(data.alert); } if (storage.indexOf($('#storage_selection_id').html()) != -1){ - empty_summary('storage_selection', 'Storage Pool') + empty_summary('storage_selection', 'Storage Pool'); } }, 'json'); } } function delete_storage() { - storage = get_selected_storage() + var storage = get_selected_storage(); if (validate_selected(storage, "storage pool")) { $.post('<%= url_for :controller => "storage", :action => "delete_pools", :id => @pool %>', { storage_pool_ids: storage.toString() }, @@ -42,15 +42,15 @@ $.jGrowl(data.alert); } if (storage.indexOf($('#storage_selection_id').html()) != -1){ - empty_summary('storage_selection', 'Storage Pool') + empty_summary('storage_selection', 'Storage Pool'); } }, 'json'); } } function storage_select(selected_rows) { - var selected_ids = new Array() ; - for(i=0; i<selected_rows.length; i++) { + var selected_ids = new Array(); + for(i=0; i<selected_rows.length; i++) { selected_ids[i] = selected_rows[i].id; } if (selected_ids.length == 1) @@ -80,7 +80,7 @@ <div class="data_section"> <div class="no-grid-items"> <%= image_tag 'no-grid-items.png', :style => 'float: left;' %> - + <div class="no-grid-items-text"> No storage Volumes found in this pool. <br/><br/> <%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> diff --git a/src/app/views/hardware/show_vms.rhtml b/src/app/views/hardware/show_vms.rhtml index 5ff5cc9..ee14758 100644 --- a/src/app/views/hardware/show_vms.rhtml +++ b/src/app/views/hardware/show_vms.rhtml @@ -11,7 +11,7 @@ } function delete_vm_pools() { - vm_pools = get_selected_vm_pools() + var vm_pools = get_selected_vm_pools(); if (validate_selected(vm_pools, "vm_pool")) { $.post('<%= url_for :controller => "resources", :action => "delete", :id => @pool %>', { vm_pool_ids: vm_pools.toString() }, diff --git a/src/app/views/host/_grid.rhtml b/src/app/views/host/_grid.rhtml index 553adf9..21b563e 100644 --- a/src/app/views/host/_grid.rhtml +++ b/src/app/views/host/_grid.rhtml @@ -1,6 +1,14 @@ <%= render :partial => 'graph/load_graph.rhtml' %> +<% pool_controller = 'hardware' unless (defined? pool_controller) and !(pool_controller.nil?) %> <% hosts_per_page.nil? ? hosts_per_page = 40: hosts_per_page = hosts_per_page %> +<% if (hwpool.nil? or + ((hwpool.is_a? HardwarePool) and (hwpool.hosts.size > hosts_per_page)) or + ((hwpool.is_a? SmartPool) and (hwpool.tagged_hosts.size > hosts_per_page))) + usepager = 'true' + else + usepager = 'false' + end %> <div id="<%= table_id %>_div"> <%= "<form id=\"#{table_id}_form\">" if checkboxes %> <table id="<%= table_id %>" style="display:none"></table> @@ -10,7 +18,7 @@ $("#<%= table_id %>").flexigrid ( { - url: '<%= url_for :controller => "hardware", + url: '<%= url_for :controller => pool_controller, :action => "hosts_json", :escape => false, :id => (hwpool.nil? ? nil : hwpool.id), @@ -38,8 +46,8 @@ ], sortname: "hostname", sortorder: "asc", - usepager: <%= (hwpool.nil? or hwpool.hosts.size > hosts_per_page) ? 'true' : 'false' %>, - useRp: <%= (hwpool.nil? or hwpool.hosts.size > hosts_per_page) ? 'true' : 'false' %>, + usepager: <%= usepager %>, + useRp: <%= usepager %>, rp: <%= hosts_per_page %>, showTableToggleBtn: true, onSelect: <%= on_select %>, diff --git a/src/app/views/host/add_to_smart_pool.rhtml b/src/app/views/host/add_to_smart_pool.rhtml new file mode 100644 index 0000000..a89f8de --- /dev/null +++ b/src/app/views/host/add_to_smart_pool.rhtml @@ -0,0 +1,28 @@ +<%- content_for :title do -%> + <%= _("Add Host to Smart Pool") %> +<%- end -%> +<%- content_for :description do -%> + Select hosts from the list below to add to the <%= @pool.name %> smart pool.</a> +<%- end -%> +<div id="dialog-content-area"> +<div class="dialog_body_small"> +<div class="panel_header"></div> + <%= render :partial => "/host/grid", :locals => { :table_id => "add_smart_hosts_grid", + :hwpool => nil, + :pool_controller => "smart_pools", + :exclude_pool => @pool.id, + :exclude_host => nil, + :checkboxes => true, + :on_select => false, + :on_deselect => false, + :on_hover => false, + :on_unhover => false, + :is_popup => true, + :hosts_per_page => 10} %> +</div> + +<%= popup_footer("add_hosts_to_smart_pool('#{url_for :controller => "smart_pools", + :action => "add_hosts", + :id => @pool}')", + "Add Hosts") %> +</div> diff --git a/src/app/views/host/addhost.html.erb b/src/app/views/host/addhost.html.erb index 7edd4c5..967643e 100644 --- a/src/app/views/host/addhost.html.erb +++ b/src/app/views/host/addhost.html.erb @@ -24,4 +24,4 @@ :action => "add_hosts", :id => @hardware_pool}')", "Add Hosts") %> -</div> \ No newline at end of file +</div> diff --git a/src/app/views/layouts/_navigation_tabs.rhtml b/src/app/views/layouts/_navigation_tabs.rhtml index 4b0f18d..af3fa61 100644 --- a/src/app/views/layouts/_navigation_tabs.rhtml +++ b/src/app/views/layouts/_navigation_tabs.rhtml @@ -30,6 +30,23 @@ <li id="nav_access"> <%= link_to "User Access", {:action => 'show_users', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> <li id="nav_tasks"> <%= link_to "Tasks", {:action => 'show_tasks', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> </ul> +<% elsif controller.controller_name == "smart_pools" %> + <script> + $(document).ready(function(){ + $tabs = $("#smart_pools_nav_tabs").tabs({ + pool_type: "smart_pools", + selected: <%if params[:tab]%><%=params[:tab]%><%else%>1<%end%> + }); + }); + </script> + <ul id="smart_pools_nav_tabs" class="ui-tabs-nav"> + <li id="nav_summary" class="ui-tabs-selected"><%= link_to "Summary", {:action => 'show', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> + <li id="nav_hosts"> <%= link_to "Hosts", {:action => 'show_hosts', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> + <li id="nav_storage"><%= link_to "Storage", {:action => 'show_storage', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> + <li id="nav_pools"> <%= link_to "Pools", {:action => 'show_pools', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> + <li id="nav_vms"> <%= link_to "Virtual Machines", {:action => 'show_vms', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> + <li id="nav_access"> <%= link_to "User Access", {:action => 'show_users', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> + </ul> <% elsif controller.controller_name == "search" %> <ul id="resources_nav_tabs" class="ui-tabs-nav"> <li id="nav_search" class="ui-tabs-selected"><a href="#">Search Results</a></li> diff --git a/src/app/views/layouts/_side_toolbar.rhtml b/src/app/views/layouts/_side_toolbar.rhtml index 763f4a2..e1958f1 100644 --- a/src/app/views/layouts/_side_toolbar.rhtml +++ b/src/app/views/layouts/_side_toolbar.rhtml @@ -1,24 +1,41 @@ <% pool = @current_pool_id ? Pool.find(@current_pool_id) : nil %> +<% if pool and pool[:type]=="HardwarePool" + delete_url = url_for(:controller => "hardware", :action => "destroy") + elsif pool and pool[:type]=="VmResourcePool" + delete_url = url_for(:controller => "resources", :action => "destroy") + elsif pool and pool[:type]=="SmartPool" + delete_url = url_for(:controller => "smart_pools", :action => "destroy") + else + delete_url = "" + end %> + <%if pool -%> -<%if pool[:type]=="HardwarePool" -%> -<div class="toolbar" style="float:left;"> - <a href="<%= url_for :controller => :hardware, :action => 'new', :parent_id => pool %>" rel="facebox[.bolder]"> - <%=image_tag "icon_add_hardwarepool.png", :title=>"Add Hardware Pool" %> - </a> -</div> + <%if pool[:type]=="HardwarePool" -%> + <div class="toolbar" style="float:left;"> + <a href="<%= url_for :controller => :hardware, :action => 'new', :parent_id => pool %>" rel="facebox[.bolder]"> + <%=image_tag "icon_add_hardwarepool.png", :title=>"Add Hardware Pool" %> + </a> + </div> + <div class="toolbar" style="float:left;"> + <a href="<%= url_for :controller => 'resources', :action => 'new', :parent_id => pool %>" rel="facebox[.bolder]"> + <%= image_tag "icon_add_vmpool.png", :title=>"Add Virtual Machine Pool" %> + </a> + </div> + <% end -%> +<% end -%> <div class="toolbar" style="float:left;"> - <a href="<%= url_for :controller => 'resources', :action => 'new', :parent_id => pool %>" rel="facebox[.bolder]"> - <%= image_tag "icon_add_vmpool.png", :title=>"Add Virtual Machine Pool" %> + <a href="<%= url_for :controller => :smart_pools, :action => 'new' %>" rel="facebox[.bolder]"> + <%=image_tag "icon_add_hardwarepool.png", :title=>"Add Smart Pool" %> </a> </div> -<% end -%> -<div class="toolbar" style="float:left;"> +<%if pool -%> + <div class="toolbar" style="float:left;"> <a href="#conf_nav_delete_pool" rel="facebox[.bolder]"> <%= image_tag "icon_delete.gif", :title=>"Delete Selected Pool" %> </a> -</div> -<div class="toolbar" style="display:none;"> - <%= confirmation_dialog("conf_nav_delete_pool", "Are you sure?", "delete_#{pool[:type]=='HardwarePool' ? 'hw' : 'vm'}_pool(#{pool.id})") %> -</div> + </div> + <div class="toolbar" style="display:none;"> + <%= confirmation_dialog("conf_nav_delete_pool", "Are you sure?", "delete_pool('#{delete_url}', #{pool.id})") %> + </div> <% end -%> <div class="toolbar"></div> diff --git a/src/app/views/layouts/_tree.rhtml b/src/app/views/layouts/_tree.rhtml index eb15676..0e6e138 100644 --- a/src/app/views/layouts/_tree.rhtml +++ b/src/app/views/layouts/_tree.rhtml @@ -12,12 +12,14 @@ //animated: "normal", url: "<%= url_for :controller =>'/tree', :action => 'fetch_json' %>", hardware_url: "<%= url_for :controller =>'/hardware', :action => 'show' %>", - resource_url: "<%= url_for :controller =>'/resources', :action => 'show' %>" + resource_url: "<%= url_for :controller =>'/resources', :action => 'show' %>", + smart_url: "<%= url_for :controller =>'/smart_pools', :action => 'show' %>" }); var tree_reload = { url: "<%= url_for :controller =>'/tree', :action => 'fetch_json' %>", hardware_url: "<%= url_for :controller =>'/hardware', :action => 'show' %>", - resource_url: "<%= url_for :controller =>'/resources', :action => 'show' %>" + resource_url: "<%= url_for :controller =>'/resources', :action => 'show' %>", + smart_url: "<%= url_for :controller =>'/smart_pools', :action => 'show' %>" } $('#test-tree').everyTime(15000,function(){ load(tree_reload, {}, this, this); diff --git a/src/app/views/layouts/redux.rhtml b/src/app/views/layouts/redux.rhtml index d6cfe24..01540d4 100644 --- a/src/app/views/layouts/redux.rhtml +++ b/src/app/views/layouts/redux.rhtml @@ -90,32 +90,6 @@ }); return false;})},function(){}); }); - - function delete_vm_pool(id, parent) - { - $(document).trigger('close.facebox'); - $.post('<%= url_for :controller => "resources", :action => "destroy" %>', - {id: id}, - function(data,status){ - // need to redirect to the parent using the new ajax reload stuff - $("#vmpools_grid").flexReload(); - if (data.alert) { - $.jGrowl(data.alert); - } - }, 'json'); - } - function delete_hw_pool(id, parent) - { - $(document).trigger('close.facebox'); - $.post('<%= url_for :controller => "hardware", :action => "destroy" %>', - {id: id}, - function(data,status){ - // need to redirect to the parent using the new ajax reload stuff - if (data.alert) { - $.jGrowl(data.alert); - } - }, 'json'); - } </script> <%= yield :scripts -%> </head> diff --git a/src/app/views/resources/show_vms.rhtml b/src/app/views/resources/show_vms.rhtml index 857f56b..beca048 100644 --- a/src/app/views/resources/show_vms.rhtml +++ b/src/app/views/resources/show_vms.rhtml @@ -26,7 +26,7 @@ } function delete_vms() { - vms = get_selected_vms() + var vms = get_selected_vms(); if (validate_selected(vms, "vm")) { $.post('<%= url_for :controller => "vm", :action => "delete", :id => @pool %>', { vm_ids: vms.toString() }, @@ -43,7 +43,7 @@ } function vm_actions(action) { - vms = get_selected_vms() + var vms = get_selected_vms(); if (validate_selected(vms, "vm")) { jQuery.facebox('<div id="vm_action_results">'); $('#vm_action_results').load('<%= url_for :controller => "resources", @@ -70,10 +70,12 @@ <div class="data_section"> <%= render :partial => "/vm/grid", :locals => { :table_id => "vms_grid", :pool => @pool, + :exclude_pool => nil, :on_select => "vms_select", :on_deselect => "load_widget_deselect", :on_hover => "load_widget_hover", - :on_unhover => "load_widget_unhover" } %> + :on_unhover => "load_widget_unhover", + :is_popup => false } %> </div> <div class="selection_detail" id="vms_selection"> <div class="selection_left"> diff --git a/src/app/views/smart_pools/_form.rhtml b/src/app/views/smart_pools/_form.rhtml new file mode 100644 index 0000000..2f2156a --- /dev/null +++ b/src/app/views/smart_pools/_form.rhtml @@ -0,0 +1,6 @@ +<%= error_messages_for 'vm_resource_pool' %> + +<!--[form:vm_resource_pool]--> +<%= text_field_with_label "Name", 'smart_pool', 'name' %> +<!--[eoform:vm_resource_pool]--> + diff --git a/src/app/views/smart_pools/_pools_grid.rhtml b/src/app/views/smart_pools/_pools_grid.rhtml new file mode 100644 index 0000000..a5f1a99 --- /dev/null +++ b/src/app/views/smart_pools/_pools_grid.rhtml @@ -0,0 +1,39 @@ +<% resources_per_page = 40 %> +<div id="<%= table_id %>_div"> +<form id="<%= table_id %>_form"> +<table id="<%= table_id %>" style="display:none"></table> +</form> +</div> +<script type="text/javascript"> + $("#<%= table_id %>").flexigrid + ( + { + url: '<%= url_for :controller => "smart_pools", :action => "pools_json", :id => pool.id %>', + dataType: 'json', + colModel : [ + {display: '', name : 'id', width : 20, sortable : false, align: 'left', process: <%= table_id %>checkbox}, + {display: 'Name', name : 'name', width : 160, sortable : true, align: 'left'}, + {display: 'Type', width : 160, sortable : true, align: 'left'} + ], + sortname: "name", + sortorder: "asc", + usepager: <%= pool.tagged_pools.size > resources_per_page ? 'true' : 'false' %>, + useRp: <%= pool.tagged_pools.size > resources_per_page ? 'true' : 'false' %>, + rp: <%= resources_per_page %>, + showTableToggleBtn: true, + onSelect: <%= on_select %>, + onDeselect: <%= on_deselect %>, + onHover: <%= on_hover %>, + onUnhover: <%= on_unhover %> + } + ); + function <%= table_id %>checkbox(celDiv) + { + $(celDiv).html('<input type="checkbox" name="grid_checkbox'+$(celDiv).html()+'" class="grid_checkbox" value="'+$(celDiv).html()+'"/>'); + } + function <%= table_id %>_load_widget(celDiv) + { + load_widget(celDiv, "resource"); + }; + +</script> diff --git a/src/app/views/smart_pools/add_pool_dialog.rhtml b/src/app/views/smart_pools/add_pool_dialog.rhtml new file mode 100644 index 0000000..0d8cea6 --- /dev/null +++ b/src/app/views/smart_pools/add_pool_dialog.rhtml @@ -0,0 +1,52 @@ +<%- content_for :title do -%> + Add a Hardware or Virtual Machine Pool +<%- end -%> +<%- content_for :description do -%> + Choose a Hardware or Virtual Machine Pool to add to this Smart Pool +<%- end -%> + +<script type="text/javascript"> + $(document).ready(function(){ + $("#add_tree").asynch_treeview({ + //animated: "normal", + current_pool_id: <%=@current_pool_id%>, + disabled_pools: [<%=@selected_pools.join(',')%>], + url: "<%= url_for :controller =>'/hardware', :action => 'json_view_tree' %>", + current: "disabled", + hardware_url: "#", + resource_url: "#", + onclick: "add_pool_to_smart_pool", + action_type: "javascript" + }) + }); + function add_pool_to_smart_pool(added_pool_id) + { + $.post('<%= url_for :controller => "smart_pools", :action => "add_pools", :id => @pool %>', + { resource_ids: added_pool_id }, + function(data,status){ + grid = $("#smart_pools_grid"); + if (grid.size()>0 && grid != null) { + grid.flexReload(); + } else { + $tabs.tabs("load",$tabs.data('selected.tabs')); + } + $("smart_pools_grid").flexReload() + jQuery(document).trigger('close.facebox'); + if (data.alert) { + $.jGrowl(data.alert); + } + }, 'json'); + } +</script> + +<div class="dialog_tree"> + <ul id="add_tree" class="filetree treeview-famfamfam treeview"></ul> +</div> + +<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')">Cancel</a></div> + <div class="button_right_grey"></div> + </div> +</div> diff --git a/src/app/views/smart_pools/new.rhtml b/src/app/views/smart_pools/new.rhtml new file mode 100644 index 0000000..7d488af --- /dev/null +++ b/src/app/views/smart_pools/new.rhtml @@ -0,0 +1,26 @@ +<%- content_for :title do -%> + <%= _("Add New Smart Pool") %> +<%- end -%> +<%- content_for :description do -%> + Add a new Smart Pool. +<%- end -%> + +<form method="POST" action="<%= url_for :action => 'create' %>" id="smart_pool_form" > + <div class="dialog_form"> + <%= render :partial => 'form' %> + </div> + <%= popup_footer("$('#smart_pool_form').submit()", "Create Smart Pool") %> +</form> + +<script type="text/javascript"> +$(function() { + var hwpooloptions = { + target: '<%= url_for :action => 'create' %>', // target element to update + dataType: 'json', + success: afterSmartPool // post-submit callback + }; + + // bind form using 'ajaxForm' + $('#smart_pool_form').ajaxForm(hwpooloptions); +}); +</script> diff --git a/src/app/views/smart_pools/show.rhtml b/src/app/views/smart_pools/show.rhtml new file mode 100644 index 0000000..45b1753 --- /dev/null +++ b/src/app/views/smart_pools/show.rhtml @@ -0,0 +1,17 @@ +<div class="data_section_summary"> + + <div class="summary_title"><%= image_tag "icon_hdwarepool.png", :style=>"vertical-align:middle;" %> <%= @pool.name %></div><br/><br/> + + <div class="summary_subtitle"><%= image_tag "icon_smry_res.png", :style=>"vertical-align:middle;" %> Resources</div><br/> + <div id="availability_graphs"> + What do we show here for Smart Pools? + </div> + + <br/><br/> + <div class="summary_subtitle"><%= image_tag "icon_smry_his.png", :style=>"vertical-align:middle;" %> History</div><br/> + What do we show here for Smart Pools? + + <div class="summary_subtitle"><%= image_tag "icon_smry_perf.png", :style=>"vertical-align:middle;" %> Performance</div><br/> + What do we show here for Smart Pools? +</div> + diff --git a/src/app/views/hardware/show_hosts.rhtml b/src/app/views/smart_pools/show_hosts.rhtml similarity index 50% copy from src/app/views/hardware/show_hosts.rhtml copy to src/app/views/smart_pools/show_hosts.rhtml index 31c575d..a4b6be7 100644 --- a/src/app/views/hardware/show_hosts.rhtml +++ b/src/app/views/smart_pools/show_hosts.rhtml @@ -1,89 +1,77 @@ <div id="toolbar_nav"> <ul> - <li><a href="<%= url_for :controller => 'host', :action => 'addhost', :hardware_pool_id => @pool %>" rel="facebox[.bolder]"><%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> Add Host</a></li> - <li> - <a id="move_link" href="#" onClick="return validate_for_move();"><%= image_tag "icon_move.png", :style=>"vertical-align:middle;" %> Move</a> - <a id="move_link_hidden" href="<%= url_for :controller => 'hardware', :action => 'move', :id => @pool, :resource_type=>'hosts' %>" rel="facebox[.bolder]" style="display:none" ></a> - </li> - <% if @pool.id != HardwarePool.get_default_pool.id %> - <li><a href="#" onClick="remove_hosts()"><%= image_tag "icon_remove.png" %> Remove</a></li> - <% end %> + <li><a href="<%= url_for :controller => 'host', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]"><%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> Add Host</a></li> + <li><a href="#" onClick="remove_hosts_from_smart_pool()"><%= image_tag "icon_remove.png" %> Remove</a></li> </ul> </div> <script type="text/javascript"> - function get_selected_hosts() + function get_selected_hosts_for_smart_pool() { - return get_selected_checkboxes("hosts_grid_form") + return get_selected_checkboxes("smart_hosts_grid_form"); } - function validate_for_move() + function remove_hosts_from_smart_pool() { - if (validate_selected(get_selected_hosts(), 'host')) { - $('#move_link_hidden').click() - } - } - function remove_hosts() - { - hosts = get_selected_hosts() + var hosts = get_selected_hosts_for_smart_pool(); if (validate_selected(hosts, "host")) { - $.post('<%= url_for :controller => "hardware", :action => "move_hosts", :id => @pool %>', - { resource_ids: hosts.toString(), target_pool_id: <%= HardwarePool.get_default_pool.id %> }, + $.post('<%= url_for :controller => "smart_pools", :action => "remove_hosts", :id => @pool %>', + { resource_ids: hosts.toString() }, function(data,status){ $tabs.tabs("load",$tabs.data('selected.tabs')); if (data.alert) { $.jGrowl(data.alert); } - if (hosts.indexOf($('#hosts_selection_id').html()) != -1){ - empty_summary('hosts_selection', 'Host') - } + if (hosts.indexOf($('#smart_hosts_selection_id').html()) != -1){ + empty_summary('smart_hosts_selection', 'Host'); + } }, 'json'); } } - function hosts_select(selected_rows) + function smart_hosts_select(selected_rows) { - var selected_ids = new Array() - for(i=0; i<selected_rows.length; i++) { - load_widget_select(selected_rows[i]); + var selected_ids = new Array(); + for(i=0; i<selected_rows.length; i++) { selected_ids[i] = selected_rows[i].id; } if (selected_ids.length == 1) { - $('#hosts_selection').load('<%= url_for :controller => "host", :action => "show", :id => nil %>/' + parseInt(selected_ids[0].substring(3))) + $('#smart_hosts_selection').load('<%= url_for :controller => "host", :action => "show", :id => nil %>/' + parseInt(selected_ids[0].substring(3))); } } </script> <div class="panel_header"></div> -<% if @pool.hosts.size != 0 %> +<% if @pool.tagged_hosts.size != 0 %> <div class="data_section"> - <%= render :partial => "/host/grid", :locals => { :table_id => "hosts_grid", + <%= render :partial => "/host/grid", :locals => { :table_id => "smart_hosts_grid", :hwpool => @pool, + :pool_controller => "smart_pools", :exclude_pool => nil, :exclude_host => nil, - :show_pool => false, + :show_pool => true, :checkboxes => true, - :on_select => "hosts_select", + :on_select => "smart_hosts_select", :on_deselect => "load_widget_deselect", :on_hover => "load_widget_hover", :on_unhover => "load_widget_unhover", :is_popup => false, :hosts_per_page => 40} %> </div> - <div class="selection_detail" id="hosts_selection"> - <div class="selection_left"> - <div>Select a host above.</div> - </div> + <div class="selection_detail" id="smart_hosts_selection"> + <div class="selection_left"> + <div>Select a host above.</div> + </div> </div> <% else %> <div class="data_section"> <div class="no-grid-items"> <%= image_tag 'no-grid-items.png', :style => 'float: left;' %> - + <div class="no-grid-items-text"> No hosts found in this pool. <br/><br/> <%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> - <a href="<%= url_for :controller => 'host', :action => 'addhost', :hardware_pool_id => @pool %>" rel="facebox[.bolder]">Add first host to this hardware pool</a> + <a href="<%= url_for :controller => 'host', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]">Add first host to this smart pool</a> </div> </div> </div> diff --git a/src/app/views/smart_pools/show_pools.rhtml b/src/app/views/smart_pools/show_pools.rhtml new file mode 100644 index 0000000..8e89701 --- /dev/null +++ b/src/app/views/smart_pools/show_pools.rhtml @@ -0,0 +1,74 @@ +<div id="toolbar_nav"> + <ul> + <li><a href="<%= url_for :controller => 'smart_pools', :action => 'add_pool_dialog', :id => @pool %>" rel="facebox[.bolder]"><%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> Add Pool</a></li> + <li><a href="#" onClick="remove_pools_from_smart_pool()"><%= image_tag "icon_remove.png" %> Remove</a></li> + </ul> +</div> + +<script type="text/javascript"> + function get_selected_pools_for_smart_pool() + { + return get_selected_checkboxes("smart_pools_grid_form"); + } + function remove_pools_from_smart_pool() + { + var pools = get_selected_pools_for_smart_pool(); + if (validate_selected(pools, "pool")) { + $.post('<%= url_for :controller => "smart_pools", :action => "remove_pools", :id => @pool %>', + { resource_ids: pools.toString() }, + function(data,status){ + $tabs.tabs("load",$tabs.data('selected.tabs')); + if (data.alert) { + $.jGrowl(data.alert); + } + if (pools.indexOf($('#smart_pools_selection_id').html()) != -1){ + empty_summary('smart_pools_selection', 'Pool'); + } + + }, 'json'); + } + } + function smart_pools_select(selected_rows) + { + var selected_ids = new Array(); + for(i=0; i<selected_rows.length; i++) { + selected_ids[i] = selected_rows[i].id; + } + if (selected_ids.length == 1) + { + $('#smart_pools_selection').load('<%= url_for :controller => "search", :action => "single_result" %>', + { class_and_id: selected_ids[0].substring(3)}); + } + } +</script> + +<div class="panel_header"></div> +<% if @pool.tagged_pools.size != 0 %> + <div class="data_section"> + <%= render :partial => "/smart_pools/pools_grid", :locals => { :table_id => "smart_pools_grid", + :pool => @pool, + :pool_controller => "smart_pools", + :checkboxes => true, + :on_select => "smart_pools_select", + :on_deselect => false, + :on_hover => false, + :on_unhover => false} %> + </div> + <div class="selection_detail" id="smart_pools_selection"> + <div class="selection_left"> + <div>Select a pool above.</div> + </div> + </div> +<% else %> + <div class="data_section"> + <div class="no-grid-items"> + <%= image_tag 'no-grid-items.png', :style => 'float: left;' %> + + <div class="no-grid-items-text"> + No pools found in this pool. <br/><br/> + <%= image_tag "icon_addpool.png", :style=>"vertical-align:middle;" %> + <a href="<%= url_for :controller => 'pool', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]">Add first Pool to this smart pool</a> + </div> + </div> + </div> +<% end %> diff --git a/src/app/views/smart_pools/show_storage.rhtml b/src/app/views/smart_pools/show_storage.rhtml new file mode 100644 index 0000000..7cf425a --- /dev/null +++ b/src/app/views/smart_pools/show_storage.rhtml @@ -0,0 +1,72 @@ +<div id="toolbar_nav"> +<ul> + <li><a href="<%= url_for :controller => 'storage', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]"><%= image_tag "icon_addstorage.png", :style=>"vertical-align:middle;" %> Add Storage Pool</a></li> + <li><a href="#" onClick="remove_storage_from_smart_pool()"><%= image_tag "icon_remove.png" %> Remove</a></li> + </ul> +</div> + +<script type="text/javascript"> + function get_selected_storage_for_smart_pool() + { + return get_selected_checkboxes("smart_storage_grid_form"); + } + function remove_storage_from_smart_pool() + { + var storage = get_selected_storage_for_smart_pool(); + if (validate_selected(storage, "storage pool")) { + $.post('<%= url_for :controller => "smart_pools", :action => "remove_storage", :id => @pool %>', + { resource_ids: storage.toString() }, + function(data,status){ + $tabs.tabs("load",$tabs.data('selected.tabs')); + if (data.alert) { + $.jGrowl(data.alert); + } + if (storage.indexOf($('#smart_storage_selection_id').html()) != -1){ + empty_summary('smart_storage_selection', 'Storage Pool'); + } + }, 'json'); + } + } + function smart_storage_select(selected_rows) + { + var selected_ids = new Array() ; + for(i=0; i<selected_rows.length; i++) { + selected_ids[i] = selected_rows[i].id; + } + if (selected_ids.length == 1) + { + $('#smart_storage_selection').load('<%= url_for :controller => "storage", :action => "show" %>', + { id: parseInt(selected_ids[0].substring(3))}); + } + } + +</script> +<div class="panel_header"></div> +<% if @pool.tagged_storage_pools.size != 0 %> + <div class="data_section"> + <%= render :partial => "/storage/grid", :locals => { :table_id => "smart_storage_grid", + :hwpool => @pool, + :pool_controller => "smart_pools", + :exclude_pool => nil, + :on_select => "smart_storage_select", + :is_popup => false} %> + </div> + + <div class="selection_detail" id="smart_storage_selection"> + <div class="selection_left"> + <div>Select a storage pool.</div> + </div> + </div> +<% else %> + <div class="data_section"> + <div class="no-grid-items"> + <%= image_tag 'no-grid-items.png', :style => 'float: left;' %> + + <div class="no-grid-items-text"> + No storage Pools found in this pool. <br/><br/> + <%= image_tag "icon_addstorage.png", :style=>"vertical-align:middle;" %> + <a href="<%= url_for :controller => 'storage', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]">Add first storage volume to this smart pool</a> + </div> + </div> + </div> +<% end %> diff --git a/src/app/views/smart_pools/show_users.rhtml b/src/app/views/smart_pools/show_users.rhtml new file mode 100644 index 0000000..7d1efb8 --- /dev/null +++ b/src/app/views/smart_pools/show_users.rhtml @@ -0,0 +1,2 @@ + <%= render :partial => "/user/show", :locals => { :parent_controller => "smart_pools", + :pool => @pool } %> diff --git a/src/app/views/smart_pools/show_vms.rhtml b/src/app/views/smart_pools/show_vms.rhtml new file mode 100644 index 0000000..e56600b --- /dev/null +++ b/src/app/views/smart_pools/show_vms.rhtml @@ -0,0 +1,77 @@ +<div id="toolbar_nav"> + <ul> + <li><a href="<%= url_for :controller => 'vm', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]"><%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> Add Virtual Machine</a></li> + <li><a href="#" onClick="remove_vms_from_smart_pool()"><%= image_tag "icon_remove.png" %> Remove</a></li> + </ul> +</div> + +<script type="text/javascript"> + function get_selected_vms_for_smart_pool() + { + return get_selected_checkboxes("smart_vms_grid_form"); + } + function remove_vms_from_smart_pool() + { + var vms = get_selected_vms_for_smart_pool(); + if (validate_selected(vms, "vm")) { + $.post('<%= url_for :controller => "smart_pools", :action => "remove_vms", :id => @pool %>', + { resource_ids: vms.toString() }, + function(data,status){ + $tabs.tabs("load",$tabs.data('selected.tabs')); + if (data.alert) { + $.jGrowl(data.alert); + } + if (vms.indexOf($('#smart_vms_selection_id').html()) != -1){ + empty_summary('smart_vms_selection', 'Vm'); + } + + }, 'json'); + } + } + function smart_vms_select(selected_rows) + { + var selected_ids = new Array(); + for(i=0; i<selected_rows.length; i++) { + selected_ids[i] = selected_rows[i].id; + } + if (selected_ids.length == 1) + { + $('#smart_vms_selection').load('<%= url_for :controller => "vm", :action => "show", :id => nil %>/' + parseInt(selected_ids[0].substring(3))); + } + } +</script> + +<div class="panel_header"></div> +<% if @pool.tagged_vms.size != 0 %> + <div class="data_section"> + <%= render :partial => "/vm/grid", :locals => { :table_id => "smart_vms_grid", + :pool => @pool, + :pool_controller => "smart_pools", + :exclude_pool => nil, + :show_pool => true, + :checkboxes => true, + :on_select => "smart_vms_select", + :on_deselect => "load_widget_deselect", + :on_hover => "load_widget_hover", + :on_unhover => "load_widget_unhover", + :is_popup => false, + :vms_per_page => 40} %> + </div> + <div class="selection_detail" id="smart_vms_selection"> + <div class="selection_left"> + <div>Select a vm above.</div> + </div> + </div> +<% else %> + <div class="data_section"> + <div class="no-grid-items"> + <%= image_tag 'no-grid-items.png', :style => 'float: left;' %> + + <div class="no-grid-items-text"> + No vms found in this pool. <br/><br/> + <%= image_tag "icon_addvm.png", :style=>"vertical-align:middle;" %> + <a href="<%= url_for :controller => 'vm', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]">Add first VM to this smart pool</a> + </div> + </div> + </div> +<% end %> diff --git a/src/app/views/storage/_grid.rhtml b/src/app/views/storage/_grid.rhtml index c36f4d3..c8876bb 100644 --- a/src/app/views/storage/_grid.rhtml +++ b/src/app/views/storage/_grid.rhtml @@ -1,4 +1,12 @@ -<% storage_per_page = 40 %> +<% storage_per_page = 40 unless (defined? storage_per_page) and !(storage_per_page.nil?) %> +<% pool_controller = 'hardware' unless (defined? pool_controller) and !(pool_controller.nil?) %> +<% if (hwpool.nil? or + ((hwpool.is_a? HardwarePool) and (hwpool.storage_pools.size > storage_per_page)) or + ((hwpool.is_a? SmartPool) and (hwpool.tagged_storage_pools.size > storage_per_page))) + usepager = 'true' + else + usepager = 'false' + end %> <div id="<%= table_id %>_div"> <form id="<%= table_id %>_form"> @@ -9,7 +17,10 @@ $("#<%= table_id %>").flexigrid ( { - url: '<%= url_for :controller => "hardware", :action => "storage_pools_json", :id => (hwpool.nil? ? nil : hwpool.id), :exclude_pool => exclude_pool %>', + url: '<%= url_for :controller => pool_controller, + :action => "storage_pools_json", + :id => (hwpool.nil? ? nil : hwpool.id), + :exclude_pool => exclude_pool %>', dataType: 'json', <% if is_popup %> width: 700, @@ -23,8 +34,8 @@ ], sortname: "ip_addr", sortorder: "asc", - usepager: <%= (hwpool.nil? or hwpool.storage_pools.size > storage_per_page) ? 'true' : 'false' %>, - useRp: <%= (hwpool.nil? or hwpool.storage_pools.size > storage_per_page) ? 'true' : 'false' %>, + usepager: <%= usepager %>, + useRp: <%= usepager %>, rp: <%= storage_per_page %>, showTableToggleBtn: true, onSelect: <%= on_select %> diff --git a/src/app/views/storage/add_to_smart_pool.rhtml b/src/app/views/storage/add_to_smart_pool.rhtml new file mode 100644 index 0000000..2eedae3 --- /dev/null +++ b/src/app/views/storage/add_to_smart_pool.rhtml @@ -0,0 +1,22 @@ +<%- content_for :title do -%> + <%= _("Add Storage Pool to Smart Pool") %> +<%- end -%> +<%- content_for :description do -%> + Select storage pools from the list below to add to the <%= @pool.name %> smart pool.</a> +<%- end -%> +<div id="dialog-content-area"> +<div class="dialog_body_small"> +<div class="panel_header"></div> + <%= render :partial => "/storage/grid", :locals => { :table_id => "add_smart_storage_grid", + :hwpool => nil, + :pool_controller => "smart_pools", + :exclude_pool => @pool.id, + :on_select => false, + :is_popup => true} %> +</div> + +<%= popup_footer("add_storage_to_smart_pool('#{url_for :controller => "smart_pools", + :action => "add_storage", + :id => @pool}')", + "Add Storage Pools") %> +</div> diff --git a/src/app/views/user/_show.rhtml b/src/app/views/user/_show.rhtml index 916afe8..5b3ffb7 100644 --- a/src/app/views/user/_show.rhtml +++ b/src/app/views/user/_show.rhtml @@ -12,7 +12,7 @@ } function delete_users() { - permissions = get_selected_users(); + var permissions = get_selected_users(); if (validate_selected(permissions, "user")) { $.post('<%= url_for :controller => "permission", :action => "delete", :id => pool.id %>', { permission_ids: permissions.toString() }, @@ -26,7 +26,7 @@ } function update_users(role) { - permissions = get_selected_users() + var permissions = get_selected_users(); if (validate_selected(permissions, "users")) { $.post('<%= url_for :controller => "permission", :action => "update_roles" %>', { permission_ids: permissions.toString(), user_role: role }, diff --git a/src/app/views/vm/_grid.rhtml b/src/app/views/vm/_grid.rhtml index c56e6b8..a322ea3 100644 --- a/src/app/views/vm/_grid.rhtml +++ b/src/app/views/vm/_grid.rhtml @@ -1,42 +1,56 @@ <%= render :partial => 'graph/load_graph.rhtml' %> -<% vms_per_page = 10 %> +<% pool_controller = 'resources' unless (defined? pool_controller) and !(pool_controller.nil?) %> +<% vms_per_page = 40 unless (defined? vms_per_page) and !(vms_per_page.nil?) %> +<% if (pool.nil? or + ((pool.is_a? VmResourcePool) and (pool.vms.size > vms_per_page)) or + ((pool.is_a? SmartPool) and (pool.tagged_vms.size > vms_per_page))) + usepager = 'true' + else + usepager = 'false' + end %> <div id="<%= table_id %>_div"> <form id="<%= table_id %>_form"> <table id="<%= table_id %>" style="display:none"></table> </form> </div> <script type="text/javascript"> - $("#<%= table_id %>").flexigrid - ( - { - url: '<%= url_for :controller => "resources", :action => "vms_json", :id => pool.id %>', - dataType: 'json', - colModel : [ - {display: '', name : 'id', width : 20, sortable : false, align: 'left', process: <%= table_id %>checkbox}, - {display: 'Description', name : 'description', width : 180, sortable : true, align: 'left'}, - {display: 'UUID', name : 'uuid', width : 180, sortable : true, align: 'left'}, - {display: 'CPUs', name : 'num_vcpus_allocated', width : 40, sortable : true, align: 'left'}, - {display: 'Memory (MB)', name : 'memory_allocated', width : 60, sortable : true, align: 'right'}, - {display: 'vNIC Mac Addr', name : 'vnic_mac_addr', width : 60, sortable : true, align: 'right'}, - {display: 'State', name : 'state', width : 50, sortable : true, align: 'right'}, + $("#<%= table_id %>").flexigrid + ( + { + url: '<%= url_for :controller => pool_controller, + :action => "vms_json", + :id => (pool.nil? ? nil : pool.id), + :exclude_pool => exclude_pool %>', + dataType: 'json', + <% if is_popup %> + width: 700, + <% end %> + colModel : [ + {display: '', name : 'id', width : 20, sortable : false, align: 'left', process: <%= table_id %>checkbox}, + {display: 'Description', name : 'description', width : 180, sortable : true, align: 'left'}, + {display: 'UUID', name : 'uuid', width : 180, sortable : true, align: 'left'}, + {display: 'CPUs', name : 'num_vcpus_allocated', width : 40, sortable : true, align: 'left'}, + {display: 'Memory (MB)', name : 'memory_allocated', width : 60, sortable : true, align: 'right'}, + {display: 'vNIC Mac Addr', name : 'vnic_mac_addr', width : 60, sortable : true, align: 'right'}, + {display: 'State', name : 'state', width : 50, sortable : true, align: 'right'}, {display: 'Load', name : 'load', width: 180, sortable : false, align: 'left', process: <%= table_id %>_load_widget } - ], - sortname: "description", - sortorder: "asc", - usepager: <%= pool.vms.size > vms_per_page ? 'true' : 'false' %>, - useRp: <%= pool.vms.size > vms_per_page ? 'true' : 'false' %>, - rp: <%= vms_per_page %>, - showTableToggleBtn: true, - onSelect: <%= on_select %>, + ], + sortname: "description", + sortorder: "asc", + usepager: <%= usepager %>, + useRp: <%= usepager %>, + rp: <%= vms_per_page %>, + showTableToggleBtn: true, + onSelect: <%= on_select %>, onDeselect: <%= on_deselect %>, onHover: <%= on_hover %>, onUnhover: <%= on_unhover %> - } - ); - function <%= table_id %>checkbox(celDiv) - { - $(celDiv).html('<input type="checkbox" name="grid_checkbox'+$(celDiv).html()+'" class="grid_checkbox" value="'+$(celDiv).html()+'"/>'); - } + } + ); + function <%= table_id %>checkbox(celDiv) + { + $(celDiv).html('<input type="checkbox" name="grid_checkbox'+$(celDiv).html()+'" class="grid_checkbox" value="'+$(celDiv).html()+'"/>'); + } function <%= table_id %>_load_widget(celDiv) { load_widget(celDiv, "vm"); diff --git a/src/app/views/vm/add_to_smart_pool.rhtml b/src/app/views/vm/add_to_smart_pool.rhtml new file mode 100644 index 0000000..cdfe92d --- /dev/null +++ b/src/app/views/vm/add_to_smart_pool.rhtml @@ -0,0 +1,27 @@ +<%- content_for :title do -%> + <%= _("Add Vm to Smart Pool") %> +<%- end -%> +<%- content_for :description do -%> + Select vms from the list below to add to the <%= @pool.name %> smart pool.</a> +<%- end -%> +<div id="dialog-content-area"> +<div class="dialog_body_small"> +<div class="panel_header"></div> + <%= render :partial => "/vm/grid", :locals => { :table_id => "add_smart_vms_grid", + :pool => nil, + :pool_controller => "smart_pools", + :exclude_pool => @pool.id, + :checkboxes => true, + :on_select => false, + :on_deselect => false, + :on_hover => false, + :on_unhover => false, + :is_popup => true, + :vms_per_page => 40} %> +</div> + +<%= popup_footer("add_vms_to_smart_pool('#{url_for :controller => "smart_pools", + :action => "add_vms", + :id => @pool}')", + "Add Vms") %> +</div> diff --git a/src/db/migrate/017_add_smart_pools.rb b/src/db/migrate/017_add_smart_pools.rb index 6d83c02..5550a89 100644 --- a/src/db/migrate/017_add_smart_pools.rb +++ b/src/db/migrate/017_add_smart_pools.rb @@ -47,7 +47,7 @@ class AddSmartPools < ActiveRecord::Migration new_permission = Permission.new({:pool_id => dir_root.id, :uid => permission.uid, :user_role => permission.user_role}) - new_permission.save! + new_permission.save_with_new_children end end end diff --git a/src/public/javascripts/jquery-treeview/jquery.treeview.async.js b/src/public/javascripts/jquery-treeview/jquery.treeview.async.js index b10a130..4dacda6 100644 --- a/src/public/javascripts/jquery-treeview/jquery.treeview.async.js +++ b/src/public/javascripts/jquery-treeview/jquery.treeview.async.js @@ -43,7 +43,7 @@ function load(settings, params, child, container) { } else { span_onclick = "" } - if (settings.current_pool_id==this.id) { + if (settings.current_pool_id==this.id || !((settings.disabled_pools == undefined) || ($.inArray(this.id,settings.disabled_pools)==-1))) { current.html("<span class=\"" + settings.current_class + ">" + this.text + "</span>") .appendTo(parent); } else { diff --git a/src/public/javascripts/jquery.ovirt.treeview.js b/src/public/javascripts/jquery.ovirt.treeview.js index 16cf260..bb41667 100644 --- a/src/public/javascripts/jquery.ovirt.treeview.js +++ b/src/public/javascripts/jquery.ovirt.treeview.js @@ -21,10 +21,18 @@ function load(settings, params, child, container) { settings.link_to=settings.hardware_url settings.span_class="folder"; settings.current_class = settings.current + "_folder"; - } else { + } else if (this.type=="VmResourcePool") { settings.link_to=settings.resource_url; settings.span_class="file"; settings.current_class = settings.current + "_file"; + } else if (this.type=="SmartPool") { + settings.link_to=settings.smart_url; + settings.span_class="file"; + settings.current_class = settings.current + "_file"; + } else { + settings.link_to=""; + settings.span_class="file"; + settings.current_class = settings.current + "_file"; } var span_onclick; var current = $("<li/>").attr("id", this.id || ""); @@ -64,7 +72,7 @@ function load(settings, params, child, container) { } } $(container).find('li').remove(); - createNode.call(response, child); + $.each(response, createNode, [child]); $(container).ovirt_treeview({add: child}); for (var i = 0; i < selectedNodes.length; i++){ $('#test-tree li#' + selectedNodes[i] +' > div').click(); diff --git a/src/public/javascripts/ovirt.js b/src/public/javascripts/ovirt.js index af0b9f6..470a53a 100644 --- a/src/public/javascripts/ovirt.js +++ b/src/public/javascripts/ovirt.js @@ -42,7 +42,7 @@ function add_hosts(url) $.post(url, { resource_ids: hosts.toString() }, function(data,status){ - jQuery(document).trigger('close.facebox'); + $(document).trigger('close.facebox'); grid = $("#hosts_grid"); if (grid.size()>0 && grid != null) { grid.flexReload(); @@ -62,7 +62,7 @@ function add_storage(url) $.post(url, { resource_ids: storage.toString() }, function(data,status){; - jQuery(document).trigger('close.facebox'); + $(document).trigger('close.facebox'); grid = $("#storage_grid"); if (grid.size()>0 && grid != null) { grid.flexReload(); @@ -75,6 +75,66 @@ function add_storage(url) }, 'json'); } } +function add_hosts_to_smart_pool(url) +{ + hosts= get_selected_checkboxes("add_smart_hosts_grid_form"); + if (validate_selected(hosts, "host")) { + $.post(url, + { resource_ids: hosts.toString() }, + function(data,status){ + $(document).trigger('close.facebox'); + grid = $("#smart_hosts_grid"); + if (grid.size()>0 && grid != null) { + grid.flexReload(); + } else { + $tabs.tabs("load",$tabs.data('selected.tabs')); + } + if (data.alert) { + $.jGrowl(data.alert); + } + }, 'json'); + } +} +function add_storage_to_smart_pool(url) +{ + storage= get_selected_checkboxes("add_smart_storage_grid_form"); + if (validate_selected(storage, "storage pool")) { + $.post(url, + { resource_ids: storage.toString() }, + function(data,status){ + $(document).trigger('close.facebox'); + grid = $("#smart_storage_grid"); + if (grid.size()>0 && grid != null) { + grid.flexReload(); + } else { + $tabs.tabs("load",$tabs.data('selected.tabs')); + } + if (data.alert) { + $.jGrowl(data.alert); + } + }, 'json'); + } +} +function add_vms_to_smart_pool(url) +{ + vms= get_selected_checkboxes("add_smart_vms_grid_form"); + if (validate_selected(vms, "vm")) { + $.post(url, + { resource_ids: vms.toString() }, + function(data,status){ + $(document).trigger('close.facebox'); + grid = $("#smart_vms_grid"); + if (grid.size()>0 && grid != null) { + grid.flexReload(); + } else { + $tabs.tabs("load",$tabs.data('selected.tabs')); + } + if (data.alert) { + $.jGrowl(data.alert); + } + }, 'json'); + } +} // deal with ajax form response, filling in validation messages where required. function ajax_validation(response, status) { @@ -102,7 +162,7 @@ function ajax_validation(response, status) function afterHwPool(response, status){ ajax_validation(response, status); if (response.success) { - jQuery(document).trigger('close.facebox'); + $(document).trigger('close.facebox'); // FIXME do we need to reload the tree here // this is for reloading the host/storage grid when @@ -128,7 +188,7 @@ function afterHwPool(response, status){ function afterVmPool(response, status){ ajax_validation(response, status); if (response.success) { - jQuery(document).trigger('close.facebox'); + $(document).trigger('close.facebox'); grid = $("#vmpools_grid"); if (grid.size()>0 && grid != null) { grid.flexReload(); @@ -137,10 +197,16 @@ function afterVmPool(response, status){ } } } +function afterSmartPool(response, status){ + ajax_validation(response, status); + if (response.success) { + $(document).trigger('close.facebox'); + } +} function afterStoragePool(response, status){ ajax_validation(response, status); if (response.success) { - jQuery(document).trigger('close.facebox'); + $(document).trigger('close.facebox'); grid = $("#storage_grid"); if (grid.size()>0 && grid != null) { grid.flexReload(); @@ -152,7 +218,7 @@ function afterStoragePool(response, status){ function afterPermission(response, status){ ajax_validation(response, status); if (response.success) { - jQuery(document).trigger('close.facebox'); + $(document).trigger('close.facebox'); grid = $("#users_grid"); if (grid.size()>0 && grid!= null) { grid.flexReload(); @@ -164,7 +230,7 @@ function afterPermission(response, status){ function afterVm(response, status){ ajax_validation(response, status); if (response.success) { - jQuery(document).trigger('close.facebox'); + $(document).trigger('close.facebox'); grid = $("#vms_grid"); if (grid.size()>0 && grid != null) { grid.flexReload(); @@ -212,7 +278,23 @@ function delete_or_remove_storage() } else if (selected[0].value == "delete") { delete_storage(); } - jQuery(document).trigger('close.facebox'); + $(document).trigger('close.facebox'); +} +function delete_pool(delete_url, id) +{ + $(document).trigger('close.facebox'); + + if (delete_url==='') { + $.jGrowl("Invalid Pool Type"); + return; + } + $.post(delete_url, + {id: id}, + function(data,status){ + if (data.alert) { + $.jGrowl(data.alert); + } + }, 'json'); } -- 1.5.5.1
Jason Guiditta
2008-Sep-19 15:56 UTC
[Ovirt-devel] [PATCH] finished smart pools implementation. (revised)
This works for me, AYE(ACK for non-pirates). However, I noted some occasional weirdness with refresh from no grid to having a grid. If you go to a different tab after adding an item and then come back, it works fine. This is not a functional problem though, so it might just be some odd behaviour by my browser. If not, we can address as a bug. -j On Thu, 2008-09-18 at 17:06 -0400, Scott Seago wrote:> Nav now works for smart pools (but Jay's going to do some tweaking). All of the smart pool tabs work properly with add/remove functions, although summary is stubbed out. > search results are not yet integrated with smart pools. > > Signed-off-by: Scott Seago <sseago at redhat.com> > --- > src/app/controllers/application.rb | 13 +- > src/app/controllers/hardware_controller.rb | 122 +++-------- > src/app/controllers/host_controller.rb | 5 + > src/app/controllers/pool_controller.rb | 31 +++- > src/app/controllers/resources_controller.rb | 4 +- > src/app/controllers/smart_pool_controller.rb | 22 -- > src/app/controllers/smart_pools_controller.rb | 239 ++++++++++++++++++++ > src/app/controllers/storage_controller.rb | 5 + > src/app/controllers/tree_controller.rb | 14 +- > src/app/controllers/vm_controller.rb | 5 + > src/app/models/directory_pool.rb | 1 + > src/app/models/pool.rb | 42 +++- > src/app/models/smart_pool.rb | 23 ++ > src/app/views/hardware/_move_menu.rhtml | 17 -- > src/app/views/hardware/show_hosts.rhtml | 20 +- > src/app/views/hardware/show_storage.rhtml | 14 +- > src/app/views/hardware/show_vms.rhtml | 2 +- > src/app/views/host/_grid.rhtml | 14 +- > src/app/views/host/add_to_smart_pool.rhtml | 28 +++ > src/app/views/host/addhost.html.erb | 2 +- > src/app/views/layouts/_navigation_tabs.rhtml | 17 ++ > src/app/views/layouts/_side_toolbar.rhtml | 45 +++-- > src/app/views/layouts/_tree.rhtml | 6 +- > src/app/views/layouts/redux.rhtml | 26 -- > src/app/views/resources/show_vms.rhtml | 8 +- > src/app/views/smart_pools/_form.rhtml | 6 + > src/app/views/smart_pools/_pools_grid.rhtml | 39 ++++ > src/app/views/smart_pools/add_pool_dialog.rhtml | 52 +++++ > src/app/views/smart_pools/new.rhtml | 26 ++ > src/app/views/smart_pools/show.rhtml | 17 ++ > .../{hardware => smart_pools}/show_hosts.rhtml | 64 ++--- > src/app/views/smart_pools/show_pools.rhtml | 74 ++++++ > src/app/views/smart_pools/show_storage.rhtml | 72 ++++++ > src/app/views/smart_pools/show_users.rhtml | 2 + > src/app/views/smart_pools/show_vms.rhtml | 77 +++++++ > src/app/views/storage/_grid.rhtml | 19 ++- > src/app/views/storage/add_to_smart_pool.rhtml | 22 ++ > src/app/views/user/_show.rhtml | 4 +- > src/app/views/vm/_grid.rhtml | 70 ++++--- > src/app/views/vm/add_to_smart_pool.rhtml | 27 +++ > src/db/migrate/017_add_smart_pools.rb | 2 +- > .../jquery-treeview/jquery.treeview.async.js | 2 +- > src/public/javascripts/jquery.ovirt.treeview.js | 12 +- > src/public/javascripts/ovirt.js | 98 ++++++++- > 44 files changed, 1112 insertions(+), 298 deletions(-) > delete mode 100644 src/app/controllers/smart_pool_controller.rb > create mode 100644 src/app/controllers/smart_pools_controller.rb > delete mode 100644 src/app/views/hardware/_move_menu.rhtml > create mode 100644 src/app/views/host/add_to_smart_pool.rhtml > create mode 100644 src/app/views/smart_pools/_form.rhtml > create mode 100644 src/app/views/smart_pools/_pools_grid.rhtml > create mode 100644 src/app/views/smart_pools/add_pool_dialog.rhtml > create mode 100644 src/app/views/smart_pools/new.rhtml > create mode 100644 src/app/views/smart_pools/show.rhtml > copy src/app/views/{hardware => smart_pools}/show_hosts.rhtml (50%) > create mode 100644 src/app/views/smart_pools/show_pools.rhtml > create mode 100644 src/app/views/smart_pools/show_storage.rhtml > create mode 100644 src/app/views/smart_pools/show_users.rhtml > create mode 100644 src/app/views/smart_pools/show_vms.rhtml > create mode 100644 src/app/views/storage/add_to_smart_pool.rhtml > create mode 100644 src/app/views/vm/add_to_smart_pool.rhtml > > diff --git a/src/app/controllers/application.rb b/src/app/controllers/application.rb > index 3126748..6dcf6f8 100644 > --- a/src/app/controllers/application.rb > +++ b/src/app/controllers/application.rb > @@ -89,7 +89,7 @@ class ApplicationController < ActionController::Base > end > > # don't define find_opts for array inputs > - def json_hash(full_items, attributes, arg_list=[], find_opts={}) > + def json_hash(full_items, attributes, arg_list=[], find_opts={}, id_method=:id) > page = params[:page].to_i > paginate_opts = {:page => page, > :order => "#{params[:sortname]} #{params[:sortorder]}", > @@ -101,7 +101,7 @@ class ApplicationController < ActionController::Base > json_hash[:total] = item_list.total_entries > json_hash[:rows] = item_list.collect do |item| > item_hash = {} > - item_hash[:id] = item.id > + item_hash[:id] = item.send(id_method) > item_hash[:cell] = attributes.collect do |attr| > if attr.is_a? Array > value = item > @@ -115,9 +115,12 @@ class ApplicationController < ActionController::Base > end > json_hash > end > - # don't define find_opts for array inputs > - def json_list(full_items, attributes, arg_list=[], find_opts={}) > - render :json => json_hash(full_items, attributes, arg_list, find_opts).to_json > + > + # json_list is a helper method used to format data for paginated flexigrid tables > + # > + # FIXME: what is the intent of this comment? don't define find_opts for array inputs > + def json_list(full_items, attributes, arg_list=[], find_opts={}, id_method=:id) > + render :json => json_hash(full_items, attributes, arg_list, find_opts, id_method).to_json > end > > > diff --git a/src/app/controllers/hardware_controller.rb b/src/app/controllers/hardware_controller.rb > index a366e4c..42ff9cb 100644 > --- a/src/app/controllers/hardware_controller.rb > +++ b/src/app/controllers/hardware_controller.rb > @@ -1,4 +1,4 @@ > -# > +# > # Copyright (C) 2008 Red Hat, Inc. > # Written by Scott Seago <sseago at redhat.com> > # > @@ -20,10 +20,6 @@ > > class HardwareController < PoolController > > - XML_OPTS = { > - :include => [ :storage_pools, :hosts, :quota ] > - } > - > EQ_ATTRIBUTES = [ :name, :parent_id ] > > verify :method => [:post, :put], :only => [ :create, :update ], > @@ -59,12 +55,12 @@ class HardwareController < PoolController > end > > def json_view_tree > - json_tree_internal(Permission::PRIV_VIEW, false) > + json_tree_internal(Permission::PRIV_VIEW, :select_hardware_and_vm_pools) > end > def json_move_tree > - json_tree_internal(Permission::PRIV_MODIFY, true) > + json_tree_internal(Permission::PRIV_MODIFY, :select_hardware_pools) > end > - def json_tree_internal(privilege, filter_vm_pools) > + def json_tree_internal(privilege, filter_method) > id = params[:id] > if id > @pool = Pool.find(id) > @@ -77,11 +73,9 @@ class HardwareController < PoolController > end > if @pool > pools = @pool.children > - pools = Pool.select_hardware_pools(pools) if filter_vm_pools > open_list = [] > else > pools = Pool.list_for_user(get_login_user,Permission::PRIV_VIEW) > - pools = Pool.select_hardware_pools(pools) if filter_vm_pools > current_id = params[:current_id] > if current_id > current_pool = Pool.find(current_id) > @@ -90,26 +84,26 @@ class HardwareController < PoolController > open_list = [] > end > end > + pools = Pool.send(filter_method, pools) > > - render :json => Pool.nav_json(pools, open_list, filter_vm_pools) > + render :json => Pool.nav_json(pools, open_list, > + (filter_method==:select_hardware_pools)) > end > > def show_vms > show > end > > - def show_hosts > - @hardware_pools = HardwarePool.find :all > + def show_hosts > show > end > - > + > def show_graphs > show > end > > def show_storage > show > - @hardware_pools = HardwarePool.find :all > end > > def show_tasks > @@ -142,21 +136,16 @@ class HardwareController < PoolController > # filtering on which pool to exclude > id = params[:exclude_pool] > hosts = Host > - find_opts = {:include => :hardware_pool, > + find_opts = {:include => :hardware_pool, > :conditions => ["pools.id != ?", id]} > include_pool = true > end > - attr_list = [] > - attr_list << :id if params[:checkboxes] > - attr_list << :hostname > - attr_list << [:hardware_pool, :name] if include_pool > - attr_list += [:uuid, :hypervisor_type, :num_cpus, :cpu_speed, :arch, :memory_in_mb, :status_str, :load_average] > - json_list(hosts, attr_list, [:all], find_opts) > + super(:full_items => hosts,:include_pool => include_pool,:find_opts => find_opts) > end > > def vm_pools_json > - json_list(Pool, > - [:id, :name, :id], > + json_list(Pool, > + [:id, :name, :id], > [@pool, :children], > {:finder => 'call_finder', :conditions => ["type = 'VmResourcePool'"]}) > end > @@ -172,24 +161,22 @@ class HardwareController < PoolController > # filtering on which pool to exclude > id = params[:exclude_pool] > storage_pools = StoragePool > - find_opts = {:include => :hardware_pool, > + find_opts = {:include => :hardware_pool, > :conditions => ["pools.id != ?", id]} > include_pool = true > end > - attr_list = [:id, :display_name, :ip_addr, :get_type_label] > - attr_list.insert(2, [:hardware_pool, :name]) if include_pool > - json_list(storage_pools, attr_list, [:all], find_opts) > + super(:full_items => storage_pools,:include_pool => include_pool,:find_opts => find_opts) > end > > def storage_volumes_json > - json_list(@pool.all_storage_volumes, > + json_list(@pool.all_storage_volumes, > [:display_name, :size_in_gb, :get_type_label]) > end > > def move > pre_modify > @resource_type = params[:resource_type] > - render :layout => 'popup' > + render :layout => 'popup' > end > > def new > @@ -279,87 +266,44 @@ class HardwareController < PoolController > end > end > > - #FIXME: we need permissions checks. user must have permission on src pool > - # in addition to the current pool (which is checked). We also need to fail > - # for hosts that aren't currently empty > def add_hosts > - host_ids_str = params[:resource_ids] > - host_ids = host_ids_str.split(",").collect {|x| x.to_i} > - > - begin > - @pool.transaction do > - @pool.move_hosts(host_ids, @pool.id) > - end > - render :json => { :object => "host", :success => true, > - :alert => "Hosts were successfully added to this Hardware pool." } > - rescue > - render :json => { :object => "host", :success => false, > - :alert => "Error adding Hosts to this Hardware pool." } > - end > + edit_items(Host, :move_hosts, @pool.id, :add) > end > > - #FIXME: we need permissions checks. user must have permission on src pool > - # in addition to the current pool (which is checked). We also need to fail > - # for hosts that aren't currently empty > def move_hosts > - target_pool_id = params[:target_pool_id] > - host_ids_str = params[:resource_ids] > - host_ids = host_ids_str.split(",").collect {|x| x.to_i} > - > - begin > - @pool.transaction do > - @pool.move_hosts(host_ids, target_pool_id) > - end > - render :json => { :object => "host", :success => true, > - :alert => "Hosts were successfully moved." } > - rescue > - render :json => { :object => "host", :success => false, > - :alert => "Error moving hosts." } > - end > + edit_items(Host, :move_hosts, params[:target_pool_id], :move) > end > > - #FIXME: we need permissions checks. user must have permission on src pool > - # in addition to the current pool (which is checked). We also need to fail > - # for storage that aren't currently empty > def add_storage > - storage_pool_ids_str = params[:resource_ids] > - storage_pool_ids = storage_pool_ids_str.split(",").collect {|x| x.to_i} > - > - begin > - @pool.transaction do > - @pool.move_storage(storage_pool_ids, @pool.id) > - end > - render :json => { :object => "storage_pool", :success => true, > - :alert => "Storage Pools were successfully added to this Hardware pool." } > - rescue > - render :json => { :object => "storage_pool", :success => false, > - :alert => "Error adding storage pools to this Hardware pool." } > - end > + edit_items(StoragePool, :move_storage, @pool.id, :add) > + end > + > + def move_storage > + edit_items(StoragePool, :move_storage, params[:target_pool_id], :move) > end > > #FIXME: we need permissions checks. user must have permission on src pool > # in addition to the current pool (which is checked). We also need to fail > # for storage that aren't currently empty > - def move_storage > - target_pool_id = params[:target_pool_id] > - storage_pool_ids_str = params[:resource_ids] > - storage_pool_ids = storage_pool_ids_str.split(",").collect {|x| x.to_i} > + def edit_items(item_class, item_method, target_pool_id, item_action) > + resource_ids_str = params[:resource_ids] > + resource_ids = resource_ids_str.split(",").collect {|x| x.to_i} > > begin > @pool.transaction do > - @pool.move_storage(storage_pool_ids, target_pool_id) > + @pool.send(item_method, resource_ids, target_pool_id) > end > - render :json => { :object => "storage_pool", :success => true, > - :alert => "Storage Pools were successfully moved." } > + render :json => { :success => true, > + :alert => "#{item_action.to_s} #{item_class.table_name.humanize} successful." } > rescue > - render :json => { :object => "storage_pool", :success => false, > - :alert => "Error moving storage pools." } > + render :json => { :success => false, > + :alert => "#{item_action.to_s} #{item_class.table_name.humanize} failed." } > end > end > > def removestorage > pre_modify > - render :layout => 'popup' > + render :layout => 'popup' > end > > def destroy > diff --git a/src/app/controllers/host_controller.rb b/src/app/controllers/host_controller.rb > index 5174c88..417d11f 100644 > --- a/src/app/controllers/host_controller.rb > +++ b/src/app/controllers/host_controller.rb > @@ -84,6 +84,11 @@ class HostController < ApplicationController > render :layout => 'popup' > end > > + def add_to_smart_pool > + @pool = SmartPool.find(params[:smart_pool_id]) > + render :layout => 'popup' > + end > + > def new > end > > diff --git a/src/app/controllers/pool_controller.rb b/src/app/controllers/pool_controller.rb > index ce41701..02ef290 100644 > --- a/src/app/controllers/pool_controller.rb > +++ b/src/app/controllers/pool_controller.rb > @@ -23,9 +23,14 @@ class PoolController < ApplicationController > before_filter :pre_show_pool, :only => [:show_vms, :show_users, > :show_hosts, :show_storage, > :users_json, :show_tasks, :tasks, > - :vms_json, :vm_pools_json, > + :vm_pools_json, > + :pools_json, :show_pools, > :storage_volumes_json, :quick_summary] > > + XML_OPTS = { > + :include => [ :storage_pools, :hosts, :quota ] > + } > + > def show > respond_to do |format| > format.html { > @@ -86,6 +91,28 @@ class PoolController < ApplicationController > json_hash(@pool.tasks, attr_list, [:all], find_opts) > end > > + def hosts_json(args) > + attr_list = [] > + attr_list << :id if params[:checkboxes] > + attr_list << :hostname > + attr_list << [:hardware_pool, :name] if args[:include_pool] > + attr_list += [:uuid, :hypervisor_type, :num_cpus, :cpu_speed, :arch, :memory_in_mb, :status_str, :load_average] > + json_list(args[:full_items], attr_list, [:all], args[:find_opts]) > + end > + > + def storage_pools_json(args) > + attr_list = [:id, :display_name, :ip_addr, :get_type_label] > + attr_list.insert(2, [:hardware_pool, :name]) if args[:include_pool] > + json_list(args[:full_items], attr_list, [:all], args[:find_opts]) > + end > + > + def vms_json(args) > + attr_list = [:id, :description, :uuid, > + :num_vcpus_allocated, :memory_allocated_in_mb, > + :vnic_mac_addr, :state, :id] > + json_list(args[:full_items], attr_list, [:all], args[:find_opts]) > + end > + > def new > render :layout => 'popup' > end > @@ -120,7 +147,7 @@ class PoolController < ApplicationController > @current_pool_id=@pool.id > set_perms(@perm_obj) > unless @can_view > - flash[:notice] = 'You do not have permission to view this pool pool: redirecting to top level' > + flash[:notice] = 'You do not have permission to view this pool: redirecting to top level' > respond_to do |format| > format.html { redirect_to :controller => "dashboard" } > format.xml { head :forbidden } > diff --git a/src/app/controllers/resources_controller.rb b/src/app/controllers/resources_controller.rb > index a0a65a6..2c54ccc 100644 > --- a/src/app/controllers/resources_controller.rb > +++ b/src/app/controllers/resources_controller.rb > @@ -68,8 +68,8 @@ class ResourcesController < PoolController > end > > def vms_json > - json_list(@pool.vms, > - [:id, :description, :uuid, :num_vcpus_allocated, :memory_allocated_in_mb, :vnic_mac_addr, :state, :id]) > + pre_show > + super(:full_items => @pool.vms, :find_opts => {}, :include_pool => :true) > end > > def create > diff --git a/src/app/controllers/smart_pool_controller.rb b/src/app/controllers/smart_pool_controller.rb > deleted file mode 100644 > index eb087a6..0000000 > --- a/src/app/controllers/smart_pool_controller.rb > +++ /dev/null > @@ -1,22 +0,0 @@ > -# > -# 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 SmartPoolController < ApplicationController > -end > diff --git a/src/app/controllers/smart_pools_controller.rb b/src/app/controllers/smart_pools_controller.rb > new file mode 100644 > index 0000000..99ae8b8 > --- /dev/null > +++ b/src/app/controllers/smart_pools_controller.rb > @@ -0,0 +1,239 @@ > +# > +# 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 SmartPoolsController < PoolController > + > + before_filter :pre_modify, :only => [:add_hosts, :remove_hosts, > + :add_storage, :remove_storage, > + :add_vms, :remove_vms, > + :add_pools, :remove_pools] > + def show_vms > + show > + end > + > + def show_hosts > + show > + end > + > + def show_pools > + show > + end > + > + def show_storage > + show > + end > + > + def create > + begin > + @pool.create_with_parent(@parent) > + render :json => { :object => "smart_pool", :success => true, > + :alert => "Smart Pool was successfully created." } > + rescue > + render :json => { :object => "smart_pool", :success => false, > + :errors => @pool.errors.localize_error_messages.to_a} > + end > + end > + > + def update > + begin > + @pool.update_attributes!(params[:smart_pool]) > + render :json => { :object => "smart_pool", :success => true, > + :alert => "Smart Pool was successfully modified." } > + rescue > + render :json => { :object => "smart_pool", :success => false, > + :errors => @pool.errors.localize_error_messages.to_a} > + end > + end > + > + def add_pool_dialog > + pre_modify > + @selected_pools = @pool.tagged_pools.collect {|pool| pool.id} > + render :layout => 'popup' > + end > + > + def hosts_json > + super(items_json_internal(Host, :tagged_hosts)) > + end > + > + def storage_pools_json > + super(items_json_internal(StoragePool, :tagged_storage_pools)) > + end > + > + def vms_json > + super(items_json_internal(Vm, :tagged_vms)) > + end > + > + def pools_json > + args = items_json_internal(Pool, :tagged_pools) > + attr_list = [:id, :name, :get_type_label] > + json_list(args[:full_items], attr_list, [:all], args[:find_opts], :class_and_id) > + > + end > + > + def items_json_internal(item_class, item_assoc) > + if params[:id] > + pre_show > + full_items = @pool.send(item_assoc) > + find_opts = {} > + else > + # FIXME: no permissions or usage checks here yet > + # filtering on which pool to exclude > + id = params[:exclude_pool] > + full_items = item_class > + pool_items = SmartPool.find(id, > + :include => item_assoc).send(item_assoc).collect {|x| x.id} > + if pool_items.empty? > + conditions = [] > + else > + conditions = ["#{item_class.table_name}.id not in (?)", pool_items] > + end > + find_opts = {:conditions => conditions} > + end > + { :full_items => full_items, :find_opts => find_opts, :include_pool => :true} > + end > + > + def add_hosts > + edit_items(Host, :add_items, :add) > + end > + > + def remove_hosts > + edit_items(Host, :remove_items, :remove) > + end > + > + def add_storage > + edit_items(StoragePool, :add_items, :add) > + end > + > + def remove_storage > + edit_items(StoragePool, :remove_items, :remove) > + end > + > + def add_vms > + edit_items(Vm, :add_items, :add) > + end > + > + def remove_vms > + edit_items(Vm, :remove_items, :remove) > + end > + > + def add_pools > + edit_items(Pool, :add_items, :add) > + end > + > + def remove_pools > + edit_items(Pool, :remove_items, :remove) > + end > + > + def edit_items(item_class, item_method, item_action) > + resource_ids_str = params[:resource_ids] > + resource_ids = resource_ids_str.split(",").collect {|x| x.to_i} > + begin > + @pool.send(item_method,item_class, resource_ids) > + render :json => { :success => true, > + :alert => "#{item_action.to_s} #{item_class.table_name.humanize} successful." } > + rescue > + render :json => { :success => false, > + :alert => "#{item_action.to_s} #{item_class.table_name.humanize} failed." } > + end > + end > + > + def destroy > + if @pool.destroy > + alert="Smart Pool was successfully deleted." > + success=true > + else > + alert="Failed to delete Smart pool." > + success=false > + end > + render :json => { :object => "smart_pool", :success => success, :alert => alert } > + end > + > + # handled > + # show_hosts > + # show_graphs > + # show_storage > + # show > + # show_vms > + # show_tasks > + # new xxx > + # create xxx > + # hosts_json > + # storage_pools_json > + # add_hosts > + # move_hosts > + # add_storage > + # move_storage > + # removestorage > + > + #HW only > + # json_view_tree > + # json_move_tree > + # vm_pools_json > + # move > + #VM only > + # vms_json > + # delete > + # vm_actions > + #both > + # move > + # update > + # destroy > + > + #inherited > + # used > + # new > + # edit > + # show_users > + # users_json > + # unneeded > + # tasks > + # show_tasks > + # quick_summary > + > + protected > + #filter methods > + def pre_new > + @pool = SmartPool.new > + @parent = DirectoryPool.get_or_create_user_root(get_login_user) > + @perm_obj = @parent > + @current_pool_id=@parent.id > + end > + def pre_create > + @pool = SmartPool.new(params[:smart_pool]) > + @parent = DirectoryPool.get_or_create_user_root(get_login_user) > + @perm_obj = @parent > + @current_pool_id=@parent.id > + end > + def pre_edit > + @pool = SmartPool.find(params[:id]) > + @parent = @pool.parent > + @perm_obj = @pool > + @current_pool_id=@pool.id > + end > + def pre_show > + @pool = SmartPool.find(params[:id]) > + super > + end > + def pre_modify > + pre_edit > + authorize_admin > + end > + > +end > diff --git a/src/app/controllers/storage_controller.rb b/src/app/controllers/storage_controller.rb > index 7e97764..7eec618 100644 > --- a/src/app/controllers/storage_controller.rb > +++ b/src/app/controllers/storage_controller.rb > @@ -199,6 +199,11 @@ class StorageController < ApplicationController > render :layout => false > end > > + def add_to_smart_pool > + @pool = SmartPool.find(params[:smart_pool_id]) > + render :layout => 'popup' > + end > + > #FIXME: we need permissions checks. user must have permission on src pool > # in addition to the current pool (which is checked). We also need to fail > # for storage that aren't currently empty > diff --git a/src/app/controllers/tree_controller.rb b/src/app/controllers/tree_controller.rb > index 5ad8426..1aed544 100644 > --- a/src/app/controllers/tree_controller.rb > +++ b/src/app/controllers/tree_controller.rb > @@ -1,10 +1,18 @@ > class TreeController < ApplicationController > - > + > + def get_pools > + # TODO: split these into separate hash elements for HW and smart pools > + pools = HardwarePool.get_default_pool.full_set_nested(:method => :json_hash_element, > + :privilege => Permission::PRIV_VIEW, :user => get_login_user) > + pools += DirectoryPool.get_smart_root.full_set_nested(:method => :json_hash_element, > + :privilege => Permission::PRIV_VIEW, :user => get_login_user, > + :smart_pool_set => true) > + end > def fetch_nav > - @pools = HardwarePool.get_default_pool.full_set_nested(:method => :json_hash_element) > + @pools = get_pools > end > > def fetch_json > - render :json => HardwarePool.get_default_pool.full_set_nested(:method => :json_hash_element).to_json > + render :json => get_pools.to_json > end > end > diff --git a/src/app/controllers/vm_controller.rb b/src/app/controllers/vm_controller.rb > index d3f16b6..6d06b48 100644 > --- a/src/app/controllers/vm_controller.rb > +++ b/src/app/controllers/vm_controller.rb > @@ -35,6 +35,11 @@ class VmController < ApplicationController > render :layout => 'selection' > end > > + def add_to_smart_pool > + @pool = SmartPool.find(params[:smart_pool_id]) > + render :layout => 'popup' > + end > + > def new > render :layout => 'popup' > end > diff --git a/src/app/models/directory_pool.rb b/src/app/models/directory_pool.rb > index f62d980..82486af 100644 > --- a/src/app/models/directory_pool.rb > +++ b/src/app/models/directory_pool.rb > @@ -55,6 +55,7 @@ class DirectoryPool < Pool > permission.save! > end > end > + user_root > end > > end > diff --git a/src/app/models/pool.rb b/src/app/models/pool.rb > index 9d71fa5..eb71be8 100644 > --- a/src/app/models/pool.rb > +++ b/src/app/models/pool.rb > @@ -111,6 +111,9 @@ class Pool < ActiveRecord::Base > def self.select_vm_pools(pools) > pools.select {|pool| pool[:type] == "VmResourcePool"} > end > + def self.select_hardware_and_vm_pools(pools) > + pools.select {|pool| ["HardwarePool", "VmResourcePool"].include?(pool[:type])} > + end > > def sub_hardware_pools > children({:conditions => "type='HardwarePool'"}) > @@ -225,22 +228,44 @@ class Pool < ActiveRecord::Base > # or :current_id to specify which pool gets ":selected => true" set > def full_set_nested(opts={}) > method = opts.delete(:method) {:hash_element} > + privilege = opts.delete(:privilege) > + user = opts.delete(:user) > + smart_pool_set = opts.delete(:smart_pool_set) > + if privilege and user > + opts[:include] = "permissions" > + opts[:conditions] = "permissions.uid='#{user}' and > + permissions.user_role in > + ('#{Permission.roles_for_privilege(privilege).join("', '")}')" > + end > current_id = opts.delete(:current_id) > opts.delete(:order) > subtree_list = full_set(opts) > - return_tree = send(method) > - ref_hash = { id => return_tree} > + subtree_list -= [self] if smart_pool_set > + return_tree_list = [] > + ref_hash = {} > subtree_list.each do |pool| > - unless pool.id==return_tree[:id] > - new_element = pool.send(method) > - ref_hash[pool.id] = new_element > - parent = ref_hash[pool.parent_id] > + new_element = pool.send(method) > + ref_hash[pool.id] = new_element > + parent = ref_hash[pool.parent_id] > + if parent > parent[:children] ||= [] > parent[:children] << new_element > + else > + # for smart pools include the parent DirectoryPool > + if smart_pool_set and pool[:type]=="SmartPool" > + pool_parent = pool.parent > + parent_element = pool_parent.send(method) > + ref_hash[pool_parent.id] = parent_element > + return_tree_list << parent_element > + parent_element[:children] ||= [] > + parent_element[:children] << new_element > + else > + return_tree_list << new_element > + end > end > end > ref_hash[current_id][:selected] = true if current_id > - return_tree > + return_tree_list > end > > def self.call_finder(*args) > @@ -273,6 +298,9 @@ class Pool < ActiveRecord::Base > end > end > > + def class_and_id > + self.class.name + "_" + self.id.to_s > + end > protected > def traverse_parents > if id > diff --git a/src/app/models/smart_pool.rb b/src/app/models/smart_pool.rb > index e672c5b..9104ee5 100644 > --- a/src/app/models/smart_pool.rb > +++ b/src/app/models/smart_pool.rb > @@ -30,6 +30,10 @@ class SmartPool < Pool > :conditions => "smart_pool_tags.tagged_type = 'Vm'" > > > + def get_type_label > + "Smart Pool" > + end > + > def create_for_user(user) > create_with_parent(DirectoryPool.get_or_create_user_root(user)) > end > @@ -44,4 +48,23 @@ class SmartPool < Pool > :tagged_id=>item.id}).destroy > end > > + def add_items(item_class, item_ids) > + items = item_class.find(:all, :conditions => "id in (#{item_ids.join(', ')})") > + transaction do > + items.each { |item| add_item(item)} > + end > + end > + > + def remove_items(item_class, item_ids) > + tags = smart_pool_tags.find(:all, > + :conditions => "tagged_id in > + (#{item_ids.join(', ')}) > + and tagged_type='#{item_class.name}'") > + transaction do > + tags.each do |tag| > + tag.destroy > + end > + end > + end > + > end > diff --git a/src/app/views/hardware/_move_menu.rhtml b/src/app/views/hardware/_move_menu.rhtml > deleted file mode 100644 > index cc7ed73..0000000 > --- a/src/app/views/hardware/_move_menu.rhtml > +++ /dev/null > @@ -1,17 +0,0 @@ > -<%= image_tag "icon_move.png", :style => "vertical-align:middle;" %> Move <%= image_tag "icon_toolbar_arrow.gif", :style => "vertical-align:middle;" %> > -<ul> > - <% @hardware_pools.each { |hw_pool| %> > - <% if @pool.parent_id != hw_pool.id and @pool.id != hw_pool.id %> > - <li onclick="window.location='<%= url_for :controller => :hardware, :action => 'foobar' %>'"> <!-- FIXME point me at the right place --> > - <% else %> > - <li style="color: #CCCCCC; cursor: default;"> > - <% end %> > - <%= image_tag "icon_hdwarepool.png" %> > - <%= hw_pool.name %></a> > - </li> > - <% } %> > - > - <li style="border-top: 1px solid black; border-bottom: 1px solid black;"> > - Move to New Resource Group... > - </li> > -</ul> > diff --git a/src/app/views/hardware/show_hosts.rhtml b/src/app/views/hardware/show_hosts.rhtml > index 31c575d..d33c920 100644 > --- a/src/app/views/hardware/show_hosts.rhtml > +++ b/src/app/views/hardware/show_hosts.rhtml > @@ -14,17 +14,17 @@ > <script type="text/javascript"> > function get_selected_hosts() > { > - return get_selected_checkboxes("hosts_grid_form") > + return get_selected_checkboxes("hosts_grid_form"); > } > function validate_for_move() > { > if (validate_selected(get_selected_hosts(), 'host')) { > - $('#move_link_hidden').click() > + $('#move_link_hidden').click(); > } > } > function remove_hosts() > { > - hosts = get_selected_hosts() > + var hosts = get_selected_hosts(); > if (validate_selected(hosts, "host")) { > $.post('<%= url_for :controller => "hardware", :action => "move_hosts", :id => @pool %>', > { resource_ids: hosts.toString(), target_pool_id: <%= HardwarePool.get_default_pool.id %> }, > @@ -34,22 +34,22 @@ > $.jGrowl(data.alert); > } > if (hosts.indexOf($('#hosts_selection_id').html()) != -1){ > - empty_summary('hosts_selection', 'Host') > - } > + empty_summary('hosts_selection', 'Host'); > + } > > }, 'json'); > } > } > function hosts_select(selected_rows) > { > - var selected_ids = new Array() > - for(i=0; i<selected_rows.length; i++) { > + var selected_ids = new Array(); > + for(i=0; i<selected_rows.length; i++) { > load_widget_select(selected_rows[i]); > selected_ids[i] = selected_rows[i].id; > } > if (selected_ids.length == 1) > { > - $('#hosts_selection').load('<%= url_for :controller => "host", :action => "show", :id => nil %>/' + parseInt(selected_ids[0].substring(3))) > + $('#hosts_selection').load('<%= url_for :controller => "host", :action => "show", :id => nil %>/' + parseInt(selected_ids[0].substring(3))); > } > } > </script> > @@ -63,7 +63,7 @@ > :exclude_host => nil, > :show_pool => false, > :checkboxes => true, > - :on_select => "hosts_select", > + :on_select => "hosts_select", > :on_deselect => "load_widget_deselect", > :on_hover => "load_widget_hover", > :on_unhover => "load_widget_unhover", > @@ -79,7 +79,7 @@ > <div class="data_section"> > <div class="no-grid-items"> > <%= image_tag 'no-grid-items.png', :style => 'float: left;' %> > - > + > <div class="no-grid-items-text"> > No hosts found in this pool. <br/><br/> > <%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> > diff --git a/src/app/views/hardware/show_storage.rhtml b/src/app/views/hardware/show_storage.rhtml > index 564b9ed..6466f9b 100644 > --- a/src/app/views/hardware/show_storage.rhtml > +++ b/src/app/views/hardware/show_storage.rhtml > @@ -15,7 +15,7 @@ > <script type="text/javascript"> > function remove_storage() > { > - storage = get_selected_storage() > + var storage = get_selected_storage(); > if (validate_selected(storage, "storage pool")) { > $.post('<%= url_for :controller => "hardware", :action => "move_storage", :id => @pool %>', > { resource_ids: storage.toString(), target_pool_id: <%= HardwarePool.get_default_pool.id %> }, > @@ -25,14 +25,14 @@ > $.jGrowl(data.alert); > } > if (storage.indexOf($('#storage_selection_id').html()) != -1){ > - empty_summary('storage_selection', 'Storage Pool') > + empty_summary('storage_selection', 'Storage Pool'); > } > }, 'json'); > } > } > function delete_storage() > { > - storage = get_selected_storage() > + var storage = get_selected_storage(); > if (validate_selected(storage, "storage pool")) { > $.post('<%= url_for :controller => "storage", :action => "delete_pools", :id => @pool %>', > { storage_pool_ids: storage.toString() }, > @@ -42,15 +42,15 @@ > $.jGrowl(data.alert); > } > if (storage.indexOf($('#storage_selection_id').html()) != -1){ > - empty_summary('storage_selection', 'Storage Pool') > + empty_summary('storage_selection', 'Storage Pool'); > } > }, 'json'); > } > } > function storage_select(selected_rows) > { > - var selected_ids = new Array() ; > - for(i=0; i<selected_rows.length; i++) { > + var selected_ids = new Array(); > + for(i=0; i<selected_rows.length; i++) { > selected_ids[i] = selected_rows[i].id; > } > if (selected_ids.length == 1) > @@ -80,7 +80,7 @@ > <div class="data_section"> > <div class="no-grid-items"> > <%= image_tag 'no-grid-items.png', :style => 'float: left;' %> > - > + > <div class="no-grid-items-text"> > No storage Volumes found in this pool. <br/><br/> > <%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> > diff --git a/src/app/views/hardware/show_vms.rhtml b/src/app/views/hardware/show_vms.rhtml > index 5ff5cc9..ee14758 100644 > --- a/src/app/views/hardware/show_vms.rhtml > +++ b/src/app/views/hardware/show_vms.rhtml > @@ -11,7 +11,7 @@ > } > function delete_vm_pools() > { > - vm_pools = get_selected_vm_pools() > + var vm_pools = get_selected_vm_pools(); > if (validate_selected(vm_pools, "vm_pool")) { > $.post('<%= url_for :controller => "resources", :action => "delete", :id => @pool %>', > { vm_pool_ids: vm_pools.toString() }, > diff --git a/src/app/views/host/_grid.rhtml b/src/app/views/host/_grid.rhtml > index 553adf9..21b563e 100644 > --- a/src/app/views/host/_grid.rhtml > +++ b/src/app/views/host/_grid.rhtml > @@ -1,6 +1,14 @@ > <%= render :partial => 'graph/load_graph.rhtml' %> > +<% pool_controller = 'hardware' unless (defined? pool_controller) and !(pool_controller.nil?) %> > > <% hosts_per_page.nil? ? hosts_per_page = 40: hosts_per_page = hosts_per_page %> > +<% if (hwpool.nil? or > + ((hwpool.is_a? HardwarePool) and (hwpool.hosts.size > hosts_per_page)) or > + ((hwpool.is_a? SmartPool) and (hwpool.tagged_hosts.size > hosts_per_page))) > + usepager = 'true' > + else > + usepager = 'false' > + end %> > <div id="<%= table_id %>_div"> > <%= "<form id=\"#{table_id}_form\">" if checkboxes %> > <table id="<%= table_id %>" style="display:none"></table> > @@ -10,7 +18,7 @@ > $("#<%= table_id %>").flexigrid > ( > { > - url: '<%= url_for :controller => "hardware", > + url: '<%= url_for :controller => pool_controller, > :action => "hosts_json", > :escape => false, > :id => (hwpool.nil? ? nil : hwpool.id), > @@ -38,8 +46,8 @@ > ], > sortname: "hostname", > sortorder: "asc", > - usepager: <%= (hwpool.nil? or hwpool.hosts.size > hosts_per_page) ? 'true' : 'false' %>, > - useRp: <%= (hwpool.nil? or hwpool.hosts.size > hosts_per_page) ? 'true' : 'false' %>, > + usepager: <%= usepager %>, > + useRp: <%= usepager %>, > rp: <%= hosts_per_page %>, > showTableToggleBtn: true, > onSelect: <%= on_select %>, > diff --git a/src/app/views/host/add_to_smart_pool.rhtml b/src/app/views/host/add_to_smart_pool.rhtml > new file mode 100644 > index 0000000..a89f8de > --- /dev/null > +++ b/src/app/views/host/add_to_smart_pool.rhtml > @@ -0,0 +1,28 @@ > +<%- content_for :title do -%> > + <%= _("Add Host to Smart Pool") %> > +<%- end -%> > +<%- content_for :description do -%> > + Select hosts from the list below to add to the <%= @pool.name %> smart pool.</a> > +<%- end -%> > +<div id="dialog-content-area"> > +<div class="dialog_body_small"> > +<div class="panel_header"></div> > + <%= render :partial => "/host/grid", :locals => { :table_id => "add_smart_hosts_grid", > + :hwpool => nil, > + :pool_controller => "smart_pools", > + :exclude_pool => @pool.id, > + :exclude_host => nil, > + :checkboxes => true, > + :on_select => false, > + :on_deselect => false, > + :on_hover => false, > + :on_unhover => false, > + :is_popup => true, > + :hosts_per_page => 10} %> > +</div> > + > +<%= popup_footer("add_hosts_to_smart_pool('#{url_for :controller => "smart_pools", > + :action => "add_hosts", > + :id => @pool}')", > + "Add Hosts") %> > +</div> > diff --git a/src/app/views/host/addhost.html.erb b/src/app/views/host/addhost.html.erb > index 7edd4c5..967643e 100644 > --- a/src/app/views/host/addhost.html.erb > +++ b/src/app/views/host/addhost.html.erb > @@ -24,4 +24,4 @@ > :action => "add_hosts", > :id => @hardware_pool}')", > "Add Hosts") %> > -</div> > \ No newline at end of file > +</div> > diff --git a/src/app/views/layouts/_navigation_tabs.rhtml b/src/app/views/layouts/_navigation_tabs.rhtml > index 4b0f18d..af3fa61 100644 > --- a/src/app/views/layouts/_navigation_tabs.rhtml > +++ b/src/app/views/layouts/_navigation_tabs.rhtml > @@ -30,6 +30,23 @@ > <li id="nav_access"> <%= link_to "User Access", {:action => 'show_users', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> > <li id="nav_tasks"> <%= link_to "Tasks", {:action => 'show_tasks', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> > </ul> > +<% elsif controller.controller_name == "smart_pools" %> > + <script> > + $(document).ready(function(){ > + $tabs = $("#smart_pools_nav_tabs").tabs({ > + pool_type: "smart_pools", > + selected: <%if params[:tab]%><%=params[:tab]%><%else%>1<%end%> > + }); > + }); > + </script> > + <ul id="smart_pools_nav_tabs" class="ui-tabs-nav"> > + <li id="nav_summary" class="ui-tabs-selected"><%= link_to "Summary", {:action => 'show', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> > + <li id="nav_hosts"> <%= link_to "Hosts", {:action => 'show_hosts', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> > + <li id="nav_storage"><%= link_to "Storage", {:action => 'show_storage', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> > + <li id="nav_pools"> <%= link_to "Pools", {:action => 'show_pools', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> > + <li id="nav_vms"> <%= link_to "Virtual Machines", {:action => 'show_vms', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> > + <li id="nav_access"> <%= link_to "User Access", {:action => 'show_users', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li> > + </ul> > <% elsif controller.controller_name == "search" %> > <ul id="resources_nav_tabs" class="ui-tabs-nav"> > <li id="nav_search" class="ui-tabs-selected"><a href="#">Search Results</a></li> > diff --git a/src/app/views/layouts/_side_toolbar.rhtml b/src/app/views/layouts/_side_toolbar.rhtml > index 763f4a2..e1958f1 100644 > --- a/src/app/views/layouts/_side_toolbar.rhtml > +++ b/src/app/views/layouts/_side_toolbar.rhtml > @@ -1,24 +1,41 @@ > <% pool = @current_pool_id ? Pool.find(@current_pool_id) : nil %> > +<% if pool and pool[:type]=="HardwarePool" > + delete_url = url_for(:controller => "hardware", :action => "destroy") > + elsif pool and pool[:type]=="VmResourcePool" > + delete_url = url_for(:controller => "resources", :action => "destroy") > + elsif pool and pool[:type]=="SmartPool" > + delete_url = url_for(:controller => "smart_pools", :action => "destroy") > + else > + delete_url = "" > + end %> > + > <%if pool -%> > -<%if pool[:type]=="HardwarePool" -%> > -<div class="toolbar" style="float:left;"> > - <a href="<%= url_for :controller => :hardware, :action => 'new', :parent_id => pool %>" rel="facebox[.bolder]"> > - <%=image_tag "icon_add_hardwarepool.png", :title=>"Add Hardware Pool" %> > - </a> > -</div> > + <%if pool[:type]=="HardwarePool" -%> > + <div class="toolbar" style="float:left;"> > + <a href="<%= url_for :controller => :hardware, :action => 'new', :parent_id => pool %>" rel="facebox[.bolder]"> > + <%=image_tag "icon_add_hardwarepool.png", :title=>"Add Hardware Pool" %> > + </a> > + </div> > + <div class="toolbar" style="float:left;"> > + <a href="<%= url_for :controller => 'resources', :action => 'new', :parent_id => pool %>" rel="facebox[.bolder]"> > + <%= image_tag "icon_add_vmpool.png", :title=>"Add Virtual Machine Pool" %> > + </a> > + </div> > + <% end -%> > +<% end -%> > <div class="toolbar" style="float:left;"> > - <a href="<%= url_for :controller => 'resources', :action => 'new', :parent_id => pool %>" rel="facebox[.bolder]"> > - <%= image_tag "icon_add_vmpool.png", :title=>"Add Virtual Machine Pool" %> > + <a href="<%= url_for :controller => :smart_pools, :action => 'new' %>" rel="facebox[.bolder]"> > + <%=image_tag "icon_add_hardwarepool.png", :title=>"Add Smart Pool" %> > </a> > </div> > -<% end -%> > -<div class="toolbar" style="float:left;"> > +<%if pool -%> > + <div class="toolbar" style="float:left;"> > <a href="#conf_nav_delete_pool" rel="facebox[.bolder]"> > <%= image_tag "icon_delete.gif", :title=>"Delete Selected Pool" %> > </a> > -</div> > -<div class="toolbar" style="display:none;"> > - <%= confirmation_dialog("conf_nav_delete_pool", "Are you sure?", "delete_#{pool[:type]=='HardwarePool' ? 'hw' : 'vm'}_pool(#{pool.id})") %> > -</div> > + </div> > + <div class="toolbar" style="display:none;"> > + <%= confirmation_dialog("conf_nav_delete_pool", "Are you sure?", "delete_pool('#{delete_url}', #{pool.id})") %> > + </div> > <% end -%> > <div class="toolbar"></div> > diff --git a/src/app/views/layouts/_tree.rhtml b/src/app/views/layouts/_tree.rhtml > index eb15676..0e6e138 100644 > --- a/src/app/views/layouts/_tree.rhtml > +++ b/src/app/views/layouts/_tree.rhtml > @@ -12,12 +12,14 @@ > //animated: "normal", > url: "<%= url_for :controller =>'/tree', :action => 'fetch_json' %>", > hardware_url: "<%= url_for :controller =>'/hardware', :action => 'show' %>", > - resource_url: "<%= url_for :controller =>'/resources', :action => 'show' %>" > + resource_url: "<%= url_for :controller =>'/resources', :action => 'show' %>", > + smart_url: "<%= url_for :controller =>'/smart_pools', :action => 'show' %>" > }); > var tree_reload = { > url: "<%= url_for :controller =>'/tree', :action => 'fetch_json' %>", > hardware_url: "<%= url_for :controller =>'/hardware', :action => 'show' %>", > - resource_url: "<%= url_for :controller =>'/resources', :action => 'show' %>" > + resource_url: "<%= url_for :controller =>'/resources', :action => 'show' %>", > + smart_url: "<%= url_for :controller =>'/smart_pools', :action => 'show' %>" > } > $('#test-tree').everyTime(15000,function(){ > load(tree_reload, {}, this, this); > diff --git a/src/app/views/layouts/redux.rhtml b/src/app/views/layouts/redux.rhtml > index d6cfe24..01540d4 100644 > --- a/src/app/views/layouts/redux.rhtml > +++ b/src/app/views/layouts/redux.rhtml > @@ -90,32 +90,6 @@ > }); > return false;})},function(){}); > }); > - > - function delete_vm_pool(id, parent) > - { > - $(document).trigger('close.facebox'); > - $.post('<%= url_for :controller => "resources", :action => "destroy" %>', > - {id: id}, > - function(data,status){ > - // need to redirect to the parent using the new ajax reload stuff > - $("#vmpools_grid").flexReload(); > - if (data.alert) { > - $.jGrowl(data.alert); > - } > - }, 'json'); > - } > - function delete_hw_pool(id, parent) > - { > - $(document).trigger('close.facebox'); > - $.post('<%= url_for :controller => "hardware", :action => "destroy" %>', > - {id: id}, > - function(data,status){ > - // need to redirect to the parent using the new ajax reload stuff > - if (data.alert) { > - $.jGrowl(data.alert); > - } > - }, 'json'); > - } > </script> > <%= yield :scripts -%> > </head> > diff --git a/src/app/views/resources/show_vms.rhtml b/src/app/views/resources/show_vms.rhtml > index 857f56b..beca048 100644 > --- a/src/app/views/resources/show_vms.rhtml > +++ b/src/app/views/resources/show_vms.rhtml > @@ -26,7 +26,7 @@ > } > function delete_vms() > { > - vms = get_selected_vms() > + var vms = get_selected_vms(); > if (validate_selected(vms, "vm")) { > $.post('<%= url_for :controller => "vm", :action => "delete", :id => @pool %>', > { vm_ids: vms.toString() }, > @@ -43,7 +43,7 @@ > } > function vm_actions(action) > { > - vms = get_selected_vms() > + var vms = get_selected_vms(); > if (validate_selected(vms, "vm")) { > jQuery.facebox('<div id="vm_action_results">'); > $('#vm_action_results').load('<%= url_for :controller => "resources", > @@ -70,10 +70,12 @@ > <div class="data_section"> > <%= render :partial => "/vm/grid", :locals => { :table_id => "vms_grid", > :pool => @pool, > + :exclude_pool => nil, > :on_select => "vms_select", > :on_deselect => "load_widget_deselect", > :on_hover => "load_widget_hover", > - :on_unhover => "load_widget_unhover" } %> > + :on_unhover => "load_widget_unhover", > + :is_popup => false } %> > </div> > <div class="selection_detail" id="vms_selection"> > <div class="selection_left"> > diff --git a/src/app/views/smart_pools/_form.rhtml b/src/app/views/smart_pools/_form.rhtml > new file mode 100644 > index 0000000..2f2156a > --- /dev/null > +++ b/src/app/views/smart_pools/_form.rhtml > @@ -0,0 +1,6 @@ > +<%= error_messages_for 'vm_resource_pool' %> > + > +<!--[form:vm_resource_pool]--> > +<%= text_field_with_label "Name", 'smart_pool', 'name' %> > +<!--[eoform:vm_resource_pool]--> > + > diff --git a/src/app/views/smart_pools/_pools_grid.rhtml b/src/app/views/smart_pools/_pools_grid.rhtml > new file mode 100644 > index 0000000..a5f1a99 > --- /dev/null > +++ b/src/app/views/smart_pools/_pools_grid.rhtml > @@ -0,0 +1,39 @@ > +<% resources_per_page = 40 %> > +<div id="<%= table_id %>_div"> > +<form id="<%= table_id %>_form"> > +<table id="<%= table_id %>" style="display:none"></table> > +</form> > +</div> > +<script type="text/javascript"> > + $("#<%= table_id %>").flexigrid > + ( > + { > + url: '<%= url_for :controller => "smart_pools", :action => "pools_json", :id => pool.id %>', > + dataType: 'json', > + colModel : [ > + {display: '', name : 'id', width : 20, sortable : false, align: 'left', process: <%= table_id %>checkbox}, > + {display: 'Name', name : 'name', width : 160, sortable : true, align: 'left'}, > + {display: 'Type', width : 160, sortable : true, align: 'left'} > + ], > + sortname: "name", > + sortorder: "asc", > + usepager: <%= pool.tagged_pools.size > resources_per_page ? 'true' : 'false' %>, > + useRp: <%= pool.tagged_pools.size > resources_per_page ? 'true' : 'false' %>, > + rp: <%= resources_per_page %>, > + showTableToggleBtn: true, > + onSelect: <%= on_select %>, > + onDeselect: <%= on_deselect %>, > + onHover: <%= on_hover %>, > + onUnhover: <%= on_unhover %> > + } > + ); > + function <%= table_id %>checkbox(celDiv) > + { > + $(celDiv).html('<input type="checkbox" name="grid_checkbox'+$(celDiv).html()+'" class="grid_checkbox" value="'+$(celDiv).html()+'"/>'); > + } > + function <%= table_id %>_load_widget(celDiv) > + { > + load_widget(celDiv, "resource"); > + }; > + > +</script> > diff --git a/src/app/views/smart_pools/add_pool_dialog.rhtml b/src/app/views/smart_pools/add_pool_dialog.rhtml > new file mode 100644 > index 0000000..0d8cea6 > --- /dev/null > +++ b/src/app/views/smart_pools/add_pool_dialog.rhtml > @@ -0,0 +1,52 @@ > +<%- content_for :title do -%> > + Add a Hardware or Virtual Machine Pool > +<%- end -%> > +<%- content_for :description do -%> > + Choose a Hardware or Virtual Machine Pool to add to this Smart Pool > +<%- end -%> > + > +<script type="text/javascript"> > + $(document).ready(function(){ > + $("#add_tree").asynch_treeview({ > + //animated: "normal", > + current_pool_id: <%=@current_pool_id%>, > + disabled_pools: [<%=@selected_pools.join(',')%>], > + url: "<%= url_for :controller =>'/hardware', :action => 'json_view_tree' %>", > + current: "disabled", > + hardware_url: "#", > + resource_url: "#", > + onclick: "add_pool_to_smart_pool", > + action_type: "javascript" > + }) > + }); > + function add_pool_to_smart_pool(added_pool_id) > + { > + $.post('<%= url_for :controller => "smart_pools", :action => "add_pools", :id => @pool %>', > + { resource_ids: added_pool_id }, > + function(data,status){ > + grid = $("#smart_pools_grid"); > + if (grid.size()>0 && grid != null) { > + grid.flexReload(); > + } else { > + $tabs.tabs("load",$tabs.data('selected.tabs')); > + } > + $("smart_pools_grid").flexReload() > + jQuery(document).trigger('close.facebox'); > + if (data.alert) { > + $.jGrowl(data.alert); > + } > + }, 'json'); > + } > +</script> > + > +<div class="dialog_tree"> > + <ul id="add_tree" class="filetree treeview-famfamfam treeview"></ul> > +</div> > + > +<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')">Cancel</a></div> > + <div class="button_right_grey"></div> > + </div> > +</div> > diff --git a/src/app/views/smart_pools/new.rhtml b/src/app/views/smart_pools/new.rhtml > new file mode 100644 > index 0000000..7d488af > --- /dev/null > +++ b/src/app/views/smart_pools/new.rhtml > @@ -0,0 +1,26 @@ > +<%- content_for :title do -%> > + <%= _("Add New Smart Pool") %> > +<%- end -%> > +<%- content_for :description do -%> > + Add a new Smart Pool. > +<%- end -%> > + > +<form method="POST" action="<%= url_for :action => 'create' %>" id="smart_pool_form" > > + <div class="dialog_form"> > + <%= render :partial => 'form' %> > + </div> > + <%= popup_footer("$('#smart_pool_form').submit()", "Create Smart Pool") %> > +</form> > + > +<script type="text/javascript"> > +$(function() { > + var hwpooloptions = { > + target: '<%= url_for :action => 'create' %>', // target element to update > + dataType: 'json', > + success: afterSmartPool // post-submit callback > + }; > + > + // bind form using 'ajaxForm' > + $('#smart_pool_form').ajaxForm(hwpooloptions); > +}); > +</script> > diff --git a/src/app/views/smart_pools/show.rhtml b/src/app/views/smart_pools/show.rhtml > new file mode 100644 > index 0000000..45b1753 > --- /dev/null > +++ b/src/app/views/smart_pools/show.rhtml > @@ -0,0 +1,17 @@ > +<div class="data_section_summary"> > + > + <div class="summary_title"><%= image_tag "icon_hdwarepool.png", :style=>"vertical-align:middle;" %> <%= @pool.name %></div><br/><br/> > + > + <div class="summary_subtitle"><%= image_tag "icon_smry_res.png", :style=>"vertical-align:middle;" %> Resources</div><br/> > + <div id="availability_graphs"> > + What do we show here for Smart Pools? > + </div> > + > + <br/><br/> > + <div class="summary_subtitle"><%= image_tag "icon_smry_his.png", :style=>"vertical-align:middle;" %> History</div><br/> > + What do we show here for Smart Pools? > + > + <div class="summary_subtitle"><%= image_tag "icon_smry_perf.png", :style=>"vertical-align:middle;" %> Performance</div><br/> > + What do we show here for Smart Pools? > +</div> > + > diff --git a/src/app/views/hardware/show_hosts.rhtml b/src/app/views/smart_pools/show_hosts.rhtml > similarity index 50% > copy from src/app/views/hardware/show_hosts.rhtml > copy to src/app/views/smart_pools/show_hosts.rhtml > index 31c575d..a4b6be7 100644 > --- a/src/app/views/hardware/show_hosts.rhtml > +++ b/src/app/views/smart_pools/show_hosts.rhtml > @@ -1,89 +1,77 @@ > <div id="toolbar_nav"> > <ul> > - <li><a href="<%= url_for :controller => 'host', :action => 'addhost', :hardware_pool_id => @pool %>" rel="facebox[.bolder]"><%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> Add Host</a></li> > - <li> > - <a id="move_link" href="#" onClick="return validate_for_move();"><%= image_tag "icon_move.png", :style=>"vertical-align:middle;" %> Move</a> > - <a id="move_link_hidden" href="<%= url_for :controller => 'hardware', :action => 'move', :id => @pool, :resource_type=>'hosts' %>" rel="facebox[.bolder]" style="display:none" ></a> > - </li> > - <% if @pool.id != HardwarePool.get_default_pool.id %> > - <li><a href="#" onClick="remove_hosts()"><%= image_tag "icon_remove.png" %> Remove</a></li> > - <% end %> > + <li><a href="<%= url_for :controller => 'host', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]"><%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> Add Host</a></li> > + <li><a href="#" onClick="remove_hosts_from_smart_pool()"><%= image_tag "icon_remove.png" %> Remove</a></li> > </ul> > </div> > > <script type="text/javascript"> > - function get_selected_hosts() > + function get_selected_hosts_for_smart_pool() > { > - return get_selected_checkboxes("hosts_grid_form") > + return get_selected_checkboxes("smart_hosts_grid_form"); > } > - function validate_for_move() > + function remove_hosts_from_smart_pool() > { > - if (validate_selected(get_selected_hosts(), 'host')) { > - $('#move_link_hidden').click() > - } > - } > - function remove_hosts() > - { > - hosts = get_selected_hosts() > + var hosts = get_selected_hosts_for_smart_pool(); > if (validate_selected(hosts, "host")) { > - $.post('<%= url_for :controller => "hardware", :action => "move_hosts", :id => @pool %>', > - { resource_ids: hosts.toString(), target_pool_id: <%= HardwarePool.get_default_pool.id %> }, > + $.post('<%= url_for :controller => "smart_pools", :action => "remove_hosts", :id => @pool %>', > + { resource_ids: hosts.toString() }, > function(data,status){ > $tabs.tabs("load",$tabs.data('selected.tabs')); > if (data.alert) { > $.jGrowl(data.alert); > } > - if (hosts.indexOf($('#hosts_selection_id').html()) != -1){ > - empty_summary('hosts_selection', 'Host') > - } > + if (hosts.indexOf($('#smart_hosts_selection_id').html()) != -1){ > + empty_summary('smart_hosts_selection', 'Host'); > + } > > }, 'json'); > } > } > - function hosts_select(selected_rows) > + function smart_hosts_select(selected_rows) > { > - var selected_ids = new Array() > - for(i=0; i<selected_rows.length; i++) { > - load_widget_select(selected_rows[i]); > + var selected_ids = new Array(); > + for(i=0; i<selected_rows.length; i++) { > selected_ids[i] = selected_rows[i].id; > } > if (selected_ids.length == 1) > { > - $('#hosts_selection').load('<%= url_for :controller => "host", :action => "show", :id => nil %>/' + parseInt(selected_ids[0].substring(3))) > + $('#smart_hosts_selection').load('<%= url_for :controller => "host", :action => "show", :id => nil %>/' + parseInt(selected_ids[0].substring(3))); > } > } > </script> > > <div class="panel_header"></div> > -<% if @pool.hosts.size != 0 %> > +<% if @pool.tagged_hosts.size != 0 %> > <div class="data_section"> > - <%= render :partial => "/host/grid", :locals => { :table_id => "hosts_grid", > + <%= render :partial => "/host/grid", :locals => { :table_id => "smart_hosts_grid", > :hwpool => @pool, > + :pool_controller => "smart_pools", > :exclude_pool => nil, > :exclude_host => nil, > - :show_pool => false, > + :show_pool => true, > :checkboxes => true, > - :on_select => "hosts_select", > + :on_select => "smart_hosts_select", > :on_deselect => "load_widget_deselect", > :on_hover => "load_widget_hover", > :on_unhover => "load_widget_unhover", > :is_popup => false, > :hosts_per_page => 40} %> > </div> > - <div class="selection_detail" id="hosts_selection"> > - <div class="selection_left"> > - <div>Select a host above.</div> > - </div> > + <div class="selection_detail" id="smart_hosts_selection"> > + <div class="selection_left"> > + <div>Select a host above.</div> > + </div> > </div> > <% else %> > <div class="data_section"> > <div class="no-grid-items"> > <%= image_tag 'no-grid-items.png', :style => 'float: left;' %> > - > + > <div class="no-grid-items-text"> > No hosts found in this pool. <br/><br/> > <%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> > - <a href="<%= url_for :controller => 'host', :action => 'addhost', :hardware_pool_id => @pool %>" rel="facebox[.bolder]">Add first host to this hardware pool</a> > + <a href="<%= url_for :controller => 'host', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]">Add first host to this smart pool</a> > </div> > </div> > </div> > diff --git a/src/app/views/smart_pools/show_pools.rhtml b/src/app/views/smart_pools/show_pools.rhtml > new file mode 100644 > index 0000000..8e89701 > --- /dev/null > +++ b/src/app/views/smart_pools/show_pools.rhtml > @@ -0,0 +1,74 @@ > +<div id="toolbar_nav"> > + <ul> > + <li><a href="<%= url_for :controller => 'smart_pools', :action => 'add_pool_dialog', :id => @pool %>" rel="facebox[.bolder]"><%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> Add Pool</a></li> > + <li><a href="#" onClick="remove_pools_from_smart_pool()"><%= image_tag "icon_remove.png" %> Remove</a></li> > + </ul> > +</div> > + > +<script type="text/javascript"> > + function get_selected_pools_for_smart_pool() > + { > + return get_selected_checkboxes("smart_pools_grid_form"); > + } > + function remove_pools_from_smart_pool() > + { > + var pools = get_selected_pools_for_smart_pool(); > + if (validate_selected(pools, "pool")) { > + $.post('<%= url_for :controller => "smart_pools", :action => "remove_pools", :id => @pool %>', > + { resource_ids: pools.toString() }, > + function(data,status){ > + $tabs.tabs("load",$tabs.data('selected.tabs')); > + if (data.alert) { > + $.jGrowl(data.alert); > + } > + if (pools.indexOf($('#smart_pools_selection_id').html()) != -1){ > + empty_summary('smart_pools_selection', 'Pool'); > + } > + > + }, 'json'); > + } > + } > + function smart_pools_select(selected_rows) > + { > + var selected_ids = new Array(); > + for(i=0; i<selected_rows.length; i++) { > + selected_ids[i] = selected_rows[i].id; > + } > + if (selected_ids.length == 1) > + { > + $('#smart_pools_selection').load('<%= url_for :controller => "search", :action => "single_result" %>', > + { class_and_id: selected_ids[0].substring(3)}); > + } > + } > +</script> > + > +<div class="panel_header"></div> > +<% if @pool.tagged_pools.size != 0 %> > + <div class="data_section"> > + <%= render :partial => "/smart_pools/pools_grid", :locals => { :table_id => "smart_pools_grid", > + :pool => @pool, > + :pool_controller => "smart_pools", > + :checkboxes => true, > + :on_select => "smart_pools_select", > + :on_deselect => false, > + :on_hover => false, > + :on_unhover => false} %> > + </div> > + <div class="selection_detail" id="smart_pools_selection"> > + <div class="selection_left"> > + <div>Select a pool above.</div> > + </div> > + </div> > +<% else %> > + <div class="data_section"> > + <div class="no-grid-items"> > + <%= image_tag 'no-grid-items.png', :style => 'float: left;' %> > + > + <div class="no-grid-items-text"> > + No pools found in this pool. <br/><br/> > + <%= image_tag "icon_addpool.png", :style=>"vertical-align:middle;" %> > + <a href="<%= url_for :controller => 'pool', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]">Add first Pool to this smart pool</a> > + </div> > + </div> > + </div> > +<% end %> > diff --git a/src/app/views/smart_pools/show_storage.rhtml b/src/app/views/smart_pools/show_storage.rhtml > new file mode 100644 > index 0000000..7cf425a > --- /dev/null > +++ b/src/app/views/smart_pools/show_storage.rhtml > @@ -0,0 +1,72 @@ > +<div id="toolbar_nav"> > +<ul> > + <li><a href="<%= url_for :controller => 'storage', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]"><%= image_tag "icon_addstorage.png", :style=>"vertical-align:middle;" %> Add Storage Pool</a></li> > + <li><a href="#" onClick="remove_storage_from_smart_pool()"><%= image_tag "icon_remove.png" %> Remove</a></li> > + </ul> > +</div> > + > +<script type="text/javascript"> > + function get_selected_storage_for_smart_pool() > + { > + return get_selected_checkboxes("smart_storage_grid_form"); > + } > + function remove_storage_from_smart_pool() > + { > + var storage = get_selected_storage_for_smart_pool(); > + if (validate_selected(storage, "storage pool")) { > + $.post('<%= url_for :controller => "smart_pools", :action => "remove_storage", :id => @pool %>', > + { resource_ids: storage.toString() }, > + function(data,status){ > + $tabs.tabs("load",$tabs.data('selected.tabs')); > + if (data.alert) { > + $.jGrowl(data.alert); > + } > + if (storage.indexOf($('#smart_storage_selection_id').html()) != -1){ > + empty_summary('smart_storage_selection', 'Storage Pool'); > + } > + }, 'json'); > + } > + } > + function smart_storage_select(selected_rows) > + { > + var selected_ids = new Array() ; > + for(i=0; i<selected_rows.length; i++) { > + selected_ids[i] = selected_rows[i].id; > + } > + if (selected_ids.length == 1) > + { > + $('#smart_storage_selection').load('<%= url_for :controller => "storage", :action => "show" %>', > + { id: parseInt(selected_ids[0].substring(3))}); > + } > + } > + > +</script> > +<div class="panel_header"></div> > +<% if @pool.tagged_storage_pools.size != 0 %> > + <div class="data_section"> > + <%= render :partial => "/storage/grid", :locals => { :table_id => "smart_storage_grid", > + :hwpool => @pool, > + :pool_controller => "smart_pools", > + :exclude_pool => nil, > + :on_select => "smart_storage_select", > + :is_popup => false} %> > + </div> > + > + <div class="selection_detail" id="smart_storage_selection"> > + <div class="selection_left"> > + <div>Select a storage pool.</div> > + </div> > + </div> > +<% else %> > + <div class="data_section"> > + <div class="no-grid-items"> > + <%= image_tag 'no-grid-items.png', :style => 'float: left;' %> > + > + <div class="no-grid-items-text"> > + No storage Pools found in this pool. <br/><br/> > + <%= image_tag "icon_addstorage.png", :style=>"vertical-align:middle;" %> > + <a href="<%= url_for :controller => 'storage', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]">Add first storage volume to this smart pool</a> > + </div> > + </div> > + </div> > +<% end %> > diff --git a/src/app/views/smart_pools/show_users.rhtml b/src/app/views/smart_pools/show_users.rhtml > new file mode 100644 > index 0000000..7d1efb8 > --- /dev/null > +++ b/src/app/views/smart_pools/show_users.rhtml > @@ -0,0 +1,2 @@ > + <%= render :partial => "/user/show", :locals => { :parent_controller => "smart_pools", > + :pool => @pool } %> > diff --git a/src/app/views/smart_pools/show_vms.rhtml b/src/app/views/smart_pools/show_vms.rhtml > new file mode 100644 > index 0000000..e56600b > --- /dev/null > +++ b/src/app/views/smart_pools/show_vms.rhtml > @@ -0,0 +1,77 @@ > +<div id="toolbar_nav"> > + <ul> > + <li><a href="<%= url_for :controller => 'vm', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]"><%= image_tag "icon_addhost.png", :style=>"vertical-align:middle;" %> Add Virtual Machine</a></li> > + <li><a href="#" onClick="remove_vms_from_smart_pool()"><%= image_tag "icon_remove.png" %> Remove</a></li> > + </ul> > +</div> > + > +<script type="text/javascript"> > + function get_selected_vms_for_smart_pool() > + { > + return get_selected_checkboxes("smart_vms_grid_form"); > + } > + function remove_vms_from_smart_pool() > + { > + var vms = get_selected_vms_for_smart_pool(); > + if (validate_selected(vms, "vm")) { > + $.post('<%= url_for :controller => "smart_pools", :action => "remove_vms", :id => @pool %>', > + { resource_ids: vms.toString() }, > + function(data,status){ > + $tabs.tabs("load",$tabs.data('selected.tabs')); > + if (data.alert) { > + $.jGrowl(data.alert); > + } > + if (vms.indexOf($('#smart_vms_selection_id').html()) != -1){ > + empty_summary('smart_vms_selection', 'Vm'); > + } > + > + }, 'json'); > + } > + } > + function smart_vms_select(selected_rows) > + { > + var selected_ids = new Array(); > + for(i=0; i<selected_rows.length; i++) { > + selected_ids[i] = selected_rows[i].id; > + } > + if (selected_ids.length == 1) > + { > + $('#smart_vms_selection').load('<%= url_for :controller => "vm", :action => "show", :id => nil %>/' + parseInt(selected_ids[0].substring(3))); > + } > + } > +</script> > + > +<div class="panel_header"></div> > +<% if @pool.tagged_vms.size != 0 %> > + <div class="data_section"> > + <%= render :partial => "/vm/grid", :locals => { :table_id => "smart_vms_grid", > + :pool => @pool, > + :pool_controller => "smart_pools", > + :exclude_pool => nil, > + :show_pool => true, > + :checkboxes => true, > + :on_select => "smart_vms_select", > + :on_deselect => "load_widget_deselect", > + :on_hover => "load_widget_hover", > + :on_unhover => "load_widget_unhover", > + :is_popup => false, > + :vms_per_page => 40} %> > + </div> > + <div class="selection_detail" id="smart_vms_selection"> > + <div class="selection_left"> > + <div>Select a vm above.</div> > + </div> > + </div> > +<% else %> > + <div class="data_section"> > + <div class="no-grid-items"> > + <%= image_tag 'no-grid-items.png', :style => 'float: left;' %> > + > + <div class="no-grid-items-text"> > + No vms found in this pool. <br/><br/> > + <%= image_tag "icon_addvm.png", :style=>"vertical-align:middle;" %> > + <a href="<%= url_for :controller => 'vm', :action => 'add_to_smart_pool', :smart_pool_id => @pool %>" rel="facebox[.bolder]">Add first VM to this smart pool</a> > + </div> > + </div> > + </div> > +<% end %> > diff --git a/src/app/views/storage/_grid.rhtml b/src/app/views/storage/_grid.rhtml > index c36f4d3..c8876bb 100644 > --- a/src/app/views/storage/_grid.rhtml > +++ b/src/app/views/storage/_grid.rhtml > @@ -1,4 +1,12 @@ > -<% storage_per_page = 40 %> > +<% storage_per_page = 40 unless (defined? storage_per_page) and !(storage_per_page.nil?) %> > +<% pool_controller = 'hardware' unless (defined? pool_controller) and !(pool_controller.nil?) %> > +<% if (hwpool.nil? or > + ((hwpool.is_a? HardwarePool) and (hwpool.storage_pools.size > storage_per_page)) or > + ((hwpool.is_a? SmartPool) and (hwpool.tagged_storage_pools.size > storage_per_page))) > + usepager = 'true' > + else > + usepager = 'false' > + end %> > > <div id="<%= table_id %>_div"> > <form id="<%= table_id %>_form"> > @@ -9,7 +17,10 @@ > $("#<%= table_id %>").flexigrid > ( > { > - url: '<%= url_for :controller => "hardware", :action => "storage_pools_json", :id => (hwpool.nil? ? nil : hwpool.id), :exclude_pool => exclude_pool %>', > + url: '<%= url_for :controller => pool_controller, > + :action => "storage_pools_json", > + :id => (hwpool.nil? ? nil : hwpool.id), > + :exclude_pool => exclude_pool %>', > dataType: 'json', > <% if is_popup %> > width: 700, > @@ -23,8 +34,8 @@ > ], > sortname: "ip_addr", > sortorder: "asc", > - usepager: <%= (hwpool.nil? or hwpool.storage_pools.size > storage_per_page) ? 'true' : 'false' %>, > - useRp: <%= (hwpool.nil? or hwpool.storage_pools.size > storage_per_page) ? 'true' : 'false' %>, > + usepager: <%= usepager %>, > + useRp: <%= usepager %>, > rp: <%= storage_per_page %>, > showTableToggleBtn: true, > onSelect: <%= on_select %> > diff --git a/src/app/views/storage/add_to_smart_pool.rhtml b/src/app/views/storage/add_to_smart_pool.rhtml > new file mode 100644 > index 0000000..2eedae3 > --- /dev/null > +++ b/src/app/views/storage/add_to_smart_pool.rhtml > @@ -0,0 +1,22 @@ > +<%- content_for :title do -%> > + <%= _("Add Storage Pool to Smart Pool") %> > +<%- end -%> > +<%- content_for :description do -%> > + Select storage pools from the list below to add to the <%= @pool.name %> smart pool.</a> > +<%- end -%> > +<div id="dialog-content-area"> > +<div class="dialog_body_small"> > +<div class="panel_header"></div> > + <%= render :partial => "/storage/grid", :locals => { :table_id => "add_smart_storage_grid", > + :hwpool => nil, > + :pool_controller => "smart_pools", > + :exclude_pool => @pool.id, > + :on_select => false, > + :is_popup => true} %> > +</div> > + > +<%= popup_footer("add_storage_to_smart_pool('#{url_for :controller => "smart_pools", > + :action => "add_storage", > + :id => @pool}')", > + "Add Storage Pools") %> > +</div> > diff --git a/src/app/views/user/_show.rhtml b/src/app/views/user/_show.rhtml > index 916afe8..5b3ffb7 100644 > --- a/src/app/views/user/_show.rhtml > +++ b/src/app/views/user/_show.rhtml > @@ -12,7 +12,7 @@ > } > function delete_users() > { > - permissions = get_selected_users(); > + var permissions = get_selected_users(); > if (validate_selected(permissions, "user")) { > $.post('<%= url_for :controller => "permission", :action => "delete", :id => pool.id %>', > { permission_ids: permissions.toString() }, > @@ -26,7 +26,7 @@ > } > function update_users(role) > { > - permissions = get_selected_users() > + var permissions = get_selected_users(); > if (validate_selected(permissions, "users")) { > $.post('<%= url_for :controller => "permission", :action => "update_roles" %>', > { permission_ids: permissions.toString(), user_role: role }, > diff --git a/src/app/views/vm/_grid.rhtml b/src/app/views/vm/_grid.rhtml > index c56e6b8..a322ea3 100644 > --- a/src/app/views/vm/_grid.rhtml > +++ b/src/app/views/vm/_grid.rhtml > @@ -1,42 +1,56 @@ > <%= render :partial => 'graph/load_graph.rhtml' %> > -<% vms_per_page = 10 %> > +<% pool_controller = 'resources' unless (defined? pool_controller) and !(pool_controller.nil?) %> > +<% vms_per_page = 40 unless (defined? vms_per_page) and !(vms_per_page.nil?) %> > +<% if (pool.nil? or > + ((pool.is_a? VmResourcePool) and (pool.vms.size > vms_per_page)) or > + ((pool.is_a? SmartPool) and (pool.tagged_vms.size > vms_per_page))) > + usepager = 'true' > + else > + usepager = 'false' > + end %> > <div id="<%= table_id %>_div"> > <form id="<%= table_id %>_form"> > <table id="<%= table_id %>" style="display:none"></table> > </form> > </div> > <script type="text/javascript"> > - $("#<%= table_id %>").flexigrid > - ( > - { > - url: '<%= url_for :controller => "resources", :action => "vms_json", :id => pool.id %>', > - dataType: 'json', > - colModel : [ > - {display: '', name : 'id', width : 20, sortable : false, align: 'left', process: <%= table_id %>checkbox}, > - {display: 'Description', name : 'description', width : 180, sortable : true, align: 'left'}, > - {display: 'UUID', name : 'uuid', width : 180, sortable : true, align: 'left'}, > - {display: 'CPUs', name : 'num_vcpus_allocated', width : 40, sortable : true, align: 'left'}, > - {display: 'Memory (MB)', name : 'memory_allocated', width : 60, sortable : true, align: 'right'}, > - {display: 'vNIC Mac Addr', name : 'vnic_mac_addr', width : 60, sortable : true, align: 'right'}, > - {display: 'State', name : 'state', width : 50, sortable : true, align: 'right'}, > + $("#<%= table_id %>").flexigrid > + ( > + { > + url: '<%= url_for :controller => pool_controller, > + :action => "vms_json", > + :id => (pool.nil? ? nil : pool.id), > + :exclude_pool => exclude_pool %>', > + dataType: 'json', > + <% if is_popup %> > + width: 700, > + <% end %> > + colModel : [ > + {display: '', name : 'id', width : 20, sortable : false, align: 'left', process: <%= table_id %>checkbox}, > + {display: 'Description', name : 'description', width : 180, sortable : true, align: 'left'}, > + {display: 'UUID', name : 'uuid', width : 180, sortable : true, align: 'left'}, > + {display: 'CPUs', name : 'num_vcpus_allocated', width : 40, sortable : true, align: 'left'}, > + {display: 'Memory (MB)', name : 'memory_allocated', width : 60, sortable : true, align: 'right'}, > + {display: 'vNIC Mac Addr', name : 'vnic_mac_addr', width : 60, sortable : true, align: 'right'}, > + {display: 'State', name : 'state', width : 50, sortable : true, align: 'right'}, > {display: 'Load', name : 'load', width: 180, sortable : false, align: 'left', process: <%= table_id %>_load_widget } > - ], > - sortname: "description", > - sortorder: "asc", > - usepager: <%= pool.vms.size > vms_per_page ? 'true' : 'false' %>, > - useRp: <%= pool.vms.size > vms_per_page ? 'true' : 'false' %>, > - rp: <%= vms_per_page %>, > - showTableToggleBtn: true, > - onSelect: <%= on_select %>, > + ], > + sortname: "description", > + sortorder: "asc", > + usepager: <%= usepager %>, > + useRp: <%= usepager %>, > + rp: <%= vms_per_page %>, > + showTableToggleBtn: true, > + onSelect: <%= on_select %>, > onDeselect: <%= on_deselect %>, > onHover: <%= on_hover %>, > onUnhover: <%= on_unhover %> > - } > - ); > - function <%= table_id %>checkbox(celDiv) > - { > - $(celDiv).html('<input type="checkbox" name="grid_checkbox'+$(celDiv).html()+'" class="grid_checkbox" value="'+$(celDiv).html()+'"/>'); > - } > + } > + ); > + function <%= table_id %>checkbox(celDiv) > + { > + $(celDiv).html('<input type="checkbox" name="grid_checkbox'+$(celDiv).html()+'" class="grid_checkbox" value="'+$(celDiv).html()+'"/>'); > + } > function <%= table_id %>_load_widget(celDiv) > { > load_widget(celDiv, "vm"); > diff --git a/src/app/views/vm/add_to_smart_pool.rhtml b/src/app/views/vm/add_to_smart_pool.rhtml > new file mode 100644 > index 0000000..cdfe92d > --- /dev/null > +++ b/src/app/views/vm/add_to_smart_pool.rhtml > @@ -0,0 +1,27 @@ > +<%- content_for :title do -%> > + <%= _("Add Vm to Smart Pool") %> > +<%- end -%> > +<%- content_for :description do -%> > + Select vms from the list below to add to the <%= @pool.name %> smart pool.</a> > +<%- end -%> > +<div id="dialog-content-area"> > +<div class="dialog_body_small"> > +<div class="panel_header"></div> > + <%= render :partial => "/vm/grid", :locals => { :table_id => "add_smart_vms_grid", > + :pool => nil, > + :pool_controller => "smart_pools", > + :exclude_pool => @pool.id, > + :checkboxes => true, > + :on_select => false, > + :on_deselect => false, > + :on_hover => false, > + :on_unhover => false, > + :is_popup => true, > + :vms_per_page => 40} %> > +</div> > + > +<%= popup_footer("add_vms_to_smart_pool('#{url_for :controller => "smart_pools", > + :action => "add_vms", > + :id => @pool}')", > + "Add Vms") %> > +</div> > diff --git a/src/db/migrate/017_add_smart_pools.rb b/src/db/migrate/017_add_smart_pools.rb > index 6d83c02..5550a89 100644 > --- a/src/db/migrate/017_add_smart_pools.rb > +++ b/src/db/migrate/017_add_smart_pools.rb > @@ -47,7 +47,7 @@ class AddSmartPools < ActiveRecord::Migration > new_permission = Permission.new({:pool_id => dir_root.id, > :uid => permission.uid, > :user_role => permission.user_role}) > - new_permission.save! > + new_permission.save_with_new_children > end > end > end > diff --git a/src/public/javascripts/jquery-treeview/jquery.treeview.async.js b/src/public/javascripts/jquery-treeview/jquery.treeview.async.js > index b10a130..4dacda6 100644 > --- a/src/public/javascripts/jquery-treeview/jquery.treeview.async.js > +++ b/src/public/javascripts/jquery-treeview/jquery.treeview.async.js > @@ -43,7 +43,7 @@ function load(settings, params, child, container) { > } else { > span_onclick = "" > } > - if (settings.current_pool_id==this.id) { > + if (settings.current_pool_id==this.id || !((settings.disabled_pools == undefined) || ($.inArray(this.id,settings.disabled_pools)==-1))) { > current.html("<span class=\"" + settings.current_class + ">" + this.text + "</span>") > .appendTo(parent); > } else { > diff --git a/src/public/javascripts/jquery.ovirt.treeview.js b/src/public/javascripts/jquery.ovirt.treeview.js > index 16cf260..bb41667 100644 > --- a/src/public/javascripts/jquery.ovirt.treeview.js > +++ b/src/public/javascripts/jquery.ovirt.treeview.js > @@ -21,10 +21,18 @@ function load(settings, params, child, container) { > settings.link_to=settings.hardware_url > settings.span_class="folder"; > settings.current_class = settings.current + "_folder"; > - } else { > + } else if (this.type=="VmResourcePool") { > settings.link_to=settings.resource_url; > settings.span_class="file"; > settings.current_class = settings.current + "_file"; > + } else if (this.type=="SmartPool") { > + settings.link_to=settings.smart_url; > + settings.span_class="file"; > + settings.current_class = settings.current + "_file"; > + } else { > + settings.link_to=""; > + settings.span_class="file"; > + settings.current_class = settings.current + "_file"; > } > var span_onclick; > var current = $("<li/>").attr("id", this.id || ""); > @@ -64,7 +72,7 @@ function load(settings, params, child, container) { > } > } > $(container).find('li').remove(); > - createNode.call(response, child); > + $.each(response, createNode, [child]); > $(container).ovirt_treeview({add: child}); > for (var i = 0; i < selectedNodes.length; i++){ > $('#test-tree li#' + selectedNodes[i] +' > div').click(); > diff --git a/src/public/javascripts/ovirt.js b/src/public/javascripts/ovirt.js > index af0b9f6..470a53a 100644 > --- a/src/public/javascripts/ovirt.js > +++ b/src/public/javascripts/ovirt.js > @@ -42,7 +42,7 @@ function add_hosts(url) > $.post(url, > { resource_ids: hosts.toString() }, > function(data,status){ > - jQuery(document).trigger('close.facebox'); > + $(document).trigger('close.facebox'); > grid = $("#hosts_grid"); > if (grid.size()>0 && grid != null) { > grid.flexReload(); > @@ -62,7 +62,7 @@ function add_storage(url) > $.post(url, > { resource_ids: storage.toString() }, > function(data,status){; > - jQuery(document).trigger('close.facebox'); > + $(document).trigger('close.facebox'); > grid = $("#storage_grid"); > if (grid.size()>0 && grid != null) { > grid.flexReload(); > @@ -75,6 +75,66 @@ function add_storage(url) > }, 'json'); > } > } > +function add_hosts_to_smart_pool(url) > +{ > + hosts= get_selected_checkboxes("add_smart_hosts_grid_form"); > + if (validate_selected(hosts, "host")) { > + $.post(url, > + { resource_ids: hosts.toString() }, > + function(data,status){ > + $(document).trigger('close.facebox'); > + grid = $("#smart_hosts_grid"); > + if (grid.size()>0 && grid != null) { > + grid.flexReload(); > + } else { > + $tabs.tabs("load",$tabs.data('selected.tabs')); > + } > + if (data.alert) { > + $.jGrowl(data.alert); > + } > + }, 'json'); > + } > +} > +function add_storage_to_smart_pool(url) > +{ > + storage= get_selected_checkboxes("add_smart_storage_grid_form"); > + if (validate_selected(storage, "storage pool")) { > + $.post(url, > + { resource_ids: storage.toString() }, > + function(data,status){ > + $(document).trigger('close.facebox'); > + grid = $("#smart_storage_grid"); > + if (grid.size()>0 && grid != null) { > + grid.flexReload(); > + } else { > + $tabs.tabs("load",$tabs.data('selected.tabs')); > + } > + if (data.alert) { > + $.jGrowl(data.alert); > + } > + }, 'json'); > + } > +} > +function add_vms_to_smart_pool(url) > +{ > + vms= get_selected_checkboxes("add_smart_vms_grid_form"); > + if (validate_selected(vms, "vm")) { > + $.post(url, > + { resource_ids: vms.toString() }, > + function(data,status){ > + $(document).trigger('close.facebox'); > + grid = $("#smart_vms_grid"); > + if (grid.size()>0 && grid != null) { > + grid.flexReload(); > + } else { > + $tabs.tabs("load",$tabs.data('selected.tabs')); > + } > + if (data.alert) { > + $.jGrowl(data.alert); > + } > + }, 'json'); > + } > +} > // deal with ajax form response, filling in validation messages where required. > function ajax_validation(response, status) > { > @@ -102,7 +162,7 @@ function ajax_validation(response, status) > function afterHwPool(response, status){ > ajax_validation(response, status); > if (response.success) { > - jQuery(document).trigger('close.facebox'); > + $(document).trigger('close.facebox'); > // FIXME do we need to reload the tree here > > // this is for reloading the host/storage grid when > @@ -128,7 +188,7 @@ function afterHwPool(response, status){ > function afterVmPool(response, status){ > ajax_validation(response, status); > if (response.success) { > - jQuery(document).trigger('close.facebox'); > + $(document).trigger('close.facebox'); > grid = $("#vmpools_grid"); > if (grid.size()>0 && grid != null) { > grid.flexReload(); > @@ -137,10 +197,16 @@ function afterVmPool(response, status){ > } > } > } > +function afterSmartPool(response, status){ > + ajax_validation(response, status); > + if (response.success) { > + $(document).trigger('close.facebox'); > + } > +} > function afterStoragePool(response, status){ > ajax_validation(response, status); > if (response.success) { > - jQuery(document).trigger('close.facebox'); > + $(document).trigger('close.facebox'); > grid = $("#storage_grid"); > if (grid.size()>0 && grid != null) { > grid.flexReload(); > @@ -152,7 +218,7 @@ function afterStoragePool(response, status){ > function afterPermission(response, status){ > ajax_validation(response, status); > if (response.success) { > - jQuery(document).trigger('close.facebox'); > + $(document).trigger('close.facebox'); > grid = $("#users_grid"); > if (grid.size()>0 && grid!= null) { > grid.flexReload(); > @@ -164,7 +230,7 @@ function afterPermission(response, status){ > function afterVm(response, status){ > ajax_validation(response, status); > if (response.success) { > - jQuery(document).trigger('close.facebox'); > + $(document).trigger('close.facebox'); > grid = $("#vms_grid"); > if (grid.size()>0 && grid != null) { > grid.flexReload(); > @@ -212,7 +278,23 @@ function delete_or_remove_storage() > } else if (selected[0].value == "delete") { > delete_storage(); > } > - jQuery(document).trigger('close.facebox'); > + $(document).trigger('close.facebox'); > +} > +function delete_pool(delete_url, id) > +{ > + $(document).trigger('close.facebox'); > + > + if (delete_url==='') { > + $.jGrowl("Invalid Pool Type"); > + return; > + } > + $.post(delete_url, > + {id: id}, > + function(data,status){ > + if (data.alert) { > + $.jGrowl(data.alert); > + } > + }, 'json'); > } > >