foreman_remote_execution 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/execution_interface.js +6 -0
  3. data/app/assets/javascripts/template_invocation.js +18 -0
  4. data/app/assets/stylesheets/template_invocation.css.scss +53 -0
  5. data/app/controllers/api/v2/job_invocations_controller.rb +64 -0
  6. data/app/controllers/job_invocations_controller.rb +11 -2
  7. data/app/controllers/template_invocations_controller.rb +16 -0
  8. data/app/helpers/remote_execution_helper.rb +78 -15
  9. data/app/lib/actions/middleware/bind_job_invocation.rb +29 -0
  10. data/app/lib/actions/remote_execution/run_host_job.rb +20 -53
  11. data/app/lib/actions/remote_execution/run_hosts_job.rb +30 -9
  12. data/app/lib/actions/remote_execution/run_proxy_command.rb +64 -3
  13. data/app/models/concerns/foreman_remote_execution/host_extensions.rb +43 -5
  14. data/app/models/concerns/foreman_remote_execution/nic_extensions.rb +25 -0
  15. data/app/models/concerns/foreman_remote_execution/subnet_extensions.rb +10 -0
  16. data/app/models/concerns/foreman_remote_execution/taxonomy_extensions.rb +16 -0
  17. data/app/models/input_template_renderer.rb +5 -1
  18. data/app/models/job_invocation.rb +74 -7
  19. data/app/models/job_invocation_api_composer.rb +62 -0
  20. data/app/models/job_invocation_composer.rb +4 -1
  21. data/app/models/job_template.rb +2 -4
  22. data/app/models/setting/remote_execution.rb +6 -2
  23. data/app/models/target_remote_execution_proxy.rb +4 -0
  24. data/app/models/template_input.rb +14 -2
  25. data/app/models/template_invocation.rb +12 -1
  26. data/app/models/template_invocation_input_value.rb +1 -1
  27. data/app/overrides/execution_interface.rb +9 -0
  28. data/app/overrides/foreman/nics/_execution_interface.html.erb +1 -0
  29. data/app/overrides/foreman/subnets/_rex_tab.html.erb +1 -0
  30. data/app/overrides/foreman/subnets/_rex_tab_pane.html.erb +5 -0
  31. data/app/overrides/subnet_proxies.rb +9 -0
  32. data/app/services/proxy_load_balancer.rb +30 -0
  33. data/app/views/api/v2/job_invocations/base.json.rabl +3 -0
  34. data/app/views/api/v2/job_invocations/create.json.rabl +3 -0
  35. data/app/views/api/v2/job_invocations/index.json.rabl +3 -0
  36. data/app/views/api/v2/job_invocations/main.json.rabl +3 -0
  37. data/app/views/api/v2/job_invocations/show.json.rabl +18 -0
  38. data/app/views/api/v2/job_templates/base.json.rabl +1 -1
  39. data/app/views/job_invocations/_form.html.erb +9 -0
  40. data/app/views/job_invocations/_tab_hosts.html.erb +10 -14
  41. data/app/views/job_invocations/_tab_overview.html.erb +2 -9
  42. data/app/views/job_invocations/show.html.erb +8 -1
  43. data/app/views/job_invocations/show.js.erb +6 -0
  44. data/app/views/template_invocations/_output_line_set.html.erb +7 -0
  45. data/app/views/template_invocations/_refresh.js.erb +7 -0
  46. data/app/views/template_invocations/show.html.erb +38 -0
  47. data/app/views/template_invocations/show.js.erb +16 -0
  48. data/config/routes.rb +4 -0
  49. data/db/migrate/20150826191632_create_target_remote_execution_proxies.rb +14 -0
  50. data/db/migrate/20150903192731_add_execution_to_interface.rb +22 -0
  51. data/doc/source/design/index.md +5 -0
  52. data/doc/source/design/wireframes.pdf +0 -0
  53. data/lib/foreman_remote_execution.rb +1 -1
  54. data/lib/foreman_remote_execution/engine.rb +13 -4
  55. data/lib/foreman_remote_execution/version.rb +1 -1
  56. data/test/factories/foreman_remote_execution_factories.rb +46 -1
  57. data/test/functional/api/v2/job_invocations_controller_test.rb +45 -0
  58. data/test/test_plugin_helper.rb +18 -0
  59. data/test/unit/actions/run_hosts_job_test.rb +13 -8
  60. data/test/unit/actions/run_proxy_command_test.rb +109 -5
  61. data/test/unit/concerns/host_extensions_test.rb +90 -0
  62. data/test/unit/concerns/nic_extensions_test.rb +9 -0
  63. data/test/unit/input_template_renderer_test.rb +24 -10
  64. data/test/unit/job_invocation_api_composer_test.rb +117 -0
  65. data/test/unit/job_invocation_composer_test.rb +16 -1
  66. data/test/unit/job_invocation_test.rb +48 -3
  67. data/test/unit/proxy_load_balancer_test.rb +25 -0
  68. metadata +57 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f8d8e0e19bc92e9e21f80c8a6e3e92be602746bf
