On Tue, May 27, 2008 at 10:22:58AM -0400, Scott Seago
wrote:>
> >From 95b8ffe92a8ed62837e71ec59c5fcfea1622e27c Mon Sep 17 00:00:00 2001
> From: Scott Seago <sseago at redhat.com>
> Date: Tue, 27 May 2008 10:19:08 -0400
> Subject: [PATCH] hooked up VM Actions support. The confirmation dialog here
needs a bit of styling work, but otherwise it works.
>
>
> Signed-off-by: Scott Seago <sseago at redhat.com>
> ---
> wui/src/app/controllers/resources_controller.rb | 97
+++++++++++++---------
> wui/src/app/controllers/vm_controller.rb | 17 ++---
> wui/src/app/helpers/application_helper.rb | 12 +++
> wui/src/app/models/vm.rb | 10 +++
> wui/src/app/models/vm_task.rb | 20 +++--
> wui/src/app/views/layouts/confirmation.rhtml | 2 +
> wui/src/app/views/resources/show_vms.rhtml | 14 +++-
> wui/src/app/views/resources/vm_actions.rhtml | 35 ++++++++
> 8 files changed, 147 insertions(+), 60 deletions(-)
> create mode 100644 wui/src/app/views/layouts/confirmation.rhtml
> create mode 100644 wui/src/app/views/resources/vm_actions.rhtml
>
> diff --git a/wui/src/app/controllers/resources_controller.rb
b/wui/src/app/controllers/resources_controller.rb
> index aef2fd5..febbbb6 100644
> --- a/wui/src/app/controllers/resources_controller.rb
> +++ b/wui/src/app/controllers/resources_controller.rb
> @@ -24,6 +24,7 @@ class ResourcesController < ApplicationController
> end
>
> before_filter :pre_json, :only => [:vms_json, :users_json]
> + before_filter :pre_vm_actions, :only => [:vm_actions]
>
> # GETs should be safe (see
http://www.w3.org/2001/tag/doc/whenToUseGet.html)
> verify :method => :post, :only => [ :destroy, :create, :update ],
> @@ -69,12 +70,12 @@ class ResourcesController < ApplicationController
> # resource's vms list page
> def show_vms
> show
> - @actions = [["Start", VmTask::ACTION_START_VM],
> - ["Shutdown", VmTask::ACTION_SHUTDOWN_VM,
"break"],
> - ["Suspend", VmTask::ACTION_SUSPEND_VM],
> - ["Resume", VmTask::ACTION_RESUME_VM],
> - ["Save", VmTask::ACTION_SAVE_VM],
> - ["Restore", VmTask::ACTION_RESTORE_VM]]
> + @actions = [VmTask.label_and_action(VmTask::ACTION_START_VM),
> + (VmTask.label_and_action(VmTask::ACTION_SHUTDOWN_VM)
<< "break"),
> + VmTask.label_and_action(VmTask::ACTION_SUSPEND_VM),
> + VmTask.label_and_action(VmTask::ACTION_RESUME_VM),
> + VmTask.label_and_action(VmTask::ACTION_SAVE_VM),
> + VmTask.label_and_action(VmTask::ACTION_RESTORE_VM)]
> end
>
> # resource's users list page
> @@ -143,45 +144,54 @@ class ResourcesController < ApplicationController
> end
>
> def vm_actions
> - @vm_resource_pool = VmResourcePool.find(params[:vm_resource_pool_id])
> - set_perms(@vm_resource_pool)
> - unless @can_modify
> - flash[:notice] = 'You do not have permission to perform VM
actions for this VM Resource Pool '
> - redirect_to :action => 'show', :id =>
@vm_resource_pool
> - else
> - params[:vm_actions].each do |name, param|
> - print "param: ", name, ", ", param,
"\n"
> - end
> - if params[:vm_actions][:vms]
> - vms = params[:vm_actions][:vms]
> - if params[:vm_actions][VmTask::ACTION_START_VM]
> - flash[:notice] = "Starting Machines
#{vms.join(',')}."
> - elsif params[:vm_actions][VmTask::ACTION_SHUTDOWN_VM]
> - flash[:notice] = "Stopping Machines
#{vms.join(',')}."
> - elsif params[:vm_actions][:other_actions]
> - case params[:vm_actions][:other_actions]
> - when VmTask::ACTION_SHUTDOWN_VM then flash[:notice] =
"Stopping Machines #{vms.join(',')}."
> - when VmTask::ACTION_START_VM then flash[:notice] =
"Starting Machines #{vms.join(',')}."
> - when VmTask::ACTION_SUSPEND_VM then flash[:notice] =
"Suspending Machines #{vms.join(',')}."
> - when VmTask::ACTION_RESUME_VM then flash[:notice] =
"Resuming Machines #{vms.join(',')}."
> - when VmTask::ACTION_SAVE_VM then flash[:notice] = "Saving
Machines #{vms.join(',')}."
> - when VmTask::ACTION_RESTORE_VM then flash[:notice] =
"Restoring Machines #{vms.join(',')}."
> - when "destroy" then flash[:notice] = "Destroying
Machines #{vms.join(',')}."
> + @action = params[:vm_action]
> + @action_label = VmTask.action_label(@action)
> + vms_str = params[:vm_ids]
> + @vms = vms_str.split(",").collect {|x| Vm.find(x.to_i)}
> + @success_list = []
> + @failure_list = []
> + begin
> + @vm_resource_pool.transaction do
> + @vms.each do |vm|
> + if vm.queue_action(@user, @action)
> + @success_list << vm
> + print vm.description, vm.id, "\n"
> else
> - flash[:notice] = 'No Action Chosen.'
> + @failure_list << vm
> end
> - else
> - flash[:notice] = 'No Action Chosen.'
> end
> - else
> - flash[:notice] = 'No Virtual Machines Selected.'
> - end
> - if params[:vm_actions][:vm_resource_pool_id]
> - redirect_to :action => 'show', :id =>
params[:vm_actions][:vm_resource_pool_id]
> - else
> - redirect_to :action => 'list'
> end
> + rescue
> + flash[:errmsg] = 'Error queueing VM actions.'
> + @success_list = []
> + @failure_list = []
> end
> + render :layout => 'confirmation'
> +
> + #if params[:vm_actions][:vms]
> + # vms = params[:vm_actions][:vms]
> + # if params[:vm_actions][VmTask::ACTION_START_VM]
> + # flash[:notice] = "Starting Machines
#{vms.join(',')}."
> + # elsif params[:vm_actions][VmTask::ACTION_SHUTDOWN_VM]
> + # flash[:notice] = "Stopping Machines
#{vms.join(',')}."
> + # elsif params[:vm_actions][:other_actions]
> + # case params[:vm_actions][:other_actions]
> + # when VmTask::ACTION_SHUTDOWN_VM then flash[:notice] =
"Stopping Machines #{vms.join(',')}."
> + # when VmTask::ACTION_START_VM then flash[:notice] = "Starting
Machines #{vms.join(',')}."
> + # when VmTask::ACTION_SUSPEND_VM then flash[:notice] =
"Suspending Machines #{vms.join(',')}."
> + # when VmTask::ACTION_RESUME_VM then flash[:notice] =
"Resuming Machines #{vms.join(',')}."
> + # when VmTask::ACTION_SAVE_VM then flash[:notice] = "Saving
Machines #{vms.join(',')}."
> + # when VmTask::ACTION_RESTORE_VM then flash[:notice] =
"Restoring Machines #{vms.join(',')}."
> + # when "destroy" then flash[:notice] = "Destroying
Machines #{vms.join(',')}."
> + # else
> + # flash[:notice] = 'No Action Chosen.'
> + # end
> + # else
> + # flash[:notice] = 'No Action Chosen.'
> + # end
> + #else
> + # flash[:notice] = 'No Virtual Machines Selected.'
> + #end
> end
>
> protected
> @@ -215,5 +225,12 @@ class ResourcesController < ApplicationController
> pre_show
> show
> 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
> + authorize_user
> + end
>
> end
> diff --git a/wui/src/app/controllers/vm_controller.rb
b/wui/src/app/controllers/vm_controller.rb
> index 7eba30c..ac29beb 100644
> --- a/wui/src/app/controllers/vm_controller.rb
> +++ b/wui/src/app/controllers/vm_controller.rb
> @@ -138,20 +138,15 @@ class VmController < ApplicationController
> end
>
> def vm_action
> - if @vm.get_action_list.include?(params[:vm_action])
> - @task = VmTask.new({ :user => get_login_user,
> - :vm_id => params[:id],
> - :action => params[:vm_action],
> - :state => Task::STATE_QUEUED})
> - if @task.save
> - flash[:notice] = "#{params[:vm_action]} was successfully
queued."
> + begin
> + if @vm.queue_action(get_login_user, params[:vm_action])
> + render :json => { :object => "vm", :success =>
true, :alert => "#{vm_action} was successfully queued." }
> else
> - flash[:notice] = "Error in inserting task for
#{params[:vm_action]}."
> + render :json => { :object => "vm", :success =>
false, :alert => "#{vm_action} is an invalid action." }
> end
> - else
> - flash[:notice] = "#{params[:vm_action]} is an invalid
action."
> + rescue
> + render :json => { :object => "vm", :success =>
false, :alert => "Error in queueing #{vm_action}." }
> end
> - redirect_to :controller => 'vm', :action =>
'show', :id => params[:id]
> end
>
> def cancel_queued_tasks
> diff --git a/wui/src/app/helpers/application_helper.rb
b/wui/src/app/helpers/application_helper.rb
> index 4dbf2b8..20c344f 100644
> --- a/wui/src/app/helpers/application_helper.rb
> +++ b/wui/src/app/helpers/application_helper.rb
> @@ -94,6 +94,18 @@ module ApplicationHelper
> }
> end
>
> + def ok_footer
> + %{
> + <div style="background: url(#{image_path
"fb_footer.jpg"}) repeat-x; height: 37px; text-align:right; padding:
9px 9px 0 0;">
> + <div class="button">
> + <div class="button_left_grey"></div>
> + <div class="button_middle_grey"><a
href="#"
onclick="jQuery(document).trigger('close.facebox')">OK</a></div>
> + <div class="button_right_grey"></div>
> + </div>
> + </div>
> + }
> + end
> +
>
> def timeout_flash(name)
> %{
> diff --git a/wui/src/app/models/vm.rb b/wui/src/app/models/vm.rb
> index 7a9cc79..f80c50b 100644
> --- a/wui/src/app/models/vm.rb
> +++ b/wui/src/app/models/vm.rb
> @@ -170,6 +170,16 @@ class Vm < ActiveRecord::Base
> vm_tasks
> end
>
> + def queue_action(user, action)
> + return false unless get_action_list.include?(action)
> + task = VmTask.new({ :user => user,
> + :vm_id => id,
> + :action => action,
> + :state => Task::STATE_QUEUED})
> + task.save!
> + return true
> + end
> +
> protected
> def validate
> resources = vm_resource_pool.max_resources_for_vm(self)
> diff --git a/wui/src/app/models/vm_task.rb b/wui/src/app/models/vm_task.rb
> index f458a68..7e46b93 100644
> --- a/wui/src/app/models/vm_task.rb
> +++ b/wui/src/app/models/vm_task.rb
> @@ -34,37 +34,37 @@ class VmTask < Task
> ACTION_UPDATE_STATE_VM = "update_state_vm"
>
> # a hash of task actions which point to a hash which define valid state
transitions
> - ACTIONS = { ACTION_CREATE_VM => { :label => "Create
VM",
> + ACTIONS = { ACTION_CREATE_VM => { :label => "Create",
> :start => Vm::STATE_PENDING,
> :running => Vm::STATE_CREATING,
> :success => Vm::STATE_STOPPED,
> :failure =>
Vm::STATE_CREATE_FAILED},
> - ACTION_START_VM => { :label => "Start
VM",
> + ACTION_START_VM => { :label => "Start",
> :start => Vm::STATE_STOPPED,
> :running => Vm::STATE_STARTING,
> :success => Vm::STATE_RUNNING,
> :failure => Vm::STATE_STOPPED},
> - ACTION_SHUTDOWN_VM => { :label => "Shutdown
VM",
> + ACTION_SHUTDOWN_VM => { :label =>
"Shutdown",
> :start => Vm::STATE_RUNNING,
> :running => Vm::STATE_STOPPING,
> :success => Vm::STATE_STOPPED,
> :failure => Vm::STATE_RUNNING},
> - ACTION_SUSPEND_VM => { :label => "Suspend
VM",
> + ACTION_SUSPEND_VM => { :label => "Suspend",
> :start => Vm::STATE_RUNNING,
> :running => Vm::STATE_SUSPENDING,
> :success => Vm::STATE_SUSPENDED,
> :failure => Vm::STATE_RUNNING},
> - ACTION_RESUME_VM => { :label => "Resume
VM",
> + ACTION_RESUME_VM => { :label => "Resume",
> :start => Vm::STATE_SUSPENDED,
> :running => Vm::STATE_RESUMING,
> :success => Vm::STATE_RUNNING,
> :failure => Vm::STATE_SUSPENDED},
> - ACTION_SAVE_VM => { :label => "Save VM",
> + ACTION_SAVE_VM => { :label => "Save",
> :start => Vm::STATE_RUNNING,
> :running => Vm::STATE_SAVING,
> :success => Vm::STATE_SAVED,
> :failure => Vm::STATE_RUNNING},
> - ACTION_RESTORE_VM => { :label => "Restore
VM",
> + ACTION_RESTORE_VM => { :label => "Restore",
> :start => Vm::STATE_SAVED,
> :running => Vm::STATE_RESTORING,
> :success => Vm::STATE_RUNNING,
> @@ -80,4 +80,10 @@ class VmTask < Task
> Vm::STATE_CREATE_FAILED => [],
> Vm::STATE_INVALID => []}
>
> + def self.action_label(action)
> + return ACTIONS[action][:label]
> + end
> + def self.label_and_action(action)
> + return [action_label(action), action]
> + end
> end
> diff --git a/wui/src/app/views/layouts/confirmation.rhtml
b/wui/src/app/views/layouts/confirmation.rhtml
> new file mode 100644
> index 0000000..736517c
> --- /dev/null
> +++ b/wui/src/app/views/layouts/confirmation.rhtml
> @@ -0,0 +1,2 @@
> +<%# currently nothing for popups here. %>
> +<%= yield %>
> diff --git a/wui/src/app/views/resources/show_vms.rhtml
b/wui/src/app/views/resources/show_vms.rhtml
> index 8f1f4a3..8e951bf 100644
> --- a/wui/src/app/views/resources/show_vms.rhtml
> +++ b/wui/src/app/views/resources/show_vms.rhtml
> @@ -5,7 +5,7 @@
> <%= image_tag "icon_move.png", :style =>
"vertical-align:middle;" %> Actions
<%= image_tag
"icon_toolbar_arrow.gif", :style =>
"vertical-align:middle;" %>
> <ul>
> <% @actions.each_index { |index| %>
> - <li
onChange="vm_actions('<%=@actions[index][1]%>')"
> + <li
onClick="vm_actions('<%=@actions[index][1]%>')"
> <% if (index == @actions.length - 1) or
@actions[index].length == 3 %>
> style="border-bottom: 1px solid black;"
> <% end %>
> @@ -27,13 +27,23 @@
> {
> vms = get_selected_vms()
> if (validate_selected(vms, "vm")) {
> - $.post('<%= url_for :controller => "vm", :action
=> "delete", :id => @pool %>',
> + $.post('<%= url_for :controller => "vm", :action
=> "delete", :id => @vm_resource_pool %>',
> { vm_ids: vms.toString() },
> function(data,status){
> $("#vms_grid").flexReload()
> });
> }
> }
> + function vm_actions(action)
> + {
> + vms = get_selected_vms()
> + 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 %>',
> + { vm_ids: vms.toString(), vm_action: action });
> + }
> + }
> function vms_select(selected_rows)
> {
> var selected_ids = new Array()
> diff --git a/wui/src/app/views/resources/vm_actions.rhtml
b/wui/src/app/views/resources/vm_actions.rhtml
> new file mode 100644
> index 0000000..d556b94
> --- /dev/null
> +++ b/wui/src/app/views/resources/vm_actions.rhtml
> @@ -0,0 +1,35 @@
> +<div class="dialog_title_small">
> + <div class="header">Virtual Machine Action
Results</div>
> + <div>Results for <%= @action_label %> action</div>
> +</div>
> +<div class="dialog_body">
> + <!-- FIXME: need to work out confirmation/popup dialog layouts to
include this stuff -->
> + <% if flash[:notice] or flash[:errmsg] %>
> + <% if flash[:notice] %>
> + <%= flash[:notice] %>
> + <% end %>
> +
> + <% if flash[:notice] and flash[:errmsg] %>
> + <br/>
> + <% end %>
> +
> + <% if flash[:errmsg] %>
> + <%= flash[:errmsg] %>
> + <% end %>
> + <br/>
> + <% end %>
> +Action succeeded for these VMs:
> +<ul>
> + <% for vm in @success_list %>
> + <li><%= vm.description %></li>
> + <% end %>
> +</ul>
> +
> +Action invalid for these VMs:
> +<ul>
> + <% for vm in @failure_list %>
> + <li><%= vm.description %></li>
> + <% end %>
> +</ul>
> +</div>
> +<%= ok_footer %>
> --
> 1.5.4.1
>
ACK and committed, with the note that a future patch will add confirmation on
deleting a VM (currently missing).
--Hugh