From: Jan Provaznik jprovazn@redhat.com
--- src/app/controllers/image_controller.rb | 2 +- src/app/controllers/instance_controller.rb | 202 ---------------------- src/app/controllers/instances_controller.rb | 202 ++++++++++++++++++++++ src/app/helpers/instance_helper.rb | 33 ---- src/app/helpers/instances_helper.rb | 33 ++++ src/app/views/dashboard/summary.haml | 2 +- src/app/views/instance/_instances.haml | 24 --- src/app/views/instance/configure.haml | 23 --- src/app/views/instance/create.haml | 2 - src/app/views/instance/delete.haml | 2 - src/app/views/instance/index.haml | 127 -------------- src/app/views/instance/new.haml | 19 -- src/app/views/instance/show.haml | 61 ------- src/app/views/instances/_instances.haml | 24 +++ src/app/views/instances/configure.haml | 23 +++ src/app/views/instances/create.haml | 2 + src/app/views/instances/delete.haml | 2 + src/app/views/instances/index.haml | 127 ++++++++++++++ src/app/views/instances/new.haml | 19 ++ src/app/views/instances/show.haml | 61 +++++++ src/app/views/pools/list.haml | 2 +- src/config/navigation.rb | 2 +- src/config/routes.rb | 2 +- src/features/step_definitions/instance.rb | 8 +- src/spec/controllers/instance_controller_spec.rb | 2 +- 25 files changed, 503 insertions(+), 503 deletions(-) delete mode 100644 src/app/controllers/instance_controller.rb create mode 100644 src/app/controllers/instances_controller.rb delete mode 100644 src/app/helpers/instance_helper.rb create mode 100644 src/app/helpers/instances_helper.rb delete mode 100644 src/app/views/instance/_instances.haml delete mode 100644 src/app/views/instance/configure.haml delete mode 100644 src/app/views/instance/create.haml delete mode 100644 src/app/views/instance/delete.haml delete mode 100644 src/app/views/instance/index.haml delete mode 100644 src/app/views/instance/new.haml delete mode 100644 src/app/views/instance/show.haml create mode 100644 src/app/views/instances/_instances.haml create mode 100644 src/app/views/instances/configure.haml create mode 100644 src/app/views/instances/create.haml create mode 100644 src/app/views/instances/delete.haml create mode 100644 src/app/views/instances/index.haml create mode 100644 src/app/views/instances/new.haml create mode 100644 src/app/views/instances/show.haml
diff --git a/src/app/controllers/image_controller.rb b/src/app/controllers/image_controller.rb index 6e3f932..8cd8cbe 100644 --- a/src/app/controllers/image_controller.rb +++ b/src/app/controllers/image_controller.rb @@ -36,7 +36,7 @@ class ImageController < ApplicationController
def show if params[:create_instance] - redirect_to :controller => 'instance', :action => 'new', 'instance[image_id]' => (params[:ids] || []).first + redirect_to :controller => 'instances', :action => 'new', 'instance[image_id]' => (params[:ids] || []).first end
require_privilege(Privilege::IMAGE_VIEW) diff --git a/src/app/controllers/instance_controller.rb b/src/app/controllers/instance_controller.rb deleted file mode 100644 index 0de246d..0000000 --- a/src/app/controllers/instance_controller.rb +++ /dev/null @@ -1,202 +0,0 @@ -# -# Copyright (C) 2009 Red Hat, Inc. -# -# 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. - -# Filters added to this controller apply to all controllers in the application. -# Likewise, all the methods added will be available for all controllers. - -require 'util/condormatic' - -class InstanceController < ApplicationController - before_filter :require_user, :get_nav_items - before_filter :instance, :only => [:show, :key] - layout :layout - - def section_id - 'runtime' - end - - def layout - return "aggregator" unless request.xhr? - end - - def index - @pools = Pool.list_for_user(@current_user, Privilege::INSTANCE_MODIFY) - - @order_dir = params[:order_dir] == 'desc' ? 'desc' : 'asc' - @order_field = params[:order_field] || 'name' - - # we can't use pool.instances, because we need custom sorting - @sorted_instances_by_pool = {} - Instance.find( - :all, - :include => [:template, :hardware_profile, :owner, :pool], - :order => @order_field + ' ' + @order_dir - ).each do |inst| - pool_id = inst.pool.id - next unless @pools.find {|p| p.id == pool_id} - (@sorted_instances_by_pool[pool_id] ||= []) << inst - end - end - - def show - end - - def key - unless @instance.instance_key.nil? - send_data @instance.instance_key.pem, - :filename => "#{@instance.instance_key.name}.pem", - :type => "text/plain" - return - end - flash[:warning] = "SSH Key not found for this Instance." - redirect_to :action => "show", :id => @instance - end - - def new - @instance = Instance.new(params[:instance]) - require_privilege(Privilege::INSTANCE_MODIFY, @instance.pool) if @instance.pool - # FIXME: we need to list only templates for particular user, - # => TODO: add TEMPLATE_* permissions - @templates = Template.paginate( - :page => params[:page] || 1, - :include => {:images => :replicated_images}, - :conditions => "replicated_images.uploaded = 't'" - ) - end - - def configure - @instance = Instance.new(params[:instance]) - require_privilege(Privilege::INSTANCE_MODIFY, @instance.pool) - # FIXME: change template.architecture to match expected HWP arch strings - if (@instance.template.architecture == "64-bit") - arch_value = "x86_64" - else - arch_value = "i386" - end - @hardware_profiles = HardwareProfile.find(:all, :include => :architecture, - :conditions => {:provider_id => nil, - "hardware_profile_properties.value" => arch_value}) - end - - def create - if params[:cancel] - redirect_to :action => 'new', :instance => {:pool_id => params[:instance][:pool_id]} - return - end - - @instance = Instance.new(params[:instance]) - @instance.state = Instance::STATE_NEW - @instance.owner = current_user - - require_privilege(Privilege::INSTANCE_MODIFY, - Pool.find(@instance.pool_id)) - #FIXME: This should probably be in a transaction - if @instance.save! - @task = InstanceTask.new({:user => current_user, - :task_target => @instance, - :action => InstanceTask::ACTION_CREATE}) - if @task.save - condormatic_instance_create(@task) - if Quota.can_start_instance?(@instance, nil) - flash[:notice] = "Instance added." - else - flash[:warning] = "Quota Exceeded: Instance will not start until you have free quota" - end - else - @pool = @instance.pool - render :action => 'configure' - end - redirect_to :action => 'index' - else - @hardware_profiles = HardwareProfile.all - render :action => 'configure' - end - end - - def instance_action - params.keys.each do |param| - if param =~ /^launch_instance_(\d+)$/ - redirect_to :action => 'new', 'instance[pool_id]' => $1 - return - end - end - - @instance = Instance.find((params[:id] || []).first) - require_privilege(Privilege::INSTANCE_CONTROL,@instance.pool) - - if params[:instance_details] - render :action => 'show' - return - end - - if params[:remove_failed] - action = remove_failed - else - # action list will be longer (restart, start, stop..) - action = if params[:shutdown] - 'stop' - #elsif params[:restart] - # 'restart' - end - - unless @instance.valid_action?(action) - raise ActionError.new("'#{action}' is an invalid action.") - end - - # not sure if task is used as everything goes through condor - #permissons check here - @task = @instance.queue_action(@current_user, action) - unless @task - raise ActionError.new("#{action} cannot be performed on this instance.") - end - - case action - when 'stop' - condormatic_instance_stop(@task) - when 'destroy' - condormatic_instance_destroy(@task) - when 'start' - condormatic_instance_create(@task) - else - raise ActionError.new("Sorry, action '#{action}' is currently not supported by condor backend.") - end - end - - flash[:notice] = "#{@instance.name}: #{action} was successfully queued." - redirect_to :action => 'index' - end - - def delete - end - - def remove_failed - action ='remove failed' - raise ActionError.new("#{action} cannot be performed on this instance.") unless - @instance.state == Instance::STATE_ERROR - condormatic_instance_reset_error(@instance) - action - end - - private - - def instance - @instance = Instance.find(params[:id]) - require_privilege(Privilege::INSTANCE_VIEW, @instance.pool) - end - -end diff --git a/src/app/controllers/instances_controller.rb b/src/app/controllers/instances_controller.rb new file mode 100644 index 0000000..3ffb287 --- /dev/null +++ b/src/app/controllers/instances_controller.rb @@ -0,0 +1,202 @@ +# +# Copyright (C) 2009 Red Hat, Inc. +# +# 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. + +# Filters added to this controller apply to all controllers in the application. +# Likewise, all the methods added will be available for all controllers. + +require 'util/condormatic' + +class InstancesController < ApplicationController + before_filter :require_user, :get_nav_items + before_filter :instance, :only => [:show, :key] + layout :layout + + def section_id + 'runtime' + end + + def layout + return "aggregator" unless request.xhr? + end + + def index + @pools = Pool.list_for_user(@current_user, Privilege::INSTANCE_MODIFY) + + @order_dir = params[:order_dir] == 'desc' ? 'desc' : 'asc' + @order_field = params[:order_field] || 'name' + + # we can't use pool.instances, because we need custom sorting + @sorted_instances_by_pool = {} + Instance.find( + :all, + :include => [:template, :hardware_profile, :owner, :pool], + :order => @order_field + ' ' + @order_dir + ).each do |inst| + pool_id = inst.pool.id + next unless @pools.find {|p| p.id == pool_id} + (@sorted_instances_by_pool[pool_id] ||= []) << inst + end + end + + def show + end + + def key + unless @instance.instance_key.nil? + send_data @instance.instance_key.pem, + :filename => "#{@instance.instance_key.name}.pem", + :type => "text/plain" + return + end + flash[:warning] = "SSH Key not found for this Instance." + redirect_to :action => "show", :id => @instance + end + + def new + @instance = Instance.new(params[:instance]) + require_privilege(Privilege::INSTANCE_MODIFY, @instance.pool) if @instance.pool + # FIXME: we need to list only templates for particular user, + # => TODO: add TEMPLATE_* permissions + @templates = Template.paginate( + :page => params[:page] || 1, + :include => {:images => :replicated_images}, + :conditions => "replicated_images.uploaded = 't'" + ) + end + + def configure + @instance = Instance.new(params[:instance]) + require_privilege(Privilege::INSTANCE_MODIFY, @instance.pool) + # FIXME: change template.architecture to match expected HWP arch strings + if (@instance.template.architecture == "64-bit") + arch_value = "x86_64" + else + arch_value = "i386" + end + @hardware_profiles = HardwareProfile.find(:all, :include => :architecture, + :conditions => {:provider_id => nil, + "hardware_profile_properties.value" => arch_value}) + end + + def create + if params[:cancel] + redirect_to :action => 'new', :instance => {:pool_id => params[:instance][:pool_id]} + return + end + + @instance = Instance.new(params[:instance]) + @instance.state = Instance::STATE_NEW + @instance.owner = current_user + + require_privilege(Privilege::INSTANCE_MODIFY, + Pool.find(@instance.pool_id)) + #FIXME: This should probably be in a transaction + if @instance.save! + @task = InstanceTask.new({:user => current_user, + :task_target => @instance, + :action => InstanceTask::ACTION_CREATE}) + if @task.save + condormatic_instance_create(@task) + if Quota.can_start_instance?(@instance, nil) + flash[:notice] = "Instance added." + else + flash[:warning] = "Quota Exceeded: Instance will not start until you have free quota" + end + else + @pool = @instance.pool + render :action => 'configure' + end + redirect_to :action => 'index' + else + @hardware_profiles = HardwareProfile.all + render :action => 'configure' + end + end + + def instance_action + params.keys.each do |param| + if param =~ /^launch_instance_(\d+)$/ + redirect_to :action => 'new', 'instance[pool_id]' => $1 + return + end + end + + @instance = Instance.find((params[:id] || []).first) + require_privilege(Privilege::INSTANCE_CONTROL,@instance.pool) + + if params[:instance_details] + render :action => 'show' + return + end + + if params[:remove_failed] + action = remove_failed + else + # action list will be longer (restart, start, stop..) + action = if params[:shutdown] + 'stop' + #elsif params[:restart] + # 'restart' + end + + unless @instance.valid_action?(action) + raise ActionError.new("'#{action}' is an invalid action.") + end + + # not sure if task is used as everything goes through condor + #permissons check here + @task = @instance.queue_action(@current_user, action) + unless @task + raise ActionError.new("#{action} cannot be performed on this instance.") + end + + case action + when 'stop' + condormatic_instance_stop(@task) + when 'destroy' + condormatic_instance_destroy(@task) + when 'start' + condormatic_instance_create(@task) + else + raise ActionError.new("Sorry, action '#{action}' is currently not supported by condor backend.") + end + end + + flash[:notice] = "#{@instance.name}: #{action} was successfully queued." + redirect_to :action => 'index' + end + + def delete + end + + def remove_failed + action ='remove failed' + raise ActionError.new("#{action} cannot be performed on this instance.") unless + @instance.state == Instance::STATE_ERROR + condormatic_instance_reset_error(@instance) + action + end + + private + + def instance + @instance = Instance.find(params[:id]) + require_privilege(Privilege::INSTANCE_VIEW, @instance.pool) + end + +end diff --git a/src/app/helpers/instance_helper.rb b/src/app/helpers/instance_helper.rb deleted file mode 100644 index fea3cf4..0000000 --- a/src/app/helpers/instance_helper.rb +++ /dev/null @@ -1,33 +0,0 @@ -# -# Copyright (C) 2009 Red Hat, Inc. -# -# 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. - -# Filters added to this controller apply to all controllers in the application. -# Likewise, all the methods added will be available for all controllers. - -module InstanceHelper - def owner_name(inst) - return '' unless inst.owner - # if last_name is set, use full name, - # else use login - if inst.owner.last_name.blank? - inst.owner.login - else - "#{inst.owner.first_name} #{inst.owner.last_name}" - end - end -end diff --git a/src/app/helpers/instances_helper.rb b/src/app/helpers/instances_helper.rb new file mode 100644 index 0000000..740b01f --- /dev/null +++ b/src/app/helpers/instances_helper.rb @@ -0,0 +1,33 @@ +# +# Copyright (C) 2009 Red Hat, Inc. +# +# 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. + +# Filters added to this controller apply to all controllers in the application. +# Likewise, all the methods added will be available for all controllers. + +module InstancesHelper + def owner_name(inst) + return '' unless inst.owner + # if last_name is set, use full name, + # else use login + if inst.owner.last_name.blank? + inst.owner.login + else + "#{inst.owner.first_name} #{inst.owner.last_name}" + end + end +end diff --git a/src/app/views/dashboard/summary.haml b/src/app/views/dashboard/summary.haml index ff116d4..5eb49a5 100644 --- a/src/app/views/dashboard/summary.haml +++ b/src/app/views/dashboard/summary.haml @@ -35,7 +35,7 @@ Add a Provider %a{:href => url_for(:controller => "users", :action => "new")} Create a User - %a{:href => url_for(:controller => "instance", :action => "index")} + %a{:href => url_for(:controller => "instances", :action => "index")} View Instances - else %a{:href => url_for(:controller => "", :action => "")} diff --git a/src/app/views/instance/_instances.haml b/src/app/views/instance/_instances.haml deleted file mode 100644 index 5af1838..0000000 --- a/src/app/views/instance/_instances.haml +++ /dev/null @@ -1,24 +0,0 @@ -- columns = [ | - {:id => 'id', :header => ''}, | - {:header => 'Actions'}, | - {:id => 'name', :header => 'Name', :sortable => true}, | - {:header => 'Details'}, | - {:id => 'template', :header => 'Template'}, | - {:id => 'state', :sortable => true, :header => 'State'}, | - {:id => 'time_last_running', :header => 'Time last running'}, | -] | - -- opts = { :order => @order, - :order_dir => @order_dir, - :title => "Instances for #{@pool.name}", - :check_all => 'id' } - -= paginated_table('instances_table', columns, @instances, opts) do |rec| - %tr{:class => "#{cycle('even', 'odd')}"} - %td= check_box_tag 'ids[]', rec.id - %td= rec.get_action_list.map {|action| link_to action, :controller => "instance", :action => "instance_action", :id => rec, :instance_action => action}.join(" | ") - %td= rec.name - %td Details - %td= rec.template.name - %td= rec.state - %td= rec.time_last_running diff --git a/src/app/views/instance/configure.haml b/src/app/views/instance/configure.haml deleted file mode 100644 index 809c044..0000000 --- a/src/app/views/instance/configure.haml +++ /dev/null @@ -1,23 +0,0 @@ -%h2 Launch instance -- form_for @instance, :url => {:action => 'create'} do - = hidden_field :instance, :template_id - = hidden_field :instance, :pool_id - %ul - %li - = label :instance, :name - = text_field :instance, :name - %li - = label :instance, :template - = text_field_tag :template_name, @instance.template ? @instance.template.name : '', :disabled => true - %li - = label :instance, :pool - = text_field_tag :pool_name, @instance.pool ? @instance.pool.name : '', :disabled => true - %li - = label :instance, :hardware_profile - = select :instance, :hardware_profile_id, @hardware_profiles.map {|p| [ p.name, p.id ]}, { :include_blank => false } - %li - = label :instance, :realm - = select :instance, :realm_id, @instance.pool.realms.map {|r| [ r.name, r.id ]}, { :include_blank => true } - - = submit_tag 'Cancel', :name => 'cancel' - = submit_tag 'Launch', :name => 'launch' diff --git a/src/app/views/instance/create.haml b/src/app/views/instance/create.haml deleted file mode 100644 index 6fd9474..0000000 --- a/src/app/views/instance/create.haml +++ /dev/null @@ -1,2 +0,0 @@ -%h1 Instance#create -%p Find me in app/views/instance/create.html.erb diff --git a/src/app/views/instance/delete.haml b/src/app/views/instance/delete.haml deleted file mode 100644 index 63de29b..0000000 --- a/src/app/views/instance/delete.haml +++ /dev/null @@ -1,2 +0,0 @@ -%h1 Instance#delete -%p Find me in app/views/instance/delete.html.erb diff --git a/src/app/views/instance/index.haml b/src/app/views/instance/index.haml deleted file mode 100644 index 83690b7..0000000 --- a/src/app/views/instance/index.haml +++ /dev/null @@ -1,127 +0,0 @@ -- columns = [ | - {:name => '', :sortable => false}, | - {:name => 'STATUS', :sortable => false}, | - {:name => 'VM NAME', :sort_attr => 'name'}, | - {:name => 'TYPE', :sort_attr => 'hardware_profiles.name'}, | - {:name => 'TEMPLATE', :sort_attr => 'templates.name'}, | - {:name => 'PUBLIC ADDRESS', :sort_attr => 'public_addresses'}, | - {:name => 'PROVIDER', :sortable => false}, | - {:name => 'CREATED BY', :sort_attr => 'users.last_name'}, | -] | - -- pool_columns = [ | - { :name => "Pool name", :sort_attr => :name }, | - { :name => "Alerts", :sortable => false }, | - { :name => "Capacity", :sortable => false }, | - { :name => "Zone", :sort_attr => "zones.name" } | -] | - - -- form_tag(:action => 'instance_action') do - .actionsidebar.grid_3 - %dl - %dt Actions - %dd - %h5 Control Instances - %ul - %li.start.disabled - %span - = submit_tag "Start", :name => "start", :class => "icon", :disabled => true - %li.stop.disabled - %span - = submit_tag "Stop", :name => "stop", :class => "icon", :disabled => true - %li.restart.disabled - %span - = submit_tag "Restart", :name => "restart", :class => "icon", :disabled => true - %li.shutdown - %span - = submit_tag "Shutdown", :name => "shutdown", :class => "icon" - %li.console.disabled - %span - = submit_tag "Console Access", :name => "console_access", :class => "icon", :disabled => true - %li.VD.disabled - %span - = submit_tag "Virtual Desktop", :name => "vd", :class => "icon", :disabled => true - %li.delete - %span - = submit_tag "Remove Failed", :name => "remove_failed", :class => "icon" - %dd - %h5 Manage Instances - %ul - %li.snapshot.disabled - %span - = submit_tag "Create Snapshot", :name => "snapshot", :class => "icon", :disabled => true - %li.grantaccess.disabled - %span - = submit_tag "Grant Access", :name => "grantaccess", :class => "icon", :disabled => true - %li.info - %span - = submit_tag "Instance Details", :name => "instance_details", :class => "icon" - %li.request_help.disabled - %span - = submit_tag "Request Help", :name => "request_help", :class => "icon", :disabled => true - - .grid_5 - %h2 My Quota - %table - %thead - %tr - %th % Quota Used - %th - Quota - %span.small (Instances) - %tbody - %tr - - quota = current_user.quota.maximum_running_instances - %td - - if quota.respond_to? '>' and quota > 0 - = "%.2f" % ((current_user.quota.running_instances / quota.to_f) * 100) - - else - = 0 - %td - = quota or "unlimited" - .grid_8 - %h2 Pool Status - %table - =sortable_table_header pool_columns - - @pools.each do |pool| - %tr - %td - = pool.name - %td N/A - %td.capacity - %span.good - %td - =pool.zone.name - .grid_13 - %h2 Instances by Pool - - @pools.each do |pool| - .grid_6.alpha.poolname - %h4= pool.name - = link_to image_tag("blnk.png", :border=>0) + "Launch Instance", {:controller => "instance", :action => "new", 'instance[pool_id]' => pool.id}, :class => "button iconbutton fr" - - .grid_4.poolfilter - %input{:type => "radio", :id => "all_" + pool.id.to_s, :name => "filter_" + pool.id.to_s} - %label{:for => "all_" + pool.id.to_s} Show All - %input{:type => "radio", :id => "summary_" + pool.id.to_s, :name => "filter_" + pool.id.to_s} - %label{:for => "summary_" + pool.id.to_s} Summary View - .search.grid_3.omega - %input{:type => "search", :placeholder => "Search Instance"} - %button.action Search - %table.gap - = sortable_table_header(columns) - %tbody - - if not instances = @sorted_instances_by_pool[pool.id] or instances.empty? - %tr - %td{:colspan => 8} No Instances - - else - - instances.each do |inst| - %tr - %td= radio_button_tag 'id[]', inst.id - %td= inst.state - %td= inst.name - %td= inst.hardware_profile.name - %td= inst.template.name - %td= inst.public_addresses - %td= inst.cloud_account ? inst.cloud_account.provider.name : '' - %td= owner_name(inst) diff --git a/src/app/views/instance/new.haml b/src/app/views/instance/new.haml deleted file mode 100644 index 8038a2b..0000000 --- a/src/app/views/instance/new.haml +++ /dev/null @@ -1,19 +0,0 @@ -%h3 Show Templates -%hr -%ul - - @templates.each do |tpl| - %li - - form_tag(:action => 'configure') do - = hidden_field :instance, :template_id, :value => tpl.id - = hidden_field :instance, :pool_id, :value => @instance.pool.id - = image_tag "platform_#{tpl.platform}.png", :size => "32x32", :alt => tpl.platform - %h3= tpl.name - %p= tpl.summary - %p - %label Group: - System - %label Version: - 2.5 - = submit_tag 'Launch', :name => 'launch' -= will_paginate(@templates) -= page_entries_info(@templates) diff --git a/src/app/views/instance/show.haml b/src/app/views/instance/show.haml deleted file mode 100644 index cb34dde..0000000 --- a/src/app/views/instance/show.haml +++ /dev/null @@ -1,61 +0,0 @@ -%h2 Instance Details -- form_tag(:action => 'index') do - %ul - %li - = label_tag :name, 'Name' - %span= @instance.name - %li - = label_tag :status, 'Status' - %span= @instance.state - %li - = label_tag :public_addresses, 'Public Addresses' - %span= @instance.public_addresses - %li - = label_tag :private_addresses, 'Private Addresses' - %span= @instance.private_addresses - %li - = label_tag :operating_system, 'Operating system' - %span= "#{@instance.template.xml.platform} #{@instance.template.xml.platform_version}" - %li - = label_tag :provider, 'Provider' - %span= @instance.cloud_account.provider.name if @instance.cloud_account - %li - = label_tag :base_template, 'Base Template' - %span= @instance.template.name - %li - = label_tag :architecture, 'Architecture' - %span= @instance.hardware_profile.architecture.value - %li - = label_tag :memory, 'Memory' - %span= @instance.hardware_profile.memory.value - %li - = label_tag :storage, 'Storage' - %span= @instance.hardware_profile.storage.value - %li - = label_tag :instantiation_time, 'Instantiation Time' - %span= @instance.created_at.strftime("%d-%b-%Y %H:%M:%S") - %li - = label_tag :uptime, 'Uptime' - %span= @instance.total_state_time(@instance.state) - %li - = label_tag :current_alerts, 'Current Alerts' - %span= 0 - %li - = label_tag :console_connection, 'Console Connection' - %span= 'via SSH' - - unless @instance.instance_key_id.nil? - %li - = label_tag :instance_key, 'SSH key' - %span= link_to("Download", { :controller => "instance", :action => "key", :id => @instance }) - %li - = label_tag :owner, 'Owner' - %span= "#{@instance.owner.first_name} #{@instance.owner.last_name}" - %li - = label_tag :shared_to, 'Shared to' - %span= "N/A" - - if @instance.state == Instance::STATE_ERROR - %li - = label_tag :error, 'Error' - %span= @instance.last_error - - = submit_tag 'Back', :name => 'back' diff --git a/src/app/views/instances/_instances.haml b/src/app/views/instances/_instances.haml new file mode 100644 index 0000000..5dbca9f --- /dev/null +++ b/src/app/views/instances/_instances.haml @@ -0,0 +1,24 @@ +- columns = [ | + {:id => 'id', :header => ''}, | + {:header => 'Actions'}, | + {:id => 'name', :header => 'Name', :sortable => true}, | + {:header => 'Details'}, | + {:id => 'template', :header => 'Template'}, | + {:id => 'state', :sortable => true, :header => 'State'}, | + {:id => 'time_last_running', :header => 'Time last running'}, | +] | + +- opts = { :order => @order, + :order_dir => @order_dir, + :title => "Instances for #{@pool.name}", + :check_all => 'id' } + += paginated_table('instances_table', columns, @instances, opts) do |rec| + %tr{:class => "#{cycle('even', 'odd')}"} + %td= check_box_tag 'ids[]', rec.id + %td= rec.get_action_list.map {|action| link_to action, :controller => "instances", :action => "instance_action", :id => rec, :instance_action => action}.join(" | ") + %td= rec.name + %td Details + %td= rec.template.name + %td= rec.state + %td= rec.time_last_running diff --git a/src/app/views/instances/configure.haml b/src/app/views/instances/configure.haml new file mode 100644 index 0000000..809c044 --- /dev/null +++ b/src/app/views/instances/configure.haml @@ -0,0 +1,23 @@ +%h2 Launch instance +- form_for @instance, :url => {:action => 'create'} do + = hidden_field :instance, :template_id + = hidden_field :instance, :pool_id + %ul + %li + = label :instance, :name + = text_field :instance, :name + %li + = label :instance, :template + = text_field_tag :template_name, @instance.template ? @instance.template.name : '', :disabled => true + %li + = label :instance, :pool + = text_field_tag :pool_name, @instance.pool ? @instance.pool.name : '', :disabled => true + %li + = label :instance, :hardware_profile + = select :instance, :hardware_profile_id, @hardware_profiles.map {|p| [ p.name, p.id ]}, { :include_blank => false } + %li + = label :instance, :realm + = select :instance, :realm_id, @instance.pool.realms.map {|r| [ r.name, r.id ]}, { :include_blank => true } + + = submit_tag 'Cancel', :name => 'cancel' + = submit_tag 'Launch', :name => 'launch' diff --git a/src/app/views/instances/create.haml b/src/app/views/instances/create.haml new file mode 100644 index 0000000..6fd9474 --- /dev/null +++ b/src/app/views/instances/create.haml @@ -0,0 +1,2 @@ +%h1 Instance#create +%p Find me in app/views/instance/create.html.erb diff --git a/src/app/views/instances/delete.haml b/src/app/views/instances/delete.haml new file mode 100644 index 0000000..63de29b --- /dev/null +++ b/src/app/views/instances/delete.haml @@ -0,0 +1,2 @@ +%h1 Instance#delete +%p Find me in app/views/instance/delete.html.erb diff --git a/src/app/views/instances/index.haml b/src/app/views/instances/index.haml new file mode 100644 index 0000000..9c2efb8 --- /dev/null +++ b/src/app/views/instances/index.haml @@ -0,0 +1,127 @@ +- columns = [ | + {:name => '', :sortable => false}, | + {:name => 'STATUS', :sortable => false}, | + {:name => 'VM NAME', :sort_attr => 'name'}, | + {:name => 'TYPE', :sort_attr => 'hardware_profiles.name'}, | + {:name => 'TEMPLATE', :sort_attr => 'templates.name'}, | + {:name => 'PUBLIC ADDRESS', :sort_attr => 'public_addresses'}, | + {:name => 'PROVIDER', :sortable => false}, | + {:name => 'CREATED BY', :sort_attr => 'users.last_name'}, | +] | + +- pool_columns = [ | + { :name => "Pool name", :sort_attr => :name }, | + { :name => "Alerts", :sortable => false }, | + { :name => "Capacity", :sortable => false }, | + { :name => "Zone", :sort_attr => "zones.name" } | +] | + + +- form_tag(:action => 'instance_action') do + .actionsidebar.grid_3 + %dl + %dt Actions + %dd + %h5 Control Instances + %ul + %li.start.disabled + %span + = submit_tag "Start", :name => "start", :class => "icon", :disabled => true + %li.stop.disabled + %span + = submit_tag "Stop", :name => "stop", :class => "icon", :disabled => true + %li.restart.disabled + %span + = submit_tag "Restart", :name => "restart", :class => "icon", :disabled => true + %li.shutdown + %span + = submit_tag "Shutdown", :name => "shutdown", :class => "icon" + %li.console.disabled + %span + = submit_tag "Console Access", :name => "console_access", :class => "icon", :disabled => true + %li.VD.disabled + %span + = submit_tag "Virtual Desktop", :name => "vd", :class => "icon", :disabled => true + %li.delete + %span + = submit_tag "Remove Failed", :name => "remove_failed", :class => "icon" + %dd + %h5 Manage Instances + %ul + %li.snapshot.disabled + %span + = submit_tag "Create Snapshot", :name => "snapshot", :class => "icon", :disabled => true + %li.grantaccess.disabled + %span + = submit_tag "Grant Access", :name => "grantaccess", :class => "icon", :disabled => true + %li.info + %span + = submit_tag "Instance Details", :name => "instance_details", :class => "icon" + %li.request_help.disabled + %span + = submit_tag "Request Help", :name => "request_help", :class => "icon", :disabled => true + + .grid_5 + %h2 My Quota + %table + %thead + %tr + %th % Quota Used + %th + Quota + %span.small (Instances) + %tbody + %tr + - quota = current_user.quota.maximum_running_instances + %td + - if quota.respond_to? '>' and quota > 0 + = "%.2f" % ((current_user.quota.running_instances / quota.to_f) * 100) + - else + = 0 + %td + = quota or "unlimited" + .grid_8 + %h2 Pool Status + %table + =sortable_table_header pool_columns + - @pools.each do |pool| + %tr + %td + = pool.name + %td N/A + %td.capacity + %span.good + %td + =pool.zone.name + .grid_13 + %h2 Instances by Pool + - @pools.each do |pool| + .grid_6.alpha.poolname + %h4= pool.name + = link_to image_tag("blnk.png", :border=>0) + "Launch Instance", {:controller => "instances", :action => "new", 'instance[pool_id]' => pool.id}, :class => "button iconbutton fr" + + .grid_4.poolfilter + %input{:type => "radio", :id => "all_" + pool.id.to_s, :name => "filter_" + pool.id.to_s} + %label{:for => "all_" + pool.id.to_s} Show All + %input{:type => "radio", :id => "summary_" + pool.id.to_s, :name => "filter_" + pool.id.to_s} + %label{:for => "summary_" + pool.id.to_s} Summary View + .search.grid_3.omega + %input{:type => "search", :placeholder => "Search Instance"} + %button.action Search + %table.gap + = sortable_table_header(columns) + %tbody + - if not instances = @sorted_instances_by_pool[pool.id] or instances.empty? + %tr + %td{:colspan => 8} No Instances + - else + - instances.each do |inst| + %tr + %td= radio_button_tag 'id[]', inst.id + %td= inst.state + %td= inst.name + %td= inst.hardware_profile.name + %td= inst.template.name + %td= inst.public_addresses + %td= inst.cloud_account ? inst.cloud_account.provider.name : '' + %td= owner_name(inst) diff --git a/src/app/views/instances/new.haml b/src/app/views/instances/new.haml new file mode 100644 index 0000000..8038a2b --- /dev/null +++ b/src/app/views/instances/new.haml @@ -0,0 +1,19 @@ +%h3 Show Templates +%hr +%ul + - @templates.each do |tpl| + %li + - form_tag(:action => 'configure') do + = hidden_field :instance, :template_id, :value => tpl.id + = hidden_field :instance, :pool_id, :value => @instance.pool.id + = image_tag "platform_#{tpl.platform}.png", :size => "32x32", :alt => tpl.platform + %h3= tpl.name + %p= tpl.summary + %p + %label Group: + System + %label Version: + 2.5 + = submit_tag 'Launch', :name => 'launch' += will_paginate(@templates) += page_entries_info(@templates) diff --git a/src/app/views/instances/show.haml b/src/app/views/instances/show.haml new file mode 100644 index 0000000..33b2897 --- /dev/null +++ b/src/app/views/instances/show.haml @@ -0,0 +1,61 @@ +%h2 Instance Details +- form_tag(:action => 'index') do + %ul + %li + = label_tag :name, 'Name' + %span= @instance.name + %li + = label_tag :status, 'Status' + %span= @instance.state + %li + = label_tag :public_addresses, 'Public Addresses' + %span= @instance.public_addresses + %li + = label_tag :private_addresses, 'Private Addresses' + %span= @instance.private_addresses + %li + = label_tag :operating_system, 'Operating system' + %span= "#{@instance.template.xml.platform} #{@instance.template.xml.platform_version}" + %li + = label_tag :provider, 'Provider' + %span= @instance.cloud_account.provider.name if @instance.cloud_account + %li + = label_tag :base_template, 'Base Template' + %span= @instance.template.name + %li + = label_tag :architecture, 'Architecture' + %span= @instance.hardware_profile.architecture.value + %li + = label_tag :memory, 'Memory' + %span= @instance.hardware_profile.memory.value + %li + = label_tag :storage, 'Storage' + %span= @instance.hardware_profile.storage.value + %li + = label_tag :instantiation_time, 'Instantiation Time' + %span= @instance.created_at.strftime("%d-%b-%Y %H:%M:%S") + %li + = label_tag :uptime, 'Uptime' + %span= @instance.total_state_time(@instance.state) + %li + = label_tag :current_alerts, 'Current Alerts' + %span= 0 + %li + = label_tag :console_connection, 'Console Connection' + %span= 'via SSH' + - unless @instance.instance_key_id.nil? + %li + = label_tag :instance_key, 'SSH key' + %span= link_to("Download", { :controller => "instances", :action => "key", :id => @instance }) + %li + = label_tag :owner, 'Owner' + %span= "#{@instance.owner.first_name} #{@instance.owner.last_name}" + %li + = label_tag :shared_to, 'Shared to' + %span= "N/A" + - if @instance.state == Instance::STATE_ERROR + %li + = label_tag :error, 'Error' + %span= @instance.last_error + + = submit_tag 'Back', :name => 'back' diff --git a/src/app/views/pools/list.haml b/src/app/views/pools/list.haml index 2014ed9..675891d 100644 --- a/src/app/views/pools/list.haml +++ b/src/app/views/pools/list.haml @@ -1,3 +1,3 @@ = render :partial => "instance/instances"
-= link_to "Add a new instance", {:controller => "instance", :action => "new", "instance[pool_id]" => @pool}, :class=>"actionlink" += link_to "Add a new instance", {:controller => "instances", :action => "new", "instance[pool_id]" => @pool}, :class=>"actionlink" diff --git a/src/config/navigation.rb b/src/config/navigation.rb index fbc4fab..c29b9c9 100644 --- a/src/config/navigation.rb +++ b/src/config/navigation.rb @@ -37,7 +37,7 @@ SimpleNavigation::Configuration.run do |navigation| second_level.item :images, t(:images), '#', :class => 'disabled' end first_level.item :runtime, t(:runtime), '#', :class => 'runtime' do |second_level| - second_level.item :instance_management, t(:instance_management), :controller => 'instance' + second_level.item :instance_management, t(:instance_management), :controller => 'instances' end first_level.item :help, t(:help), '#', :id => 'help', :class => "disabled" end diff --git a/src/config/routes.rb b/src/config/routes.rb index d736b93..8afbb6a 100644 --- a/src/config/routes.rb +++ b/src/config/routes.rb @@ -45,7 +45,7 @@ ActionController::Routing::Routes.draw do |map| map.resources :users
map.dashboard '/dashboard', :controller => 'dashboard' - map.instance '/instance', :controller => 'instance' + map.instance '/instances', :controller => 'instances' map.templates '/templates', :controller => 'templates' map.settings '/settings', :controller => 'settings' map.root :dashboard diff --git a/src/features/step_definitions/instance.rb b/src/features/step_definitions/instance.rb index 725f75c..a708fd1 100644 --- a/src/features/step_definitions/instance.rb +++ b/src/features/step_definitions/instance.rb @@ -15,17 +15,17 @@ Given /^a mock pending instance exists$/ do end
Given /^I am viewing the mock instance detail$/ do - visit url_for :action => 'show', :controller => 'instance', + visit url_for :action => 'show', :controller => 'instances', :id => mock_instance end
When /^I am viewing the pending instance detail$/ do - visit url_for :action => 'show', :controller => 'instance', + visit url_for :action => 'show', :controller => 'instances', :id => pending_instance end
When /^I manually go to the key action for this instance$/ do - visit url_for :action => 'key', :controller => 'instance', + visit url_for :action => 'key', :controller => 'instances', :id => pending_instance end
@@ -36,4 +36,4 @@ end Then /^I should see the Save dialog for a (.+) file$/ do |filetype| response.headers["Content-Disposition"].should match(/^attachment;\sfilename=.*#{filetype}$/) -end \ No newline at end of file +end diff --git a/src/spec/controllers/instance_controller_spec.rb b/src/spec/controllers/instance_controller_spec.rb index 3df886a..241c05b 100644 --- a/src/spec/controllers/instance_controller_spec.rb +++ b/src/spec/controllers/instance_controller_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper'
-describe InstanceController do +describe InstancesController do fixtures :all before(:each) do @admin_permission = Factory :admin_permission