4
- data.tar.gz: 0b1fec43cafcb5cf997572113a54b581f715e465
3
+ metadata.gz: f7b17c729ed77837816fc91f385aec89be98be24
4
+ data.tar.gz: 32d6a582df1ffb8e3d20163481176e651070127e
5
5
  SHA512:
6
- metadata.gz: b10f8a9378e50fb25140a93a37141791f5080ee4f92027a005b1e68b8561fbc756d8780b90240f4bddd0cd50b38927f7ed849c94155ae59a3812341b0045dc2d
7
- data.tar.gz: f0e678cf3bd185d40de34820c4d1e35cefc0d7429daedfff0d2440cb7744b49f97925259d74e1cf3743cb02492e7eedc916ca0e96d56543ae9d5055cf6d53f35
6
+ metadata.gz: 733f0235a691db6d71bc9ad72bcf1d3c45db6c95530ed9a57d39203d59401b92858ffb9954c2dccba622ae5a3819147fae35415a1073e1cb920fb138ef89ef46
7
+ data.tar.gz: 35cfdf9e050b3ebe132c955c0f21c41fbd97e33a3dee871f52e556b446a6d64625b66b0c558bd5d01a23465695b0a1cb233d2e39d5ac3f43c48e5aa6793e3d62
@@ -0,0 +1,6 @@
1
+ $(document).on('click', '.interface_execution', function () {
2
+ confirm_flag_change(this, '.interface_execution', __("Another interface is already set as execution. Are you sure you want to use this one instead?"));
3
+
4
+ var modal_form = $('#interfaceModal').find('.modal-body').contents();
5
+ $('#interfaceForms .interface_execution:checked').attr("checked", false);
6
+ });
@@ -31,6 +31,11 @@ function job_invocation_form_binds() {
31
31
  $('#job_template_' + $(this).val()).show();
32
32
  });
33
33
 
34
+ $('input.trigger_mode_selector').on('click', function () {
35
+ $("#trigger_mode_future").hide();
36
+ $('#trigger_mode_' + $(this).val()).show();
37
+ });
38
+
34
39
  $('select#job_invocation_job_name').on('change', refresh_execution_form);
35
40
 
36
41
  $('button#refresh_execution_form').on('click', refresh_execution_form);
@@ -39,3 +44,16 @@ function job_invocation_form_binds() {
39
44
 
40
45
  $('select#targeting_bookmark_id').on('change', refresh_search_query);
41
46
  }
47
+
48
+ function delayed_refresh(url, data){
49
+ setTimeout(function () {
50
+ $.ajax(
51
+ {
52
+ url: url,
53
+ data: data,
54
+ dataType: "script",
55
+ error: function() { $("div.terminal div.printable").append(__('<div class="line error">There was an error while updating the status, try <a href="javascript:window.location.href=window.location.href">refreshing</a> the page</div>')) }
56
+ }
57
+ )
58
+ }, 1000);
59
+ }
@@ -14,3 +14,56 @@ fieldset.provider_form {
14
14
  margin-left: 90px;
15
15
  }
16
16
  }
