Skip to content

Commit

Permalink
746
Browse files Browse the repository at this point in the history
  • Loading branch information
shlomizadok committed Oct 22, 2014
1 parent e14b575 commit 16fd768
Show file tree
Hide file tree
Showing 22 changed files with 384 additions and 56 deletions.
23 changes: 23 additions & 0 deletions app/assets/javascripts/hosts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
$(function () {
$("#build-review").click(function() {
$("#review_before_build .modal-body #build_status").html('');
$('.loading').addClass('visible');
$.ajax({
type:'get',
url: $(this).attr('data-url'),
success: function(result){
$("#review_before_build .modal-body #build_status").html(result);
},
complete: function(){
$('.loading').removeClass('visible');
}
})
});
$('#review_before_build').on('change', "#host_build", function () {
$('#build_form').find('input.submit').val((this.checked) ? (__("Reboot and build")) : (__("Build")));
});

$('#review_before_build').on('click', "#recheck_review", function () {
$("#build-review").click();
});
});
38 changes: 38 additions & 0 deletions app/assets/stylesheets/hosts.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#review_before_build {
#build_form {
padding: 0px;
border: none;
.modal-footer {
border-top: none;
padding: 0px;
}
}
.list-group {
float: left;
clear: both;
width: 100%;
.list-group-item {
background: transparent;
border: none;
font-size: 90%;
width: 90%;
}
}

.build_state {
max-height: 400px;
overflow: auto;
}

.loading {
display: none;
width: 100%;
text-align: center;
&.visible {
display: block;
img {
width: 22px;
}
}
}
}
51 changes: 24 additions & 27 deletions app/controllers/hosts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class HostsController < ApplicationController

PUPPETMASTER_ACTIONS=[ :externalNodes, :lookup ]
SEARCHABLE_ACTIONS= %w[index active errors out_of_sync pending disabled ]
AJAX_REQUESTS=%w{compute_resource_selected hostgroup_or_environment_selected current_parameters puppetclass_parameters process_hostgroup process_taxonomy}
AJAX_REQUESTS=%w{compute_resource_selected hostgroup_or_environment_selected current_parameters puppetclass_parameters process_hostgroup process_taxonomy review_before_build}
BOOT_DEVICES={ :disk => N_('Disk'), :cdrom => N_('CDROM'), :pxe => N_('PXE'), :bios => N_('BIOS') }
MULTIPLE_ACTIONS = %w(multiple_parameters update_multiple_parameters select_multiple_hostgroup
update_multiple_hostgroup select_multiple_environment update_multiple_environment
Expand All @@ -17,10 +17,11 @@ class HostsController < ApplicationController

add_puppetmaster_filters PUPPETMASTER_ACTIONS
before_filter :ajax_request, :only => AJAX_REQUESTS
before_filter :find_resource, :only => [:show, :clone, :edit, :update, :destroy, :puppetrun,
before_filter :find_resource, :only => [:show, :clone, :edit, :update, :destroy, :puppetrun, :review_before_build,
:setBuild, :cancelBuild, :power, :overview, :bmc, :vm,
:runtime, :resources, :templates, :ipmi_boot, :console,
:toggle_manage, :pxe_config, :storeconfig_klasses, :disassociate]

before_filter :taxonomy_scope, :only => [:new, :edit] + AJAX_REQUESTS
before_filter :set_host_type, :only => [:update]
before_filter :find_multiple, :only => MULTIPLE_ACTIONS
Expand Down Expand Up @@ -187,10 +188,26 @@ def puppetrun
redirect_to host_path(@host)
end

def review_before_build
@build = @host.build_status
render :layout => false
end

def setBuild
forward_url_options
if @host.setBuild
process_success :success_msg => _("Enabled %s for rebuild on next boot") % (@host), :success_redirect => :back
if (params[:host] && params[:host][:build] == '1')
begin
process_success :success_msg => _("Enabled %s for reboot and rebuild") % (@host), :success_redirect => :back if @host.power.reset
rescue => error
logger.warn(error.to_s)
logger.debug error.backtrace.join("\n")
warning(_('Failed to reboot %s.') % @host)
process_success :success_msg => _("Enabled %s for rebuild on next boot") % (@host), :success_redirect => :back
end
else
process_success :success_msg => _("Enabled %s for rebuild on next boot") % (@host), :success_redirect => :back
end
else
process_error :redirect => :back, :error_msg => _("Failed to enable %{host} for installation: %{errors}") % { :host => @host, :errors => @host.errors.full_messages }
end
Expand Down Expand Up @@ -523,30 +540,10 @@ def process_taxonomy
end

def template_used
host = params[:host]
kinds = if params[:provisioning] == 'image'
cr = ComputeResource.find_by_id(host[:compute_resource_id])
images = cr.try(:images)
if images.nil?
[TemplateKind.find('finish')]
else
uuid = host[:compute_attributes][cr.image_param_name]
image_kind = images.find_by_uuid(uuid).try(:user_data) ? 'user_data' : 'finish'
[TemplateKind.find(image_kind)]
end
else
TemplateKind.all
end

templates = kinds.map do |kind|
ConfigTemplate.find_template({:kind => kind.name,
:operatingsystem_id => host[:operatingsystem_id],
:hostgroup_id => host[:hostgroup_id],
:environment_id => host[:environment_id]
})
end.compact
host = Host.new(params[:host])
templates = host.available_template_kinds(params[:provisioning])
return not_found if templates.empty?
render :partial => "provisioning", :locals => {:templates => templates}
render :partial => 'provisioning', :locals => { :templates => templates }
end

private
Expand All @@ -562,7 +559,7 @@ def action_permission
:view
when 'puppetrun', 'multiple_puppetrun', 'update_multiple_puppetrun'
:puppetrun
when 'setBuild', 'cancelBuild', 'multiple_build', 'submit_multiple_build'
when 'setBuild', 'cancelBuild', 'multiple_build', 'submit_multiple_build', 'review_before_build'
:build
when 'power'
:power
Expand Down
36 changes: 34 additions & 2 deletions app/helpers/hosts_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,16 @@ def host_title_actions(host)
:disabled => host.can_be_built?,
:title => _("Cancel build request for this host"))
else
link_to_if_authorized(_("Build"), hash_for_setBuild_host_path(:id => host).merge(:auth_object => host, :permission => 'build_hosts'),
link_to_if_authorized(_("Build"), hash_for_host_path(:id => host).merge(:auth_object => host, :permission => 'build_hosts', :anchor => "review_before_build"),
:disabled => !host.can_be_built?,
:title => _("Enable rebuild on next host boot"),
:confirm => _("Rebuild %s on next reboot?\nThis would also delete all of its current facts and reports") % host)
:class => "btn",
:id => "build-review",
:data => { :toggle => 'modal',
:target => '#review_before_build',
:url => review_before_build_host_path(:id => host)
}
)
end
),
if host.compute_resource_id || host.bmc_available?
Expand Down Expand Up @@ -329,4 +335,30 @@ def link_status(f)
return '' if f.object.new_record?
'(' + (f.object.link ? _('Up') : _('Down')) + ')'
end

