[Ovirt-devel] [PATCH] initial push of smart pool code. (revised)
Scott Seago
sseago at redhat.com
Wed Sep 3 16:12:31 UTC 2008
This isn't complete, but I want to get it committed before the repo refactoring. This patch includes the controller refactoring needed for adding the new smart pool controllers, but I have not yet added any code to the new controllers. The models are in place for smart pools, but they aren't used anywhere yet. In addition, I've added a new DirectoryPool pool type that is used solely as a placeholder -- so that we can have a common root for all hardware and smart pools, and that we can organize smart pools by user.
Since we need this pushed before the repo refactoring, this patch should be acked if it doesn't break anything. Separate review comments are, of course, welcome -- but anything that doesn't break the WUI will be fixed in a subsequent (post-repo-reorg) patch)
Signed-off-by: Scott Seago <sseago at redhat.com>
---
wui/src/app/controllers/application.rb | 3 +-
wui/src/app/controllers/hardware_controller.rb | 111 ++--------------
wui/src/app/controllers/pool_controller.rb | 132 ++++++++++++++++++++
wui/src/app/controllers/resources_controller.rb | 128 ++++---------------
wui/src/app/controllers/smart_pool_controller.rb | 22 ++++
wui/src/app/controllers/tree_controller.rb | 4 +-
wui/src/app/models/directory_pool.rb | 60 +++++++++
wui/src/app/models/hardware_pool.rb | 18 +--
wui/src/app/models/host.rb | 3 +
wui/src/app/models/pool.rb | 21 +++
wui/src/app/models/smart_pool.rb | 47 +++++++
wui/src/app/models/smart_pool_tag.rb | 37 ++++++
wui/src/app/models/storage_pool.rb | 3 +
wui/src/app/models/vm.rb | 4 +
wui/src/app/views/hardware/show_hosts.rhtml | 2 +-
wui/src/app/views/hardware/show_storage.rhtml | 2 +-
wui/src/app/views/layouts/_navigation_tabs.rhtml | 10 +-
wui/src/app/views/resources/edit.rhtml | 4 +-
wui/src/app/views/resources/quick_summary.rhtml | 20 ++--
wui/src/app/views/resources/show.rhtml | 12 +-
wui/src/app/views/resources/show_tasks.rhtml | 4 +-
wui/src/app/views/resources/show_users.rhtml | 2 +-
wui/src/app/views/resources/show_vms.rhtml | 12 +-
wui/src/db/migrate/017_add_smart_pools.rb | 62 +++++++++
wui/src/dutils/active_record_env.rb | 4 +
wui/src/script/grant_admin_privileges | 9 +-
.../betternestedset/lib/better_nested_set.rb | 37 ++++--
27 files changed, 506 insertions(+), 267 deletions(-)
create mode 100644 wui/src/app/controllers/pool_controller.rb
create mode 100644 wui/src/app/controllers/smart_pool_controller.rb
create mode 100644 wui/src/app/models/directory_pool.rb
create mode 100644 wui/src/app/models/smart_pool.rb
create mode 100644 wui/src/app/models/smart_pool_tag.rb
create mode 100644 wui/src/db/migrate/017_add_smart_pools.rb
diff --git a/wui/src/app/controllers/application.rb b/wui/src/app/controllers/application.rb
index b95577a..3126748 100644
--- a/wui/src/app/controllers/application.rb
+++ b/wui/src/app/controllers/application.rb
@@ -29,8 +29,7 @@ class ApplicationController < ActionController::Base
before_filter :pre_new, :only => [:new]
before_filter :pre_create, :only => [:create]
before_filter :pre_edit, :only => [:edit, :update, :destroy]
- before_filter :pre_show, :only => [:show, :show_vms, :show_users,
- :show_hosts, :show_storage]
+ before_filter :pre_show, :only => [:show]
before_filter :authorize_admin, :only => [:new, :create, :edit, :update, :destroy]
before_filter :is_logged_in
diff --git a/wui/src/app/controllers/hardware_controller.rb b/wui/src/app/controllers/hardware_controller.rb
index 7c1d916..091ce97 100644
--- a/wui/src/app/controllers/hardware_controller.rb
+++ b/wui/src/app/controllers/hardware_controller.rb
@@ -18,7 +18,7 @@
# also available at http://www.gnu.org/copyleft/gpl.html.
#
-class HardwareController < ApplicationController
+class HardwareController < PoolController
XML_OPTS = {
:include => [ :storage_pools, :hosts, :quota ]
@@ -31,10 +31,8 @@ class HardwareController < ApplicationController
verify :method => [:post, :delete], :only => :destroy,
:redirect_to => { :action => :list }
- before_filter :pre_json, :only => [:vm_pools_json, :users_json,
- :storage_volumes_json, :show_tasks, :tasks]
- before_filter :pre_modify, :only => [:add_hosts, :move_hosts,
- :add_storage, :move_storage,
+ before_filter :pre_modify, :only => [:add_hosts, :move_hosts,
+ :add_storage, :move_storage,
:create_storage, :delete_storage]
def index
@@ -60,27 +58,6 @@ class HardwareController < ApplicationController
end
end
- def show
- set_perms(@perm_obj)
- unless @can_view
- flash[:notice] = 'You do not have permission to view this hardware pool: redirecting to top level'
- respond_to do |format|
- format.html { redirect_to :controller => "dashboard" }
- format.xml { head :forbidden }
- end
- return
- end
- respond_to do |format|
- format.html {
- render :layout => 'tabs-and-content' if params[:ajax]
- render :layout => false if params[:nolayout]
- }
- format.xml {
- render :xml => @pool.to_xml(XML_OPTS)
- }
- end
- end
-
def json_view_tree
json_tree_internal(Permission::PRIV_VIEW, false)
end
@@ -121,11 +98,6 @@ class HardwareController < ApplicationController
show
end
- def show_users
- @roles = Permission::ROLES.keys
- show
- end
-
def show_hosts
@hardware_pools = HardwarePool.find :all
show
@@ -145,53 +117,23 @@ class HardwareController < ApplicationController
["Host Task", "HostTask"],
["Storage Task", "StorageTask", "break"],
["Show All", ""]]
- @task_states = [["Queued", Task::STATE_QUEUED],
- ["Running", Task::STATE_RUNNING],
- ["Paused", Task::STATE_PAUSED],
- ["Finished", Task::STATE_FINISHED],
- ["Failed", Task::STATE_FAILED],
- ["Canceled", Task::STATE_CANCELED, "break"],
- ["Show All", ""]]
- params[:page]=1
- params[:sortname]="tasks.created_at"
- params[:sortorder]="desc"
- @tasks = tasks_internal
- show
- end
-
- def tasks
- render :json => tasks_internal.to_json
+ super
end
def tasks_internal
@task_type = params[:task_type]
@task_type ||=""
- @task_state = params[:task_state]
- @task_state ||=Task::STATE_QUEUED
- conditions = {}
- conditions[:type] = @task_type unless @task_type.empty?
- conditions[:state] = @task_state unless @task_state.empty?
- find_opts = {:include => [:storage_pool, :host, :vm]}
- find_opts[:conditions] = conditions unless conditions.empty?
- attr_list = []
- attr_list << :id if params[:checkboxes]
- attr_list += [:type_label, :task_obj, :action, :state, :user, :created_at, :args, :message]
- json_hash(@pool.tasks, attr_list, [:all], find_opts)
- end
-
- def quick_summary
- pre_show
- render :layout => 'selection'
+ super
end
def hosts_json
if params[:exclude_host]
- pre_json
+ pre_show
hosts = @pool.hosts
find_opts = {:conditions => ["id != ?", params[:exclude_host]]}
include_pool = false
elsif params[:id]
- pre_json
+ pre_show
hosts = @pool.hosts
find_opts = {}
include_pool = false
@@ -219,14 +161,9 @@ class HardwareController < ApplicationController
{:finder => 'call_finder', :conditions => ["type = 'VmResourcePool'"]})
end
- def users_json
- json_list(@pool.permissions,
- [:grid_id, :uid, :user_role, :source])
- end
-
def storage_pools_json
if params[:id]
- pre_json
+ pre_show
storage_pools = @pool.storage_pools
find_opts = {}
include_pool = false
@@ -258,7 +195,7 @@ class HardwareController < ApplicationController
def new
@resource_type = params[:resource_type]
@resource_ids = params[:resource_ids]
- render :layout => 'popup'
+ super
end
def create
@@ -293,10 +230,6 @@ class HardwareController < ApplicationController
end
end
- def edit
- render :layout => 'popup'
- end
-
def update
if params[:hardware_pool]
# FIXME: For the REST API, we allow moving hosts/storage through
@@ -455,28 +388,23 @@ class HardwareController < ApplicationController
:alert => alert } }
format.xml { head status }
end
- end
+ end
- private
+ protected
#filter methods
def pre_new
@pool = HardwarePool.new
- @parent = Pool.find(params[:parent_id])
- @perm_obj = @parent
- @current_pool_id=@parent.id
+ super
end
def pre_create
# FIXME: REST and browsers send params differently. Should be fixed
# in the views
if params[:pool]
@pool = HardwarePool.new(params[:pool])
- @parent = Pool.find(params[:parent_id])
else
@pool = HardwarePool.new(params[:hardware_pool])
- @parent = Pool.find(params[:hardware_pool][:parent_id])
end
- @perm_obj = @parent
- @current_pool_id=@parent.id
+ super
end
def pre_edit
@pool = HardwarePool.find(params[:id])
@@ -486,18 +414,7 @@ class HardwareController < ApplicationController
end
def pre_show
@pool = HardwarePool.find(params[:id])
- @perm_obj = @pool
- @current_pool_id=@pool.id
- set_perms(@perm_obj)
- unless @can_view
- flash[:notice] = 'You do not have permission to view this Hardware Pool: redirecting to top level'
- # FIXME: figure out the return type and render appropriately
- redirect_to :action => 'list'
- return
- end
- end
- def pre_json
- pre_show
+ super
end
def pre_modify
pre_edit
diff --git a/wui/src/app/controllers/pool_controller.rb b/wui/src/app/controllers/pool_controller.rb
new file mode 100644
index 0000000..ce41701
--- /dev/null
+++ b/wui/src/app/controllers/pool_controller.rb
@@ -0,0 +1,132 @@
+#
+# 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 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,
+ :storage_volumes_json, :quick_summary]
+
+ def show
+ respond_to do |format|
+ format.html {
+ render :layout => 'tabs-and-content' if params[:ajax]
+ render :layout => false if params[:nolayout]
+ }
+ format.xml {
+ render :xml => @pool.to_xml(XML_OPTS)
+ }
+ end
+ end
+
+ def quick_summary
+ render :layout => 'selection'
+ end
+
+ # resource's users list page
+ def show_users
+ @roles = Permission::ROLES.keys
+ show
+ end
+
+ def users_json
+ json_list(@pool.permissions,
+ [:grid_id, :uid, :user_role, :source])
+ end
+
+ def show_tasks
+ @task_states = [["Queued", Task::STATE_QUEUED],
+ ["Running", Task::STATE_RUNNING],
+ ["Paused", Task::STATE_PAUSED],
+ ["Finished", Task::STATE_FINISHED],
+ ["Failed", Task::STATE_FAILED],
+ ["Canceled", Task::STATE_CANCELED, "break"],
+ ["Show All", ""]]
+ params[:page]=1
+ params[:sortname]="tasks.created_at"
+ params[:sortorder]="desc"
+ @tasks = tasks_internal
+ show
+ end
+
+ def tasks
+ render :json => tasks_internal.to_json
+ end
+
+ def tasks_internal
+ @task_state = params[:task_state]
+ @task_state ||=Task::STATE_QUEUED
+ conditions = {}
+ conditions[:type] = @task_type unless @task_type.empty?
+ conditions[:state] = @task_state unless @task_state.empty?
+ find_opts = {:include => [:storage_pool, :host, :vm]}
+ find_opts[:conditions] = conditions unless conditions.empty?
+ attr_list = []
+ attr_list << :id if params[:checkboxes]
+ attr_list += [:type_label, :task_obj, :action, :state, :user, :created_at, :args, :message]
+ json_hash(@pool.tasks, attr_list, [:all], find_opts)
+ end
+
+ def new
+ render :layout => 'popup'
+ end
+
+ def edit
+ render :layout => 'popup'
+ end
+
+ protected
+ def pre_new
+ @parent = Pool.find(params[:parent_id])
+ @perm_obj = @parent
+ @redir_controller = @perm_obj.get_controller
+ @current_pool_id=@parent.id
+ end
+ def pre_create
+ #this is currently only true for the rest API for hardware pools
+ if params[:hardware_pool]
+ @parent = Pool.find(params[:hardware_pool][:parent_id])
+ else
+ @parent = Pool.find(params[:parent_id])
+ end
+ @perm_obj = @parent
+ @redir_controller = @perm_obj.get_controller
+ @current_pool_id=@parent.id
+ end
+ def pre_show_pool
+ pre_show
+ end
+ def pre_show
+ @perm_obj = @pool
+ @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'
+ respond_to do |format|
+ format.html { redirect_to :controller => "dashboard" }
+ format.xml { head :forbidden }
+ end
+ return
+ end
+ end
+
+end
diff --git a/wui/src/app/controllers/resources_controller.rb b/wui/src/app/controllers/resources_controller.rb
index 5a8276c..a0a65a6 100644
--- a/wui/src/app/controllers/resources_controller.rb
+++ b/wui/src/app/controllers/resources_controller.rb
@@ -17,14 +17,12 @@
# MA 02110-1301, USA. A copy of the GNU General Public License is
# also available at http://www.gnu.org/copyleft/gpl.html.
-class ResourcesController < ApplicationController
+class ResourcesController < PoolController
def index
list
render :action => 'list'
end
- before_filter :pre_json, :only => [:vms_json, :users_json,
- :show_tasks, :tasks]
before_filter :pre_vm_actions, :only => [:vm_actions]
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
@@ -49,17 +47,7 @@ class ResourcesController < ApplicationController
["Resume", VmTask::ACTION_RESUME_VM],
["Save", VmTask::ACTION_SAVE_VM],
["Restore", VmTask::ACTION_RESTORE_VM]]
- if params[:ajax]
- render :layout => 'tabs-and-content'
- end
- if params[:nolayout]
- render :layout => false
- end
- end
-
- def quick_summary
- pre_show
- render :layout => 'selection'
+ super
end
# resource's vms list page
@@ -73,81 +61,36 @@ class ResourcesController < ApplicationController
show
end
- # resource's users list page
- def show_users
- @roles = Permission::ROLES.keys
- show
- end
-
- def show_tasks
- @task_states = [["Queued", Task::STATE_QUEUED],
- ["Running", Task::STATE_RUNNING],
- ["Paused", Task::STATE_PAUSED],
- ["Finished", Task::STATE_FINISHED],
- ["Failed", Task::STATE_FAILED],
- ["Canceled", Task::STATE_CANCELED, "break"],
- ["Show All", ""]]
- params[:page]=1
- params[:sortname]="tasks.created_at"
- params[:sortorder]="desc"
- @tasks = tasks_internal
- show
- end
-
- def tasks
- render :json => tasks_internal.to_json
- end
-
def tasks_internal
+ @task_type = ""
@task_state = params[:task_state]
- @task_state ||=Task::STATE_QUEUED
- conditions = {}
- conditions[:state] = @task_state unless @task_state.empty?
- find_opts = {:include => [:storage_pool, :host, :vm]}
- find_opts[:conditions] = conditions unless conditions.empty?
- attr_list = []
- attr_list << :id if params[:checkboxes]
- attr_list += [:type_label, :task_obj, :action, :state, :user, :created_at, :args, :message]
- json_hash(@vm_resource_pool.tasks, attr_list, [:all], find_opts)
+ super
end
def vms_json
- json_list(@vm_resource_pool.vms,
+ json_list(@pool.vms,
[:id, :description, :uuid, :num_vcpus_allocated, :memory_allocated_in_mb, :vnic_mac_addr, :state, :id])
end
- def users_json
- json_list(@vm_resource_pool.permissions,
- [:grid_id, :uid, :user_role, :source])
- end
-
- def new
- render :layout => 'popup'
- end
-
def create
begin
- @vm_resource_pool.create_with_parent(@parent)
+ @pool.create_with_parent(@parent)
render :json => { :object => "vm_resource_pool", :success => true,
:alert => "Virtual Machine Pool was successfully created." }
rescue
render :json => { :object => "vm_resource_pool", :success => false,
- :errors => @vm_resource_pool.errors.localize_error_messages.to_a}
+ :errors => @pool.errors.localize_error_messages.to_a}
end
end
- def edit
- render :layout => 'popup'
- end
-
def update
begin
- @vm_resource_pool.update_attributes!(params[:vm_resource_pool])
+ @pool.update_attributes!(params[:vm_resource_pool])
render :json => { :object => "vm_resource_pool", :success => true,
:alert => "Virtual Machine Pool was successfully modified." }
rescue
render :json => { :object => "vm_resource_pool", :success => false,
- :errors => @vm_resource_pool.errors.localize_error_messages.to_a}
+ :errors => @pool.errors.localize_error_messages.to_a}
end
end
@@ -174,7 +117,7 @@ class ResourcesController < ApplicationController
end
def destroy
- if @vm_resource_pool.destroy
+ if @pool.destroy
alert="Virtual Machine Pool was successfully deleted."
success=true
else
@@ -192,7 +135,7 @@ class ResourcesController < ApplicationController
@success_list = []
@failure_list = []
begin
- @vm_resource_pool.transaction do
+ @pool.transaction do
@vms.each do |vm|
if vm.queue_action(@user, @action)
@success_list << vm
@@ -212,45 +155,30 @@ class ResourcesController < ApplicationController
protected
def pre_new
- @vm_resource_pool = VmResourcePool.new
- @parent = Pool.find(params[:parent_id])
- @perm_obj = @parent
- @redir_controller = @perm_obj.get_controller
- @current_pool_id=@parent.id
+ @pool = VmResourcePool.new
+ super
end
def pre_create
- @vm_resource_pool = VmResourcePool.new(params[:vm_resource_pool])
- @parent = Pool.find(params[:parent_id])
- @perm_obj = @parent
- @redir_controller = @perm_obj.get_controller
- @current_pool_id=@parent.id
- end
- def pre_show
- @vm_resource_pool = VmResourcePool.find(params[:id])
- @perm_obj = @vm_resource_pool
- @current_pool_id=@vm_resource_pool.id
- set_perms(@perm_obj)
- @is_hwpool_admin = @vm_resource_pool.parent.can_modify(@user)
- unless @can_view
- flash[:notice] = 'You do not have permission to view this VM Resource Pool: redirecting to top level'
- redirect_to :action => 'dashboard'
- end
+ @pool = VmResourcePool.new(params[:vm_resource_pool])
+ super
end
def pre_edit
- @vm_resource_pool = VmResourcePool.find(params[:id])
- @parent = @vm_resource_pool.parent
- @perm_obj = @vm_resource_pool.parent
- @redir_obj = @vm_resource_pool
- @current_pool_id=@vm_resource_pool.id
+ @pool = VmResourcePool.find(params[:id])
+ @parent = @pool.parent
+ @perm_obj = @pool.parent
+ @redir_obj = @pool
+ @current_pool_id=@pool.id
end
- def pre_json
- pre_show
+ def pre_show
+ @pool = VmResourcePool.find(params[:id])
+ @is_hwpool_admin = @pool.parent.can_modify(@user)
+ super
end
def pre_vm_actions
- @vm_resource_pool = VmResourcePool.find(params[:id])
- @parent = @vm_resource_pool.parent
- @perm_obj = @vm_resource_pool
- @redir_obj = @vm_resource_pool
+ @pool = VmResourcePool.find(params[:id])
+ @parent = @pool.parent
+ @perm_obj = @pool
+ @redir_obj = @pool
authorize_user
end
diff --git a/wui/src/app/controllers/smart_pool_controller.rb b/wui/src/app/controllers/smart_pool_controller.rb
new file mode 100644
index 0000000..eb087a6
--- /dev/null
+++ b/wui/src/app/controllers/smart_pool_controller.rb
@@ -0,0 +1,22 @@
+#
+# 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/wui/src/app/controllers/tree_controller.rb b/wui/src/app/controllers/tree_controller.rb
index c7dbe35..5ad8426 100644
--- a/wui/src/app/controllers/tree_controller.rb
+++ b/wui/src/app/controllers/tree_controller.rb
@@ -1,10 +1,10 @@
class TreeController < ApplicationController
def fetch_nav
- @pools = Pool.root.full_set_nested(:method => :json_hash_element)
+ @pools = HardwarePool.get_default_pool.full_set_nested(:method => :json_hash_element)
end
def fetch_json
- render :json => Pool.root.full_set_nested(:method => :json_hash_element).to_json
+ render :json => HardwarePool.get_default_pool.full_set_nested(:method => :json_hash_element).to_json
end
end
diff --git a/wui/src/app/models/directory_pool.rb b/wui/src/app/models/directory_pool.rb
new file mode 100644
index 0000000..f62d980
--- /dev/null
+++ b/wui/src/app/models/directory_pool.rb
@@ -0,0 +1,60 @@
+#
+# 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 DirectoryPool < Pool
+
+ ROOT_NAME = "root"
+ HARDWARE_ROOT = "hardware"
+ SMART_ROOT = "users"
+
+ def self.get_directory_root
+ self.root(:conditions=>"type='DirectoryPool'")
+ end
+
+ def self.get_hardware_root
+ dir_root = get_directory_root
+ dir_root ? dir_root.named_child(HARDWARE_ROOT) : nil
+ end
+
+ def self.get_smart_root
+ dir_root = get_directory_root
+ dir_root ? dir_root.named_child(SMART_ROOT) : nil
+ end
+
+ def self.get_user_root(user)
+ smart_root = get_smart_root
+ smart_root ? smart_root.named_child(user) : nil
+ end
+
+ def self.get_or_create_user_root(user)
+ user_root = get_user_root(user)
+ unless user_root
+ DirectoryPool.transaction do
+ user_root = DirectoryPool.new(:name => user)
+ user_root.create_with_parent(get_smart_root)
+ permission = Permission.new({:pool_id => user_root.id,
+ :uid => user,
+ :user_role => Permission::ROLE_SUPER_ADMIN})
+ #we don't need save_with_new_children here since there are no children yet
+ permission.save!
+ end
+ end
+ end
+
+end
diff --git a/wui/src/app/models/hardware_pool.rb b/wui/src/app/models/hardware_pool.rb
index 5409862..160f663 100644
--- a/wui/src/app/models/hardware_pool.rb
+++ b/wui/src/app/models/hardware_pool.rb
@@ -19,6 +19,8 @@
class HardwarePool < Pool
+ DEFAULT_POOL_NAME = "default"
+
has_many :tasks, :dependent => :nullify
def all_storage_volumes
StorageVolume.find(:all, :include => {:storage_pool => :hardware_pool}, :conditions => "pools.id = #{id}")
@@ -34,7 +36,8 @@ class HardwarePool < Pool
# note: doesn't currently join w/ permissions
def self.get_default_pool
- self.root
+ hw_root = DirectoryPool.get_hardware_root
+ hw_root ? hw_root.named_child(DEFAULT_POOL_NAME) : nil
end
def create_with_resources(parent, resource_type= nil, resource_ids=[])
@@ -98,17 +101,4 @@ class HardwarePool < Pool
return {:total => total, :labels => labels}
end
- def self.find_by_path(path)
- segs = path.split("/")
- unless segs.shift.empty?
- raise "Path must be absolute, but is #{path}"
- end
- default_pool = get_default_pool
- if segs.shift == default_pool.name
- segs.inject(default_pool) do |pool, seg|
- pool.sub_hardware_pools.find { |p| p.name == seg } if pool
- end
- end
- end
-
end
diff --git a/wui/src/app/models/host.rb b/wui/src/app/models/host.rb
index 5b32653..3fc3abb 100644
--- a/wui/src/app/models/host.rb
+++ b/wui/src/app/models/host.rb
@@ -40,6 +40,9 @@ class Host < ActiveRecord::Base
end
end
+ has_many :smart_pool_tags, :as => :tagged, :dependent => :destroy
+ has_many :smart_pools, :through => :smart_pool_tags
+
acts_as_xapian :texts => [ :hostname, :uuid, :hypervisor_type, :arch ],
:values => [ [ :created_at, 0, "created_at", :date ],
[ :updated_at, 1, "updated_at", :date ] ],
diff --git a/wui/src/app/models/pool.rb b/wui/src/app/models/pool.rb
index 6599c72..9d71fa5 100644
--- a/wui/src/app/models/pool.rb
+++ b/wui/src/app/models/pool.rb
@@ -42,12 +42,15 @@ class Pool < ActiveRecord::Base
end
end
+ has_many :smart_pool_tags, :as => :tagged, :dependent => :destroy
+ has_many :smart_pools, :through => :smart_pool_tags
# used to allow parent traversal before obj is saved to the db
# (needed for view code 'create' form)
attr_accessor :tmp_parent
validates_presence_of :name
+ validates_uniqueness_of :name, :scope => :parent_id
# overloading this method such that we can use permissions.admins to get all the admins for an object
has_many :permissions, :dependent => :destroy, :order => "id ASC" do
@@ -125,6 +128,11 @@ class Pool < ActiveRecord::Base
self_and_siblings.select {|pool| pool[:type] == self.class.name}
end
+ def named_child(child_name)
+ matches = children(:conditions=>"name='#{child_name}'")
+ matches ? matches[0] : nil
+ end
+
def can_view(user)
has_privilege(user, Permission::PRIV_VIEW)
end
@@ -252,6 +260,19 @@ class Pool < ActiveRecord::Base
permissions.collect {|perm| perm.uid}
end
+ def self.find_by_path(path)
+ segs = path.split("/")
+ unless segs.shift.empty?
+ raise "Path must be absolute, but is #{path}"
+ end
+ default_pool = DirectoryPool.get_directory_root
+ if segs.shift == default_pool.name
+ segs.inject(default_pool) do |pool, seg|
+ pool.children.find { |p| p.name == seg } if pool
+ end
+ end
+ end
+
protected
def traverse_parents
if id
diff --git a/wui/src/app/models/smart_pool.rb b/wui/src/app/models/smart_pool.rb
new file mode 100644
index 0000000..e672c5b
--- /dev/null
+++ b/wui/src/app/models/smart_pool.rb
@@ -0,0 +1,47 @@
+#
+# 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 SmartPool < Pool
+ has_many :smart_pool_tags, :dependent => :destroy
+ has_many :tagged_pools, :through => :smart_pool_tags, :source => :pool,
+ :conditions => "smart_pool_tags.tagged_type = 'Pool'"
+ has_many :tagged_storage_pools, :through => :smart_pool_tags,
+ :source => :storage_pool,
+ :conditions => "smart_pool_tags.tagged_type = 'StoragePool'"
+ has_many :tagged_hosts, :through => :smart_pool_tags, :source => :host,
+ :conditions => "smart_pool_tags.tagged_type = 'Host'"
+ has_many :tagged_vms, :through => :smart_pool_tags, :source => :vm,
+ :conditions => "smart_pool_tags.tagged_type = 'Vm'"
+
+
+ def create_for_user(user)
+ create_with_parent(DirectoryPool.get_or_create_user_root(user))
+ end
+
+ def add_item(item)
+ tag = SmartPoolTag.new(:smart_pool => self, :tagged => item)
+ tag.save!
+ end
+ def remove_item(item)
+ smart_pool_tags.find(:first, :conditions=> {
+ :tagged_type=>item.class.base_class.to_s,
+ :tagged_id=>item.id}).destroy
+ end
+
+end
diff --git a/wui/src/app/models/smart_pool_tag.rb b/wui/src/app/models/smart_pool_tag.rb
new file mode 100644
index 0000000..e135ddf
--- /dev/null
+++ b/wui/src/app/models/smart_pool_tag.rb
@@ -0,0 +1,37 @@
+#
+# 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 SmartPoolTag < ActiveRecord::Base
+ belongs_to :smart_pool
+ belongs_to :tagged, :polymorphic => true
+ belongs_to :pool, :class_name => "Pool",
+ :foreign_key => "tagged_id"
+ belongs_to :storage_pool, :class_name => "StoragePool",
+ :foreign_key => "tagged_id"
+ belongs_to :host, :class_name => "Host",
+ :foreign_key => "tagged_id"
+ belongs_to :vm, :class_name => "Vm",
+ :foreign_key => "tagged_id"
+
+ validates_uniqueness_of :smart_pool_id, :scope => [:tagged_id, :tagged_type]
+
+ def tagged_type=(sType)
+ super(sType.to_s.classify.constantize.base_class.to_s)
+ end
+end
diff --git a/wui/src/app/models/storage_pool.rb b/wui/src/app/models/storage_pool.rb
index 460b49d..bc98f8e 100644
--- a/wui/src/app/models/storage_pool.rb
+++ b/wui/src/app/models/storage_pool.rb
@@ -30,6 +30,9 @@ class StoragePool < ActiveRecord::Base
end
end
+ has_many :smart_pool_tags, :as => :tagged, :dependent => :destroy
+ has_many :smart_pools, :through => :smart_pool_tags
+
validates_presence_of :ip_addr, :hardware_pool_id
acts_as_xapian :texts => [ :ip_addr, :target, :export_path, :type ],
diff --git a/wui/src/app/models/vm.rb b/wui/src/app/models/vm.rb
index 80c7efb..cde28af 100644
--- a/wui/src/app/models/vm.rb
+++ b/wui/src/app/models/vm.rb
@@ -28,6 +28,10 @@ class Vm < ActiveRecord::Base
end
end
has_and_belongs_to_many :storage_volumes
+
+ has_many :smart_pool_tags, :as => :tagged, :dependent => :destroy
+ has_many :smart_pools, :through => :smart_pool_tags
+
validates_presence_of :uuid, :description, :num_vcpus_allocated,
:memory_allocated_in_mb, :memory_allocated, :vnic_mac_addr
diff --git a/wui/src/app/views/hardware/show_hosts.rhtml b/wui/src/app/views/hardware/show_hosts.rhtml
index f88c64b..31c575d 100644
--- a/wui/src/app/views/hardware/show_hosts.rhtml
+++ b/wui/src/app/views/hardware/show_hosts.rhtml
@@ -27,7 +27,7 @@
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: <%= Pool.root.id %> },
+ { resource_ids: hosts.toString(), target_pool_id: <%= HardwarePool.get_default_pool.id %> },
function(data,status){
$tabs.tabs("load",$tabs.data('selected.tabs'));
if (data.alert) {
diff --git a/wui/src/app/views/hardware/show_storage.rhtml b/wui/src/app/views/hardware/show_storage.rhtml
index 02b5180..564b9ed 100644
--- a/wui/src/app/views/hardware/show_storage.rhtml
+++ b/wui/src/app/views/hardware/show_storage.rhtml
@@ -18,7 +18,7 @@
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: <%= Pool.root.id %> },
+ { resource_ids: storage.toString(), target_pool_id: <%= HardwarePool.get_default_pool.id %> },
function(data,status){
$tabs.tabs("load",$tabs.data('selected.tabs'));
if (data.alert) {
diff --git a/wui/src/app/views/layouts/_navigation_tabs.rhtml b/wui/src/app/views/layouts/_navigation_tabs.rhtml
index 629ab93..4b0f18d 100644
--- a/wui/src/app/views/layouts/_navigation_tabs.rhtml
+++ b/wui/src/app/views/layouts/_navigation_tabs.rhtml
@@ -15,7 +15,7 @@
<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 == "resources" and @vm_resource_pool != nil %>
+<% elsif controller.controller_name == "resources" and @pool != nil %>
<script>
$(document).ready(function(){
$tabs = $("#resources_nav_tabs").tabs({
@@ -25,10 +25,10 @@
});
</script>
<ul id="resources_nav_tabs" class="ui-tabs-nav">
- <li id="nav_summary" class="ui-tabs-selected"><%= link_to "Summary", {:action => 'show', :id => @vm_resource_pool.id, :nolayout => :true}, :title => "content area" %></li>
- <li id="nav_vmpool"> <%= link_to "Virtual Machines", {:action => 'show_vms', :id => @vm_resource_pool.id, :nolayout => :true}, :title => "content area" %></li>
- <li id="nav_access"> <%= link_to "User Access", {:action => 'show_users', :id => @vm_resource_pool.id, :nolayout => :true}, :title => "content area" %></li>
- <li id="nav_tasks"> <%= link_to "Tasks", {:action => 'show_tasks', :id => @vm_resource_pool.id, :nolayout => :true}, :title => "content area" %></li>
+ <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_vmpool"> <%= 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>
+ <li id="nav_tasks"> <%= link_to "Tasks", {:action => 'show_tasks', :id => @pool.id, :nolayout => :true}, :title => "content area" %></li>
</ul>
<% elsif controller.controller_name == "search" %>
<ul id="resources_nav_tabs" class="ui-tabs-nav">
diff --git a/wui/src/app/views/resources/edit.rhtml b/wui/src/app/views/resources/edit.rhtml
index a101247..c6fd264 100644
--- a/wui/src/app/views/resources/edit.rhtml
+++ b/wui/src/app/views/resources/edit.rhtml
@@ -7,7 +7,7 @@
<form method="POST" action="<%= url_for :action => 'update' %>" id="vm_pool_form" >
<div class="dialog_form">
- <%= hidden_field_tag 'id', @vm_resource_pool.id %>
+ <%= hidden_field_tag 'id', @pool.id %>
<%= render :partial => 'form' %>
</div>
<%= popup_footer("$('#vm_pool_form').submit()", "Edit Virtual Machine Pool") %>
@@ -26,7 +26,7 @@ $(function() {
refresh_summary('vmpool_selection',
'<%= url_for :controller => "resources",
:action => "quick_summary" %>',
- <%= @vm_resource_pool.id %>)
+ <%= @pool.id %>)
}
}
};
diff --git a/wui/src/app/views/resources/quick_summary.rhtml b/wui/src/app/views/resources/quick_summary.rhtml
index 60d0df7..31c4033 100644
--- a/wui/src/app/views/resources/quick_summary.rhtml
+++ b/wui/src/app/views/resources/quick_summary.rhtml
@@ -1,21 +1,21 @@
<%- content_for :title do -%>
- <%=h @vm_resource_pool.name %> quota
+ <%=h @pool.name %> quota
<%- end -%>
<%- content_for :action_links do -%>
<%if @is_hwpool_admin -%>
<%= link_to image_tag("icon_edit.png") + " Edit",
- {:controller => 'resources', :action => 'edit', :id => @vm_resource_pool},
+ {:controller => 'resources', :action => 'edit', :id => @pool},
:rel=>"facebox[.bolder]", :class=>"selection_facebox" %>
- <%if @vm_resource_pool.quota -%>
+ <%if @pool.quota -%>
<%= link_to image_tag("icon_edit.png") + " Edit Quota",
- {:controller => 'quota', :action => 'edit', :id => @vm_resource_pool.quota},
+ {:controller => 'quota', :action => 'edit', :id => @pool.quota},
:rel=>"facebox[.bolder]", :class=>"selection_facebox" %>
<a href="#confirm_delete_quota" rel="facebox[.bolder]">
<%= image_tag "icon_x.png" %> Revert to Default Quota
</a>
<% else -%>
<%= link_to image_tag("icon_edit.png") + " Edit Quota",
- {:controller => 'quota', :action => 'new', :pool_id => @vm_resource_pool },
+ {:controller => 'quota', :action => 'new', :pool_id => @pool },
:rel=>"facebox[.bolder]", :class=>"selection_facebox" %>
<% end -%>
<% end -%>
@@ -25,13 +25,13 @@
function delete_vm_quota()
{
$(document).trigger('close.facebox');
- $.post('<%= url_for :controller => "quota", :action => "destroy", :id => @vm_resource_pool.quota %>',
+ $.post('<%= url_for :controller => "quota", :action => "destroy", :id => @pool.quota %>',
{x: 1},
function(data,status){
refresh_summary('vmpool_selection',
'<%= url_for :controller => "resources",
:action => "quick_summary" %>',
- <%= @vm_resource_pool.id %>);
+ <%= @pool.id %>);
if (data.alert) {
$.jGrowl(data.alert);
}
@@ -39,8 +39,8 @@
}
</script>
- <div id="vmpool_selection_id" style="display:none"><%= @vm_resource_pool.id %></div>
- <% resources = @vm_resource_pool.full_resources %>
+ <div id="vmpool_selection_id" style="display:none"><%= @pool.id %></div>
+ <% resources = @pool.full_resources %>
<div class="selection_key">
<br/>
<% for item in resources[:labels] %>
@@ -60,5 +60,5 @@
</div>
</div>
<div class="selection_right">
- <%= render_component :controller=> 'graph', :action => 'snapshot_graph', :id => @vm_resource_pool.id, :target => 'resource' %>
+ <%= render_component :controller=> 'graph', :action => 'snapshot_graph', :id => @pool.id, :target => 'resource' %>
</div>
diff --git a/wui/src/app/views/resources/show.rhtml b/wui/src/app/views/resources/show.rhtml
index 0db3a1b..789465b 100644
--- a/wui/src/app/views/resources/show.rhtml
+++ b/wui/src/app/views/resources/show.rhtml
@@ -1,18 +1,18 @@
<div class="data_section_summary">
- <div class="summary_title"><%= image_tag "icon_vmpool.png", :style=>"vertical-align:middle;" %> <%= @vm_resource_pool.name %></div><br/><br/>
+ <div class="summary_title"><%= image_tag "icon_vmpool.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">
- <%= render_component :controller=> 'graph', :action => 'availability_graph', :id => @vm_resource_pool.id, :params => { :target => 'vcpu' } %>
- <%= render_component :controller=> 'graph', :action => 'availability_graph', :id => @vm_resource_pool.id, :params => { :target => 'vram' } %>
+ <%= render_component :controller=> 'graph', :action => 'availability_graph', :id => @pool.id, :params => { :target => 'vcpu' } %>
+ <%= render_component :controller=> 'graph', :action => 'availability_graph', :id => @pool.id, :params => { :target => 'vram' } %>
</div>
<br/><br/>
<div class="summary_subtitle"><%= image_tag "icon_smry_his.png", :style=>"vertical-align:middle;" %> History</div><br/>
- <%= render_component :controller=> 'graph', :action => 'history_graphs', :id => @vm_resource_pool.id, :params => { :poolType => 'vm' } %>
+ <%= render_component :controller=> 'graph', :action => 'history_graphs', :id => @pool.id, :params => { :poolType => 'vm' } %>
<div class="summary_subtitle"><%= image_tag "icon_smry_perf.png", :style=>"vertical-align:middle;" %> Performance</div><br/>
- <%= render_component :controller=> 'graph', :action => 'snapshot_graph', :id => @vm_resource_pool.id, :params => { :poolType => 'vm' } %>
+ <%= render_component :controller=> 'graph', :action => 'snapshot_graph', :id => @pool.id, :params => { :poolType => 'vm' } %>
</div>
<div class="selection_detail" id="vmpool_selection">
@@ -23,6 +23,6 @@
refresh_summary('vmpool_selection',
'<%= url_for :controller => "resources",
:action => "quick_summary" %>',
- <%= @vm_resource_pool.id %>)
+ <%= @pool.id %>)
</script>
diff --git a/wui/src/app/views/resources/show_tasks.rhtml b/wui/src/app/views/resources/show_tasks.rhtml
index 493264b..6c92779 100644
--- a/wui/src/app/views/resources/show_tasks.rhtml
+++ b/wui/src/app/views/resources/show_tasks.rhtml
@@ -24,7 +24,7 @@
function apply_task_state_filter(task_state)
{
$tabs.tabs("url", $tabs.data("selected.tabs"),
- "<%= url_for :action => 'show_tasks', :id => @vm_resource_pool.id,
+ "<%= url_for :action => 'show_tasks', :id => @pool.id,
:nolayout => :true %>" +
"&task_state=" + task_state);
$tabs.tabs("load", $tabs.data("selected.tabs"));
@@ -37,7 +37,7 @@
<%= render :partial => "/task/grid", :locals => { :table_id => "vm_tasks_grid",
:task_type => nil,
:task_state => @task_state,
- :pool => @vm_resource_pool,
+ :pool => @pool,
:checkboxes => false,
:on_select => "vm_tasks_grid_select" } %>
</div>
diff --git a/wui/src/app/views/resources/show_users.rhtml b/wui/src/app/views/resources/show_users.rhtml
index 7e2538d..f23018c 100644
--- a/wui/src/app/views/resources/show_users.rhtml
+++ b/wui/src/app/views/resources/show_users.rhtml
@@ -1,2 +1,2 @@
<%= render :partial => "/user/show", :locals => { :parent_controller => "resources",
- :pool => @vm_resource_pool } %>
+ :pool => @pool } %>
diff --git a/wui/src/app/views/resources/show_vms.rhtml b/wui/src/app/views/resources/show_vms.rhtml
index 45e0089..857f56b 100644
--- a/wui/src/app/views/resources/show_vms.rhtml
+++ b/wui/src/app/views/resources/show_vms.rhtml
@@ -1,6 +1,6 @@
<div id="toolbar_nav">
<ul>
- <li><a href="<%= url_for :controller => 'vm', :action => 'new', :vm_resource_pool_id => @vm_resource_pool %>" rel="facebox[.bolder]"><%= image_tag "icon_addhost.png", :style => "vertical-align:middle;" %> Add Virtual Machine</a></li>
+ <li><a href="<%= url_for :controller => 'vm', :action => 'new', :vm_resource_pool_id => @pool %>" rel="facebox[.bolder]"><%= image_tag "icon_addhost.png", :style => "vertical-align:middle;" %> Add Virtual Machine</a></li>
<li>
<%= image_tag "icon_move.png", :style => "vertical-align:middle;" %> Actions <%= image_tag "icon_toolbar_arrow.gif", :style => "vertical-align:middle;" %>
<ul>
@@ -28,7 +28,7 @@
{
vms = get_selected_vms()
if (validate_selected(vms, "vm")) {
- $.post('<%= url_for :controller => "vm", :action => "delete", :id => @vm_resource_pool %>',
+ $.post('<%= url_for :controller => "vm", :action => "delete", :id => @pool %>',
{ vm_ids: vms.toString() },
function(data,status){
$tabs.tabs("load",$tabs.data('selected.tabs'));
@@ -47,7 +47,7 @@
if (validate_selected(vms, "vm")) {
jQuery.facebox('<div id="vm_action_results">');
$('#vm_action_results').load('<%= url_for :controller => "resources",
- :action => "vm_actions", :id => @vm_resource_pool %>',
+ :action => "vm_actions", :id => @pool %>',
{ vm_ids: vms.toString(), vm_action: action });
}
}
@@ -66,10 +66,10 @@
</script>
<div class="panel_header"></div>
-<% if @vm_resource_pool.vms.size != 0 %>
+<% if @pool.vms.size != 0 %>
<div class="data_section">
<%= render :partial => "/vm/grid", :locals => { :table_id => "vms_grid",
- :pool => @vm_resource_pool,
+ :pool => @pool,
:on_select => "vms_select",
:on_deselect => "load_widget_deselect",
:on_hover => "load_widget_hover",
@@ -88,7 +88,7 @@
<div class="no-grid-items-text">
No vms found in this pool. <br/><br/>
<%= image_tag "icon_addhost.png", :style => "vertical-align:middle;" %>
- <a href="<%= url_for :controller => 'vm', :action => 'new', :vm_resource_pool_id => @vm_resource_pool %>" rel="facebox[.bolder]">Add first virtual machine to resource pool</a></li>
+ <a href="<%= url_for :controller => 'vm', :action => 'new', :vm_resource_pool_id => @pool %>" rel="facebox[.bolder]">Add first virtual machine to resource pool</a></li>
</div>
</div>
</div>
diff --git a/wui/src/db/migrate/017_add_smart_pools.rb b/wui/src/db/migrate/017_add_smart_pools.rb
new file mode 100644
index 0000000..6d83c02
--- /dev/null
+++ b/wui/src/db/migrate/017_add_smart_pools.rb
@@ -0,0 +1,62 @@
+#
+# 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 AddSmartPools < ActiveRecord::Migration
+ def self.up
+ create_table :smart_pool_tags do |t|
+ t.integer :smart_pool_id, :null => false
+ t.integer :tagged_id, :null => false
+ t.string :tagged_type, :null => false
+ end
+ execute "alter table smart_pool_tags add constraint
+ fk_smart_pool_tags_pool_id
+ foreign key (smart_pool_id) references pools(id)"
+ execute "alter table smart_pool_tags add constraint
+ unique_smart_pool_tags
+ unique (smart_pool_id, tagged_id, tagged_type)"
+
+ begin
+ dir_root = DirectoryPool.get_directory_root
+ unless dir_root
+ Pool.transaction do
+ dir_root = DirectoryPool.create(:name=>DirectoryPool::ROOT_NAME)
+ hw_root = DirectoryPool.new(:name=>DirectoryPool::HARDWARE_ROOT)
+ hw_root.create_with_parent(dir_root)
+ smart_root = DirectoryPool.new(:name=>DirectoryPool::SMART_ROOT)
+ smart_root.create_with_parent(dir_root)
+ default_pool = Pool.root(:conditions=>"type='HardwarePool'")
+ default_pool = HardwarePool.create( :name=>'default') unless default_pool
+ default_pool.move_to_child_of(hw_root)
+ default_pool.permissions.each do |permission|
+ new_permission = Permission.new({:pool_id => dir_root.id,
+ :uid => permission.uid,
+ :user_role => permission.user_role})
+ new_permission.save!
+ end
+ end
+ end
+ rescue
+ puts "Could not create DirectoryPool hierarchy..."
+ end
+ end
+
+ def self.down
+ drop_table :smart_pool_tags
+ end
+end
diff --git a/wui/src/dutils/active_record_env.rb b/wui/src/dutils/active_record_env.rb
index 9b7b416..14593f7 100644
--- a/wui/src/dutils/active_record_env.rb
+++ b/wui/src/dutils/active_record_env.rb
@@ -58,6 +58,8 @@ require 'models/permission.rb'
require 'models/quota.rb'
require 'models/hardware_pool.rb'
+require 'models/directory_pool.rb'
+require 'models/smart_pool.rb'
require 'models/host.rb'
require 'models/cpu.rb'
require 'models/nic.rb'
@@ -77,4 +79,6 @@ require 'models/nfs_storage_pool.rb'
require 'models/storage_volume.rb'
require 'models/iscsi_storage_volume.rb'
require 'models/nfs_storage_volume.rb'
+require 'models/smart_pool.rb'
+require 'models/smart_pool_tag.rb'
diff --git a/wui/src/script/grant_admin_privileges b/wui/src/script/grant_admin_privileges
index 82595cb..866fd44 100755
--- a/wui/src/script/grant_admin_privileges
+++ b/wui/src/script/grant_admin_privileges
@@ -13,10 +13,11 @@ ActiveLdap::Base.establish_connection :base => base, :host => host, :try_sasl =>
if Account.exists?("uid=#{uid}")
puts "Creating an admin account for #{uid}..."
- $hwpool = HardwarePool.get_default_pool
- permission = Permission.create(:user_role => Permission::ROLE_SUPER_ADMIN,
- :uid => uid,
- :pool_id => $hwpool.id)
+ $pool = DirectoryPool.get_directory_root
+ permission = Permission.new(:user_role => Permission::ROLE_SUPER_ADMIN,
+ :uid => uid,
+ :pool_id => $pool.id)
+ permission.save_with_new_children
else
puts "Unable to verify user: uid=#{uid}"
end
diff --git a/wui/src/vendor/plugins/betternestedset/lib/better_nested_set.rb b/wui/src/vendor/plugins/betternestedset/lib/better_nested_set.rb
index cdcf0c6..e91ca93 100644
--- a/wui/src/vendor/plugins/betternestedset/lib/better_nested_set.rb
+++ b/wui/src/vendor/plugins/betternestedset/lib/better_nested_set.rb
@@ -81,13 +81,22 @@ module SymetrieCom
# Returns the single root for the class (or just the first root, if there are several).
# Deprecation note: the original acts_as_nested_set allowed roots to have parent_id = 0,
# so we currently do the same. This silliness will not be tolerated in future versions, however.
- def root
- acts_as_nested_set_options[:class].find(:first, :conditions => "(#{acts_as_nested_set_options[:parent_column]} IS NULL OR #{acts_as_nested_set_options[:parent_column]} = 0)")
+ def root(find_opts={})
+ roots_internal(:first, find_opts)
end
# Returns the roots and/or virtual roots of all trees. See the explanation of virtual roots in the README.
- def roots
- acts_as_nested_set_options[:class].find(:all, :conditions => "(#{acts_as_nested_set_options[:parent_column]} IS NULL OR #{acts_as_nested_set_options[:parent_column]} = 0)", :order => "#{acts_as_nested_set_options[:left_column]}")
+ def roots(find_opts={})
+ roots_internal(:all, find_opts)
+ end
+ def roots_internal(all_or_one, find_opts={})
+ conditions = "(#{acts_as_nested_set_options[:parent_column]} IS NULL"
+ conditions += " OR #{acts_as_nested_set_options[:parent_column]} = 0)"
+ order_col = "#{acts_as_nested_set_options[:left_column]}"
+ opts = merge_incoming_opts({:conditions => conditions,
+ :order => order_col},
+ find_opts)
+ acts_as_nested_set_options[:class].find(all_or_one, opts)
end
# Checks the left/right indexes of all records,
@@ -128,6 +137,14 @@ module SymetrieCom
items.map! {|e| "(#{acts_as_nested_set_options[:left_column]} BETWEEN #{e[acts_as_nested_set_options[:left_column]]} AND #{e[acts_as_nested_set_options[:right_column]]})" }
"(#{items.join(' OR ')})"
end
+
+ # accept incoming opts to allow filtering of results.
+ # So far only tested in limited use cases encountered in oVirt devel.
+ def merge_incoming_opts(set_opts, incoming_opts)
+ new_conditions = incoming_opts.delete(:conditions)
+ set_opts[:conditions] = "(#{set_opts[:conditions]}) AND (#{new_conditions})" if new_conditions
+ set_opts.merge(incoming_opts)
+ end
end
@@ -255,7 +272,7 @@ module SymetrieCom
elsif new_record? || self[right_col_name] - self[left_col_name] == 1
return [self]
end
- opts = merge_incoming_opts({:conditions => "#{scope_condition} #{exclude_str} AND (#{left_col_name} BETWEEN #{self[left_col_name]} AND #{self[right_col_name]})",
+ opts = base_set_class.merge_incoming_opts({:conditions => "#{scope_condition} #{exclude_str} AND (#{left_col_name} BETWEEN #{self[left_col_name]} AND #{self[right_col_name]})",
:order => left_col_name},
find_opts)
base_set_class.find(:all, opts)
@@ -270,7 +287,7 @@ module SymetrieCom
# Returns this record's immediate children.
def children(find_opts={})
- opts = merge_incoming_opts({:conditions => "#{scope_condition} AND #{parent_col_name} = #{self.id}",
+ opts = base_set_class.merge_incoming_opts({:conditions => "#{scope_condition} AND #{parent_col_name} = #{self.id}",
:order => left_col_name},
find_opts)
base_set_class.find(:all, opts)
@@ -585,14 +602,6 @@ module SymetrieCom
self.class.connection.quote(value, column)
end
- # accept incoming opts to allow filtering of results.
- # So far only tested in limited use cases encountered in oVirt devel.
- def merge_incoming_opts(set_opts, incoming_opts)
- new_conditions = incoming_opts.delete(:conditions)
- set_opts[:conditions] = "(#{set_opts[:conditions]}) AND (#{new_conditions})" if new_conditions
- set_opts.merge(incoming_opts)
- end
-
end
end
end
--
1.5.5.1
More information about the ovirt-devel
mailing list