17
+
18
+ div.terminal {
19
+ display: block;
20
+ padding: 9.5px;
21
+ margin: 0 0 10px;
22
+ font-size: 13px;
23
+ line-height: 1.428571429;
24
+ word-break: break-all;
25
+ word-wrap: break-word;
26
+ color: #B2B2B2;
27
+ background-color: #000000;
28
+ border: 1px solid #000000;
29
+ border-radius: 4px;
30
+ font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
31
+
32
+ div.printable {
33
+ min-height: 50px;
34
+ }
35
+
36
+ div.line.error, div.line.debug {
37
+ color: #a9302a;
38
+ }
39
+
40
+ div.line.stderr {
41
+ background-color: rgba(205, 209, 207, 0.21);
42
+ color: #FFFFFF;
43
+ }
44
+
45
+ div.line span.counter {
46
+ float: left;
47
+ clear: left;
48
+ }
49
+
50
+ div.line div.content {
51
+ position: relative;
52
+ margin-left: 50px;
53
+ }
54
+
55
+ a {
56
+ color: #FFFFFF;
57
+ }
58
+
59
+ a.scroll-link-top {
60
+ position: relative;
61
+ bottom: 10px;
62
+ }
63
+
64
+ a.scroll-link-bottom {
65
+ position: relative;
66
+ z-index: 5;
67
+ }
68
+
69
+ }
@@ -0,0 +1,64 @@
1
+ module Api
2
+ module V2
3
+ class JobInvocationsController < ::Api::V2::BaseController
4
+ include ::Api::Version2
5
+ include ::Api::TaxonomyScope
6
+ include ::Foreman::Renderer
7
+
8
+ before_filter :find_optional_nested_object
9
+ before_filter :find_resource, :only => %w{show update destroy clone}
10
+ before_filter :validate_templates, :only => :create
11
+
12
+ api :GET, "/job_invocations/", N_("List job invocations")
13
+ param_group :search_and_pagination, ::Api::V2::BaseController
14
+ def index
15
+ @job_invocations = resource_scope_for_index
16
+ end
17
+
18
+ api :GET, "/job_invocations/:id", N_("Show job invocation")
19
+ param :id, :identifier, :required => true
20
+ def show
21
+ end
22
+
23
+ def_param_group :job_invocation do
24
+ param :job_invocation, Hash, :required => true, :action_aware => true do
25
+ param :job_name, String, :required => true, :desc => N_("Job name")
26
+ param :template_id, String, :required => false, :desc => N_("If using a specific template, the id of that template.")
27
+ param :targeting_type, String, :required => true, :desc => N_("Invocation type, one of %s") % Targeting::TYPES
28
+ param :inputs, Array, :required => false, :desc => N_("Inputs to use") do
29
+ param :name, String, :required => true
30
+ param :value, String, :required => true
31
+ end
32
+ param :bookmark_id, Integer, :required => false
33
+ param :search_query, Integer, :required => false
34
+ end
35
+ end
36
+
37
+ api :POST, "/job_invocations/", N_("Create a job template")
38
+ param_group :job_invocation, :as => :create
39
+ def create
40
+ composer = JobInvocationApiComposer.new(JobInvocation.new, User.current, params[:job_invocation])
41
+ composer.save!
42
+ ForemanTasks.async_task(::Actions::RemoteExecution::RunHostsJob, composer.job_invocation)
43
+ @job_invocation = composer.job_invocation
44
+ process_response @job_invocation
45
+ end
46
+
47
+ private
48
+
49
+ def validate_templates
50
+ templates = []
51
+ if params[:job_invocation][:template_id]
52
+ templates << JobTemplate.find(params[:job_invocation][:template_id])
53
+ else
54
+ templates = JobTemplate.where(:job_name => params[:job_invocation][:job_name])
55
+ if templates.pluck(:provider_type).uniq.length != templates.length
56
+ raise Foreman::Exception, _("Duplicate remote execution providers found for specified Job, please specify a single template_id.")
57
+ end
58
+ end
59
+
60
+ raise Foreman::Exception, _("No templates associated with specified Job Name") if templates.empty?
61
+ end
62
+ end
63
+ end
64
+ end
@@ -24,9 +24,17 @@ class JobInvocationsController < ApplicationController
24
24
 
25
25
  def create
26
26
  @composer = JobInvocationComposer.new.compose_from_params(params)
27
+ action = ::Actions::RemoteExecution::RunHostsJob
27
28
  if @composer.save
28
- @task = ForemanTasks.async_task(::Actions::RemoteExecution::RunHostsJob, @composer.job_invocation)
29
- redirect_to job_invocation_path(@composer.job_invocation)
29
+ job_invocation = @composer.job_invocation
30
+ if job_invocation.trigger_mode == :future
31
+ ForemanTasks.delay action,
32
+ job_invocation.delay_options,
33
+ job_invocation
34
+ else
35
+ ForemanTasks.async_task(action, job_invocation)
36
+ end
37
+ redirect_to job_invocation_path(job_invocation)
30
38
  else
31
39
  render :action => 'new'
32
40
  end
@@ -34,6 +42,7 @@ class JobInvocationsController < ApplicationController
34
42
 
35
43
  def show
36
44
  @job_invocation = resource_base.find(params[:id])
45
+ @auto_refresh = @job_invocation.last_task.try(:pending?)
37
46
  end