def build_state(build)
build.state ? 'warning' : 'danger'
end

def review_build_button(form, status)
form.submit(_("Build"),
:class => "btn btn-#{status} submit",
:title => (status == 'warning') ? _('Build') : _('Errors occurred, build may fail')
)
end

def supports_power_and_running(host)
return false unless host.compute_resource_id || host.bmc_available?
host.power.ready?
rescue ProxyAPI::ProxyException
false
end

def build_error_link(type, id)
case type
when :templates
link_to_if_authorized(_("Edit"), hash_for_edit_config_template_path(:id => id).merge(:auth_object => id),
:class => "btn btn-default btn-xs pull-right", :title => _("Edit %s" % type) )
end
end
end
13 changes: 8 additions & 5 deletions app/helpers/layout_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ def field(f, attr, options = {})
label = label.present? ? label_tag(attr, "#{label}#{required_mark}".html_safe, :class => "col-md-2 control-label") : ''

label.html_safe +
content_tag(:div, :class => size_class) do
yield.html_safe + help_block.html_safe
end.html_safe + help_inline.html_safe
content_tag(:div, :class => size_class) do
yield.html_safe + help_block.html_safe
end.html_safe + help_inline.html_safe
end.html_safe
end
end
Expand Down Expand Up @@ -297,8 +297,8 @@ def alert_header(text)
"<h4 class='alert-heading'>#{text}</h4>".html_safe
end

def alert_close
'<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>'.html_safe
def alert_close(data_dismiss = 'alert')
"<button type='button' class='close' data-dismiss='#{data_dismiss}' aria-hidden='true'>&times;</button>".html_safe
end

def trunc(text, length = 32)
Expand All @@ -307,4 +307,7 @@ def trunc(text, length = 32)
content_tag(:span, truncate(text, :length => length), options).html_safe
end

def modal_close(data_dismiss = 'modal', text = _('Close'))
button_tag(text, :class => 'btn btn-default', :data => { :dismiss => data_dismiss })
end
end
2 changes: 1 addition & 1 deletion app/models/concerns/fog_extensions/aws/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def poweroff
end

