[Ovirt-devel] [PATCH] finished smart pools implementation. (revised)

Jason Guiditta jguiditt at redhat.com
Fri Sep 19 15:56:32 UTC 2008


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');
>  }
>  
> 




More information about the ovirt-devel mailing list