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