def reset
poweroff && start
poweroff && start
end

def vm_description
Expand Down
4 changes: 2 additions & 2 deletions app/models/concerns/fog_extensions/libvirt/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ def memory=(mem)
end

def reset
poweroff
start
# @TODO: change to poweroff && start upon fix for LibVirt on Fog gem.
service.vm_action(uuid, :reset)
end

def vm_description
Expand Down
6 changes: 6 additions & 0 deletions app/models/concerns/host_common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,12 @@ def available_puppetclasses
environment.puppetclasses - parent_classes
end

def build_status
build_status = HostBuildStatus.new(self)
build_status.check_all_statuses
build_status
end

private

# fall back to our puppet proxy in case our puppet ca is not defined/used.
Expand Down
29 changes: 29 additions & 0 deletions app/models/host/managed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,35 @@ def validate_media?
managed && pxe_build? && build?
end

def available_template_kinds(provisioning = nil)
kinds = if provisioning == 'image'
cr = ComputeResource.find_by_id(self.compute_resource_id)
images = cr.try(:images)
if images.blank?
[TemplateKind.find('finish')]
else
uuid = self.compute_attributes.cr.image_param_name
image_kind = images.find_by_uuid(uuid).try(:user_data) ? 'user_data' : 'finish'
[TemplateKind.find(image_kind)]
end
else
TemplateKind.all
end

kinds.map do |kind|
ConfigTemplate.find_template({ :kind => kind.name,
:operatingsystem_id => operatingsystem_id,
:hostgroup_id => hostgroup_id,
:environment_id => environment_id
})
end.compact
end

def render_template(template)
@host = self
unattended_render(template)
end

private

def lookup_value_match
Expand Down
2 changes: 1 addition & 1 deletion app/services/foreman/access_permissions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@
:"api/v2/hosts" => [:destroy],
:"api/v2/interfaces" => [:destroy]
}
map.permission :build_hosts, {:hosts => [:setBuild, :cancelBuild, :multiple_build, :submit_multiple_build],
map.permission :build_hosts, {:hosts => [:setBuild, :cancelBuild, :multiple_build, :submit_multiple_build, :review_before_build],
:tasks => tasks_ajax_actions,
:"api/v2/tasks" => [:index] }
map.permission :power_hosts, {:hosts => [:power],
Expand Down
60 changes: 60 additions & 0 deletions app/services/host_build_status.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
class HostBuildStatus
attr_reader :host, :state, :errors
delegate :available_template_kinds, :smart_proxies, :to => :host
VALIDATION_TYPES = [:host, :templates, :proxies]

def initialize(host)
@host = host
@errors = {}
@state = true # default to true state
VALIDATION_TYPES.each {|type| @errors[type] = []}
end

def check_all_statuses
host_status
templates_status
smart_proxies_status
end

private

def host_status
return if host.valid?
host.errors.full_messages.each do |error|
fail!(:host, error.to_s, host.to_label)
end
rescue => error
fail!(:host, _('Failed to validate %s: %s') % [host, error.to_s], host.to_label)
end

def templates_status
fail!(:templates, _('No templates found for this host.')) if available_template_kinds.empty?

available_template_kinds.each do |template|
begin
valid_template = host.render_template(template.template)
fail!(:templates, _('Template %s is empty.') % template.name, template.name) if valid_template.blank?
rescue => exception
fail!(:templates, (_('Failure parsing %s: %s.') % [template.name, exception]), template.name)
end
end
end

def smart_proxies_status
fail!(:proxies, _('No smart proxies found.')) if smart_proxies.empty?

smart_proxies.each do |proxy|
begin
errors = proxy.refresh.messages.any?
fail!(:proxies, _('Failure deploying via smart proxy %s: %s.') % [proxy, errors.to_sentence], proxy.id) if errors
rescue => error
fail!(:proxies, _('Error connecting to %s: %s.') % [proxy, error], proxy.id)
end
end
end

def fail!(type, message, id = nil)
@state = false
@errors[type] << {:message => message, :edit_id => id}
end
end
2 changes: 1 addition & 1 deletion app/services/power_manager.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module PowerManager
SUPPORTED_ACTIONS = [N_('start'), N_('stop'), N_('poweroff'), N_('reboot'), N_('reset'), N_('state'),
N_('on'), N_('off'), N_('soft'), N_('cycle'), N_('status')]
N_('on'), N_('off'), N_('soft'), N_('cycle'), N_('status'), N_('ready?')]
end
Loading

0 comments on commit 16fd768

Please sign in to comment.