38
47
 
39
48
  def index
@@ -0,0 +1,16 @@
1
+ class TemplateInvocationsController < ApplicationController
2
+ def controller_permission
3
+ 'job_invocations'
4
+ end
5
+
6
+ def show
7
+ @template_invocation_task = ForemanTasks::Task.find(params[:id])
8
+ @template_invocation = @template_invocation_task.locks.where(:resource_type => 'TemplateInvocation').first.try(:resource)
9
+ @host = @template_invocation_task.locks.where(:resource_type => 'Host::Managed').first.try(:resource)
10
+ @auto_refresh = @template_invocation_task.pending?
11
+ @since = params[:since].to_f if params[:since].present?
12
+ @line_sets = @template_invocation_task.main_action.live_output
13
+ @line_sets = @line_sets.drop_while { |o| o['timestamp'].to_f <= @since } if @since
14
+ @line_counter = params[:line_counter].to_i
15
+ end
16
+ end
@@ -11,14 +11,18 @@ module RemoteExecutionHelper
11
11
  options = { :class => 'statistics-pie small', :expandable => true, :border => 0, :show_title => true }
12
12
 
13
13
  if (bulk_task = invocation.last_task)
14
+ failed_tasks = bulk_task.sub_tasks.select { |sub_task| %w(warning error).include? sub_task.result }
15
+ cancelled_tasks, failed_tasks = failed_tasks.partition { |task| task_cancelled? task }
14
16
  success = bulk_task.output['success_count'] || 0
15
- failed = bulk_task.output['failed_count'] || 0
16
- pending = (bulk_task.output['pending_count'] || 0)
17
+ cancelled = cancelled_tasks.length
18
+ failed = failed_tasks.length
19
+ pending = (bulk_task.output['pending_count'] || bulk_task.sub_tasks.count)
17
20
 
18
21
  flot_pie_chart('status', job_invocation_status(invocation),
19
22
  [{:label => _('Success'), :data => success, :color => '#5CB85C'},
20
23
  {:label => _('Failed'), :data => failed, :color => '#D9534F'},
21
- {:label => _('Pending'), :data => pending, :color => '#DEDEDE'}],
24
+ {:label => _('Pending'), :data => pending, :color => '#DEDEDE'},
25
+ {:label => _('Cancelled'), :data => cancelled, :color => '#B7312D'}],
22
26
  options)
23
27
  else
24
28
  content_tag(:h4, job_invocation_status(invocation))
@@ -28,11 +32,18 @@ module RemoteExecutionHelper
28
32
  def job_invocation_status(invocation)
29
33
  if invocation.last_task.blank?
30
34
  _('Job not started yet 0%')
35
+ elsif invocation.last_task.state == 'scheduled'
36
+ _('Job set to execute at %s') % invocation.last_task.start_at
37
+ elsif invocation.last_task.state == 'stopped' && invocation.last_task.result == 'error'
38
+ invocation.last_task.execution_plan.errors.map(&:message).join("\n")
31
39
  else
32
40
  label = invocation.last_task.pending ? _('Running') : _('Finished')
33
41
  label + ' ' + (invocation.last_task.progress * 100).to_i.to_s + '%'
34
42
  end
43
+ end
35
44
 
45
+ def task_cancelled?(task)
46
+ task.execution_plan.errors.map(&:exception).any? { |exception| exception.class == ::ForemanTasks::Task::TaskCancelledException }
36
47
  end
37
48
 
38
49
  def host_counter(label, count)
@@ -42,18 +53,39 @@ module RemoteExecutionHelper
42
53
  end
43
54
 
44
55
  def template_invocation_status(task)
45
- case task.result
46
- when 'warning', 'error'
47
- content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-exclamation-sign') + content_tag(:span, _('failed'), :class => 'status-error')
48
- when 'success'
49
- content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-ok-sign') + content_tag(:span, _('success'), :class => 'status-ok')
50
- when 'pending'
51
- content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-question-sign') + content_tag(:span, _('pending'))
52
- else
53
- task.result
56
+ if task.nil?
57
+ content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-question-sign') + content_tag(:span, _('N/A'))
58
+ else
59
+ case task.result
60
+ when 'warning', 'error'
61
+ if task_cancelled?(task)
62
+ content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-warning-sign') + content_tag(:span, _('cancelled'), :class => 'status-error')
63
+ else
64
+ content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-exclamation-sign') + content_tag(:span, _('failed'), :class => 'status-error')
65
+ end
66
+ when 'success'
67
+ content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-ok-sign') + content_tag(:span, _('success'), :class => 'status-ok')
68
+ when 'pending'
69
+ content_tag(:i, '&nbsp'.html_safe, :class => 'glyphicon glyphicon-question-sign') + content_tag(:span, _('pending'))
70
+ else
71
+ task.result
72
+ end
54
73
  end
55
74
  end
56
75
 
76
+ def template_invocation_actions(task, host)
77
+ if task.nil?
78
+ []
79
+ else
80
+ [display_link_if_authorized(_("Details"), hash_for_template_invocation_path(:id => task).merge(:auth_object => host, :permission => :view_foreman_tasks))]
81
+ end
82
+ end
83
+
84
+ def remote_execution_provider_for(task)
85
+ template_invocation = task.locks.where(:resource_type => 'TemplateInvocation').first.try(:resource) unless task.nil?
86
+ template_invocation.nil? ? _('N/A') : _(RemoteExecutionProvider.provider_for(template_invocation.template.provider_type))
87
+ end
88
+
57
89
  def job_invocation_task_buttons(task)
58
90
  buttons = []
59
91
  buttons << link_to(_('Refresh'), {}, :class => 'btn btn-default', :title => _('Refresh this page'))
@@ -79,11 +111,28 @@ module RemoteExecutionHelper
79
111
  :disabled => !task.cancellable?,
80
112
  :method => :post)
81
113
  end
82
- return button_group(*buttons)
114
+ return buttons
115
+ end
116
+
117
+ def template_invocation_task_buttons(task)
118
+ buttons = []
119
+ if authorized_for(:permission => :view_foreman_tasks, :auth_object => task)
120
+ buttons << link_to(_("Task Details"), foreman_tasks_task_path(task),
121
+ :class => "btn btn-default",
122
+ :title => _('See the task details'))
123
+ end
124
+ if authorized_for(:permission => :edit_foreman_tasks, :auth_object => task)
125
+ buttons << link_to(_("Cancel Job"), cancel_foreman_tasks_task_path(task),
126
+ :class => "btn btn-danger",
127
+ :title => _('Try to cancel the job on a host'),
128
+ :disabled => !task.cancellable?,
129
+ :method => :post)
130
+ end
131
+ return buttons
83
132
  end
84
133
 
85
134
  def link_to_invocation_task_if_authorized(invocation)
86
- if invocation.last_task.present?
135
+ if invocation.last_task.present? && invocation.last_task.state != 'scheduled'
87
136
  link_to_if_authorized job_invocation_status(invocation),
88
137
  hash_for_foreman_tasks_task_path(invocation.last_task).merge(:auth_object => invocation.last_task, :permission => :view_foreman_tasks)
89
138
  else
@@ -93,6 +142,20 @@ module RemoteExecutionHelper
93
142
 
94
143
  def invocation_count(invocation, options = {})
95
144
  options = { :unknown_string => 'N/A' }.merge(options)
96
- (invocation.last_task.try(:output) || {}).fetch(options[:output_key], options[:unknown_string])
145
+ if invocation.last_task.nil? || invocation.last_task.state != 'scheduled'
146
+ (invocation.last_task.try(:output) || {}).fetch(options[:output_key], options[:unknown_string])
147
+ else
148
+ options[:unknown_string]
149
+ end
150
+ end
151
+
152
+ def preview_box(template_invocation, target)
153
+ renderer = InputTemplateRenderer.new(template_invocation.template, target, template_invocation)
154
+ if (preview = renderer.preview)
155
+ content_tag :pre, preview
156
+ else
157
+ alert :class => "alert-block alert-danger base in fade has-error",
158
+ :text => renderer.error_message.html_safe
159
+ end
97
160
  end
98
161
  end
@@ -0,0 +1,29 @@
1
+ module Actions
2
+ module Middleware
3
+
4
+ class BindJobInvocation < ::Dynflow::Middleware
5
+
6
+ def delay(*args)
7
+ _schedule_options, job_invocation = args
8
+ pass(*args).tap { bind(job_invocation) }
9
+ end
10
+
11
+ def plan(*args)
12
+ job_invocation = args.first
13
+ pass(*args).tap { bind(job_invocation) }
14
+ end
15
+
16
+ private
17
+
18
+ def task
19
+ @task ||= ForemanTasks::Task::DynflowTask.find_by_external_id!(action.execution_plan_id)
20
+ end
21
+
22
+ def bind(job_invocation)
23
+ job_invocation.update_attribute :last_task_id, task.id if job_invocation.last_task_id != task.id
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+ end
@@ -8,12 +8,17 @@ module Actions
8
8
 
9
9
  include ::Dynflow::Action::Cancellable
10
10
 
11
- def plan(job_invocation, host)
11
+ def plan(job_invocation, host, template_invocation, proxy, connection_options = {})
12
12
  action_subject(host, :job_name => job_invocation.job_name)
13
-
14
- template_invocation = find_template_invocation(job_invocation, host)
15
13
  hostname = find_ip_or_hostname(host)
16
- proxy = find_proxy(template_invocation, host)
14
+
15
+ raise _("Could not use any template used in the job invocation") if template_invocation.blank?
16
+
17
+ settings = { :global_proxy => 'remote_execution_global_proxy',
18
+ :fallback_proxy => 'remote_execution_fallback_proxy' }
19
+
20
+ raise _("Could not use any proxy. Consider configuring %{global_proxy} " +
21
+ "or %{fallback_proxy} in settings") % settings if proxy.blank?
17
22
 
18
23
  renderer = InputTemplateRenderer.new(template_invocation.template, host, template_invocation)
19
24
  script = renderer.render
@@ -22,71 +27,33 @@ module Actions
22
27
  link!(job_invocation)
23
28
  link!(template_invocation)
24
29
 
25
- plan_action(RunProxyCommand, proxy, hostname, script)
30
+ plan_action(RunProxyCommand, proxy, hostname, script, { :connection_options => connection_options })
26
31
  end
27
32
 
28
33
  def humanized_output
29
- host_run_action = planned_actions(RunProxyCommand).first
30
- proxy_output = host_run_action && host_run_action.output[:proxy_output]
31
- return unless proxy_output
32
- output = []
33
- if proxy_output[:result]
34
- output << proxy_output[:result].map { |o| o[:output] }.join("")
35
- end
36
- output << "Exit status: #{host_run_action.exit_status}" if host_run_action.exit_status
37
- return output.join("\n")
34
+ live_output.map { |line| line['output'].chomp }.join("\n")
35
+ end
36
+
37
+ def live_output
38
+ planned_actions(RunProxyCommand).first.live_output
38
39
  end
39
40
 
40
41
  def humanized_name
41
42
  _('Run %{job_name} on %{host}') % { :job_name => input[:job_name], :host => input[:host][:name] }
42
43
  end
43
44
 
44
- def find_template_invocation(job_invocation, host)
45
- providers = available_providers(job_invocation, host)
46
- providers.each do |provider|
47
- job_invocation.template_invocations.each do |template_invocation|
48
- if template_invocation.template.provider_type == provider
49
- return template_invocation
50
- end
45
+ def find_ip_or_hostname(host)
46
+ %w(execution primary provision).each do |flag|
47
+ if host.send("#{flag}_interface") && host.send("#{flag}_interface").ip.present?
48
+ return host.execution_interface.ip
51
49
  end
52
50
  end
53
51
 
54
- raise _("Could not use any template used in the job invocation")
55
- end
56
-
57
- def find_ip_or_hostname(host)
58
52
  host.interfaces.each do |interface|
59
53
  return interface.ip unless interface.ip.blank?
60
54
  end
61
- return host.name
62
- end
63
-
64
- def available_providers(job_invocation, host)
65
- # TODO: determine from the host and job_invocation details
66
- return ['Ssh']
67
- end
68
-
69
- def find_proxy(template_invocation, host)
70
- provider = template_invocation.template.provider_type.to_s
71
- all_host_proxies(host).each do |proxies|
72
- if proxy = proxies.joins(:features).where("features.name = ?", provider).first
73
- return proxy
74
- end
75
- end
76
- raise _("Could not use any proxy: assign a proxy with provider '%{provider}' to the host or set '%{global_proxy_setting}' in settings") %\
77
- { :provider => provider, :global_proxy_setting => 'remote_execution_global_proxy' }
78
- end
79
55
 
80
- def all_host_proxies(host)
81
- Enumerator.new do |e|
82
- host.interfaces.each do |interface|
83
- if interface.subnet
84
- e << ::SmartProxy.where(:id => interface.subnet.proxies.map(&:id))
85
- end
86
- end
87
- e << host.smart_proxies
88
- e << ::SmartProxy.authorized if Setting[:remote_execution_global_proxy]
89
- end
56
+ return host.fqdn
90
57
  end
91
58
  end
92
59
  end